ETH Price: $3,017.28 (-2.36%)

Token

OptimisticPuerco (OPPuerco)
 

Overview

Max Total Supply

100 OPPuerco

Holders

3,690

Market

Price

$0.00 @ 0.000000 ETH

Onchain Market Cap

$0.00

Circulating Supply Market Cap

-

Other Info

Token Contract (WITH 18 Decimals)

Balance
0.0002 OPPuerco

Value
$0.00
0xf1b98463d6574c998f03e6edf6d7b4e5f917f915
Loading...
Loading
Loading...
Loading
Loading...
Loading

Click here to update the token information / general information

Contract Source Code Verified (Exact Match)

Contract Name:
FullFeatureToken

Compiler Version
v0.8.17+commit.8df45f5f

Optimization Enabled:
Yes with 1337 runs

Other Settings:
default evmVersion, GNU GPLv3 license

Contract Source Code (Solidity Standard Json-Input format)

File 1 of 10 : Ownable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)

pragma solidity ^0.8.0;

import "../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.
 *
 * By default, the owner account will be the one that deploys the contract. 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;

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

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        _transferOwnership(_msgSender());
    }

    /**
     * @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 {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
    }

    /**
     * @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 {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        _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 2 of 10 : Pausable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol)

pragma solidity ^0.8.0;

import "../utils/Context.sol";

/**
 * @dev Contract module which allows children to implement an emergency stop
 * mechanism that can be triggered by an authorized account.
 *
 * This module is used through inheritance. It will make available the
 * modifiers `whenNotPaused` and `whenPaused`, which can be applied to
 * the functions of your contract. Note that they will not be pausable by
 * simply including this module, only once the modifiers are put in place.
 */
abstract contract Pausable is Context {
    /**
     * @dev Emitted when the pause is triggered by `account`.
     */
    event Paused(address account);

    /**
     * @dev Emitted when the pause is lifted by `account`.
     */
    event Unpaused(address account);

    bool private _paused;

    /**
     * @dev Initializes the contract in unpaused state.
     */
    constructor() {
        _paused = false;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is not paused.
     *
     * Requirements:
     *
     * - The contract must not be paused.
     */
    modifier whenNotPaused() {
        _requireNotPaused();
        _;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is paused.
     *
     * Requirements:
     *
     * - The contract must be paused.
     */
    modifier whenPaused() {
        _requirePaused();
        _;
    }

    /**
     * @dev Returns true if the contract is paused, and false otherwise.
     */
    function paused() public view virtual returns (bool) {
        return _paused;
    }

    /**
     * @dev Throws if the contract is paused.
     */
    function _requireNotPaused() internal view virtual {
        require(!paused(), "Pausable: paused");
    }

    /**
     * @dev Throws if the contract is not paused.
     */
    function _requirePaused() internal view virtual {
        require(paused(), "Pausable: not paused");
    }

    /**
     * @dev Triggers stopped state.
     *
     * Requirements:
     *
     * - The contract must not be paused.
     */
    function _pause() internal virtual whenNotPaused {
        _paused = true;
        emit Paused(_msgSender());
    }

    /**
     * @dev Returns to normal state.
     *
     * Requirements:
     *
     * - The contract must be paused.
     */
    function _unpause() internal virtual whenPaused {
        _paused = false;
        emit Unpaused(_msgSender());
    }
}

File 3 of 10 : ERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol)

pragma solidity ^0.8.0;

import "./IERC20.sol";
import "./extensions/IERC20Metadata.sol";
import "../../utils/Context.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}.
 * For a generic mechanism see {ERC20PresetMinterPauser}.
 *
 * 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.
 *
 * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
 * functions have been added to mitigate the well-known issues around setting
 * allowances. See {IERC20-approve}.
 */
contract ERC20 is Context, IERC20, IERC20Metadata {
    mapping(address => uint256) private _balances;

    mapping(address => mapping(address => 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 override returns (string memory) {
        return _name;
    }

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

    /**
     * @dev See {IERC20-totalSupply}.
     */
    function totalSupply() public view virtual override returns (uint256) {
        return _totalSupply;
    }

    /**
     * @dev See {IERC20-balanceOf}.
     */
    function balanceOf(address account) public view virtual override 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 `amount`.
     */
    function transfer(address to, uint256 amount) public virtual override returns (bool) {
        address owner = _msgSender();
        _transfer(owner, to, amount);
        return true;
    }

    /**
     * @dev See {IERC20-allowance}.
     */
    function allowance(address owner, address spender) public view virtual override returns (uint256) {
        return _allowances[owner][spender];
    }

    /**
     * @dev See {IERC20-approve}.
     *
     * NOTE: If `amount` 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 amount) public virtual override returns (bool) {
        address owner = _msgSender();
        _approve(owner, spender, amount);
        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 `amount`.
     * - the caller must have allowance for ``from``'s tokens of at least
     * `amount`.
     */
    function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {
        address spender = _msgSender();
        _spendAllowance(from, spender, amount);
        _transfer(from, to, amount);
        return true;
    }

    /**
     * @dev Atomically increases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
        address owner = _msgSender();
        _approve(owner, spender, allowance(owner, spender) + addedValue);
        return true;
    }

    /**
     * @dev Atomically decreases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `spender` must have allowance for the caller of at least
     * `subtractedValue`.
     */
    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
        address owner = _msgSender();
        uint256 currentAllowance = allowance(owner, spender);
        require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
        unchecked {
            _approve(owner, spender, currentAllowance - subtractedValue);
        }

        return true;
    }

    /**
     * @dev Moves `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.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `from` must have a balance of at least `amount`.
     */
    function _transfer(address from, address to, uint256 amount) internal virtual {
        require(from != address(0), "ERC20: transfer from the zero address");
        require(to != address(0), "ERC20: transfer to the zero address");

        _beforeTokenTransfer(from, to, amount);

        uint256 fromBalance = _balances[from];
        require(fromBalance >= amount, "ERC20: transfer amount exceeds balance");
        unchecked {
            _balances[from] = fromBalance - amount;
            // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by
            // decrementing then incrementing.
            _balances[to] += amount;
        }

        emit Transfer(from, to, amount);

        _afterTokenTransfer(from, to, amount);
    }

    /** @dev Creates `amount` tokens and assigns them to `account`, increasing
     * the total supply.
     *
     * Emits a {Transfer} event with `from` set to the zero address.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     */
    function _mint(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: mint to the zero address");

        _beforeTokenTransfer(address(0), account, amount);

        _totalSupply += amount;
        unchecked {
            // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.
            _balances[account] += amount;
        }
        emit Transfer(address(0), account, amount);

        _afterTokenTransfer(address(0), account, amount);
    }

    /**
     * @dev Destroys `amount` tokens from `account`, reducing the
     * total supply.
     *
     * Emits a {Transfer} event with `to` set to the zero address.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     * - `account` must have at least `amount` tokens.
     */
    function _burn(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: burn from the zero address");

        _beforeTokenTransfer(account, address(0), amount);

        uint256 accountBalance = _balances[account];
        require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
        unchecked {
            _balances[account] = accountBalance - amount;
            // Overflow not possible: amount <= accountBalance <= totalSupply.
            _totalSupply -= amount;
        }

        emit Transfer(account, address(0), amount);

        _afterTokenTransfer(account, address(0), amount);
    }

    /**
     * @dev Sets `amount` 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.
     */
    function _approve(address owner, address spender, uint256 amount) internal virtual {
        require(owner != address(0), "ERC20: approve from the zero address");
        require(spender != address(0), "ERC20: approve to the zero address");

        _allowances[owner][spender] = amount;
        emit Approval(owner, spender, amount);
    }

    /**
     * @dev Updates `owner` s allowance for `spender` based on spent `amount`.
     *
     * Does not update the allowance amount in case of infinite allowance.
     * Revert if not enough allowance is available.
     *
     * Might emit an {Approval} event.
     */
    function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {
        uint256 currentAllowance = allowance(owner, spender);
        if (currentAllowance != type(uint256).max) {
            require(currentAllowance >= amount, "ERC20: insufficient allowance");
            unchecked {
                _approve(owner, spender, currentAllowance - amount);
            }
        }
    }

    /**
     * @dev Hook that is called before any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * will be transferred to `to`.
     * - when `from` is zero, `amount` tokens will be minted for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens will be burned.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}

    /**
     * @dev Hook that is called after any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * has been transferred to `to`.
     * - when `from` is zero, `amount` tokens have been minted for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens have been burned.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}
}

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

pragma solidity ^0.8.0;

/**
 * @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 amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

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

    /**
     * @dev Moves `amount` 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 amount) 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 `amount` 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 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `from` to `to` using the
     * allowance mechanism. `amount` 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 amount) external returns (bool);
}

File 5 of 10 : ERC20Burnable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)

pragma solidity ^0.8.0;

import "../ERC20.sol";
import "../../../utils/Context.sol";

/**
 * @dev Extension of {ERC20} that allows token holders to destroy both their own
 * tokens and those that they have an allowance for, in a way that can be
 * recognized off-chain (via event analysis).
 */
abstract contract ERC20Burnable is Context, ERC20 {
    /**
     * @dev Destroys `amount` tokens from the caller.
     *
     * See {ERC20-_burn}.
     */
    function burn(uint256 amount) public virtual {
        _burn(_msgSender(), amount);
    }

    /**
     * @dev Destroys `amount` tokens from `account`, deducting from the caller's
     * allowance.
     *
     * See {ERC20-_burn} and {ERC20-allowance}.
     *
     * Requirements:
     *
     * - the caller must have allowance for ``accounts``'s tokens of at least
     * `amount`.
     */
    function burnFrom(address account, uint256 amount) public virtual {
        _spendAllowance(account, _msgSender(), amount);
        _burn(account, amount);
    }
}

File 6 of 10 : ERC20Pausable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/ERC20Pausable.sol)

pragma solidity ^0.8.0;

import "../ERC20.sol";
import "../../../security/Pausable.sol";

/**
 * @dev ERC20 token with pausable token transfers, minting and burning.
 *
 * Useful for scenarios such as preventing trades until the end of an evaluation
 * period, or having an emergency switch for freezing all token transfers in the
 * event of a large bug.
 *
 * IMPORTANT: This contract does not include public pause and unpause functions. In
 * addition to inheriting this contract, you must define both functions, invoking the
 * {Pausable-_pause} and {Pausable-_unpause} internal functions, with appropriate
 * access control, e.g. using {AccessControl} or {Ownable}. Not doing so will
 * make the contract unpausable.
 */
abstract contract ERC20Pausable is ERC20, Pausable {
    /**
     * @dev See {ERC20-_beforeTokenTransfer}.
     *
     * Requirements:
     *
     * - the contract must not be paused.
     */
    function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual override {
        super._beforeTokenTransfer(from, to, amount);

        require(!paused(), "ERC20Pausable: token transfer while paused");
    }
}

File 7 of 10 : IERC20Metadata.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)

pragma solidity ^0.8.0;

import "../IERC20.sol";

/**
 * @dev Interface for the optional metadata functions from the ERC20 standard.
 *
 * _Available since v4.1._
 */
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 8 of 10 : Context.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

pragma solidity ^0.8.0;

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

File 9 of 10 : FullFeatureToken.sol
// SPDX-License-Identifier: GPL-3.0

pragma solidity 0.8.17;

/**
 * Security notice: Refer to our product documentation for security advice
 * around the configuration of our smart contracts https://docs.bitbond.com/
 */

import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";
import { ERC20Burnable } from "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol";
import { ERC20Pausable } from "@openzeppelin/contracts/token/ERC20/extensions/ERC20Pausable.sol";
import { LibCommon } from "./lib/LibCommon.sol";

contract FullFeatureToken is ERC20, ERC20Burnable, ERC20Pausable, Ownable {
  uint256 private constant MAX_BPS_AMOUNT = 10_000;
  uint256 private constant MAX_ALLOWED_BPS = 5_000;
  /// @notice mapping of blacklisted addresses to a boolean
  mapping(address => bool) private _isBlacklisted;
  /// @notice mapping of whitelisted addresses to a boolean
  mapping(address => bool) public whitelist;
  /// @notice array holding all whitelisted addresses
  address[] public whitelistedAddresses;
  /// @notice support for attaching of documentation for security tokens
  string public initialDocumentUri;
  /// @notice the security token documentation
  string public documentUri;
  /// @notice initial number of tokens which will be minted during initialization
  uint256 public immutable initialSupply;
  /// @notice initial max amount of tokens allowed per wallet
  uint256 public immutable initialMaxTokenAmountPerAddress;
  /// @notice max amount of tokens allowed per wallet
  uint256 public maxTokenAmountPerAddress;
  /// @notice set of features supported by the token
  struct ERC20ConfigProps {
    bool _isMintable;
    bool _isBurnable;
    bool _isPausable;
    bool _isBlacklistEnabled;
    bool _isDocumentAllowed;
    bool _isWhitelistEnabled;
    bool _isMaxAmountOfTokensSet;
    bool _isForceTransferAllowed;
    bool _isTaxable;
    bool _isDeflationary;
  }
  /// @notice features of the token
  ERC20ConfigProps private configProps;
  /// @notice owner of the contract
  address public immutable initialTokenOwner;
  /// @notice number of decimals of the token
  uint8 private immutable _decimals;
  address public taxAddress;
  uint256 public taxBPS;
  uint256 public deflationBPS;

  /// @notice emitted when an address is blacklisted
  event UserBlacklisted(address indexed addr);
  /// @notice emitted when an address is unblacklisted
  event UserUnBlacklisted(address indexed addr);
  /// @notice emitted when a new document is set for the security token
  event DocumentUriSet(string newDocUri);
  /// @notice emitted when a new max amount of tokens per wallet is set
  event MaxTokenAmountPerSet(uint256 newMaxTokenAmount);
  /// @notice emitted when a new whitelist is set
  event UsersWhitelisted(address[] updatedAddresses);
  /// @notice emitted when a new tax address or taxBPS is set
  event TaxConfigSet(address indexed _taxAddress, uint256 indexed _taxBPS);
  /// @notice emitted when a new deflationBPS is set
  event DeflationConfigSet(uint256 indexed _deflationBPS);

  /// @notice raised when the amount sent is zero
  error InvalidMaxTokenAmount(uint256 maxTokenAmount);
  /// @notice raised when the decimals are not in the range 0 - 18
  error InvalidDecimals(uint8 decimals);
  /// @notice raised when setting maxTokenAmount less than current
  error MaxTokenAmountPerAddrLtPrevious();
  /// @notice raised when blacklisting is not enabled
  error BlacklistNotEnabled();
  /// @notice raised when the address is already blacklisted
  error AddrAlreadyBlacklisted(address addr);
  /// @notice raised when the address is already unblacklisted
  error AddrAlreadyUnblacklisted(address addr);
  /// @notice raised when attempting to blacklist a whitelisted address
  error CannotBlacklistWhitelistedAddr(address addr);
  /// @notice raised when a recipient address is blacklisted
  error RecipientBlacklisted(address addr);
  /// @notice raised when a sender address is blacklisted
  error SenderBlacklisted(address addr);
  /// @notice raised when a recipient address is not whitelisted
  error RecipientNotWhitelisted(address addr);
  /// @notice raised when a sender address is not whitelisted
  error SenderNotWhitelisted(address addr);
  /// @notice raised when recipient balance exceeds maxTokenAmountPerAddress
  error DestBalanceExceedsMaxAllowed(address addr);
  /// @notice raised minting is not enabled
  error MintingNotEnabled();
  /// @notice raised when burning is not enabled
  error BurningNotEnabled();
  /// @notice raised when pause is not enabled
  error PausingNotEnabled();
  /// @notice raised when whitelist is not enabled
  error WhitelistNotEnabled();
  /// @notice raised when attempting to whitelist a blacklisted address
  error CannotWhitelistBlacklistedAddr(address addr);
  /// @notice raised when trying to set a document URI when not allowed
  error DocumentUriNotAllowed();
  /// @notice raised when trying to set a max amount of tokens when not allowed
  error MaxTokenAmountNotAllowed();
  /// @notice raised when trying to set a tax address or taxBPS when not allowed
  error TokenIsNotTaxable();
  /// @notice raised when trying to set a deflationBPS when not allowed
  error TokenIsNotDeflationary();
  /// @notice raised when trying to set an invalid taxBPS
  error InvalidTaxBPS(uint256 bps);
  /// @notice raised when trying to set and invalid deflationBPS
  error InvalidDeflationBPS(uint256 bps);

  /**
   * @notice modifier for validating if transfer is possible and valid
   * @param sender the sender of the transaction
   * @param recipient the recipient of the transaction
   */
  modifier validateTransfer(address sender, address recipient) {
    if (isWhitelistEnabled()) {
      if (!whitelist[sender]) {
        revert SenderNotWhitelisted(sender);
      }
      if (!whitelist[recipient]) {
        revert RecipientNotWhitelisted(recipient);
      }
      if (
        sender != msg.sender && msg.sender != owner() && !whitelist[msg.sender]
      ) {
        revert SenderNotWhitelisted(msg.sender);
      }
    }
    if (isBlacklistEnabled()) {
      if (_isBlacklisted[sender]) {
        revert SenderBlacklisted(sender);
      }
      if (_isBlacklisted[recipient]) {
        revert RecipientBlacklisted(recipient);
      }
      if (
        sender != msg.sender &&
        msg.sender != owner() &&
        _isBlacklisted[msg.sender]
      ) {
        revert SenderBlacklisted(msg.sender);
      }
    }
    _;
  }

  constructor(
    string memory name_,
    string memory symbol_,
    uint256 initialSupplyToSet,
    uint8 decimalsToSet,
    address tokenOwner,
    ERC20ConfigProps memory customConfigProps,
    uint256 maxTokenAmount,
    string memory newDocumentUri,
    address _taxAddress,
    uint256 _taxBPS,
    uint256 _deflationBPS
  ) ERC20(name_, symbol_) {
    if (customConfigProps._isMaxAmountOfTokensSet) {
      if (maxTokenAmount == 0) {
        revert InvalidMaxTokenAmount(maxTokenAmount);
      }
    }
    if (decimalsToSet > 18) {
      revert InvalidDecimals(decimalsToSet);
    }
    if (customConfigProps._isTaxable) {
      if (_taxBPS > MAX_ALLOWED_BPS) {
        revert InvalidTaxBPS(_taxBPS);
      }
      LibCommon.validateAddress(_taxAddress);
      taxAddress = _taxAddress;
      taxBPS = _taxBPS;
    }
    if (customConfigProps._isDeflationary) {
      if (_deflationBPS > MAX_ALLOWED_BPS) {
        revert InvalidDeflationBPS(_deflationBPS);
      }
      deflationBPS = _deflationBPS;
    }
    LibCommon.validateAddress(tokenOwner);

    initialSupply = initialSupplyToSet;
    initialMaxTokenAmountPerAddress = maxTokenAmount;
    initialDocumentUri = newDocumentUri;
    initialTokenOwner = tokenOwner;
    _decimals = decimalsToSet;
    configProps = customConfigProps;
    documentUri = newDocumentUri;
    maxTokenAmountPerAddress = maxTokenAmount;

    if (initialSupplyToSet != 0) {
      _mint(tokenOwner, initialSupplyToSet * 10 ** decimalsToSet);
    }

    if (tokenOwner != msg.sender) {
      transferOwnership(tokenOwner);
    }
  }

  /**
   * @notice hook called before any transfer of tokens. This includes minting and burning
   * imposed by the ERC20 standard
   * @param from - address of the sender
   * @param to - address of the recipient
   * @param amount - amount of tokens to transfer
   */
  function _beforeTokenTransfer(
    address from,
    address to,
    uint256 amount
  ) internal virtual override(ERC20, ERC20Pausable) {
    super._beforeTokenTransfer(from, to, amount);
  }

  /// @notice method which checks if the token is pausable
  function isPausable() public view returns (bool) {
    return configProps._isPausable;
  }

  /// @notice method which checks if the token is mintable
  function isMintable() public view returns (bool) {
    return configProps._isMintable;
  }

  /// @notice method which checks if the token is burnable
  function isBurnable() public view returns (bool) {
    return configProps._isBurnable;
  }

  /// @notice method which checks if the token supports blacklisting
  function isBlacklistEnabled() public view returns (bool) {
    return configProps._isBlacklistEnabled;
  }

  /// @notice method which checks if the token supports whitelisting
  function isWhitelistEnabled() public view returns (bool) {
    return configProps._isWhitelistEnabled;
  }

  /// @notice method which checks if the token supports max amount of tokens per wallet
  function isMaxAmountOfTokensSet() public view returns (bool) {
    return configProps._isMaxAmountOfTokensSet;
  }

  /// @notice method which checks if the token supports documentUris
  function isDocumentUriAllowed() public view returns (bool) {
    return configProps._isDocumentAllowed;
  }

  /// @notice method which checks if the token supports force transfers
  function isForceTransferAllowed() public view returns (bool) {
    return configProps._isForceTransferAllowed;
  }

  /// @notice method which returns the number of decimals for the token
  function decimals() public view virtual override returns (uint8) {
    return _decimals;
  }

  /// @notice method which checks if the token is taxable
  function isTaxable() public view returns (bool) {
    return configProps._isTaxable;
  }

  /// @notice method which checks if the token is deflationary
  function isDeflationary() public view returns (bool) {
    return configProps._isDeflationary;
  }

  /**
   * @notice which returns an array of all the whitelisted addresses
   * @return whitelistedAddresses array of all the whitelisted addresses
   */
  function getWhitelistedAddresses() external view returns (address[] memory) {
    return whitelistedAddresses;
  }

  /**
   * @notice method which allows the owner to set a documentUri
   * @param newDocumentUri - the new documentUri
   * @dev only callable by the owner
   */
  function setDocumentUri(
    string memory newDocumentUri
  ) external onlyOwner whenNotPaused {
    if (!isDocumentUriAllowed()) {
      revert DocumentUriNotAllowed();
    }
    documentUri = newDocumentUri;
    emit DocumentUriSet(newDocumentUri);
  }

  /**
   * @notice method which allows the owner to set a max amount of tokens per wallet
   * @param newMaxTokenAmount - the new max amount of tokens per wallet
   * @dev only callable by the owner
   */
  function setMaxTokenAmountPerAddress(
    uint256 newMaxTokenAmount
  ) external onlyOwner whenNotPaused {
    if (!isMaxAmountOfTokensSet()) {
      revert MaxTokenAmountNotAllowed();
    }
    if (newMaxTokenAmount <= maxTokenAmountPerAddress) {
      revert MaxTokenAmountPerAddrLtPrevious();
    }

    maxTokenAmountPerAddress = newMaxTokenAmount;
    emit MaxTokenAmountPerSet(newMaxTokenAmount);
  }

  /**
   * @notice method which allows the owner to blacklist an address
   * @param addr - the address to blacklist
   * @dev only callable by the owner
   * @dev only callable if the token is not paused
   * @dev only callable if the token supports blacklisting
   * @dev only callable if the address is not already blacklisted
   * @dev only callable if the address is not whitelisted
   */
  function blackList(address addr) external onlyOwner whenNotPaused {
    LibCommon.validateAddress(addr);
    if (!isBlacklistEnabled()) {
      revert BlacklistNotEnabled();
    }
    if (_isBlacklisted[addr]) {
      revert AddrAlreadyBlacklisted(addr);
    }
    if (isWhitelistEnabled() && whitelist[addr]) {
      revert CannotBlacklistWhitelistedAddr(addr);
    }

    _isBlacklisted[addr] = true;
    emit UserBlacklisted(addr);
  }

  /**
   * @notice method which allows the owner to unblacklist an address
   * @param addr - the address to unblacklist
   * @dev only callable by the owner
   * @dev only callable if the token is not paused
   * @dev only callable if the token supports blacklisting
   * @dev only callable if the address is blacklisted
   */
  function removeFromBlacklist(address addr) external onlyOwner whenNotPaused {
    LibCommon.validateAddress(addr);
    if (!isBlacklistEnabled()) {
      revert BlacklistNotEnabled();
    }
    if (!_isBlacklisted[addr]) {
      revert AddrAlreadyUnblacklisted(addr);
    }
    delete _isBlacklisted[addr];
    emit UserUnBlacklisted(addr);
  }

  /**
   * @notice method which allows the owner to set the tax config
   * @param _taxAddress - the new taxAddress
   * @param _taxBPS - the new taxBPS
   */
  function setTaxConfig(
    address _taxAddress,
    uint256 _taxBPS
  ) external onlyOwner whenNotPaused {
    if (!isTaxable()) {
      revert TokenIsNotTaxable();
    }
    if (_taxBPS > MAX_ALLOWED_BPS) {
      revert InvalidTaxBPS(_taxBPS);
    }
    LibCommon.validateAddress(_taxAddress);
    taxAddress = _taxAddress;
    taxBPS = _taxBPS;
    emit TaxConfigSet(_taxAddress, _taxBPS);
  }

  /**
   * @notice method which allows the owner to set the deflation config
   * @param _deflationBPS - the new deflationBPS
   */
  function setDeflationConfig(
    uint256 _deflationBPS
  ) external onlyOwner whenNotPaused {
    if (!isDeflationary()) {
      revert TokenIsNotDeflationary();
    }
    if (_deflationBPS > MAX_ALLOWED_BPS) {
      revert InvalidDeflationBPS(_deflationBPS);
    }
    deflationBPS = _deflationBPS;
    emit DeflationConfigSet(_deflationBPS);
  }

  /**
   * @notice method which allows to transfer a predefined amount of tokens to a predefined address
   * @param to - the address to transfer the tokens to
   * @param amount - the amount of tokens to transfer
   * @return true if the transfer was successful
   * @dev only callable if the token is not paused
   * @dev only callable if the balance of the receiver is lower than the max amount of tokens per wallet
   * @dev checks if blacklisting is enabled and if the sender and receiver are not blacklisted
   * @dev checks if whitelisting is enabled and if the sender and receiver are whitelisted
   * @dev captures the tax during the transfer if tax is enabvled
   * @dev burns the deflationary amount during the transfer if deflation is enabled
   */
  function transfer(
    address to,
    uint256 amount
  )
    public
    virtual
    override
    whenNotPaused
    validateTransfer(msg.sender, to)
    returns (bool)
  {
    uint256 taxAmount = _taxAmount(msg.sender, amount);
    uint256 deflationAmount = _deflationAmount(amount);
    uint256 amountToTransfer = amount - taxAmount - deflationAmount;

    if (isMaxAmountOfTokensSet()) {
      if (balanceOf(to) + amountToTransfer > maxTokenAmountPerAddress) {
        revert DestBalanceExceedsMaxAllowed(to);
      }
    }

    if (taxAmount != 0) {
      _transfer(msg.sender, taxAddress, taxAmount);
    }
    if (deflationAmount != 0) {
      _burn(msg.sender, deflationAmount);
    }
    return super.transfer(to, amountToTransfer);
  }

  /**
   * @notice method which allows to transfer a predefined amount of tokens from a predefined address to a predefined address
   * @param from - the address to transfer the tokens from
   * @param to - the address to transfer the tokens to
   * @param amount - the amount of tokens to transfer
   * @return true if the transfer was successful
   * @dev only callable if the token is not paused
   * @dev only callable if the balance of the receiver is lower than the max amount of tokens per wallet
   * @dev checks if blacklisting is enabled and if the sender and receiver are not blacklisted
   * @dev checks if whitelisting is enabled and if the sender and receiver are whitelisted
   * @dev captures the tax during the transfer if tax is enabvled
   * @dev burns the deflationary amount during the transfer if deflation is enabled
   */
  function transferFrom(
    address from,
    address to,
    uint256 amount
  )
    public
    virtual
    override
    whenNotPaused
    validateTransfer(from, to)
    returns (bool)
  {
    uint256 taxAmount = _taxAmount(from, amount);
    uint256 deflationAmount = _deflationAmount(amount);
    uint256 amountToTransfer = amount - taxAmount - deflationAmount;

    if (isMaxAmountOfTokensSet()) {
      if (balanceOf(to) + amountToTransfer > maxTokenAmountPerAddress) {
        revert DestBalanceExceedsMaxAllowed(to);
      }
    }

    if (taxAmount != 0) {
      _transfer(from, taxAddress, taxAmount);
    }
    if (deflationAmount != 0) {
      _burn(from, deflationAmount);
    }

    if (isForceTransferAllowed() && owner() == msg.sender) {
      _transfer(from, to, amountToTransfer);
      return true;
    } else {
      return super.transferFrom(from, to, amountToTransfer);
    }
  }

  /**
   * @notice method which allows to mint a predefined amount of tokens to a predefined address
   * @param to - the address to mint the tokens to
   * @param amount - the amount of tokens to mint
   * @dev only callable by the owner
   * @dev only callable if the token is not paused
   * @dev only callable if the token supports additional minting
   * @dev only callable if the balance of the receiver is lower than the max amount of tokens per wallet
   * @dev checks if blacklisting is enabled and if the receiver is not blacklisted
   * @dev checks if whitelisting is enabled and if the receiver is whitelisted
   */
  function mint(address to, uint256 amount) external onlyOwner whenNotPaused {
    if (!isMintable()) {
      revert MintingNotEnabled();
    }
    if (isMaxAmountOfTokensSet()) {
      if (balanceOf(to) + amount > maxTokenAmountPerAddress) {
        revert DestBalanceExceedsMaxAllowed(to);
      }
    }
    if (isBlacklistEnabled()) {
      if (_isBlacklisted[to]) {
        revert RecipientBlacklisted(to);
      }
    }
    if (isWhitelistEnabled()) {
      if (!whitelist[to]) {
        revert RecipientNotWhitelisted(to);
      }
    }

    super._mint(to, amount);
  }

  /**
   * @notice method which allows to burn a predefined amount of tokens
   * @param amount - the amount of tokens to burn
   * @dev only callable by the owner
   * @dev only callable if the token is not paused
   * @dev only callable if the token supports burning
   */
  function burn(uint256 amount) public override onlyOwner whenNotPaused {
    if (!isBurnable()) {
      revert BurningNotEnabled();
    }
    super.burn(amount);
  }

  /**
   * @notice method which allows to burn a predefined amount of tokens from a predefined address
   * @param from - the address to burn the tokens from
   * @param amount - the amount of tokens to burn
   * @dev only callable by the owner
   * @dev only callable if the token is not paused
   * @dev only callable if the token supports burning
   */
  function burnFrom(
    address from,
    uint256 amount
  ) public override onlyOwner whenNotPaused {
    if (!isBurnable()) {
      revert BurningNotEnabled();
    }
    super.burnFrom(from, amount);
  }

  /**
   * @notice method which allows to pause the token
   * @dev only callable by the owner
   */
  function pause() external onlyOwner {
    if (!isPausable()) {
      revert PausingNotEnabled();
    }
    _pause();
  }

  /**
   * @notice method which allows to unpause the token
   * @dev only callable by the owner
   */
  function unpause() external onlyOwner {
    if (!isPausable()) {
      revert PausingNotEnabled();
    }
    _unpause();
  }

  /**
   * @notice method which allows to removing the owner of the token
   * @dev methods which are only callable by the owner will not be callable anymore
   * @dev only callable by the owner
   * @dev only callable if the token is not paused
   */
  function renounceOwnership() public override onlyOwner whenNotPaused {
    super.renounceOwnership();
  }

  /**
   * @notice method which allows to transfer the ownership of the token
   * @param newOwner - the address of the new owner
   * @dev only callable by the owner
   * @dev only callable if the token is not paused
   */
  function transferOwnership(
    address newOwner
  ) public override onlyOwner whenNotPaused {
    super.transferOwnership(newOwner);
  }

  /**
   * @notice method which allows to update the whitelist of the token
   * @param updatedAddresses - the new set of addresses
   * @dev only callable by the owner
   * @dev only callable if the token supports whitelisting
   */
  function updateWhitelist(
    address[] calldata updatedAddresses
  ) external onlyOwner whenNotPaused {
    if (!isWhitelistEnabled()) {
      revert WhitelistNotEnabled();
    }
    _clearWhitelist();
    _addManyToWhitelist(updatedAddresses);
    whitelistedAddresses = updatedAddresses;
    emit UsersWhitelisted(updatedAddresses);
  }

  /**
   * @notice method which allows for adding a new set of addresses to the whitelist
   * @param addresses - the addresses to add to the whitelist
   * @dev called internally by the contract
   * @dev only callable if any of the addresses are not already whitelisted
   */
  function _addManyToWhitelist(address[] calldata addresses) private {
    for (uint256 i; i < addresses.length; ) {
      LibCommon.validateAddress(addresses[i]);
      if (configProps._isBlacklistEnabled && _isBlacklisted[addresses[i]]) {
        revert CannotWhitelistBlacklistedAddr(addresses[i]);
      }
      whitelist[addresses[i]] = true;
      unchecked {
        ++i;
      }
    }
  }

  /**
   * @notice method which allows for removing a set of addresses from the whitelist
   */
  function _clearWhitelist() private {
    unchecked {
      address[] memory addresses = whitelistedAddresses;
      for (uint256 i; i < addresses.length; i++) {
        delete whitelist[addresses[i]];
      }
    }
  }

  /**
   * @notice method which returns the amount of tokens to be taxed during a transfer
   * @param sender - the address of the originating account
   * @param amount - the total amount of tokens sent in the transfer
   * @dev if the tax address is the same as the originating account performing the transfer, no tax is applied
   */
  function _taxAmount(
    address sender,
    uint256 amount
  ) internal view returns (uint256 taxAmount) {
    taxAmount = 0;
    if (taxBPS != 0 && sender != taxAddress) {
      taxAmount = (amount * taxBPS) / MAX_BPS_AMOUNT;
    }
  }

  /**
   * @notice method which returns the amount of tokens to be burned during a transfer
   * @param amount - the total amount of tokens sent in the transfer
   */
  function _deflationAmount(
    uint256 amount
  ) internal view returns (uint256 deflationAmount) {
    deflationAmount = 0;
    if (deflationBPS != 0) {
      deflationAmount = (amount * deflationBPS) / MAX_BPS_AMOUNT;
    }
  }
}

File 10 of 10 : LibCommon.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;

library LibCommon {
  /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
  /*                       CUSTOM ERRORS                        */
  /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

  /// @dev The ETH transfer has failed.
  error ETHTransferFailed();

  /// @dev The address is the zero address.
  error ZeroAddress();

  /// @notice raised when an ERC20 transfer fails
  error TransferFailed();

  /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
  /*                       ETH OPERATIONS                       */
  /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

  /// @notice Taken from Solady (https://github.com/vectorized/solady/blob/main/src/utils/SafeTransferLib.sol)
  /// @dev Sends `amount` (in wei) ETH to `to`.
  /// Reverts upon failure.
  function safeTransferETH(address to, uint256 amount) internal {
    // solhint-disable-next-line no-inline-assembly
    assembly {
      // Transfer the ETH and check if it succeeded or not.
      if iszero(call(gas(), to, amount, 0, 0, 0, 0)) {
        // Store the function selector of `ETHTransferFailed()`.
        // bytes4(keccak256(bytes("ETHTransferFailed()"))) = 0xb12d13eb
        mstore(0x00, 0xb12d13eb)
        // Revert with (offset, size).
        revert(0x1c, 0x04)
      }
    }
  }

  /// @notice Validates that the address is not the zero address using assembly.
  /// @dev Reverts if the address is the zero address.
  function validateAddress(address addr) internal pure {
    // solhint-disable-next-line no-inline-assembly
    assembly {
      if iszero(shl(96, addr)) {
        // Store the function selector of `ZeroAddress()`.
        // bytes4(keccak256(bytes("ZeroAddress()"))) = 0xd92e233d
        mstore(0x00, 0xd92e233d)
        // Revert with (offset, size).
        revert(0x1c, 0x04)
      }
    }
  }

  /// @notice Helper function to transfer ERC20 tokens without the need for SafeERC20.
  /// @dev Reverts if the ERC20 transfer fails.
  /// @param tokenAddress The address of the ERC20 token.
  /// @param from The address to transfer the tokens from.
  /// @param to The address to transfer the tokens to.
  /// @param amount The amount of tokens to transfer.
  function safeTransferFrom(
    address tokenAddress,
    address from,
    address to,
    uint256 amount
  ) internal returns (bool) {
    // solhint-disable-next-line avoid-low-level-calls
    (bool success, bytes memory data) = tokenAddress.call(
      abi.encodeWithSignature(
        "transferFrom(address,address,uint256)",
        from,
        to,
        amount
      )
    );
    if (!success) {
      if (data.length != 0) {
        // bubble up error
        // solhint-disable-next-line no-inline-assembly
        assembly {
          let returndata_size := mload(data)
          revert(add(32, data), returndata_size)
        }
      } else {
        revert TransferFailed();
      }
    }
    return true;
  }

  /// @notice Helper function to transfer ERC20 tokens without the need for SafeERC20.
  /// @dev Reverts if the ERC20 transfer fails.
  /// @param tokenAddress The address of the ERC20 token.
  /// @param to The address to transfer the tokens to.
  /// @param amount The amount of tokens to transfer.
  function safeTransfer(
    address tokenAddress,
    address to,
    uint256 amount
  ) internal returns (bool) {
    // solhint-disable-next-line avoid-low-level-calls
    (bool success, bytes memory data) = tokenAddress.call(
      abi.encodeWithSignature("transfer(address,uint256)", to, amount)
    );
    if (!success) {
      if (data.length != 0) {
        // bubble up error
        // solhint-disable-next-line no-inline-assembly
        assembly {
          let returndata_size := mload(data)
          revert(add(32, data), returndata_size)
        }
      } else {
        revert TransferFailed();
      }
    }
    return true;
  }
}

Settings
{
  "metadata": {
    "useLiteralContent": true
  },
  "optimizer": {
    "enabled": true,
    "runs": 1337
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "abi"
      ]
    }
  }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"string","name":"name_","type":"string"},{"internalType":"string","name":"symbol_","type":"string"},{"internalType":"uint256","name":"initialSupplyToSet","type":"uint256"},{"internalType":"uint8","name":"decimalsToSet","type":"uint8"},{"internalType":"address","name":"tokenOwner","type":"address"},{"components":[{"internalType":"bool","name":"_isMintable","type":"bool"},{"internalType":"bool","name":"_isBurnable","type":"bool"},{"internalType":"bool","name":"_isPausable","type":"bool"},{"internalType":"bool","name":"_isBlacklistEnabled","type":"bool"},{"internalType":"bool","name":"_isDocumentAllowed","type":"bool"},{"internalType":"bool","name":"_isWhitelistEnabled","type":"bool"},{"internalType":"bool","name":"_isMaxAmountOfTokensSet","type":"bool"},{"internalType":"bool","name":"_isForceTransferAllowed","type":"bool"},{"internalType":"bool","name":"_isTaxable","type":"bool"},{"internalType":"bool","name":"_isDeflationary","type":"bool"}],"internalType":"struct FullFeatureToken.ERC20ConfigProps","name":"customConfigProps","type":"tuple"},{"internalType":"uint256","name":"maxTokenAmount","type":"uint256"},{"internalType":"string","name":"newDocumentUri","type":"string"},{"internalType":"address","name":"_taxAddress","type":"address"},{"internalType":"uint256","name":"_taxBPS","type":"uint256"},{"internalType":"uint256","name":"_deflationBPS","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"AddrAlreadyBlacklisted","type":"error"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"AddrAlreadyUnblacklisted","type":"error"},{"inputs":[],"name":"BlacklistNotEnabled","type":"error"},{"inputs":[],"name":"BurningNotEnabled","type":"error"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"CannotBlacklistWhitelistedAddr","type":"error"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"CannotWhitelistBlacklistedAddr","type":"error"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"DestBalanceExceedsMaxAllowed","type":"error"},{"inputs":[],"name":"DocumentUriNotAllowed","type":"error"},{"inputs":[{"internalType":"uint8","name":"decimals","type":"uint8"}],"name":"InvalidDecimals","type":"error"},{"inputs":[{"internalType":"uint256","name":"bps","type":"uint256"}],"name":"InvalidDeflationBPS","type":"error"},{"inputs":[{"internalType":"uint256","name":"maxTokenAmount","type":"uint256"}],"name":"InvalidMaxTokenAmount","type":"error"},{"inputs":[{"internalType":"uint256","name":"bps","type":"uint256"}],"name":"InvalidTaxBPS","type":"error"},{"inputs":[],"name":"MaxTokenAmountNotAllowed","type":"error"},{"inputs":[],"name":"MaxTokenAmountPerAddrLtPrevious","type":"error"},{"inputs":[],"name":"MintingNotEnabled","type":"error"},{"inputs":[],"name":"PausingNotEnabled","type":"error"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"RecipientBlacklisted","type":"error"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"RecipientNotWhitelisted","type":"error"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"SenderBlacklisted","type":"error"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"SenderNotWhitelisted","type":"error"},{"inputs":[],"name":"TokenIsNotDeflationary","type":"error"},{"inputs":[],"name":"TokenIsNotTaxable","type":"error"},{"inputs":[],"name":"WhitelistNotEnabled","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":"uint256","name":"_deflationBPS","type":"uint256"}],"name":"DeflationConfigSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"newDocUri","type":"string"}],"name":"DocumentUriSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newMaxTokenAmount","type":"uint256"}],"name":"MaxTokenAmountPerSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_taxAddress","type":"address"},{"indexed":true,"internalType":"uint256","name":"_taxBPS","type":"uint256"}],"name":"TaxConfigSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"addr","type":"address"}],"name":"UserBlacklisted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"addr","type":"address"}],"name":"UserUnBlacklisted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address[]","name":"updatedAddresses","type":"address[]"}],"name":"UsersWhitelisted","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":"amount","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":"address","name":"addr","type":"address"}],"name":"blackList","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burnFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"deflationBPS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"documentUri","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getWhitelistedAddresses","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"initialDocumentUri","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"initialMaxTokenAmountPerAddress","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"initialSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"initialTokenOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isBlacklistEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isBurnable","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isDeflationary","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isDocumentUriAllowed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isForceTransferAllowed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isMaxAmountOfTokensSet","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isMintable","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isPausable","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isTaxable","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isWhitelistEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxTokenAmountPerAddress","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"removeFromBlacklist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_deflationBPS","type":"uint256"}],"name":"setDeflationConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"newDocumentUri","type":"string"}],"name":"setDocumentUri","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newMaxTokenAmount","type":"uint256"}],"name":"setMaxTokenAmountPerAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_taxAddress","type":"address"},{"internalType":"uint256","name":"_taxBPS","type":"uint256"}],"name":"setTaxConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"taxAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"taxBPS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":"amount","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":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"updatedAddresses","type":"address[]"}],"name":"updateWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"whitelist","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"whitelistedAddresses","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]

6101006040523480156200001257600080fd5b5060405162003810380380620038108339810160408190526200003591620008d6565b8a8a600362000045838262000a7a565b50600462000054828262000a7a565b50506005805460ff19169055506200006c3362000380565b8560c0015115620000a15784600003620000a1576040516364824b8d60e01b8152600481018690526024015b60405180910390fd5b60128860ff161115620000cd5760405163ca95039160e01b815260ff8916600482015260240162000098565b85610100015115620001385761138882111562000101576040516365a0074b60e11b81526004810183905260240162000098565b6200011783620003da60201b6200196c1760201c565b600d80546001600160a01b0319166001600160a01b038516179055600e8290555b8561012001511562000172576113888111156200016c576040516305dba32960e51b81526004810182905260240162000098565b600f8190555b6200018887620003da60201b6200196c1760201c565b608089905260a08590526009620001a0858262000a7a565b50866001600160a01b031660c0816001600160a01b0316815250508760ff1660e08160ff168152505085600c60008201518160000160006101000a81548160ff02191690831515021790555060208201518160000160016101000a81548160ff02191690831515021790555060408201518160000160026101000a81548160ff02191690831515021790555060608201518160000160036101000a81548160ff02191690831515021790555060808201518160000160046101000a81548160ff02191690831515021790555060a08201518160000160056101000a81548160ff02191690831515021790555060c08201518160000160066101000a81548160ff02191690831515021790555060e08201518160000160076101000a81548160ff0219169083151502179055506101008201518160000160086101000a81548160ff0219169083151502179055506101208201518160000160096101000a81548160ff02191690831515021790555090505083600a908162000322919062000a7a565b50600b859055881562000353576200035387620003418a600a62000c5b565b6200034d908c62000c73565b620003f4565b6001600160a01b03871633146200036f576200036f87620004c5565b505050505050505050505062000ca3565b600580546001600160a01b03838116610100818102610100600160a81b031985161790945560405193909204169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b8060601b620003f15763d92e233d6000526004601cfd5b50565b6001600160a01b0382166200044c5760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015260640162000098565b6200045a60008383620004ef565b80600260008282546200046e919062000c8d565b90915550506001600160a01b038216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b620004cf6200050c565b620004d962000570565b620003f181620005b860201b620019821760201c565b620005078383836200063460201b62001a0f1760201c565b505050565b6005546001600160a01b036101009091041633146200056e5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640162000098565b565b60055460ff16156200056e5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015260640162000098565b620005c26200050c565b6001600160a01b038116620006295760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840162000098565b620003f18162000380565b6200064c8383836200050760201b62001a881760201c565b60055460ff1615620005075760405162461bcd60e51b815260206004820152602a60248201527f45524332305061757361626c653a20746f6b656e207472616e736665722077686044820152691a5b19481c185d5cd95960b21b606482015260840162000098565b634e487b7160e01b600052604160045260246000fd5b60405161014081016001600160401b0381118282101715620006f057620006f0620006b4565b60405290565b604051601f8201601f191681016001600160401b0381118282101715620007215762000721620006b4565b604052919050565b600082601f8301126200073b57600080fd5b81516001600160401b03811115620007575762000757620006b4565b60206200076d601f8301601f19168201620006f6565b82815285828487010111156200078257600080fd5b60005b83811015620007a257858101830151828201840152820162000785565b506000928101909101919091529392505050565b805160ff81168114620007c857600080fd5b919050565b80516001600160a01b0381168114620007c857600080fd5b80518015158114620007c857600080fd5b600061014082840312156200080a57600080fd5b62000814620006ca565b90506200082182620007e5565b81526200083160208301620007e5565b60208201526200084460408301620007e5565b60408201526200085760608301620007e5565b60608201526200086a60808301620007e5565b60808201526200087d60a08301620007e5565b60a08201526200089060c08301620007e5565b60c0820152620008a360e08301620007e5565b60e0820152610100620008b8818401620007e5565b90820152610120620008cc838201620007e5565b9082015292915050565b60008060008060008060008060008060006102808c8e031215620008f957600080fd5b8b516001600160401b038111156200091057600080fd5b6200091e8e828f0162000729565b60208e0151909c5090506001600160401b038111156200093d57600080fd5b6200094b8e828f0162000729565b9a505060408c015198506200096360608d01620007b6565b97506200097360808d01620007cd565b9650620009848d60a08e01620007f6565b6101e08d01516102008e015191975095506001600160401b03811115620009aa57600080fd5b620009b88e828f0162000729565b945050620009ca6102208d01620007cd565b92506102408c015191506102608c015190509295989b509295989b9093969950565b600181811c9082168062000a0157607f821691505b60208210810362000a2257634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200050757600081815260208120601f850160051c8101602086101562000a515750805b601f850160051c820191505b8181101562000a725782815560010162000a5d565b505050505050565b81516001600160401b0381111562000a965762000a96620006b4565b62000aae8162000aa78454620009ec565b8462000a28565b602080601f83116001811462000ae6576000841562000acd5750858301515b600019600386901b1c1916600185901b17855562000a72565b600085815260208120601f198616915b8281101562000b175788860151825594840194600190910190840162000af6565b508582101562000b365787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b634e487b7160e01b600052601160045260246000fd5b600181815b8085111562000b9d57816000190482111562000b815762000b8162000b46565b8085161562000b8f57918102915b93841c939080029062000b61565b509250929050565b60008262000bb65750600162000c55565b8162000bc55750600062000c55565b816001811462000bde576002811462000be95762000c09565b600191505062000c55565b60ff84111562000bfd5762000bfd62000b46565b50506001821b62000c55565b5060208310610133831016604e8410600b841016171562000c2e575081810a62000c55565b62000c3a838362000b5c565b806000190482111562000c515762000c5162000b46565b0290505b92915050565b600062000c6c60ff84168362000ba5565b9392505050565b808202811582820484141762000c555762000c5562000b46565b8082018082111562000c555762000c5562000b46565b60805160a05160c05160e051612b3362000cdd60003960006103d7015260006105b501526000610630015260006104190152612b336000f3fe608060405234801561001057600080fd5b506004361061032b5760003560e01c806370a08231116101b2578063a32f6976116100f9578063ba4e5c49116100a2578063dd62ed3e1161007c578063dd62ed3e146106d5578063f19c4e3b1461070e578063f2fde38b14610721578063f820f5671461073457600080fd5b8063ba4e5c49146106a6578063d48e4127146106b9578063d8f67851146106c257600080fd5b8063a9059cbb116100d3578063a9059cbb14610678578063a9d866851461068b578063b7bda68f1461069357600080fd5b8063a32f69761461062b578063a457c2d714610652578063a476df611461066557600080fd5b80638da5cb5b1161015b57806395d89b411161013557806395d89b41146105ef5780639b19251a146105f7578063a09a16011461061a57600080fd5b80638da5cb5b146105865780638dac7191146105b05780638e8c10a2146105d757600080fd5b80638456cb591161018c5780638456cb591461055c578063878dd33214610564578063883356d91461057657600080fd5b806370a0823114610518578063715018a61461054157806379cc67901461054957600080fd5b80633f4ba83a11610276578063537df3b61161021f5780635c975abb116101f95780635c975abb146104e25780636c5adaae146104ed5780636d0280271461050357600080fd5b8063537df3b6146104b1578063542e9667146104c45780635a3990ce146104cd57600080fd5b806346b45af71161025057806346b45af71461047c5780634838d165146104875780634ac0bc321461049a57600080fd5b80633f4ba83a1461044e57806340c10f191461045657806342966c681461046957600080fd5b806323b872dd116102d857806335377214116102b25780633537721414610401578063378dc3dc14610414578063395093511461043b57600080fd5b806323b872dd146103b45780632fa782eb146103c7578063313ce567146103d057600080fd5b8063095ea7b311610309578063095ea7b31461036b57806318160ddd1461038e578063184d69ab146103a057600080fd5b806302252c4d14610330578063044ab74e1461034557806306fdde0314610363575b600080fd5b61034361033e366004612623565b610747565b005b61034d610814565b60405161035a919061263c565b60405180910390f35b61034d6108a2565b61037e6103793660046126a1565b610934565b604051901515815260200161035a565b6002545b60405190815260200161035a565b600c5465010000000000900460ff1661037e565b61037e6103c23660046126cb565b61094e565b610392600e5481565b60405160ff7f000000000000000000000000000000000000000000000000000000000000000016815260200161035a565b61034361040f366004612707565b610cbd565b6103927f000000000000000000000000000000000000000000000000000000000000000081565b61037e6104493660046126a1565b610d6e565b610343610dad565b6103436104643660046126a1565b610de8565b610343610477366004612623565b610f5d565b600c5460ff1661037e565b61034361049536600461277c565b610fa1565b600c5468010000000000000000900460ff1661037e565b6103436104bf36600461277c565b611103565b610392600f5481565b600c546601000000000000900460ff1661037e565b60055460ff1661037e565b600c54670100000000000000900460ff1661037e565b61050b6111ec565b60405161035a9190612797565b61039261052636600461277c565b6001600160a01b031660009081526020819052604090205490565b61034361124d565b6103436105573660046126a1565b611265565b6103436112a7565b600c546301000000900460ff1661037e565b600c54610100900460ff1661037e565b60055461010090046001600160a01b03165b6040516001600160a01b03909116815260200161035a565b6105987f000000000000000000000000000000000000000000000000000000000000000081565b600c546901000000000000000000900460ff1661037e565b61034d6112e0565b61037e61060536600461277c565b60076020526000908152604090205460ff1681565b600c5462010000900460ff1661037e565b6103927f000000000000000000000000000000000000000000000000000000000000000081565b61037e6106603660046126a1565b6112ef565b6103436106733660046127fa565b6113a4565b61037e6106863660046126a1565b611434565b61034d611751565b600d54610598906001600160a01b031681565b6105986106b4366004612623565b61175e565b610392600b5481565b6103436106d0366004612623565b611788565b6103926106e33660046128ab565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b61034361071c3660046126a1565b611853565b61034361072f36600461277c565b611953565b600c54640100000000900460ff1661037e565b61074f611a8d565b610757611aed565b600c546601000000000000900460ff1661079d576040517f6273340f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600b5481116107d8576040517fa43d2d7600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600b8190556040518181527f2905481c6fd1a037492016c4760435a52203d82a6f34dc3de40f464c1bf42d59906020015b60405180910390a150565b600a8054610821906128de565b80601f016020809104026020016040519081016040528092919081815260200182805461084d906128de565b801561089a5780601f1061086f5761010080835404028352916020019161089a565b820191906000526020600020905b81548152906001019060200180831161087d57829003601f168201915b505050505081565b6060600380546108b1906128de565b80601f01602080910402602001604051908101604052809291908181526020018280546108dd906128de565b801561092a5780601f106108ff5761010080835404028352916020019161092a565b820191906000526020600020905b81548152906001019060200180831161090d57829003601f168201915b5050505050905090565b600033610942818585611b40565b60019150505b92915050565b6000610958611aed565b8383610970600c5460ff650100000000009091041690565b15610a79576001600160a01b03821660009081526007602052604090205460ff166109be5760405163bf3f938960e01b81526001600160a01b03831660048201526024015b60405180910390fd5b6001600160a01b03811660009081526007602052604090205460ff16610a0257604051632ac2e20360e21b81526001600160a01b03821660048201526024016109b5565b6001600160a01b0382163314801590610a3d575060055461010090046001600160a01b03166001600160a01b0316336001600160a01b031614155b8015610a5957503360009081526007602052604090205460ff16155b15610a795760405163bf3f938960e01b81523360048201526024016109b5565b600c546301000000900460ff1615610b8b576001600160a01b03821660009081526006602052604090205460ff1615610ad05760405163578f3e1360e01b81526001600160a01b03831660048201526024016109b5565b6001600160a01b03811660009081526006602052604090205460ff1615610b15576040516332e38af360e21b81526001600160a01b03821660048201526024016109b5565b6001600160a01b0382163314801590610b50575060055461010090046001600160a01b03166001600160a01b0316336001600160a01b031614155b8015610b6b57503360009081526006602052604090205460ff165b15610b8b5760405163578f3e1360e01b81523360048201526024016109b5565b6000610b978786611c98565b90506000610ba486611ce2565b9050600081610bb3848961292e565b610bbd919061292e565b600c549091506601000000000000900460ff1615610c2c57600b5481610bf88a6001600160a01b031660009081526020819052604090205490565b610c029190612941565b1115610c2c5760405163f6202a8f60e01b81526001600160a01b03891660048201526024016109b5565b8215610c4a57600d54610c4a908a906001600160a01b031685611d11565b8115610c5a57610c5a8983611f0b565b600c54670100000000000000900460ff168015610c8757506005546001600160a01b036101009091041633145b15610ca357610c97898983611d11565b60019550505050610cb4565b610cae898983612080565b95505050505b50509392505050565b610cc5611a8d565b610ccd611aed565b600c5465010000000000900460ff16610d12576040517f0b1b4e5500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610d1a612099565b610d24828261214d565b610d306008838361259e565b507f6141feff42f24e29d1af3d91bffa3d40521e53485e9c92e358c4d946c0adbd388282604051610d62929190612954565b60405180910390a15050565b3360008181526001602090815260408083206001600160a01b03871684529091528120549091906109429082908690610da8908790612941565b611b40565b610db5611a8d565b600c5462010000900460ff16610dde5760405163f00085b960e01b815260040160405180910390fd5b610de66122ab565b565b610df0611a8d565b610df8611aed565b600c5460ff16610e34576040517f3990ac6800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600c546601000000000000900460ff1615610ea057600b5481610e6c846001600160a01b031660009081526020819052604090205490565b610e769190612941565b1115610ea05760405163f6202a8f60e01b81526001600160a01b03831660048201526024016109b5565b600c546301000000900460ff1615610ef7576001600160a01b03821660009081526006602052604090205460ff1615610ef7576040516332e38af360e21b81526001600160a01b03831660048201526024016109b5565b600c5465010000000000900460ff1615610f4f576001600160a01b03821660009081526007602052604090205460ff16610f4f57604051632ac2e20360e21b81526001600160a01b03831660048201526024016109b5565b610f5982826122fd565b5050565b610f65611a8d565b610f6d611aed565b600c54610100900460ff16610f9557604051636cb5913960e01b815260040160405180910390fd5b610f9e816123c8565b50565b610fa9611a8d565b610fb1611aed565b610fba8161196c565b600c546301000000900460ff16610fe457604051633abeadc360e21b815260040160405180910390fd5b6001600160a01b03811660009081526006602052604090205460ff1615611042576040517f70b8fc840000000000000000000000000000000000000000000000000000000081526001600160a01b03821660048201526024016109b5565b600c5465010000000000900460ff16801561107557506001600160a01b03811660009081526007602052604090205460ff165b156110b7576040517febdacb5f0000000000000000000000000000000000000000000000000000000081526001600160a01b03821660048201526024016109b5565b6001600160a01b038116600081815260066020526040808220805460ff19166001179055517f7f8b7dc89dae85811a7a85800b892b5816ad5d381c856f1b56490f8fc470c9cb9190a250565b61110b611a8d565b611113611aed565b61111c8161196c565b600c546301000000900460ff1661114657604051633abeadc360e21b815260040160405180910390fd5b6001600160a01b03811660009081526006602052604090205460ff166111a3576040517f3d7c1f4a0000000000000000000000000000000000000000000000000000000081526001600160a01b03821660048201526024016109b5565b6001600160a01b038116600081815260066020526040808220805460ff19169055517f4ca5b343d678ca6f1f96e8c8a2115c41c2d40641fd872b928ba6f95d3648b9d19190a250565b6060600880548060200260200160405190810160405280929190818152602001828054801561092a57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611226575050505050905090565b611255611a8d565b61125d611aed565b610de66123d2565b61126d611a8d565b611275611aed565b600c54610100900460ff1661129d57604051636cb5913960e01b815260040160405180910390fd5b610f5982826123e4565b6112af611a8d565b600c5462010000900460ff166112d85760405163f00085b960e01b815260040160405180910390fd5b610de66123f9565b6060600480546108b1906128de565b3360008181526001602090815260408083206001600160a01b03871684529091528120549091908381101561138c5760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f00000000000000000000000000000000000000000000000000000060648201526084016109b5565b6113998286868403611b40565b506001949350505050565b6113ac611a8d565b6113b4611aed565b600c54640100000000900460ff166113f8576040517f70a43fce00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600a61140482826129ee565b507f4456a0b562609d67398ddb488f136db285cd3c92343e0a7ba684925669237ade81604051610809919061263c565b600061143e611aed565b3383611456600c5460ff650100000000009091041690565b1561155a576001600160a01b03821660009081526007602052604090205460ff1661149f5760405163bf3f938960e01b81526001600160a01b03831660048201526024016109b5565b6001600160a01b03811660009081526007602052604090205460ff166114e357604051632ac2e20360e21b81526001600160a01b03821660048201526024016109b5565b6001600160a01b038216331480159061151e575060055461010090046001600160a01b03166001600160a01b0316336001600160a01b031614155b801561153a57503360009081526007602052604090205460ff16155b1561155a5760405163bf3f938960e01b81523360048201526024016109b5565b600c546301000000900460ff161561166c576001600160a01b03821660009081526006602052604090205460ff16156115b15760405163578f3e1360e01b81526001600160a01b03831660048201526024016109b5565b6001600160a01b03811660009081526006602052604090205460ff16156115f6576040516332e38af360e21b81526001600160a01b03821660048201526024016109b5565b6001600160a01b0382163314801590611631575060055461010090046001600160a01b03166001600160a01b0316336001600160a01b031614155b801561164c57503360009081526006602052604090205460ff165b1561166c5760405163578f3e1360e01b81523360048201526024016109b5565b60006116783386611c98565b9050600061168586611ce2565b9050600081611694848961292e565b61169e919061292e565b600c549091506601000000000000900460ff161561170d57600b54816116d98a6001600160a01b031660009081526020819052604090205490565b6116e39190612941565b111561170d5760405163f6202a8f60e01b81526001600160a01b03891660048201526024016109b5565b821561172b57600d5461172b9033906001600160a01b031685611d11565b811561173b5761173b3383611f0b565b6117458882612436565b98975050505050505050565b60098054610821906128de565b6008818154811061176e57600080fd5b6000918252602090912001546001600160a01b0316905081565b611790611a8d565b611798611aed565b600c546901000000000000000000900460ff166117e1576040517fcd9e529800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611388811115611820576040517fbb746520000000000000000000000000000000000000000000000000000000008152600481018290526024016109b5565b600f81905560405181907fc1ff65ee907dc079b64ed9913d53f4bd593bd6ebd9b2a2708db2916d49e17ec390600090a250565b61185b611a8d565b611863611aed565b600c5468010000000000000000900460ff166118ab576040517fc8a478a500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113888111156118ea576040517fcb400e96000000000000000000000000000000000000000000000000000000008152600481018290526024016109b5565b6118f38261196c565b600d805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b038416908117909155600e8290556040518291907facc44e32fd5ca4240f6dbe6e8cf4eb49349c17c5ce5f80f1919a9c97b50d398a90600090a35050565b61195b611a8d565b611963611aed565b610f9e81611982565b8060601b610f9e5763d92e233d6000526004601cfd5b61198a611a8d565b6001600160a01b038116611a065760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016109b5565b610f9e81612444565b60055460ff1615611a885760405162461bcd60e51b815260206004820152602a60248201527f45524332305061757361626c653a20746f6b656e207472616e7366657220776860448201527f696c65207061757365640000000000000000000000000000000000000000000060648201526084016109b5565b505050565b6005546001600160a01b03610100909104163314610de65760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016109b5565b60055460ff1615610de65760405162461bcd60e51b815260206004820152601060248201527f5061757361626c653a207061757365640000000000000000000000000000000060448201526064016109b5565b6001600160a01b038316611bbb5760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f726573730000000000000000000000000000000000000000000000000000000060648201526084016109b5565b6001600160a01b038216611c375760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f737300000000000000000000000000000000000000000000000000000000000060648201526084016109b5565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6000600e54600014158015611cbb5750600d546001600160a01b03848116911614155b1561094857612710600e5483611cd19190612aae565b611cdb9190612ac5565b9392505050565b6000600f54600014611d0c57612710600f5483611cff9190612aae565b611d099190612ac5565b90505b919050565b6001600160a01b038316611d8d5760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f647265737300000000000000000000000000000000000000000000000000000060648201526084016109b5565b6001600160a01b038216611e095760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f657373000000000000000000000000000000000000000000000000000000000060648201526084016109b5565b611e148383836124b5565b6001600160a01b03831660009081526020819052604090205481811015611ea35760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e6365000000000000000000000000000000000000000000000000000060648201526084016109b5565b6001600160a01b03848116600081815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35b50505050565b6001600160a01b038216611f875760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f730000000000000000000000000000000000000000000000000000000000000060648201526084016109b5565b611f93826000836124b5565b6001600160a01b038216600090815260208190526040902054818110156120225760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f636500000000000000000000000000000000000000000000000000000000000060648201526084016109b5565b6001600160a01b0383166000818152602081815260408083208686039055600280548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3505050565b60003361208e8582856124c0565b611399858585611d11565b600060088054806020026020016040519081016040528092919081815260200182805480156120f157602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116120d3575b5050505050905060005b8151811015610f59576007600083838151811061211a5761211a612ae7565b6020908102919091018101516001600160a01b03168252810191909152604001600020805460ff191690556001016120fb565b60005b81811015611a885761218783838381811061216d5761216d612ae7565b9050602002016020810190612182919061277c565b61196c565b600c546301000000900460ff1680156121e45750600660008484848181106121b1576121b1612ae7565b90506020020160208101906121c6919061277c565b6001600160a01b0316815260208101919091526040016000205460ff165b1561224e578282828181106121fb576121fb612ae7565b9050602002016020810190612210919061277c565b6040517f2cf5f7dd0000000000000000000000000000000000000000000000000000000081526001600160a01b0390911660048201526024016109b5565b60016007600085858581811061226657612266612ae7565b905060200201602081019061227b919061277c565b6001600160a01b031681526020810191909152604001600020805460ff1916911515919091179055600101612150565b6122b361254c565b6005805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b6001600160a01b0382166123535760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016109b5565b61235f600083836124b5565b80600260008282546123719190612941565b90915550506001600160a01b038216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b610f9e3382611f0b565b6123da611a8d565b610de66000612444565b6123ef8233836124c0565b610f598282611f0b565b612401611aed565b6005805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586122e03390565b600033610942818585611d11565b600580546001600160a01b038381166101008181027fffffffffffffffffffffff0000000000000000000000000000000000000000ff85161790945560405193909204169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b611a88838383611a0f565b6001600160a01b038381166000908152600160209081526040808320938616835292905220546000198114611f05578181101561253f5760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e636500000060448201526064016109b5565b611f058484848403611b40565b60055460ff16610de65760405162461bcd60e51b815260206004820152601460248201527f5061757361626c653a206e6f742070617573656400000000000000000000000060448201526064016109b5565b8280548282559060005260206000209081019282156125fe579160200282015b828111156125fe57815473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b038435161782556020909201916001909101906125be565b5061260a92915061260e565b5090565b5b8082111561260a576000815560010161260f565b60006020828403121561263557600080fd5b5035919050565b600060208083528351808285015260005b818110156126695785810183015185820160400152820161264d565b506000604082860101526040601f19601f8301168501019250505092915050565b80356001600160a01b0381168114611d0c57600080fd5b600080604083850312156126b457600080fd5b6126bd8361268a565b946020939093013593505050565b6000806000606084860312156126e057600080fd5b6126e98461268a565b92506126f76020850161268a565b9150604084013590509250925092565b6000806020838503121561271a57600080fd5b823567ffffffffffffffff8082111561273257600080fd5b818501915085601f83011261274657600080fd5b81358181111561275557600080fd5b8660208260051b850101111561276a57600080fd5b60209290920196919550909350505050565b60006020828403121561278e57600080fd5b611cdb8261268a565b6020808252825182820181905260009190848201906040850190845b818110156127d85783516001600160a01b0316835292840192918401916001016127b3565b50909695505050505050565b634e487b7160e01b600052604160045260246000fd5b60006020828403121561280c57600080fd5b813567ffffffffffffffff8082111561282457600080fd5b818401915084601f83011261283857600080fd5b81358181111561284a5761284a6127e4565b604051601f8201601f19908116603f01168101908382118183101715612872576128726127e4565b8160405282815287602084870101111561288b57600080fd5b826020860160208301376000928101602001929092525095945050505050565b600080604083850312156128be57600080fd5b6128c78361268a565b91506128d56020840161268a565b90509250929050565b600181811c908216806128f257607f821691505b60208210810361291257634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b8181038181111561094857610948612918565b8082018082111561094857610948612918565b60208082528181018390526000908460408401835b86811015612995576001600160a01b036129828461268a565b1682529183019190830190600101612969565b509695505050505050565b601f821115611a8857600081815260208120601f850160051c810160208610156129c75750805b601f850160051c820191505b818110156129e6578281556001016129d3565b505050505050565b815167ffffffffffffffff811115612a0857612a086127e4565b612a1c81612a1684546128de565b846129a0565b602080601f831160018114612a515760008415612a395750858301515b600019600386901b1c1916600185901b1785556129e6565b600085815260208120601f198616915b82811015612a8057888601518255948401946001909101908401612a61565b5085821015612a9e5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b808202811582820484141761094857610948612918565b600082612ae257634e487b7160e01b600052601260045260246000fd5b500490565b634e487b7160e01b600052603260045260246000fdfea264697066735822122030d0fa8f27a883250c7a7bacf402c50c65a40c6ec96ccb650d9fc1a5f93ae6a064736f6c63430008110033000000000000000000000000000000000000000000000000000000000000028000000000000000000000000000000000000000000000000000000000000002c0000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000000120000000000000000000000005f4f120d8435ea38f0f4635a910fee03801be88d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000005f4f120d8435ea38f0f4635a910fee03801be88d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000104f7074696d697374696350756572636f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000084f5050756572636f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

Deployed Bytecode

0x608060405234801561001057600080fd5b506004361061032b5760003560e01c806370a08231116101b2578063a32f6976116100f9578063ba4e5c49116100a2578063dd62ed3e1161007c578063dd62ed3e146106d5578063f19c4e3b1461070e578063f2fde38b14610721578063f820f5671461073457600080fd5b8063ba4e5c49146106a6578063d48e4127146106b9578063d8f67851146106c257600080fd5b8063a9059cbb116100d3578063a9059cbb14610678578063a9d866851461068b578063b7bda68f1461069357600080fd5b8063a32f69761461062b578063a457c2d714610652578063a476df611461066557600080fd5b80638da5cb5b1161015b57806395d89b411161013557806395d89b41146105ef5780639b19251a146105f7578063a09a16011461061a57600080fd5b80638da5cb5b146105865780638dac7191146105b05780638e8c10a2146105d757600080fd5b80638456cb591161018c5780638456cb591461055c578063878dd33214610564578063883356d91461057657600080fd5b806370a0823114610518578063715018a61461054157806379cc67901461054957600080fd5b80633f4ba83a11610276578063537df3b61161021f5780635c975abb116101f95780635c975abb146104e25780636c5adaae146104ed5780636d0280271461050357600080fd5b8063537df3b6146104b1578063542e9667146104c45780635a3990ce146104cd57600080fd5b806346b45af71161025057806346b45af71461047c5780634838d165146104875780634ac0bc321461049a57600080fd5b80633f4ba83a1461044e57806340c10f191461045657806342966c681461046957600080fd5b806323b872dd116102d857806335377214116102b25780633537721414610401578063378dc3dc14610414578063395093511461043b57600080fd5b806323b872dd146103b45780632fa782eb146103c7578063313ce567146103d057600080fd5b8063095ea7b311610309578063095ea7b31461036b57806318160ddd1461038e578063184d69ab146103a057600080fd5b806302252c4d14610330578063044ab74e1461034557806306fdde0314610363575b600080fd5b61034361033e366004612623565b610747565b005b61034d610814565b60405161035a919061263c565b60405180910390f35b61034d6108a2565b61037e6103793660046126a1565b610934565b604051901515815260200161035a565b6002545b60405190815260200161035a565b600c5465010000000000900460ff1661037e565b61037e6103c23660046126cb565b61094e565b610392600e5481565b60405160ff7f000000000000000000000000000000000000000000000000000000000000001216815260200161035a565b61034361040f366004612707565b610cbd565b6103927f000000000000000000000000000000000000000000000000000000000000006481565b61037e6104493660046126a1565b610d6e565b610343610dad565b6103436104643660046126a1565b610de8565b610343610477366004612623565b610f5d565b600c5460ff1661037e565b61034361049536600461277c565b610fa1565b600c5468010000000000000000900460ff1661037e565b6103436104bf36600461277c565b611103565b610392600f5481565b600c546601000000000000900460ff1661037e565b60055460ff1661037e565b600c54670100000000000000900460ff1661037e565b61050b6111ec565b60405161035a9190612797565b61039261052636600461277c565b6001600160a01b031660009081526020819052604090205490565b61034361124d565b6103436105573660046126a1565b611265565b6103436112a7565b600c546301000000900460ff1661037e565b600c54610100900460ff1661037e565b60055461010090046001600160a01b03165b6040516001600160a01b03909116815260200161035a565b6105987f0000000000000000000000005f4f120d8435ea38f0f4635a910fee03801be88d81565b600c546901000000000000000000900460ff1661037e565b61034d6112e0565b61037e61060536600461277c565b60076020526000908152604090205460ff1681565b600c5462010000900460ff1661037e565b6103927f000000000000000000000000000000000000000000000000000000000000000081565b61037e6106603660046126a1565b6112ef565b6103436106733660046127fa565b6113a4565b61037e6106863660046126a1565b611434565b61034d611751565b600d54610598906001600160a01b031681565b6105986106b4366004612623565b61175e565b610392600b5481565b6103436106d0366004612623565b611788565b6103926106e33660046128ab565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b61034361071c3660046126a1565b611853565b61034361072f36600461277c565b611953565b600c54640100000000900460ff1661037e565b61074f611a8d565b610757611aed565b600c546601000000000000900460ff1661079d576040517f6273340f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600b5481116107d8576040517fa43d2d7600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600b8190556040518181527f2905481c6fd1a037492016c4760435a52203d82a6f34dc3de40f464c1bf42d59906020015b60405180910390a150565b600a8054610821906128de565b80601f016020809104026020016040519081016040528092919081815260200182805461084d906128de565b801561089a5780601f1061086f5761010080835404028352916020019161089a565b820191906000526020600020905b81548152906001019060200180831161087d57829003601f168201915b505050505081565b6060600380546108b1906128de565b80601f01602080910402602001604051908101604052809291908181526020018280546108dd906128de565b801561092a5780601f106108ff5761010080835404028352916020019161092a565b820191906000526020600020905b81548152906001019060200180831161090d57829003601f168201915b5050505050905090565b600033610942818585611b40565b60019150505b92915050565b6000610958611aed565b8383610970600c5460ff650100000000009091041690565b15610a79576001600160a01b03821660009081526007602052604090205460ff166109be5760405163bf3f938960e01b81526001600160a01b03831660048201526024015b60405180910390fd5b6001600160a01b03811660009081526007602052604090205460ff16610a0257604051632ac2e20360e21b81526001600160a01b03821660048201526024016109b5565b6001600160a01b0382163314801590610a3d575060055461010090046001600160a01b03166001600160a01b0316336001600160a01b031614155b8015610a5957503360009081526007602052604090205460ff16155b15610a795760405163bf3f938960e01b81523360048201526024016109b5565b600c546301000000900460ff1615610b8b576001600160a01b03821660009081526006602052604090205460ff1615610ad05760405163578f3e1360e01b81526001600160a01b03831660048201526024016109b5565b6001600160a01b03811660009081526006602052604090205460ff1615610b15576040516332e38af360e21b81526001600160a01b03821660048201526024016109b5565b6001600160a01b0382163314801590610b50575060055461010090046001600160a01b03166001600160a01b0316336001600160a01b031614155b8015610b6b57503360009081526006602052604090205460ff165b15610b8b5760405163578f3e1360e01b81523360048201526024016109b5565b6000610b978786611c98565b90506000610ba486611ce2565b9050600081610bb3848961292e565b610bbd919061292e565b600c549091506601000000000000900460ff1615610c2c57600b5481610bf88a6001600160a01b031660009081526020819052604090205490565b610c029190612941565b1115610c2c5760405163f6202a8f60e01b81526001600160a01b03891660048201526024016109b5565b8215610c4a57600d54610c4a908a906001600160a01b031685611d11565b8115610c5a57610c5a8983611f0b565b600c54670100000000000000900460ff168015610c8757506005546001600160a01b036101009091041633145b15610ca357610c97898983611d11565b60019550505050610cb4565b610cae898983612080565b95505050505b50509392505050565b610cc5611a8d565b610ccd611aed565b600c5465010000000000900460ff16610d12576040517f0b1b4e5500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610d1a612099565b610d24828261214d565b610d306008838361259e565b507f6141feff42f24e29d1af3d91bffa3d40521e53485e9c92e358c4d946c0adbd388282604051610d62929190612954565b60405180910390a15050565b3360008181526001602090815260408083206001600160a01b03871684529091528120549091906109429082908690610da8908790612941565b611b40565b610db5611a8d565b600c5462010000900460ff16610dde5760405163f00085b960e01b815260040160405180910390fd5b610de66122ab565b565b610df0611a8d565b610df8611aed565b600c5460ff16610e34576040517f3990ac6800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600c546601000000000000900460ff1615610ea057600b5481610e6c846001600160a01b031660009081526020819052604090205490565b610e769190612941565b1115610ea05760405163f6202a8f60e01b81526001600160a01b03831660048201526024016109b5565b600c546301000000900460ff1615610ef7576001600160a01b03821660009081526006602052604090205460ff1615610ef7576040516332e38af360e21b81526001600160a01b03831660048201526024016109b5565b600c5465010000000000900460ff1615610f4f576001600160a01b03821660009081526007602052604090205460ff16610f4f57604051632ac2e20360e21b81526001600160a01b03831660048201526024016109b5565b610f5982826122fd565b5050565b610f65611a8d565b610f6d611aed565b600c54610100900460ff16610f9557604051636cb5913960e01b815260040160405180910390fd5b610f9e816123c8565b50565b610fa9611a8d565b610fb1611aed565b610fba8161196c565b600c546301000000900460ff16610fe457604051633abeadc360e21b815260040160405180910390fd5b6001600160a01b03811660009081526006602052604090205460ff1615611042576040517f70b8fc840000000000000000000000000000000000000000000000000000000081526001600160a01b03821660048201526024016109b5565b600c5465010000000000900460ff16801561107557506001600160a01b03811660009081526007602052604090205460ff165b156110b7576040517febdacb5f0000000000000000000000000000000000000000000000000000000081526001600160a01b03821660048201526024016109b5565b6001600160a01b038116600081815260066020526040808220805460ff19166001179055517f7f8b7dc89dae85811a7a85800b892b5816ad5d381c856f1b56490f8fc470c9cb9190a250565b61110b611a8d565b611113611aed565b61111c8161196c565b600c546301000000900460ff1661114657604051633abeadc360e21b815260040160405180910390fd5b6001600160a01b03811660009081526006602052604090205460ff166111a3576040517f3d7c1f4a0000000000000000000000000000000000000000000000000000000081526001600160a01b03821660048201526024016109b5565b6001600160a01b038116600081815260066020526040808220805460ff19169055517f4ca5b343d678ca6f1f96e8c8a2115c41c2d40641fd872b928ba6f95d3648b9d19190a250565b6060600880548060200260200160405190810160405280929190818152602001828054801561092a57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611226575050505050905090565b611255611a8d565b61125d611aed565b610de66123d2565b61126d611a8d565b611275611aed565b600c54610100900460ff1661129d57604051636cb5913960e01b815260040160405180910390fd5b610f5982826123e4565b6112af611a8d565b600c5462010000900460ff166112d85760405163f00085b960e01b815260040160405180910390fd5b610de66123f9565b6060600480546108b1906128de565b3360008181526001602090815260408083206001600160a01b03871684529091528120549091908381101561138c5760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f00000000000000000000000000000000000000000000000000000060648201526084016109b5565b6113998286868403611b40565b506001949350505050565b6113ac611a8d565b6113b4611aed565b600c54640100000000900460ff166113f8576040517f70a43fce00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600a61140482826129ee565b507f4456a0b562609d67398ddb488f136db285cd3c92343e0a7ba684925669237ade81604051610809919061263c565b600061143e611aed565b3383611456600c5460ff650100000000009091041690565b1561155a576001600160a01b03821660009081526007602052604090205460ff1661149f5760405163bf3f938960e01b81526001600160a01b03831660048201526024016109b5565b6001600160a01b03811660009081526007602052604090205460ff166114e357604051632ac2e20360e21b81526001600160a01b03821660048201526024016109b5565b6001600160a01b038216331480159061151e575060055461010090046001600160a01b03166001600160a01b0316336001600160a01b031614155b801561153a57503360009081526007602052604090205460ff16155b1561155a5760405163bf3f938960e01b81523360048201526024016109b5565b600c546301000000900460ff161561166c576001600160a01b03821660009081526006602052604090205460ff16156115b15760405163578f3e1360e01b81526001600160a01b03831660048201526024016109b5565b6001600160a01b03811660009081526006602052604090205460ff16156115f6576040516332e38af360e21b81526001600160a01b03821660048201526024016109b5565b6001600160a01b0382163314801590611631575060055461010090046001600160a01b03166001600160a01b0316336001600160a01b031614155b801561164c57503360009081526006602052604090205460ff165b1561166c5760405163578f3e1360e01b81523360048201526024016109b5565b60006116783386611c98565b9050600061168586611ce2565b9050600081611694848961292e565b61169e919061292e565b600c549091506601000000000000900460ff161561170d57600b54816116d98a6001600160a01b031660009081526020819052604090205490565b6116e39190612941565b111561170d5760405163f6202a8f60e01b81526001600160a01b03891660048201526024016109b5565b821561172b57600d5461172b9033906001600160a01b031685611d11565b811561173b5761173b3383611f0b565b6117458882612436565b98975050505050505050565b60098054610821906128de565b6008818154811061176e57600080fd5b6000918252602090912001546001600160a01b0316905081565b611790611a8d565b611798611aed565b600c546901000000000000000000900460ff166117e1576040517fcd9e529800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611388811115611820576040517fbb746520000000000000000000000000000000000000000000000000000000008152600481018290526024016109b5565b600f81905560405181907fc1ff65ee907dc079b64ed9913d53f4bd593bd6ebd9b2a2708db2916d49e17ec390600090a250565b61185b611a8d565b611863611aed565b600c5468010000000000000000900460ff166118ab576040517fc8a478a500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113888111156118ea576040517fcb400e96000000000000000000000000000000000000000000000000000000008152600481018290526024016109b5565b6118f38261196c565b600d805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b038416908117909155600e8290556040518291907facc44e32fd5ca4240f6dbe6e8cf4eb49349c17c5ce5f80f1919a9c97b50d398a90600090a35050565b61195b611a8d565b611963611aed565b610f9e81611982565b8060601b610f9e5763d92e233d6000526004601cfd5b61198a611a8d565b6001600160a01b038116611a065760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016109b5565b610f9e81612444565b60055460ff1615611a885760405162461bcd60e51b815260206004820152602a60248201527f45524332305061757361626c653a20746f6b656e207472616e7366657220776860448201527f696c65207061757365640000000000000000000000000000000000000000000060648201526084016109b5565b505050565b6005546001600160a01b03610100909104163314610de65760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016109b5565b60055460ff1615610de65760405162461bcd60e51b815260206004820152601060248201527f5061757361626c653a207061757365640000000000000000000000000000000060448201526064016109b5565b6001600160a01b038316611bbb5760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f726573730000000000000000000000000000000000000000000000000000000060648201526084016109b5565b6001600160a01b038216611c375760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f737300000000000000000000000000000000000000000000000000000000000060648201526084016109b5565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6000600e54600014158015611cbb5750600d546001600160a01b03848116911614155b1561094857612710600e5483611cd19190612aae565b611cdb9190612ac5565b9392505050565b6000600f54600014611d0c57612710600f5483611cff9190612aae565b611d099190612ac5565b90505b919050565b6001600160a01b038316611d8d5760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f647265737300000000000000000000000000000000000000000000000000000060648201526084016109b5565b6001600160a01b038216611e095760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f657373000000000000000000000000000000000000000000000000000000000060648201526084016109b5565b611e148383836124b5565b6001600160a01b03831660009081526020819052604090205481811015611ea35760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e6365000000000000000000000000000000000000000000000000000060648201526084016109b5565b6001600160a01b03848116600081815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35b50505050565b6001600160a01b038216611f875760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f730000000000000000000000000000000000000000000000000000000000000060648201526084016109b5565b611f93826000836124b5565b6001600160a01b038216600090815260208190526040902054818110156120225760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f636500000000000000000000000000000000000000000000000000000000000060648201526084016109b5565b6001600160a01b0383166000818152602081815260408083208686039055600280548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3505050565b60003361208e8582856124c0565b611399858585611d11565b600060088054806020026020016040519081016040528092919081815260200182805480156120f157602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116120d3575b5050505050905060005b8151811015610f59576007600083838151811061211a5761211a612ae7565b6020908102919091018101516001600160a01b03168252810191909152604001600020805460ff191690556001016120fb565b60005b81811015611a885761218783838381811061216d5761216d612ae7565b9050602002016020810190612182919061277c565b61196c565b600c546301000000900460ff1680156121e45750600660008484848181106121b1576121b1612ae7565b90506020020160208101906121c6919061277c565b6001600160a01b0316815260208101919091526040016000205460ff165b1561224e578282828181106121fb576121fb612ae7565b9050602002016020810190612210919061277c565b6040517f2cf5f7dd0000000000000000000000000000000000000000000000000000000081526001600160a01b0390911660048201526024016109b5565b60016007600085858581811061226657612266612ae7565b905060200201602081019061227b919061277c565b6001600160a01b031681526020810191909152604001600020805460ff1916911515919091179055600101612150565b6122b361254c565b6005805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b6001600160a01b0382166123535760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016109b5565b61235f600083836124b5565b80600260008282546123719190612941565b90915550506001600160a01b038216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b610f9e3382611f0b565b6123da611a8d565b610de66000612444565b6123ef8233836124c0565b610f598282611f0b565b612401611aed565b6005805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586122e03390565b600033610942818585611d11565b600580546001600160a01b038381166101008181027fffffffffffffffffffffff0000000000000000000000000000000000000000ff85161790945560405193909204169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b611a88838383611a0f565b6001600160a01b038381166000908152600160209081526040808320938616835292905220546000198114611f05578181101561253f5760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e636500000060448201526064016109b5565b611f058484848403611b40565b60055460ff16610de65760405162461bcd60e51b815260206004820152601460248201527f5061757361626c653a206e6f742070617573656400000000000000000000000060448201526064016109b5565b8280548282559060005260206000209081019282156125fe579160200282015b828111156125fe57815473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b038435161782556020909201916001909101906125be565b5061260a92915061260e565b5090565b5b8082111561260a576000815560010161260f565b60006020828403121561263557600080fd5b5035919050565b600060208083528351808285015260005b818110156126695785810183015185820160400152820161264d565b506000604082860101526040601f19601f8301168501019250505092915050565b80356001600160a01b0381168114611d0c57600080fd5b600080604083850312156126b457600080fd5b6126bd8361268a565b946020939093013593505050565b6000806000606084860312156126e057600080fd5b6126e98461268a565b92506126f76020850161268a565b9150604084013590509250925092565b6000806020838503121561271a57600080fd5b823567ffffffffffffffff8082111561273257600080fd5b818501915085601f83011261274657600080fd5b81358181111561275557600080fd5b8660208260051b850101111561276a57600080fd5b60209290920196919550909350505050565b60006020828403121561278e57600080fd5b611cdb8261268a565b6020808252825182820181905260009190848201906040850190845b818110156127d85783516001600160a01b0316835292840192918401916001016127b3565b50909695505050505050565b634e487b7160e01b600052604160045260246000fd5b60006020828403121561280c57600080fd5b813567ffffffffffffffff8082111561282457600080fd5b818401915084601f83011261283857600080fd5b81358181111561284a5761284a6127e4565b604051601f8201601f19908116603f01168101908382118183101715612872576128726127e4565b8160405282815287602084870101111561288b57600080fd5b826020860160208301376000928101602001929092525095945050505050565b600080604083850312156128be57600080fd5b6128c78361268a565b91506128d56020840161268a565b90509250929050565b600181811c908216806128f257607f821691505b60208210810361291257634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b8181038181111561094857610948612918565b8082018082111561094857610948612918565b60208082528181018390526000908460408401835b86811015612995576001600160a01b036129828461268a565b1682529183019190830190600101612969565b509695505050505050565b601f821115611a8857600081815260208120601f850160051c810160208610156129c75750805b601f850160051c820191505b818110156129e6578281556001016129d3565b505050505050565b815167ffffffffffffffff811115612a0857612a086127e4565b612a1c81612a1684546128de565b846129a0565b602080601f831160018114612a515760008415612a395750858301515b600019600386901b1c1916600185901b1785556129e6565b600085815260208120601f198616915b82811015612a8057888601518255948401946001909101908401612a61565b5085821015612a9e5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b808202811582820484141761094857610948612918565b600082612ae257634e487b7160e01b600052601260045260246000fd5b500490565b634e487b7160e01b600052603260045260246000fdfea264697066735822122030d0fa8f27a883250c7a7bacf402c50c65a40c6ec96ccb650d9fc1a5f93ae6a064736f6c63430008110033

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

000000000000000000000000000000000000000000000000000000000000028000000000000000000000000000000000000000000000000000000000000002c0000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000000120000000000000000000000005f4f120d8435ea38f0f4635a910fee03801be88d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000005f4f120d8435ea38f0f4635a910fee03801be88d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000104f7074696d697374696350756572636f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000084f5050756572636f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

-----Decoded View---------------
Arg [0] : name_ (string): OptimisticPuerco
Arg [1] : symbol_ (string): OPPuerco
Arg [2] : initialSupplyToSet (uint256): 100
Arg [3] : decimalsToSet (uint8): 18
Arg [4] : tokenOwner (address): 0x5f4f120D8435ea38F0F4635A910fEe03801BE88d
Arg [5] : customConfigProps (tuple): System.Collections.Generic.List`1[Nethereum.ABI.FunctionEncoding.ParameterOutput]
Arg [6] : maxTokenAmount (uint256): 0
Arg [7] : newDocumentUri (string):
Arg [8] : _taxAddress (address): 0x5f4f120D8435ea38F0F4635A910fEe03801BE88d
Arg [9] : _taxBPS (uint256): 0
Arg [10] : _deflationBPS (uint256): 0

-----Encoded View---------------
25 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000280
Arg [1] : 00000000000000000000000000000000000000000000000000000000000002c0
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000064
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000012
Arg [4] : 0000000000000000000000005f4f120d8435ea38f0f4635a910fee03801be88d
Arg [5] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [6] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [7] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [8] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [9] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [10] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [11] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [12] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [13] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [14] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [15] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [16] : 0000000000000000000000000000000000000000000000000000000000000300
Arg [17] : 0000000000000000000000005f4f120d8435ea38f0f4635a910fee03801be88d
Arg [18] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [19] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [20] : 0000000000000000000000000000000000000000000000000000000000000010
Arg [21] : 4f7074696d697374696350756572636f00000000000000000000000000000000
Arg [22] : 0000000000000000000000000000000000000000000000000000000000000008
Arg [23] : 4f5050756572636f000000000000000000000000000000000000000000000000
Arg [24] : 0000000000000000000000000000000000000000000000000000000000000000


Deployed Bytecode Sourcemap

610:22889:8:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11338:406;;;;;;:::i;:::-;;:::i;:::-;;1259:25;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;2158:98:2;;;:::i;4444:197::-;;;;;;:::i;:::-;;:::i;:::-;;;1377:14:10;;1370:22;1352:41;;1340:2;1325:18;4444:197:2;1212:187:10;3255:106:2;3342:12;;3255:106;;;1550:25:10;;;1538:2;1523:18;3255:106:2;1404:177:10;9272:106:8;9342:11;:31;;;;;;9272:106;;16655:898;;;;;;:::i;:::-;;:::i;2256:21::-;;;;;;10030:92;;;2091:4:10;10108:9:8;2079:17:10;2061:36;;2049:2;2034:18;10030:92:8;1919:184:10;21186:339:8;;;;;;:::i;:::-;;:::i;1370:38::-;;;;;5854:234:2;;;;;;:::i;:::-;;:::i;20098:124:8:-;;;:::i;18185:574::-;;;;;;:::i;:::-;;:::i;19038:164::-;;;;;;:::i;:::-;;:::i;8777:90::-;8839:11;:23;;;8777:90;;12142:438;;;;;;:::i;:::-;;:::i;10184:88::-;10245:11;:22;;;;;;10184:88;;12912:344;;;;;;:::i;:::-;;:::i;2281:27::-;;;;;;9470:114;9544:11;:35;;;;;;9470:114;;1615:84:1;1685:7;;;;1615:84;;9840:114:8;9914:11;:35;;;;;;9840:114;;10595;;;:::i;:::-;;;;;;;:::i;3419:125:2:-;;;;;;:::i;:::-;-1:-1:-1;;;;;3519:18:2;3493:7;3519:18;;;;;;;;;;;;3419:125;20478:105:8;;;:::i;19562:204::-;;;;;;:::i;:::-;;:::i;19871:120::-;;;:::i;9093:106::-;9163:11;:31;;;;;;9093:106;;8930:90;8992:11;:23;;;;;;8930:90;;1201:85:0;1273:6;;;;;-1:-1:-1;;;;;1273:6:0;1201:85;;;-1:-1:-1;;;;;3769:55:10;;;3751:74;;3739:2;3724:18;1201:85:0;3605:226:10;2098:42:8;;;;;10339:98;10405:11;:27;;;;;;10339:98;;2369:102:2;;;:::i;963:41:8:-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;8624:90;8686:11;:23;;;;;;8624:90;;1474:56;;;;;6575:427:2;;;;;;:::i;:::-;;:::i;10875:254:8:-;;;;;;:::i;:::-;;:::i;15062:743::-;;;;;;:::i;:::-;;:::i;1176:32::-;;;:::i;2227:25::-;;;;;-1:-1:-1;;;;;2227:25:8;;;1062:37;;;;;;:::i;:::-;;:::i;1588:39::-;;;;;;13950:347;;;;;;:::i;:::-;;:::i;3987:149:2:-;;;;;;:::i;:::-;-1:-1:-1;;;;;4102:18:2;;;4076:7;4102:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;3987:149;13419:395:8;;;;;;:::i;:::-;;:::i;20811:137::-;;;;;;:::i;:::-;;:::i;9657:107::-;9729:11;:30;;;;;;9657:107;;11338:406;1094:13:0;:11;:13::i;:::-;1239:19:1::1;:17;:19::i;:::-;9544:11:8::0;:35;;;;;;11449:79:::2;;11495:26;;;;;;;;;;;;;;11449:79;11558:24;;11537:17;:45;11533:106;;11599:33;;;;;;;;;;;;;;11533:106;11645:24;:44:::0;;;11700:39:::2;::::0;1550:25:10;;;11700:39:8::2;::::0;1538:2:10;1523:18;11700:39:8::2;;;;;;;;11338:406:::0;:::o;1259:25::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;2158:98:2:-;2212:13;2244:5;2237:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2158:98;:::o;4444:197::-;4527:4;719:10:7;4581:32:2;719:10:7;4597:7:2;4606:6;4581:8;:32::i;:::-;4630:4;4623:11;;;4444:197;;;;;:::o;16655:898:8:-;16833:4;1239:19:1;:17;:19::i;:::-;16810:4:8::1;16816:2;5750:20;9342:11:::0;:31;;;;;;;;9272:106;5750:20:::1;5746:370;;;-1:-1:-1::0;;;;;5785:17:8;::::1;;::::0;;;:9:::1;:17;::::0;;;;;::::1;;5780:78;;5821:28;::::0;-1:-1:-1;;;5821:28:8;;-1:-1:-1;;;;;3769:55:10;;5821:28:8::1;::::0;::::1;3751:74:10::0;3724:18;;5821:28:8::1;;;;;;;;5780:78;-1:-1:-1::0;;;;;5870:20:8;::::1;;::::0;;;:9:::1;:20;::::0;;;;;::::1;;5865:87;;5909:34;::::0;-1:-1:-1;;;5909:34:8;;-1:-1:-1;;;;;3769:55:10;;5909:34:8::1;::::0;::::1;3751:74:10::0;3724:18;;5909:34:8::1;3605:226:10::0;5865:87:8::1;-1:-1:-1::0;;;;;5972:20:8;::::1;5982:10;5972:20;::::0;::::1;::::0;:45:::1;;-1:-1:-1::0;1273:6:0;;;;;-1:-1:-1;;;;;1273:6:0;-1:-1:-1;;;;;5996:21:8::1;:10;-1:-1:-1::0;;;;;5996:21:8::1;;;5972:45;:71;;;;-1:-1:-1::0;6032:10:8::1;6022:21;::::0;;;:9:::1;:21;::::0;;;;;::::1;;6021:22;5972:71;5959:151;;;6069:32;::::0;-1:-1:-1;;;6069:32:8;;6090:10:::1;6069:32;::::0;::::1;3751:74:10::0;3724:18;;6069:32:8::1;3605:226:10::0;5959:151:8::1;9163:11:::0;:31;;;;;;6121:389:::1;;;-1:-1:-1::0;;;;;6159:22:8;::::1;;::::0;;;:14:::1;:22;::::0;;;;;::::1;;6155:79;;;6200:25;::::0;-1:-1:-1;;;6200:25:8;;-1:-1:-1;;;;;3769:55:10;;6200:25:8::1;::::0;::::1;3751:74:10::0;3724:18;;6200:25:8::1;3605:226:10::0;6155:79:8::1;-1:-1:-1::0;;;;;6245:25:8;::::1;;::::0;;;:14:::1;:25;::::0;;;;;::::1;;6241:88;;;6289:31;::::0;-1:-1:-1;;;6289:31:8;;-1:-1:-1;;;;;3769:55:10;;6289:31:8::1;::::0;::::1;3751:74:10::0;3724:18;;6289:31:8::1;3605:226:10::0;6241:88:8::1;-1:-1:-1::0;;;;;6349:20:8;::::1;6359:10;6349:20;::::0;::::1;::::0;:53:::1;;-1:-1:-1::0;1273:6:0;;;;;-1:-1:-1;;;;;1273:6:0;-1:-1:-1;;;;;6381:21:8::1;:10;-1:-1:-1::0;;;;;6381:21:8::1;;;6349:53;:91;;;;-1:-1:-1::0;6429:10:8::1;6414:26;::::0;;;:14:::1;:26;::::0;;;;;::::1;;6349:91;6336:168;;;6466:29;::::0;-1:-1:-1;;;6466:29:8;;6484:10:::1;6466:29;::::0;::::1;3751:74:10::0;3724:18;;6466:29:8::1;3605:226:10::0;6336:168:8::1;16847:17:::2;16867:24;16878:4;16884:6;16867:10;:24::i;:::-;16847:44;;16897:23;16923:24;16940:6;16923:16;:24::i;:::-;16897:50:::0;-1:-1:-1;16953:24:8::2;16897:50:::0;16980:18:::2;16989:9:::0;16980:6;:18:::2;:::i;:::-;:36;;;;:::i;:::-;9544:11:::0;:35;16953:63;;-1:-1:-1;9544:35:8;;;;;17023:167:::2;;;17100:24;;17081:16;17065:13;17075:2;-1:-1:-1::0;;;;;3519:18:2;3493:7;3519:18;;;;;;;;;;;;3419:125;17065:13:8::2;:32;;;;:::i;:::-;:59;17061:123;;;17143:32;::::0;-1:-1:-1;;;17143:32:8;;-1:-1:-1;;;;;3769:55:10;;17143:32:8::2;::::0;::::2;3751:74:10::0;3724:18;;17143:32:8::2;3605:226:10::0;17061:123:8::2;17200:14:::0;;17196:73:::2;;17240:10;::::0;17224:38:::2;::::0;17234:4;;-1:-1:-1;;;;;17240:10:8::2;17252:9:::0;17224::::2;:38::i;:::-;17278:20:::0;;17274:69:::2;;17308:28;17314:4;17320:15;17308:5;:28::i;:::-;9914:11:::0;:35;;;;;;17353:49:::2;;;;-1:-1:-1::0;1273:6:0;;-1:-1:-1;;;;;1273:6:0;;;;;17392:10:8::2;17381:21;17353:49;17349:200;;;17412:37;17422:4;17428:2;17432:16;17412:9;:37::i;:::-;17464:4;17457:11;;;;;;;17349:200;17496:46;17515:4;17521:2;17525:16;17496:18;:46::i;:::-;17489:53;;;;;6515:1;1268::1::1;;16655:898:8::0;;;;;:::o;21186:339::-;1094:13:0;:11;:13::i;:::-;1239:19:1::1;:17;:19::i;:::-;9342:11:8::0;:31;;;;;;21295:70:::2;;21337:21;;;;;;;;;;;;;;21295:70;21370:17;:15;:17::i;:::-;21393:37;21413:16;;21393:19;:37::i;:::-;21436:39;:20;21459:16:::0;;21436:39:::2;:::i;:::-;;21486:34;21503:16;;21486:34;;;;;;;:::i;:::-;;;;;;;;21186:339:::0;;:::o;5854:234:2:-;719:10:7;5942:4:2;4102:18;;;:11;:18;;;;;;;;-1:-1:-1;;;;;4102:27:2;;;;;;;;;;5942:4;;719:10:7;5996:64:2;;719:10:7;;4102:27:2;;6021:38;;6049:10;;6021:38;:::i;:::-;5996:8;:64::i;20098:124:8:-;1094:13:0;:11;:13::i;:::-;8686:11:8;:23;;;;;;20142:60:::1;;20176:19;;-1:-1:-1::0;;;20176:19:8::1;;;;;;;;;;;20142:60;20207:10;:8;:10::i;:::-;20098:124::o:0;18185:574::-;1094:13:0;:11;:13::i;:::-;1239:19:1::1;:17;:19::i;:::-;8839:11:8::0;:23;;;18266:60:::2;;18300:19;;;;;;;;;;;;;;18266:60;9544:11:::0;:35;;;;;;18331:157:::2;;;18398:24;;18389:6;18373:13;18383:2;-1:-1:-1::0;;;;;3519:18:2;3493:7;3519:18;;;;;;;;;;;;3419:125;18373:13:8::2;:22;;;;:::i;:::-;:49;18369:113;;;18441:32;::::0;-1:-1:-1;;;18441:32:8;;-1:-1:-1;;;;;3769:55:10;;18441:32:8::2;::::0;::::2;3751:74:10::0;3724:18;;18441:32:8::2;3605:226:10::0;18369:113:8::2;9163:11:::0;:31;;;;;;18493:114:::2;;;-1:-1:-1::0;;;;;18531:18:8;::::2;;::::0;;;:14:::2;:18;::::0;;;;;::::2;;18527:74;;;18568:24;::::0;-1:-1:-1;;;18568:24:8;;-1:-1:-1;;;;;3769:55:10;;18568:24:8::2;::::0;::::2;3751:74:10::0;3724:18;;18568:24:8::2;3605:226:10::0;18527:74:8::2;9342:11:::0;:31;;;;;;18612:113:::2;;;-1:-1:-1::0;;;;;18651:13:8;::::2;;::::0;;;:9:::2;:13;::::0;;;;;::::2;;18646:73;;18683:27;::::0;-1:-1:-1;;;18683:27:8;;-1:-1:-1;;;;;3769:55:10;;18683:27:8::2;::::0;::::2;3751:74:10::0;3724:18;;18683:27:8::2;3605:226:10::0;18646:73:8::2;18731:23;18743:2;18747:6;18731:11;:23::i;:::-;18185:574:::0;;:::o;19038:164::-;1094:13:0;:11;:13::i;:::-;1239:19:1::1;:17;:19::i;:::-;8992:11:8::0;:23;;;;;;19114:60:::2;;19148:19;;-1:-1:-1::0;;;19148:19:8::2;;;;;;;;;;;19114:60;19179:18;19190:6;19179:10;:18::i;:::-;19038:164:::0;:::o;12142:438::-;1094:13:0;:11;:13::i;:::-;1239:19:1::1;:17;:19::i;:::-;12214:31:8::2;12240:4;12214:25;:31::i;:::-;9163:11:::0;:31;;;;;;12251:70:::2;;12293:21;;-1:-1:-1::0;;;12293:21:8::2;;;;;;;;;;;12251:70;-1:-1:-1::0;;;;;12330:20:8;::::2;;::::0;;;:14:::2;:20;::::0;;;;;::::2;;12326:76;;;12367:28;::::0;::::2;::::0;;-1:-1:-1;;;;;3769:55:10;;12367:28:8::2;::::0;::::2;3751:74:10::0;3724:18;;12367:28:8::2;3605:226:10::0;12326:76:8::2;9342:11:::0;:31;;;;;;12411:39:::2;;;;-1:-1:-1::0;;;;;;12435:15:8;::::2;;::::0;;;:9:::2;:15;::::0;;;;;::::2;;12411:39;12407:103;;;12467:36;::::0;::::2;::::0;;-1:-1:-1;;;;;3769:55:10;;12467:36:8::2;::::0;::::2;3751:74:10::0;3724:18;;12467:36:8::2;3605:226:10::0;12407:103:8::2;-1:-1:-1::0;;;;;12516:20:8;::::2;;::::0;;;:14:::2;:20;::::0;;;;;:27;;-1:-1:-1;;12516:27:8::2;12539:4;12516:27;::::0;;12554:21;::::2;::::0;12516:20;12554:21:::2;12142:438:::0;:::o;12912:344::-;1094:13:0;:11;:13::i;:::-;1239:19:1::1;:17;:19::i;:::-;12994:31:8::2;13020:4;12994:25;:31::i;:::-;9163:11:::0;:31;;;;;;13031:70:::2;;13073:21;;-1:-1:-1::0;;;13073:21:8::2;;;;;;;;;;;13031:70;-1:-1:-1::0;;;;;13111:20:8;::::2;;::::0;;;:14:::2;:20;::::0;;;;;::::2;;13106:79;;13148:30;::::0;::::2;::::0;;-1:-1:-1;;;;;3769:55:10;;13148:30:8::2;::::0;::::2;3751:74:10::0;3724:18;;13148:30:8::2;3605:226:10::0;13106:79:8::2;-1:-1:-1::0;;;;;13197:20:8;::::2;;::::0;;;:14:::2;:20;::::0;;;;;13190:27;;-1:-1:-1;;13190:27:8::2;::::0;;13228:23;::::2;::::0;13197:20;13228:23:::2;12912:344:::0;:::o;10595:114::-;10653:16;10684:20;10677:27;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;10677:27:8;;;;;;;;;;;;;;;;;;;;;;10595:114;:::o;20478:105::-;1094:13:0;:11;:13::i;:::-;1239:19:1::1;:17;:19::i;:::-;20553:25:8::2;:23;:25::i;19562:204::-:0;1094:13:0;:11;:13::i;:::-;1239:19:1::1;:17;:19::i;:::-;8992:11:8::0;:23;;;;;;19668:60:::2;;19702:19;;-1:-1:-1::0;;;19702:19:8::2;;;;;;;;;;;19668:60;19733:28;19748:4;19754:6;19733:14;:28::i;19871:120::-:0;1094:13:0;:11;:13::i;:::-;8686:11:8;:23;;;;;;19913:60:::1;;19947:19;;-1:-1:-1::0;;;19947:19:8::1;;;;;;;;;;;19913:60;19978:8;:6;:8::i;2369:102:2:-:0;2425:13;2457:7;2450:14;;;;;:::i;6575:427::-;719:10:7;6668:4:2;4102:18;;;:11;:18;;;;;;;;-1:-1:-1;;;;;4102:27:2;;;;;;;;;;6668:4;;719:10:7;6812:15:2;6792:16;:35;;6784:85;;;;-1:-1:-1;;;6784:85:2;;6977:2:10;6784:85:2;;;6959:21:10;7016:2;6996:18;;;6989:30;7055:34;7035:18;;;7028:62;7126:7;7106:18;;;7099:35;7151:19;;6784:85:2;6775:401:10;6784:85:2;6903:60;6912:5;6919:7;6947:15;6928:16;:34;6903:8;:60::i;:::-;-1:-1:-1;6991:4:2;;6575:427;-1:-1:-1;;;;6575:427:2:o;10875:254:8:-;1094:13:0;:11;:13::i;:::-;1239:19:1::1;:17;:19::i;:::-;9729:11:8::0;:30;;;;;;10976:74:::2;;11020:23;;;;;;;;;;;;;;10976:74;11055:11;:28;11069:14:::0;11055:11;:28:::2;:::i;:::-;;11094:30;11109:14;11094:30;;;;;;:::i;15062:743::-:0;15224:4;1239:19:1;:17;:19::i;:::-;15195:10:8::1;15207:2;5750:20;9342:11:::0;:31;;;;;;;;9272:106;5750:20:::1;5746:370;;;-1:-1:-1::0;;;;;5785:17:8;::::1;;::::0;;;:9:::1;:17;::::0;;;;;::::1;;5780:78;;5821:28;::::0;-1:-1:-1;;;5821:28:8;;-1:-1:-1;;;;;3769:55:10;;5821:28:8::1;::::0;::::1;3751:74:10::0;3724:18;;5821:28:8::1;3605:226:10::0;5780:78:8::1;-1:-1:-1::0;;;;;5870:20:8;::::1;;::::0;;;:9:::1;:20;::::0;;;;;::::1;;5865:87;;5909:34;::::0;-1:-1:-1;;;5909:34:8;;-1:-1:-1;;;;;3769:55:10;;5909:34:8::1;::::0;::::1;3751:74:10::0;3724:18;;5909:34:8::1;3605:226:10::0;5865:87:8::1;-1:-1:-1::0;;;;;5972:20:8;::::1;5982:10;5972:20;::::0;::::1;::::0;:45:::1;;-1:-1:-1::0;1273:6:0;;;;;-1:-1:-1;;;;;1273:6:0;-1:-1:-1;;;;;5996:21:8::1;:10;-1:-1:-1::0;;;;;5996:21:8::1;;;5972:45;:71;;;;-1:-1:-1::0;6032:10:8::1;6022:21;::::0;;;:9:::1;:21;::::0;;;;;::::1;;6021:22;5972:71;5959:151;;;6069:32;::::0;-1:-1:-1;;;6069:32:8;;6090:10:::1;6069:32;::::0;::::1;3751:74:10::0;3724:18;;6069:32:8::1;3605:226:10::0;5959:151:8::1;9163:11:::0;:31;;;;;;6121:389:::1;;;-1:-1:-1::0;;;;;6159:22:8;::::1;;::::0;;;:14:::1;:22;::::0;;;;;::::1;;6155:79;;;6200:25;::::0;-1:-1:-1;;;6200:25:8;;-1:-1:-1;;;;;3769:55:10;;6200:25:8::1;::::0;::::1;3751:74:10::0;3724:18;;6200:25:8::1;3605:226:10::0;6155:79:8::1;-1:-1:-1::0;;;;;6245:25:8;::::1;;::::0;;;:14:::1;:25;::::0;;;;;::::1;;6241:88;;;6289:31;::::0;-1:-1:-1;;;6289:31:8;;-1:-1:-1;;;;;3769:55:10;;6289:31:8::1;::::0;::::1;3751:74:10::0;3724:18;;6289:31:8::1;3605:226:10::0;6241:88:8::1;-1:-1:-1::0;;;;;6349:20:8;::::1;6359:10;6349:20;::::0;::::1;::::0;:53:::1;;-1:-1:-1::0;1273:6:0;;;;;-1:-1:-1;;;;;1273:6:0;-1:-1:-1;;;;;6381:21:8::1;:10;-1:-1:-1::0;;;;;6381:21:8::1;;;6349:53;:91;;;;-1:-1:-1::0;6429:10:8::1;6414:26;::::0;;;:14:::1;:26;::::0;;;;;::::1;;6349:91;6336:168;;;6466:29;::::0;-1:-1:-1;;;6466:29:8;;6484:10:::1;6466:29;::::0;::::1;3751:74:10::0;3724:18;;6466:29:8::1;3605:226:10::0;6336:168:8::1;15238:17:::2;15258:30;15269:10;15281:6;15258:10;:30::i;:::-;15238:50;;15294:23;15320:24;15337:6;15320:16;:24::i;:::-;15294:50:::0;-1:-1:-1;15350:24:8::2;15294:50:::0;15377:18:::2;15386:9:::0;15377:6;:18:::2;:::i;:::-;:36;;;;:::i;:::-;9544:11:::0;:35;15350:63;;-1:-1:-1;9544:35:8;;;;;15420:167:::2;;;15497:24;;15478:16;15462:13;15472:2;-1:-1:-1::0;;;;;3519:18:2;3493:7;3519:18;;;;;;;;;;;;3419:125;15462:13:8::2;:32;;;;:::i;:::-;:59;15458:123;;;15540:32;::::0;-1:-1:-1;;;15540:32:8;;-1:-1:-1;;;;;3769:55:10;;15540:32:8::2;::::0;::::2;3751:74:10::0;3724:18;;15540:32:8::2;3605:226:10::0;15458:123:8::2;15597:14:::0;;15593:79:::2;;15643:10;::::0;15621:44:::2;::::0;15631:10:::2;::::0;-1:-1:-1;;;;;15643:10:8::2;15655:9:::0;15621::::2;:44::i;:::-;15681:20:::0;;15677:75:::2;;15711:34;15717:10;15729:15;15711:5;:34::i;:::-;15764:36;15779:2;15783:16;15764:14;:36::i;:::-;15757:43:::0;15062:743;-1:-1:-1;;;;;;;;15062:743:8:o;1176:32::-;;;;;;;:::i;1062:37::-;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;1062:37:8;;-1:-1:-1;1062:37:8;:::o;13950:347::-;1094:13:0;:11;:13::i;:::-;1239:19:1::1;:17;:19::i;:::-;10405:11:8::0;:27;;;;;;14048:69:::2;;14086:24;;;;;;;;;;;;;;14048:69;783:5;14126:13;:31;14122:93;;;14174:34;::::0;::::2;::::0;;::::2;::::0;::::2;1550:25:10::0;;;1523:18;;14174:34:8::2;1404:177:10::0;14122:93:8::2;14220:12;:28:::0;;;14259:33:::2;::::0;14235:13;;14259:33:::2;::::0;;;::::2;13950:347:::0;:::o;13419:395::-;1094:13:0;:11;:13::i;:::-;1239:19:1::1;:17;:19::i;:::-;10245:11:8::0;:22;;;;;;13530:59:::2;;13563:19;;;;;;;;;;;;;;13530:59;783:5;13598:7;:25;13594:75;;;13640:22;::::0;::::2;::::0;;::::2;::::0;::::2;1550:25:10::0;;;1523:18;;13640:22:8::2;1404:177:10::0;13594:75:8::2;13674:38;13700:11;13674:25;:38::i;:::-;13718:10;:24:::0;;-1:-1:-1;;13718:24:8::2;-1:-1:-1::0;;;;;13718:24:8;::::2;::::0;;::::2;::::0;;;13748:6:::2;:16:::0;;;13775:34:::2;::::0;13748:16;;13718:24;13775:34:::2;::::0;-1:-1:-1;;13775:34:8::2;13419:395:::0;;:::o;20811:137::-;1094:13:0;:11;:13::i;:::-;1239:19:1::1;:17;:19::i;:::-;20910:33:8::2;20934:8;20910:23;:33::i;1674:396:9:-:0;1820:4;1816:2;1812:13;1802:258;;1975:10;1969:4;1962:24;2047:4;2041;2034:18;2074:198:0;1094:13;:11;:13::i;:::-;-1:-1:-1;;;;;2162:22:0;::::1;2154:73;;;::::0;-1:-1:-1;;;2154:73:0;;9587:2:10;2154:73:0::1;::::0;::::1;9569:21:10::0;9626:2;9606:18;;;9599:30;9665:34;9645:18;;;9638:62;9736:8;9716:18;;;9709:36;9762:19;;2154:73:0::1;9385:402:10::0;2154:73:0::1;2237:28;2256:8;2237:18;:28::i;1046:234:5:-:0;1685:7:1;;;;1217:9:5;1209:64;;;;-1:-1:-1;;;1209:64:5;;9994:2:10;1209:64:5;;;9976:21:10;10033:2;10013:18;;;10006:30;10072:34;10052:18;;;10045:62;10143:12;10123:18;;;10116:40;10173:19;;1209:64:5;9792:406:10;1209:64:5;1046:234;;;:::o;1359:130:0:-;1273:6;;-1:-1:-1;;;;;1273:6:0;;;;;719:10:7;1422:23:0;1414:68;;;;-1:-1:-1;;;1414:68:0;;10405:2:10;1414:68:0;;;10387:21:10;;;10424:18;;;10417:30;10483:34;10463:18;;;10456:62;10535:18;;1414:68:0;10203:356:10;1767:106:1;1685:7;;;;1836:9;1828:38;;;;-1:-1:-1;;;1828:38:1;;10766:2:10;1828:38:1;;;10748:21:10;10805:2;10785:18;;;10778:30;10844:18;10824;;;10817:46;10880:18;;1828:38:1;10564:340:10;10457::2;-1:-1:-1;;;;;10558:19:2;;10550:68;;;;-1:-1:-1;;;10550:68:2;;11111:2:10;10550:68:2;;;11093:21:10;11150:2;11130:18;;;11123:30;11189:34;11169:18;;;11162:62;11260:6;11240:18;;;11233:34;11284:19;;10550:68:2;10909:400:10;10550:68:2;-1:-1:-1;;;;;10636:21:2;;10628:68;;;;-1:-1:-1;;;10628:68:2;;11516:2:10;10628:68:2;;;11498:21:10;11555:2;11535:18;;;11528:30;11594:34;11574:18;;;11567:62;11665:4;11645:18;;;11638:32;11687:19;;10628:68:2;11314:398:10;10628:68:2;-1:-1:-1;;;;;10707:18:2;;;;;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;:36;;;10758:32;;1550:25:10;;;10758:32:2;;1523:18:10;10758:32:2;;;;;;;10457:340;;;:::o;22860:237:8:-;22947:17;22995:6;;23005:1;22995:11;;:35;;;;-1:-1:-1;23020:10:8;;-1:-1:-1;;;;;23010:20:8;;;23020:10;;23010:20;;22995:35;22991:102;;;730:6;23062;;23053;:15;;;;:::i;:::-;23052:34;;;;:::i;:::-;23040:46;22860:237;-1:-1:-1;;;22860:237:8:o;23268:229::-;23341:23;23401:12;;23417:1;23401:17;23397:96;;730:6;23456:12;;23447:6;:21;;;;:::i;:::-;23446:40;;;;:::i;:::-;23428:58;;23397:96;23268:229;;;:::o;7456:788:2:-;-1:-1:-1;;;;;7552:18:2;;7544:68;;;;-1:-1:-1;;;7544:68:2;;12371:2:10;7544:68:2;;;12353:21:10;12410:2;12390:18;;;12383:30;12449:34;12429:18;;;12422:62;12520:7;12500:18;;;12493:35;12545:19;;7544:68:2;12169:401:10;7544:68:2;-1:-1:-1;;;;;7630:16:2;;7622:64;;;;-1:-1:-1;;;7622:64:2;;12777:2:10;7622:64:2;;;12759:21:10;12816:2;12796:18;;;12789:30;12855:34;12835:18;;;12828:62;12926:5;12906:18;;;12899:33;12949:19;;7622:64:2;12575:399:10;7622:64:2;7697:38;7718:4;7724:2;7728:6;7697:20;:38::i;:::-;-1:-1:-1;;;;;7768:15:2;;7746:19;7768:15;;;;;;;;;;;7801:21;;;;7793:72;;;;-1:-1:-1;;;7793:72:2;;13181:2:10;7793:72:2;;;13163:21:10;13220:2;13200:18;;;13193:30;13259:34;13239:18;;;13232:62;13330:8;13310:18;;;13303:36;13356:19;;7793:72:2;12979:402:10;7793:72:2;-1:-1:-1;;;;;7899:15:2;;;:9;:15;;;;;;;;;;;7917:20;;;7899:38;;8114:13;;;;;;;;;;:23;;;;;;8163:26;;1550:25:10;;;8114:13:2;;8163:26;;1523:18:10;8163:26:2;;;;;;;8200:37;7534:710;7456:788;;;:::o;9375:659::-;-1:-1:-1;;;;;9458:21:2;;9450:67;;;;-1:-1:-1;;;9450:67:2;;13588:2:10;9450:67:2;;;13570:21:10;13627:2;13607:18;;;13600:30;13666:34;13646:18;;;13639:62;13737:3;13717:18;;;13710:31;13758:19;;9450:67:2;13386:397:10;9450:67:2;9528:49;9549:7;9566:1;9570:6;9528:20;:49::i;:::-;-1:-1:-1;;;;;9613:18:2;;9588:22;9613:18;;;;;;;;;;;9649:24;;;;9641:71;;;;-1:-1:-1;;;9641:71:2;;13990:2:10;9641:71:2;;;13972:21:10;14029:2;14009:18;;;14002:30;14068:34;14048:18;;;14041:62;14139:4;14119:18;;;14112:32;14161:19;;9641:71:2;13788:398:10;9641:71:2;-1:-1:-1;;;;;9746:18:2;;:9;:18;;;;;;;;;;;9767:23;;;9746:44;;9883:12;:22;;;;;;;9931:37;1550:25:10;;;9746:9:2;;:18;9931:37;;1523:18:10;9931:37:2;;;;;;;1046:234:5;;;:::o;5203:256:2:-;5300:4;719:10:7;5356:38:2;5372:4;719:10:7;5387:6:2;5356:15;:38::i;:::-;5404:27;5414:4;5420:2;5424:6;5404:9;:27::i;22301:218:8:-;22360:26;22389:20;22360:49;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;22360:49:8;;;;;;;;;;;;;;;;;;;;;;;22422:9;22417:92;22437:9;:16;22433:1;:20;22417:92;;;22477:9;:23;22487:9;22497:1;22487:12;;;;;;;;:::i;:::-;;;;;;;;;;;;-1:-1:-1;;;;;22477:23:8;;;;;;;;;;;-1:-1:-1;22477:23:8;22470:30;;-1:-1:-1;;22470:30:8;;;;22455:3;22417:92;;21807:394;21885:9;21880:317;21896:20;;;21880:317;;;21928:39;21954:9;;21964:1;21954:12;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;21928:25;:39::i;:::-;21979:11;:31;;;;;;:63;;;;;22014:14;:28;22029:9;;22039:1;22029:12;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;22014:28:8;;;;;;;;;;;;-1:-1:-1;22014:28:8;;;;21979:63;21975:139;;;22092:9;;22102:1;22092:12;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;22061:44;;;;;-1:-1:-1;;;;;3769:55:10;;;22061:44:8;;;3751:74:10;3724:18;;22061:44:8;3605:226:10;21975:139:8;22147:4;22121:9;:23;22131:9;;22141:1;22131:12;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;22121:23:8;;;;;;;;;;;;-1:-1:-1;22121:23:8;:30;;-1:-1:-1;;22121:30:8;;;;;;;;;;-1:-1:-1;22179:3:8;21880:317;;2433:117:1;1486:16;:14;:16::i;:::-;2491:7:::1;:15:::0;;-1:-1:-1;;2491:15:1::1;::::0;;2521:22:::1;719:10:7::0;2530:12:1::1;2521:22;::::0;-1:-1:-1;;;;;3769:55:10;;;3751:74;;3739:2;3724:18;2521:22:1::1;;;;;;;2433:117::o:0;8520:535:2:-;-1:-1:-1;;;;;8603:21:2;;8595:65;;;;-1:-1:-1;;;8595:65:2;;14582:2:10;8595:65:2;;;14564:21:10;14621:2;14601:18;;;14594:30;14660:33;14640:18;;;14633:61;14711:18;;8595:65:2;14380:355:10;8595:65:2;8671:49;8700:1;8704:7;8713:6;8671:20;:49::i;:::-;8747:6;8731:12;;:22;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;;;8899:18:2;;:9;:18;;;;;;;;;;;:28;;;;;;8952:37;1550:25:10;;;8952:37:2;;1523:18:10;8952:37:2;;;;;;;18185:574:8;;:::o;578:89:4:-;633:27;719:10:7;653:6:4;633:5;:27::i;1824:101:0:-;1094:13;:11;:13::i;:::-;1888:30:::1;1915:1;1888:18;:30::i;973:161:4:-:0;1049:46;1065:7;719:10:7;1088:6:4;1049:15;:46::i;:::-;1105:22;1111:7;1120:6;1105:5;:22::i;2186:115:1:-;1239:19;:17;:19::i;:::-;2245:7:::1;:14:::0;;-1:-1:-1;;2245:14:1::1;2255:4;2245:14;::::0;;2274:20:::1;2281:12;719:10:7::0;;640:96;3740:189:2;3819:4;719:10:7;3873:28:2;719:10:7;3890:2:2;3894:6;3873:9;:28::i;2426:187:0:-;2518:6;;;-1:-1:-1;;;;;2534:17:0;;;2518:6;2534:17;;;;;;;;;;2566:40;;2518:6;;;;;;;;2566:40;;2499:16;;2566:40;2489:124;2426:187;:::o;8370:191:8:-;8512:44;8539:4;8545:2;8549:6;8512:26;:44::i;11078:411:2:-;-1:-1:-1;;;;;4102:18:2;;;11178:24;4102:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;-1:-1:-1;;11244:37:2;;11240:243;;11325:6;11305:16;:26;;11297:68;;;;-1:-1:-1;;;11297:68:2;;14942:2:10;11297:68:2;;;14924:21:10;14981:2;14961:18;;;14954:30;15020:31;15000:18;;;14993:59;15069:18;;11297:68:2;14740:353:10;11297:68:2;11407:51;11416:5;11423:7;11451:6;11432:16;:25;11407:8;:51::i;1945:106:1:-;1685:7;;;;2003:41;;;;-1:-1:-1;;;2003:41:1;;15300:2:10;2003:41:1;;;15282:21:10;15339:2;15319:18;;;15312:30;15378:22;15358:18;;;15351:50;15418:18;;2003:41:1;15098:344:10;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;14:180:10;73:6;126:2;114:9;105:7;101:23;97:32;94:52;;;142:1;139;132:12;94:52;-1:-1:-1;165:23:10;;14:180;-1:-1:-1;14:180:10:o;199:548::-;311:4;340:2;369;358:9;351:21;401:6;395:13;444:6;439:2;428:9;424:18;417:34;469:1;479:140;493:6;490:1;487:13;479:140;;;588:14;;;584:23;;578:30;554:17;;;573:2;550:26;543:66;508:10;;479:140;;;483:3;668:1;663:2;654:6;643:9;639:22;635:31;628:42;738:2;731;727:7;722:2;714:6;710:15;706:29;695:9;691:45;687:54;679:62;;;;199:548;;;;:::o;752:196::-;820:20;;-1:-1:-1;;;;;869:54:10;;859:65;;849:93;;938:1;935;928:12;953:254;1021:6;1029;1082:2;1070:9;1061:7;1057:23;1053:32;1050:52;;;1098:1;1095;1088:12;1050:52;1121:29;1140:9;1121:29;:::i;:::-;1111:39;1197:2;1182:18;;;;1169:32;;-1:-1:-1;;;953:254:10:o;1586:328::-;1663:6;1671;1679;1732:2;1720:9;1711:7;1707:23;1703:32;1700:52;;;1748:1;1745;1738:12;1700:52;1771:29;1790:9;1771:29;:::i;:::-;1761:39;;1819:38;1853:2;1842:9;1838:18;1819:38;:::i;:::-;1809:48;;1904:2;1893:9;1889:18;1876:32;1866:42;;1586:328;;;;;:::o;2108:615::-;2194:6;2202;2255:2;2243:9;2234:7;2230:23;2226:32;2223:52;;;2271:1;2268;2261:12;2223:52;2311:9;2298:23;2340:18;2381:2;2373:6;2370:14;2367:34;;;2397:1;2394;2387:12;2367:34;2435:6;2424:9;2420:22;2410:32;;2480:7;2473:4;2469:2;2465:13;2461:27;2451:55;;2502:1;2499;2492:12;2451:55;2542:2;2529:16;2568:2;2560:6;2557:14;2554:34;;;2584:1;2581;2574:12;2554:34;2637:7;2632:2;2622:6;2619:1;2615:14;2611:2;2607:23;2603:32;2600:45;2597:65;;;2658:1;2655;2648:12;2597:65;2689:2;2681:11;;;;;2711:6;;-1:-1:-1;2108:615:10;;-1:-1:-1;;;;2108:615:10:o;2728:186::-;2787:6;2840:2;2828:9;2819:7;2815:23;2811:32;2808:52;;;2856:1;2853;2846:12;2808:52;2879:29;2898:9;2879:29;:::i;2919:681::-;3090:2;3142:21;;;3212:13;;3115:18;;;3234:22;;;3061:4;;3090:2;3313:15;;;;3287:2;3272:18;;;3061:4;3356:218;3370:6;3367:1;3364:13;3356:218;;;3435:13;;-1:-1:-1;;;;;3431:62:10;3419:75;;3549:15;;;;3514:12;;;;3392:1;3385:9;3356:218;;;-1:-1:-1;3591:3:10;;2919:681;-1:-1:-1;;;;;;2919:681:10:o;3836:184::-;-1:-1:-1;;;3885:1:10;3878:88;3985:4;3982:1;3975:15;4009:4;4006:1;3999:15;4025:922;4094:6;4147:2;4135:9;4126:7;4122:23;4118:32;4115:52;;;4163:1;4160;4153:12;4115:52;4203:9;4190:23;4232:18;4273:2;4265:6;4262:14;4259:34;;;4289:1;4286;4279:12;4259:34;4327:6;4316:9;4312:22;4302:32;;4372:7;4365:4;4361:2;4357:13;4353:27;4343:55;;4394:1;4391;4384:12;4343:55;4430:2;4417:16;4452:2;4448;4445:10;4442:36;;;4458:18;;:::i;:::-;4533:2;4527:9;4501:2;4587:13;;-1:-1:-1;;4583:22:10;;;4607:2;4579:31;4575:40;4563:53;;;4631:18;;;4651:22;;;4628:46;4625:72;;;4677:18;;:::i;:::-;4717:10;4713:2;4706:22;4752:2;4744:6;4737:18;4792:7;4787:2;4782;4778;4774:11;4770:20;4767:33;4764:53;;;4813:1;4810;4803:12;4764:53;4869:2;4864;4860;4856:11;4851:2;4843:6;4839:15;4826:46;4914:1;4892:15;;;4909:2;4888:24;4881:35;;;;-1:-1:-1;4896:6:10;4025:922;-1:-1:-1;;;;;4025:922:10:o;4952:260::-;5020:6;5028;5081:2;5069:9;5060:7;5056:23;5052:32;5049:52;;;5097:1;5094;5087:12;5049:52;5120:29;5139:9;5120:29;:::i;:::-;5110:39;;5168:38;5202:2;5191:9;5187:18;5168:38;:::i;:::-;5158:48;;4952:260;;;;;:::o;5217:437::-;5296:1;5292:12;;;;5339;;;5360:61;;5414:4;5406:6;5402:17;5392:27;;5360:61;5467:2;5459:6;5456:14;5436:18;5433:38;5430:218;;-1:-1:-1;;;5501:1:10;5494:88;5605:4;5602:1;5595:15;5633:4;5630:1;5623:15;5430:218;;5217:437;;;:::o;5659:184::-;-1:-1:-1;;;5708:1:10;5701:88;5808:4;5805:1;5798:15;5832:4;5829:1;5822:15;5848:128;5915:9;;;5936:11;;;5933:37;;;5950:18;;:::i;5981:125::-;6046:9;;;6067:10;;;6064:36;;;6080:18;;:::i;6111:659::-;6292:2;6344:21;;;6317:18;;;6400:22;;;6263:4;;6479:6;6453:2;6438:18;;6263:4;6513:231;6527:6;6524:1;6521:13;6513:231;;;-1:-1:-1;;;;;6592:26:10;6611:6;6592:26;:::i;:::-;6588:75;6576:88;;6719:15;;;;6684:12;;;;6549:1;6542:9;6513:231;;;-1:-1:-1;6761:3:10;6111:659;-1:-1:-1;;;;;;6111:659:10:o;7307:545::-;7409:2;7404:3;7401:11;7398:448;;;7445:1;7470:5;7466:2;7459:17;7515:4;7511:2;7501:19;7585:2;7573:10;7569:19;7566:1;7562:27;7556:4;7552:38;7621:4;7609:10;7606:20;7603:47;;;-1:-1:-1;7644:4:10;7603:47;7699:2;7694:3;7690:12;7687:1;7683:20;7677:4;7673:31;7663:41;;7754:82;7772:2;7765:5;7762:13;7754:82;;;7817:17;;;7798:1;7787:13;7754:82;;;7758:3;;;7307:545;;;:::o;8028:1352::-;8154:3;8148:10;8181:18;8173:6;8170:30;8167:56;;;8203:18;;:::i;:::-;8232:97;8322:6;8282:38;8314:4;8308:11;8282:38;:::i;:::-;8276:4;8232:97;:::i;:::-;8384:4;;8448:2;8437:14;;8465:1;8460:663;;;;9167:1;9184:6;9181:89;;;-1:-1:-1;9236:19:10;;;9230:26;9181:89;-1:-1:-1;;7985:1:10;7981:11;;;7977:24;7973:29;7963:40;8009:1;8005:11;;;7960:57;9283:81;;8430:944;;8460:663;7254:1;7247:14;;;7291:4;7278:18;;-1:-1:-1;;8496:20:10;;;8614:236;8628:7;8625:1;8622:14;8614:236;;;8717:19;;;8711:26;8696:42;;8809:27;;;;8777:1;8765:14;;;;8644:19;;8614:236;;;8618:3;8878:6;8869:7;8866:19;8863:201;;;8939:19;;;8933:26;-1:-1:-1;;9022:1:10;9018:14;;;9034:3;9014:24;9010:37;9006:42;8991:58;8976:74;;8863:201;-1:-1:-1;;;;;9110:1:10;9094:14;;;9090:22;9077:36;;-1:-1:-1;8028:1352:10:o;11717:168::-;11790:9;;;11821;;11838:15;;;11832:22;;11818:37;11808:71;;11859:18;;:::i;11890:274::-;11930:1;11956;11946:189;;-1:-1:-1;;;11988:1:10;11981:88;12092:4;12089:1;12082:15;12120:4;12117:1;12110:15;11946:189;-1:-1:-1;12149:9:10;;11890:274::o;14191:184::-;-1:-1:-1;;;14240:1:10;14233:88;14340:4;14337:1;14330:15;14364:4;14361:1;14354:15

Swarm Source

ipfs://30d0fa8f27a883250c7a7bacf402c50c65a40c6ec96ccb650d9fc1a5f93ae6a0
[ 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.