POL Price: $0.388689 (+3.28%)
 

Overview

POL Balance

Polygon PoS Chain LogoPolygon PoS Chain LogoPolygon PoS Chain Logo0 POL

POL Value

$0.00

Sponsored

Transaction Hash
Method
Block
From
To
Transfer Ownersh...512819292023-12-18 18:59:02273 days ago1702925942IN
Denario Silver Coin: DSC Token
0 POL0.0025324652.96051798
0x61010060512819202023-12-18 18:58:44273 days ago1702925924IN
 Create: ERC20WithFees
0 POL0.1171565354.21473982

Parent Transaction Hash Block From To
View All Internal Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
ERC20WithFees

Compiler Version
v0.8.3+commit.8d00100c

Optimization Enabled:
Yes with 2000 runs

Other Settings:
istanbul EvmVersion, MIT license
File 1 of 8 : ERC20WithFees.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.1;
import "./openzeppelin-contracts/token/ERC20/IERC20.sol";
import "./openzeppelin-contracts/utils/Context.sol";
import "./openzeppelin-contracts/token/ERC20/extensions/IERC20Metadata.sol";
import "./openzeppelin-contracts/access/Ownable2Step.sol";
import "./openzeppelin-contracts/utils/math/Math.sol";
import "./IProofOfReserveOracle.sol";

contract ERC20WithFees is Context, IERC20, IERC20Metadata, Ownable2Step {
    event FeeChanged(uint256 newFee);
    event OracleAddressChanged(address oracle);

    mapping(address => uint256) private _balances;
    mapping(address => mapping(address => uint256)) private _allowances;

    uint256 private _totalSupply;
    string public override name;
    string public override symbol;
    uint8 public immutable override decimals;

    // address of the proof of reserves oracle which provides the real world locked amount
    address public oracle;

    // Last time a fee was paid for an address
    mapping(address => uint256) private _feeLastPaid;

    // Addresses not subject to transfer fees
    mapping(address => bool) private _feeExempt;

    // Address where fees are collected
    address private _feeCollectionAddress;

    // address that can mint and burn tokens
    address private _minterAddress;

    /**
     * @notice amount of tokens automatically collected from each holder as fee
     * representing the off chain costs of managing the off chain assets
     * represented by the token
     * expressed as how many tokens are collected from 1 token for each year
     *
     * @dev fees are sent to the feeCollectionAddress, collection happens at every transfer or by calling the collectFees function
     * _feeExempt addresses are not subject to fees
     */
    uint256 public feeRate;
    uint256 private maxFeeDuration;

    uint256 public lastFeeChange;

    uint256 public immutable maxFee;
    uint256 public immutable feeChangeMinDelay;

    uint256 private immutable feePrecision;

    constructor(
        string memory name_,
        string memory symbol_,
        uint8 decimals_,
        uint256 feeRate_,
        uint256 maxFee_,
        uint256 delayFeeChange_,
        address feeCollectionTreasury_,
        address minter_
    ) Ownable2Step() {
        require(maxFee_ <= 10 ** decimals_, "ERC20WithFees: max fee too high");
        require(
            feeRate_ <= maxFee_,
            "ERC20WithFees: fee cannot be more than max fee"
        );
        require(
            feeCollectionTreasury_ != address(0),
            "ERC20WithFees: fee collection address cannot be the zero address"
        );
        require(
            minter_ != address(0),
            "ERC20WithFees: minter address cannot be the zero address"
        );

        name = name_;
        symbol = symbol_;
        decimals = decimals_;

        feeRate = feeRate_;
        maxFeeDuration = Math.mulDiv(10 ** decimals_, 365 days, feeRate_);

        lastFeeChange = block.timestamp;
        feePrecision = 365 days * 10 ** decimals_;
        maxFee = maxFee_;
        feeChangeMinDelay = delayFeeChange_;
        _feeCollectionAddress = feeCollectionTreasury_;
        _minterAddress = minter_;

        setFeeExempt(_feeCollectionAddress);
        setFeeExempt(_minterAddress);
    }

    // IERC20 implementation

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

    /**
     * @notice shows the amount of tokens that are available to be transferred, after fees are deducted
     */
    function balanceOf(address account) public view override returns (uint256) {
        uint256 fee = _calculateFee(account);
        if (_balances[account] < fee) {
            return 0;
        }
        return _balances[account] - fee;
    }

    /**
     * @notice See {IERC20-balanceOf}.
     */
    function balanceOfWithFee(address account) public view 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 sender = _msgSender();
        _transfer(sender, 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 sender = _msgSender();
        _approve(sender, 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 sender = _msgSender();
        _approve(sender, spender, allowance(sender, 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 sender = _msgSender();
        uint256 currentAllowance = allowance(sender, spender);
        require(
            currentAllowance >= subtractedValue,
            "ERC20: decreased allowance below zero"
        );
        unchecked {
            _approve(sender, spender, currentAllowance - subtractedValue);
        }

        return true;
    }

    /**
     * @dev Moves `amount` of tokens from `sender` to `recipient`.
     *
     * 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");
        require(amount > 0, "ERC20: transfer amount must be greater than 0");
        require(from != to, "ERC20: self transfer is not allowed");

        _payFee(from);
        require(
            _balances[from] >= amount,
            "ERC20: transfer amount exceeds balance"
        );
        _balances[from] = _balances[from] - amount;

        _payFee(to);
        _balances[to] += amount;

        emit Transfer(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 {
        _totalSupply += amount;
        _balances[account] += amount;

        emit Transfer(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 {
        uint256 accountBalance = _balances[account];
        require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
        unchecked {
            _balances[account] = accountBalance - amount;
        }
        _totalSupply -= amount;

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

    /**
     * @notice mints new tokens into circulation, meaning that more real-world
     * assets are now represented by the token
     * @dev only the minter can mint new tokens
     */
    function mint(uint256 amount) public onlyMinter {
        if (oracle != address(0)) {
            uint256 reserve = IProofOfReserveOracle(oracle).lockedValue();
            require(
                reserve >= amount + _totalSupply,
                "ERC20WithFees: new total supply amount would exceed reserve balance"
            );
        }
        _mint(_minterAddress, amount);
    }

    /**
     * @dev Utility function to transfer all tokens from the owner to another, taking into account the owed fees so the
     * balance of the owner will be 0 after the transfer.
     *
     */
    function transferAll(address to) public virtual returns (bool) {
        address sender = _msgSender();
        uint256 amount = balanceOf(sender);
        _transfer(sender, to, amount);
        return true;
    }

    /**
     * @notice burns tokens, meaning that less real-world assets are now
     * represented by the token
     * @dev only the minter can burn tokens, with the approval of the owner
     * this is used in the process of redeeming tokens for real-world assets
     * if the owner has not enough balance to burn + pay fees, the fee will be paid from the burn amount
     * @param account the account to burn tokens from
     * @param amount the amount of tokens to burn
     */
    function burn(
        address account,
        uint256 amount
    ) public onlyMinter returns (uint256) {
        require(
            account != address(0),
            "ERC20: can't burn from the zero address"
        );
        address sender = _msgSender();
        if (sender != account) {
            _spendAllowance(account, sender, amount);
        }
        uint256 paid = _payFee(account);

        if (paid > 0 && _balances[account] < amount) {
            amount = _balances[account];
        }

        _burn(account, amount);
        return 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);
            }
        }
    }

    // Token specific funtions to calculate and collect fees

    /**
     * @notice returns the last time the fee was deducted for the given account
     * @dev returns 0 if the account has never had a fee deducted -> never held tokens
     */
    function feeLastPaid(
        address account
    ) public view virtual returns (uint256) {
        return _feeLastPaid[account];
    }

    /**
     * @notice returns the fees to be deducted for the given account, outstanding fees before a fee change in the contract is not included
     * @dev returns 0 if the account has never held tokens or is currently exempt
     * for the period between the last fee deduction for the account and the last fee change in the contract is not included in fee calculation
     */
    function _calculateFee(address account) internal view returns (uint256) {
        if (_balances[account] == 0 || _feeExempt[account]) {
            return 0;
        }
        uint256 lastPaid = _feeLastPaid[account] > lastFeeChange
            ? _feeLastPaid[account]
            : lastFeeChange;

        uint256 elapsed = block.timestamp - lastPaid;

        if (elapsed >= maxFeeDuration) {
            return _balances[account];
        }

        return Math.mulDiv(elapsed * feeRate, _balances[account], feePrecision);
    }

    function _payFee(address account) internal returns (uint256) {
        uint256 fee = _calculateFee(account);
        if (fee > 0) {
            _balances[account] -= fee;
            _balances[_feeCollectionAddress] += fee;
            emit Transfer(account, _feeCollectionAddress, fee);
        }
        _feeLastPaid[account] = block.timestamp;

        return fee;
    }

    function setFeeRate(uint256 newFee_) public onlyOwner {
        require(
            newFee_ <= maxFee,
            "ERC20WithFees: fee cannot be more than max fee"
        );
        require(
            block.timestamp - lastFeeChange > feeChangeMinDelay,
            "ERC20WithFees: fee change delay not passed"
        );

        lastFeeChange = block.timestamp;
        feeRate = newFee_;
        maxFeeDuration = Math.mulDiv(10 ** decimals, 365 days, feeRate);

        emit FeeChanged(feeRate);
    }

    function collectFees(address[] calldata accounts) public {
        for (uint256 i = 0; i < accounts.length; i++) {
            _payFee(accounts[i]);
        }
    }

    /**
     * @dev Set this account as being exempt from storage fees. This may be used
     * in special circumstance for cold storage addresses owed by Cache, exchanges, etc.
     * @param account The account to exempt from storage fees
     */
    function setFeeExempt(address account) internal onlyOwner {
        _feeExempt[account] = true;
    }

    /**
     * @dev Set account is no longer exempt from all fees
     * @param account The account to reactivate fees
     */
    function unsetFeeExempt(address account) internal onlyOwner {
        _feeExempt[account] = false;
        _feeLastPaid[account] = block.timestamp;
    }

    /**
     * @dev Set the address that will receive all fees collected
     * @param newAddress The address to receive fees
     */

    function setFeeCollectionAddress(address newAddress) public onlyOwner {
        require(
            newAddress != address(0),
            "ERC20WithFees: collection address cannot be zero"
        );
        unsetFeeExempt(_feeCollectionAddress);
        _feeCollectionAddress = newAddress;
        setFeeExempt(newAddress);
    }

    /**
     * @dev Set the address that will mint new tokens
     * @param newAddress The address to mint tokens
     */
    function setMinterRole(address newAddress) public onlyOwner {
        require(
            newAddress != address(0),
            "ERC20WithFees: collection address cannot be zero"
        );
        unsetFeeExempt(_minterAddress);
        _minterAddress = newAddress;
        setFeeExempt(newAddress);
    }

    /**
     * @dev Set the LockedGoldOracle address
     * @param oracleAddress The address for oracle
     * @return An bool representing successfully changing oracle address
     */
    function setOracleAddress(
        address oracleAddress
    ) external onlyOwner returns (bool) {
        require(
            oracleAddress != address(0),
            "ERC20WithFees: oracle address cannot be zero"
        );
        oracle = oracleAddress;
        emit OracleAddressChanged(oracleAddress);
        return true;
    }

    /*
     * @dev Throws if called by any account other than the MINTER.
     */
    modifier onlyMinter() {
        require(
            msg.sender == _minterAddress,
            "ERC20WithFees: only minter can call this function"
        );
        _;
    }
}

File 2 of 8 : IProofOfReserveOracle.sol
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.1;

interface IProofOfReserveOracle {
    function lockedValue() external view returns (uint256);
}

File 3 of 8 : Ownable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)

pragma solidity ^0.8.1;

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 Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
        _;
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing 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 4 of 8 : Ownable2Step.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (access/Ownable2Step.sol)

pragma solidity ^0.8.0;

import "./Ownable.sol";

/**
 * @dev Contract module which provides access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership} and {acceptOwnership}.
 *
 * This module is used through inheritance. It will make available all functions
 * from parent (Ownable).
 */
abstract contract Ownable2Step is Ownable {
    address private _pendingOwner;

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

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

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

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

    /**
     * @dev The new owner accepts the ownership transfer.
     */
    function acceptOwnership() public virtual {
        address sender = _msgSender();
        require(
            pendingOwner() == sender,
            "Ownable2Step: caller is not the new owner"
        );
        _transferOwnership(sender);
    }
}

File 5 of 8 : IERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.1;

/**
 * @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 6 of 8 : IERC20Metadata.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)

pragma solidity ^0.8.1;

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 7 of 8 : Context.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

pragma solidity ^0.8.1;

/**
 * @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 8 of 8 : Math.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol)

pragma solidity ^0.8.0;

/**
 * @dev Standard math utilities missing in the Solidity language.
 */
library Math {
    enum Rounding {
        Down, // Toward negative infinity
        Up, // Toward infinity
        Zero // Toward zero
    }

    /**
     * @dev Returns the largest of two numbers.
     */
    function max(uint256 a, uint256 b) internal pure returns (uint256) {
        return a > b ? a : b;
    }

    /**
     * @dev Returns the smallest of two numbers.
     */
    function min(uint256 a, uint256 b) internal pure returns (uint256) {
        return a < b ? a : b;
    }

    /**
     * @dev Returns the average of two numbers. The result is rounded towards
     * zero.
     */
    function average(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b) / 2 can overflow.
        return (a & b) + (a ^ b) / 2;
    }

    /**
     * @dev Returns the ceiling of the division of two numbers.
     *
     * This differs from standard division with `/` in that it rounds up instead
     * of rounding down.
     */
    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b - 1) / b can overflow on addition, so we distribute.
        return a == 0 ? 0 : (a - 1) / b + 1;
    }

    /**
     * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0
     * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)
     * with further edits by Uniswap Labs also under MIT license.
     */
    function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {
        unchecked {
            // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use
            // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
            // variables such that product = prod1 * 2^256 + prod0.
            uint256 prod0; // Least significant 256 bits of the product
            uint256 prod1; // Most significant 256 bits of the product
            assembly {
                let mm := mulmod(x, y, not(0))
                prod0 := mul(x, y)
                prod1 := sub(sub(mm, prod0), lt(mm, prod0))
            }

            // Handle non-overflow cases, 256 by 256 division.
            if (prod1 == 0) {
                // Solidity will revert if denominator == 0, unlike the div opcode on its own.
                // The surrounding unchecked block does not change this fact.
                // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.
                return prod0 / denominator;
            }

            // Make sure the result is less than 2^256. Also prevents denominator == 0.
            require(denominator > prod1, "Math: mulDiv overflow");

            ///////////////////////////////////////////////
            // 512 by 256 division.
            ///////////////////////////////////////////////

            // Make division exact by subtracting the remainder from [prod1 prod0].
            uint256 remainder;
            assembly {
                // Compute remainder using mulmod.
                remainder := mulmod(x, y, denominator)

                // Subtract 256 bit number from 512 bit number.
                prod1 := sub(prod1, gt(remainder, prod0))
                prod0 := sub(prod0, remainder)
            }

            // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.
            // See https://cs.stackexchange.com/q/138556/92363.

            // Does not overflow because the denominator cannot be zero at this stage in the function.
            uint256 twos = denominator & (~denominator + 1);
            assembly {
                // Divide denominator by twos.
                denominator := div(denominator, twos)

                // Divide [prod1 prod0] by twos.
                prod0 := div(prod0, twos)

                // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.
                twos := add(div(sub(0, twos), twos), 1)
            }

            // Shift in bits from prod1 into prod0.
            prod0 |= prod1 * twos;

            // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such
            // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for
            // four bits. That is, denominator * inv = 1 mod 2^4.
            uint256 inverse = (3 * denominator) ^ 2;

            // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works
            // in modular arithmetic, doubling the correct bits in each step.
            inverse *= 2 - denominator * inverse; // inverse mod 2^8
            inverse *= 2 - denominator * inverse; // inverse mod 2^16
            inverse *= 2 - denominator * inverse; // inverse mod 2^32
            inverse *= 2 - denominator * inverse; // inverse mod 2^64
            inverse *= 2 - denominator * inverse; // inverse mod 2^128
            inverse *= 2 - denominator * inverse; // inverse mod 2^256

            // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.
            // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is
            // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1
            // is no longer required.
            result = prod0 * inverse;
            return result;
        }
    }

    /**
     * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.
     */
    function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {
        uint256 result = mulDiv(x, y, denominator);
        if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {
            result += 1;
        }
        return result;
    }

    /**
     * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.
     *
     * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11).
     */
    function sqrt(uint256 a) internal pure returns (uint256) {
        if (a == 0) {
            return 0;
        }

        // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.
        //
        // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have
        // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.
        //
        // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`
        // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`
        // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`
        //
        // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.
        uint256 result = 1 << (log2(a) >> 1);

        // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,
        // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at
        // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision
        // into the expected uint128 result.
        unchecked {
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            return min(result, a / result);
        }
    }

    /**
     * @notice Calculates sqrt(a), following the selected rounding direction.
     */
    function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = sqrt(a);
            return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 2, rounded down, of a positive value.
     * Returns 0 if given 0.
     */
    function log2(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >> 128 > 0) {
                value >>= 128;
                result += 128;
            }
            if (value >> 64 > 0) {
                value >>= 64;
                result += 64;
            }
            if (value >> 32 > 0) {
                value >>= 32;
                result += 32;
            }
            if (value >> 16 > 0) {
                value >>= 16;
                result += 16;
            }
            if (value >> 8 > 0) {
                value >>= 8;
                result += 8;
            }
            if (value >> 4 > 0) {
                value >>= 4;
                result += 4;
            }
            if (value >> 2 > 0) {
                value >>= 2;
                result += 2;
            }
            if (value >> 1 > 0) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 2, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log2(value);
            return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 10, rounded down, of a positive value.
     * Returns 0 if given 0.
     */
    function log10(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >= 10 ** 64) {
                value /= 10 ** 64;
                result += 64;
            }
            if (value >= 10 ** 32) {
                value /= 10 ** 32;
                result += 32;
            }
            if (value >= 10 ** 16) {
                value /= 10 ** 16;
                result += 16;
            }
            if (value >= 10 ** 8) {
                value /= 10 ** 8;
                result += 8;
            }
            if (value >= 10 ** 4) {
                value /= 10 ** 4;
                result += 4;
            }
            if (value >= 10 ** 2) {
                value /= 10 ** 2;
                result += 2;
            }
            if (value >= 10 ** 1) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log10(value);
            return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 256, rounded down, of a positive value.
     * Returns 0 if given 0.
     *
     * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.
     */
    function log256(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >> 128 > 0) {
                value >>= 128;
                result += 16;
            }
            if (value >> 64 > 0) {
                value >>= 64;
                result += 8;
            }
            if (value >> 32 > 0) {
                value >>= 32;
                result += 4;
            }
            if (value >> 16 > 0) {
                value >>= 16;
                result += 2;
            }
            if (value >> 8 > 0) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 256, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log256(value);
            return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);
        }
    }
}

Settings
{
  "evmVersion": "istanbul",
  "libraries": {},
  "metadata": {
    "bytecodeHash": "ipfs",
    "useLiteralContent": true
  },
  "optimizer": {
    "enabled": true,
    "runs": 2000
  },
  "remappings": [],
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"string","name":"name_","type":"string"},{"internalType":"string","name":"symbol_","type":"string"},{"internalType":"uint8","name":"decimals_","type":"uint8"},{"internalType":"uint256","name":"feeRate_","type":"uint256"},{"internalType":"uint256","name":"maxFee_","type":"uint256"},{"internalType":"uint256","name":"delayFeeChange_","type":"uint256"},{"internalType":"address","name":"feeCollectionTreasury_","type":"address"},{"internalType":"address","name":"minter_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"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":false,"internalType":"uint256","name":"newFee","type":"uint256"}],"name":"FeeChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oracle","type":"address"}],"name":"OracleAddressChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferStarted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"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":"account","type":"address"}],"name":"balanceOfWithFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burn","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"accounts","type":"address[]"}],"name":"collectFees","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":"feeChangeMinDelay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"feeLastPaid","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feeRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":"lastFeeChange","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"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":"oracle","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newAddress","type":"address"}],"name":"setFeeCollectionAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newFee_","type":"uint256"}],"name":"setFeeRate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newAddress","type":"address"}],"name":"setMinterRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"oracleAddress","type":"address"}],"name":"setOracleAddress","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"transferAll","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"}]

6101006040523480156200001257600080fd5b5060405162002ad838038062002ad8833981016040819052620000359162000697565b62000040336200031b565b6200004d86600a620007a8565b841115620000a25760405162461bcd60e51b815260206004820152601f60248201527f455243323057697468466565733a206d61782066656520746f6f20686967680060448201526064015b60405180910390fd5b838511156200010b5760405162461bcd60e51b815260206004820152602e60248201527f455243323057697468466565733a206665652063616e6e6f74206265206d6f7260448201526d65207468616e206d61782066656560901b606482015260840162000099565b6001600160a01b0382166200018b576040805162461bcd60e51b81526020600482015260248101919091527f455243323057697468466565733a2066656520636f6c6c656374696f6e20616460448201527f64726573732063616e6e6f7420626520746865207a65726f2061646472657373606482015260840162000099565b6001600160a01b038116620002095760405162461bcd60e51b815260206004820152603860248201527f455243323057697468466565733a206d696e746572206164647265737320636160448201527f6e6e6f7420626520746865207a65726f20616464726573730000000000000000606482015260840162000099565b87516200021e9060059060208b019062000521565b508651620002349060069060208a019062000521565b507fff0000000000000000000000000000000000000000000000000000000000000060f887901b16608052600c8590556200028c6200027587600a620007a8565b6301e13380876200034560201b620012491760201c565b600d5542600e55620002a086600a620007a8565b620002b0906301e1338062000893565b60e05260a084905260c0839052600a80546001600160a01b038085166001600160a01b03199283168117909355600b805491851691909216179055620002f69062000451565b600b546200030d906001600160a01b031662000451565b50505050505050506200091e565b600180546001600160a01b03191690556200034281620004d1602090811b6200134a17901c565b50565b60008080600019858709858702925082811083820303915050806000141562000391578382816200038657634e487b7160e01b600052601260045260246000fd5b04925050506200044a565b808411620003e25760405162461bcd60e51b815260206004820152601560248201527f4d6174683a206d756c446976206f766572666c6f770000000000000000000000604482015260640162000099565b600084868809851960019081018716968790049682860381900495909211909303600082900391909104909201919091029190911760038402600290811880860282030280860282030280860282030280860282030280860282030280860290910302029150505b9392505050565b6000546001600160a01b03163314620004ad5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640162000099565b6001600160a01b03166000908152600960205260409020805460ff19166001179055565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b8280546200052f90620008b5565b90600052602060002090601f0160209004810192826200055357600085556200059e565b82601f106200056e57805160ff19168380011785556200059e565b828001600101855582156200059e579182015b828111156200059e57825182559160200191906001019062000581565b50620005ac929150620005b0565b5090565b5b80821115620005ac5760008155600101620005b1565b80516001600160a01b0381168114620005df57600080fd5b919050565b600082601f830112620005f5578081fd5b81516001600160401b038082111562000612576200061262000908565b604051601f8301601f19908116603f011681019082821181831017156200063d576200063d62000908565b8160405283815260209250868385880101111562000659578485fd5b8491505b838210156200067c57858201830151818301840152908201906200065d565b838211156200068d57848385830101525b9695505050505050565b600080600080600080600080610100898b031215620006b4578384fd5b88516001600160401b0380821115620006cb578586fd5b620006d98c838d01620005e4565b995060208b0151915080821115620006ef578586fd5b50620006fe8b828c01620005e4565b975050604089015160ff8116811462000715578485fd5b80965050606089015194506080890151935060a089015192506200073c60c08a01620005c7565b91506200074c60e08a01620005c7565b90509295985092959890939650565b80825b60018086116200076f57506200079f565b818704821115620007845762000784620008f2565b808616156200079257918102915b9490941c9380026200075e565b94509492505050565b60006200044a60001960ff851684600082620007c7575060016200044a565b81620007d6575060006200044a565b8160018114620007ef5760028114620007fa576200082e565b60019150506200044a565b60ff8411156200080e576200080e620008f2565b6001841b915084821115620008275762000827620008f2565b506200044a565b5060208310610133831016604e8410600b841016171562000866575081810a83811115620008605762000860620008f2565b6200044a565b6200087584848460016200075b565b8086048211156200088a576200088a620008f2565b02949350505050565b6000816000190483118215151615620008b057620008b0620008f2565b500290565b600181811c90821680620008ca57607f821691505b60208210811415620008ec57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b60805160f81c60a05160c05160e051612168620009706000396000611aa701526000818161026101526106be0152600081816101ef01526106280152600081816102a3015261076f01526121686000f3fe608060405234801561001057600080fd5b50600436106101e55760003560e01c806379ba50971161010f578063a3a7e7f3116100a2578063ceee577e11610071578063ceee577e14610436578063dd62ed3e1461045f578063e30c397814610498578063f2fde38b146104a9576101e5565b8063a3a7e7f3146103ea578063a457c2d7146103fd578063a9059cbb14610410578063b8cc76fb14610423576101e5565b806395d89b41116100de57806395d89b41146103b3578063978bbdb9146103bb5780639dc29fac146103c4578063a0712d68146103d7576101e5565b806379ba50971461035c5780637dc0d1d0146103645780638da5cb5b1461038f578063945d1229146103a0576101e5565b8063395093511161018757806358c0f7291161015657806358c0f72914610325578063695056881461033857806370a0823114610341578063715018a614610354576101e5565b806339509351146102d757806345596e2e146102ea5780634bcc1aef146102ff5780634c69c00f14610312576101e5565b8063142a1515116101c3578063142a15151461025c57806318160ddd1461028357806323b872dd1461028b578063313ce5671461029e576101e5565b806301f59d16146101ea57806306fdde0314610224578063095ea7b314610239575b600080fd5b6102117f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020015b60405180910390f35b61022c6104bc565b60405161021b9190611ef0565b61024c610247366004611e27565b61054a565b604051901515815260200161021b565b6102117f000000000000000000000000000000000000000000000000000000000000000081565b600454610211565b61024c610299366004611dec565b610562565b6102c57f000000000000000000000000000000000000000000000000000000000000000081565b60405160ff909116815260200161021b565b61024c6102e5366004611e27565b610588565b6102fd6102f8366004611ec0565b6105c7565b005b61021161030d366004611da0565b6107de565b61024c610320366004611da0565b6107fd565b6102fd610333366004611e50565b61093a565b610211600e5481565b61021161034f366004611da0565b61099a565b6102fd6109f7565b6102fd610a5d565b600754610377906001600160a01b031681565b6040516001600160a01b03909116815260200161021b565b6000546001600160a01b0316610377565b6102fd6103ae366004611da0565b610aeb565b61022c610c07565b610211600c5481565b6102116103d2366004611e27565b610c14565b6102fd6103e5366004611ec0565b610d97565b61024c6103f8366004611da0565b610f81565b61024c61040b366004611e27565b610f9b565b61024c61041e366004611e27565b611050565b6102fd610431366004611da0565b61105e565b610211610444366004611da0565b6001600160a01b031660009081526008602052604090205490565b61021161046d366004611dba565b6001600160a01b03918216600090815260036020908152604080832093909416825291909152205490565b6001546001600160a01b0316610377565b6102fd6104b7366004611da0565b61117a565b600580546104c9906120c6565b80601f01602080910402602001604051908101604052809291908181526020018280546104f5906120c6565b80156105425780601f1061051757610100808354040283529160200191610542565b820191906000526020600020905b81548152906001019060200180831161052557829003601f168201915b505050505081565b6000336105588185856113a7565b5060019392505050565b600033610570858285611500565b61057b858585611592565b60019150505b9392505050565b3360008181526003602090815260408083206001600160a01b038716845290915281205490919061055890829086906105c2908790611f61565b6113a7565b6000546001600160a01b031633146106265760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064015b60405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000008111156106bc5760405162461bcd60e51b815260206004820152602e60248201527f455243323057697468466565733a206665652063616e6e6f74206265206d6f7260448201527f65207468616e206d617820666565000000000000000000000000000000000000606482015260840161061d565b7f0000000000000000000000000000000000000000000000000000000000000000600e54426106eb91906120af565b1161075e5760405162461bcd60e51b815260206004820152602a60248201527f455243323057697468466565733a20666565206368616e67652064656c61792060448201527f6e6f742070617373656400000000000000000000000000000000000000000000606482015260840161061d565b42600e55600c8190556107a26107957f0000000000000000000000000000000000000000000000000000000000000000600a611fbf565b6301e13380600c54611249565b600d55600c546040519081527f6bbc57480a46553fa4d156ce702beef5f3ad66303b0ed1a5d4cb44966c6584c39060200160405180910390a150565b6001600160a01b0381166000908152600260205260409020545b919050565b600080546001600160a01b031633146108585760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161061d565b6001600160a01b0382166108d45760405162461bcd60e51b815260206004820152602c60248201527f455243323057697468466565733a206f7261636c65206164647265737320636160448201527f6e6e6f74206265207a65726f0000000000000000000000000000000000000000606482015260840161061d565b6007805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0384169081179091556040519081527fe420b96152542f57ce3d2d26d939a3c2860a82361801ad0a970a3badc32d538e9060200160405180910390a1506001919050565b60005b818110156109955761098283838381811061096857634e487b7160e01b600052603260045260246000fd5b905060200201602081019061097d9190611da0565b6118db565b508061098d81612101565b91505061093d565b505050565b6000806109a6836119b2565b6001600160a01b0384166000908152600260205260409020549091508111156109d35760009150506107f8565b6001600160a01b0383166000908152600260205260409020546105819082906120af565b6000546001600160a01b03163314610a515760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161061d565b610a5b6000611ad3565b565b60015433906001600160a01b03168114610adf5760405162461bcd60e51b815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f74207468652060448201527f6e6577206f776e65720000000000000000000000000000000000000000000000606482015260840161061d565b610ae881611ad3565b50565b6000546001600160a01b03163314610b455760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161061d565b6001600160a01b038116610bc15760405162461bcd60e51b815260206004820152603060248201527f455243323057697468466565733a20636f6c6c656374696f6e2061646472657360448201527f732063616e6e6f74206265207a65726f00000000000000000000000000000000606482015260840161061d565b600b54610bd6906001600160a01b0316611af9565b600b805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b038316179055610ae881611b81565b600680546104c9906120c6565b600b546000906001600160a01b03163314610c975760405162461bcd60e51b815260206004820152603160248201527f455243323057697468466565733a206f6e6c79206d696e7465722063616e206360448201527f616c6c20746869732066756e6374696f6e000000000000000000000000000000606482015260840161061d565b6001600160a01b038316610d135760405162461bcd60e51b815260206004820152602760248201527f45524332303a2063616e2774206275726e2066726f6d20746865207a65726f2060448201527f6164647265737300000000000000000000000000000000000000000000000000606482015260840161061d565b336001600160a01b0384168114610d2f57610d2f848285611500565b6000610d3a856118db565b9050600081118015610d6357506001600160a01b03851660009081526002602052604090205484115b15610d84576001600160a01b03851660009081526002602052604090205493505b610d8e8585611bff565b50919392505050565b600b546001600160a01b03163314610e175760405162461bcd60e51b815260206004820152603160248201527f455243323057697468466565733a206f6e6c79206d696e7465722063616e206360448201527f616c6c20746869732066756e6374696f6e000000000000000000000000000000606482015260840161061d565b6007546001600160a01b031615610f6b57600754604080517fd2c4693200000000000000000000000000000000000000000000000000000000815290516000926001600160a01b03169163d2c46932916004808301926020929190829003018186803b158015610e8657600080fd5b505afa158015610e9a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ebe9190611ed8565b905060045482610ece9190611f61565b811015610f695760405162461bcd60e51b815260206004820152604360248201527f455243323057697468466565733a206e657720746f74616c20737570706c792060448201527f616d6f756e7420776f756c642065786365656420726573657276652062616c6160648201527f6e63650000000000000000000000000000000000000000000000000000000000608482015260a40161061d565b505b600b54610ae8906001600160a01b031682611d00565b60003381610f8e8261099a565b9050610558828583611592565b3360008181526003602090815260408083206001600160a01b0387168452909152812054909190838110156110385760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f000000000000000000000000000000000000000000000000000000606482015260840161061d565b61104582868684036113a7565b506001949350505050565b600033610558818585611592565b6000546001600160a01b031633146110b85760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161061d565b6001600160a01b0381166111345760405162461bcd60e51b815260206004820152603060248201527f455243323057697468466565733a20636f6c6c656374696f6e2061646472657360448201527f732063616e6e6f74206265207a65726f00000000000000000000000000000000606482015260840161061d565b600a54611149906001600160a01b0316611af9565b600a805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b038316179055610ae881611b81565b6000546001600160a01b031633146111d45760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161061d565b6001805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383169081179091556112116000546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b6000808060001985870985870292508281108382030391505080600014156112925783828161128857634e487b7160e01b600052601260045260246000fd5b0492505050610581565b8084116112e15760405162461bcd60e51b815260206004820152601560248201527f4d6174683a206d756c446976206f766572666c6f770000000000000000000000604482015260640161061d565b60008486880960026001871981018816978890046003810283188082028403028082028403028082028403028082028403028082028403029081029092039091026000889003889004909101858311909403939093029303949094049190911702949350505050565b600080546001600160a01b0383811673ffffffffffffffffffffffffffffffffffffffff19831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b0383166114225760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f7265737300000000000000000000000000000000000000000000000000000000606482015260840161061d565b6001600160a01b03821661149e5760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f7373000000000000000000000000000000000000000000000000000000000000606482015260840161061d565b6001600160a01b0383811660008181526003602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b6001600160a01b03838116600090815260036020908152604080832093861683529290522054600019811461158c578181101561157f5760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e6365000000604482015260640161061d565b61158c84848484036113a7565b50505050565b6001600160a01b03831661160e5760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f6472657373000000000000000000000000000000000000000000000000000000606482015260840161061d565b6001600160a01b03821661168a5760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f6573730000000000000000000000000000000000000000000000000000000000606482015260840161061d565b600081116117005760405162461bcd60e51b815260206004820152602d60248201527f45524332303a207472616e7366657220616d6f756e74206d757374206265206760448201527f726561746572207468616e203000000000000000000000000000000000000000606482015260840161061d565b816001600160a01b0316836001600160a01b031614156117885760405162461bcd60e51b815260206004820152602360248201527f45524332303a2073656c66207472616e73666572206973206e6f7420616c6c6f60448201527f7765640000000000000000000000000000000000000000000000000000000000606482015260840161061d565b611791836118db565b506001600160a01b0383166000908152600260205260409020548111156118205760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e63650000000000000000000000000000000000000000000000000000606482015260840161061d565b6001600160a01b0383166000908152600260205260409020546118449082906120af565b6001600160a01b038416600090815260026020526040902055611866826118db565b506001600160a01b0382166000908152600260205260408120805483929061188f908490611f61565b92505081905550816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516114f391815260200190565b6000806118e7836119b2565b90508015611991576001600160a01b038316600090815260026020526040812080548392906119179084906120af565b9091555050600a546001600160a01b031660009081526002602052604081208054839290611946908490611f61565b9091555050600a546040518281526001600160a01b03918216918516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35b6001600160a01b039290921660009081526008602052604090204290555090565b6001600160a01b03811660009081526002602052604081205415806119ef57506001600160a01b03821660009081526009602052604090205460ff165b156119fc575060006107f8565b600e546001600160a01b038316600090815260086020526040812054909110611a2757600e54611a41565b6001600160a01b0383166000908152600860205260409020545b90506000611a4f82426120af565b9050600d548110611a7b575050506001600160a01b0381166000908152600260205260409020546107f8565b611acb600c5482611a8c9190612090565b6001600160a01b0386166000908152600260205260409020547f0000000000000000000000000000000000000000000000000000000000000000611249565b949350505050565b6001805473ffffffffffffffffffffffffffffffffffffffff19169055610ae88161134a565b6000546001600160a01b03163314611b535760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161061d565b6001600160a01b03166000908152600960209081526040808320805460ff1916905560089091529020429055565b6000546001600160a01b03163314611bdb5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161061d565b6001600160a01b03166000908152600960205260409020805460ff19166001179055565b6001600160a01b03821660009081526002602052604090205481811015611c8e5760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f6365000000000000000000000000000000000000000000000000000000000000606482015260840161061d565b6001600160a01b0383166000908152600260205260408120838303905560048054849290611cbd9084906120af565b90915550506040518281526000906001600160a01b038516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906020016114f3565b8060046000828254611d129190611f61565b90915550506001600160a01b03821660009081526002602052604081208054839290611d3f908490611f61565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b80356001600160a01b03811681146107f857600080fd5b600060208284031215611db1578081fd5b61058182611d89565b60008060408385031215611dcc578081fd5b611dd583611d89565b9150611de360208401611d89565b90509250929050565b600080600060608486031215611e00578081fd5b611e0984611d89565b9250611e1760208501611d89565b9150604084013590509250925092565b60008060408385031215611e39578182fd5b611e4283611d89565b946020939093013593505050565b60008060208385031215611e62578182fd5b823567ffffffffffffffff80821115611e79578384fd5b818501915085601f830112611e8c578384fd5b813581811115611e9a578485fd5b8660208260051b8501011115611eae578485fd5b60209290920196919550909350505050565b600060208284031215611ed1578081fd5b5035919050565b600060208284031215611ee9578081fd5b5051919050565b6000602080835283518082850152825b81811015611f1c57858101830151858201604001528201611f00565b81811115611f2d5783604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b60008219821115611f7457611f7461211c565b500190565b80825b6001808611611f8b5750611fb6565b818704821115611f9d57611f9d61211c565b80861615611faa57918102915b9490941c938002611f7c565b94509492505050565b600061058160001960ff851684600082611fdb57506001610581565b81611fe857506000610581565b8160018114611ffe576002811461200857612035565b6001915050610581565b60ff8411156120195761201961211c565b6001841b91508482111561202f5761202f61211c565b50610581565b5060208310610133831016604e8410600b8410161715612068575081810a838111156120635761206361211c565b610581565b6120758484846001611f79565b8086048211156120875761208761211c565b02949350505050565b60008160001904831182151516156120aa576120aa61211c565b500290565b6000828210156120c1576120c161211c565b500390565b600181811c908216806120da57607f821691505b602082108114156120fb57634e487b7160e01b600052602260045260246000fd5b50919050565b60006000198214156121155761211561211c565b5060010190565b634e487b7160e01b600052601160045260246000fdfea2646970667358221220b4fbfa1399f9b2fd66923280dcf12d134f0e92d64a263212fe44469ed9d4302364736f6c6343000803003300000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000f424000000000000000000000000000000000000000000000000000000000004c4b400000000000000000000000000000000000000000000000000000000000f099c00000000000000000000000005d9b4e268cc65a86a24761c7984b68f5636fcb1300000000000000000000000051a5b99a7d05cf9fee836c4fde12daf46cfe4bfc000000000000000000000000000000000000000000000000000000000000001344656e6172696f2053696c76657220436f696e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034453430000000000000000000000000000000000000000000000000000000000

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106101e55760003560e01c806379ba50971161010f578063a3a7e7f3116100a2578063ceee577e11610071578063ceee577e14610436578063dd62ed3e1461045f578063e30c397814610498578063f2fde38b146104a9576101e5565b8063a3a7e7f3146103ea578063a457c2d7146103fd578063a9059cbb14610410578063b8cc76fb14610423576101e5565b806395d89b41116100de57806395d89b41146103b3578063978bbdb9146103bb5780639dc29fac146103c4578063a0712d68146103d7576101e5565b806379ba50971461035c5780637dc0d1d0146103645780638da5cb5b1461038f578063945d1229146103a0576101e5565b8063395093511161018757806358c0f7291161015657806358c0f72914610325578063695056881461033857806370a0823114610341578063715018a614610354576101e5565b806339509351146102d757806345596e2e146102ea5780634bcc1aef146102ff5780634c69c00f14610312576101e5565b8063142a1515116101c3578063142a15151461025c57806318160ddd1461028357806323b872dd1461028b578063313ce5671461029e576101e5565b806301f59d16146101ea57806306fdde0314610224578063095ea7b314610239575b600080fd5b6102117f00000000000000000000000000000000000000000000000000000000004c4b4081565b6040519081526020015b60405180910390f35b61022c6104bc565b60405161021b9190611ef0565b61024c610247366004611e27565b61054a565b604051901515815260200161021b565b6102117f0000000000000000000000000000000000000000000000000000000000f099c081565b600454610211565b61024c610299366004611dec565b610562565b6102c57f000000000000000000000000000000000000000000000000000000000000000881565b60405160ff909116815260200161021b565b61024c6102e5366004611e27565b610588565b6102fd6102f8366004611ec0565b6105c7565b005b61021161030d366004611da0565b6107de565b61024c610320366004611da0565b6107fd565b6102fd610333366004611e50565b61093a565b610211600e5481565b61021161034f366004611da0565b61099a565b6102fd6109f7565b6102fd610a5d565b600754610377906001600160a01b031681565b6040516001600160a01b03909116815260200161021b565b6000546001600160a01b0316610377565b6102fd6103ae366004611da0565b610aeb565b61022c610c07565b610211600c5481565b6102116103d2366004611e27565b610c14565b6102fd6103e5366004611ec0565b610d97565b61024c6103f8366004611da0565b610f81565b61024c61040b366004611e27565b610f9b565b61024c61041e366004611e27565b611050565b6102fd610431366004611da0565b61105e565b610211610444366004611da0565b6001600160a01b031660009081526008602052604090205490565b61021161046d366004611dba565b6001600160a01b03918216600090815260036020908152604080832093909416825291909152205490565b6001546001600160a01b0316610377565b6102fd6104b7366004611da0565b61117a565b600580546104c9906120c6565b80601f01602080910402602001604051908101604052809291908181526020018280546104f5906120c6565b80156105425780601f1061051757610100808354040283529160200191610542565b820191906000526020600020905b81548152906001019060200180831161052557829003601f168201915b505050505081565b6000336105588185856113a7565b5060019392505050565b600033610570858285611500565b61057b858585611592565b60019150505b9392505050565b3360008181526003602090815260408083206001600160a01b038716845290915281205490919061055890829086906105c2908790611f61565b6113a7565b6000546001600160a01b031633146106265760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064015b60405180910390fd5b7f00000000000000000000000000000000000000000000000000000000004c4b408111156106bc5760405162461bcd60e51b815260206004820152602e60248201527f455243323057697468466565733a206665652063616e6e6f74206265206d6f7260448201527f65207468616e206d617820666565000000000000000000000000000000000000606482015260840161061d565b7f0000000000000000000000000000000000000000000000000000000000f099c0600e54426106eb91906120af565b1161075e5760405162461bcd60e51b815260206004820152602a60248201527f455243323057697468466565733a20666565206368616e67652064656c61792060448201527f6e6f742070617373656400000000000000000000000000000000000000000000606482015260840161061d565b42600e55600c8190556107a26107957f0000000000000000000000000000000000000000000000000000000000000008600a611fbf565b6301e13380600c54611249565b600d55600c546040519081527f6bbc57480a46553fa4d156ce702beef5f3ad66303b0ed1a5d4cb44966c6584c39060200160405180910390a150565b6001600160a01b0381166000908152600260205260409020545b919050565b600080546001600160a01b031633146108585760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161061d565b6001600160a01b0382166108d45760405162461bcd60e51b815260206004820152602c60248201527f455243323057697468466565733a206f7261636c65206164647265737320636160448201527f6e6e6f74206265207a65726f0000000000000000000000000000000000000000606482015260840161061d565b6007805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0384169081179091556040519081527fe420b96152542f57ce3d2d26d939a3c2860a82361801ad0a970a3badc32d538e9060200160405180910390a1506001919050565b60005b818110156109955761098283838381811061096857634e487b7160e01b600052603260045260246000fd5b905060200201602081019061097d9190611da0565b6118db565b508061098d81612101565b91505061093d565b505050565b6000806109a6836119b2565b6001600160a01b0384166000908152600260205260409020549091508111156109d35760009150506107f8565b6001600160a01b0383166000908152600260205260409020546105819082906120af565b6000546001600160a01b03163314610a515760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161061d565b610a5b6000611ad3565b565b60015433906001600160a01b03168114610adf5760405162461bcd60e51b815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f74207468652060448201527f6e6577206f776e65720000000000000000000000000000000000000000000000606482015260840161061d565b610ae881611ad3565b50565b6000546001600160a01b03163314610b455760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161061d565b6001600160a01b038116610bc15760405162461bcd60e51b815260206004820152603060248201527f455243323057697468466565733a20636f6c6c656374696f6e2061646472657360448201527f732063616e6e6f74206265207a65726f00000000000000000000000000000000606482015260840161061d565b600b54610bd6906001600160a01b0316611af9565b600b805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b038316179055610ae881611b81565b600680546104c9906120c6565b600b546000906001600160a01b03163314610c975760405162461bcd60e51b815260206004820152603160248201527f455243323057697468466565733a206f6e6c79206d696e7465722063616e206360448201527f616c6c20746869732066756e6374696f6e000000000000000000000000000000606482015260840161061d565b6001600160a01b038316610d135760405162461bcd60e51b815260206004820152602760248201527f45524332303a2063616e2774206275726e2066726f6d20746865207a65726f2060448201527f6164647265737300000000000000000000000000000000000000000000000000606482015260840161061d565b336001600160a01b0384168114610d2f57610d2f848285611500565b6000610d3a856118db565b9050600081118015610d6357506001600160a01b03851660009081526002602052604090205484115b15610d84576001600160a01b03851660009081526002602052604090205493505b610d8e8585611bff565b50919392505050565b600b546001600160a01b03163314610e175760405162461bcd60e51b815260206004820152603160248201527f455243323057697468466565733a206f6e6c79206d696e7465722063616e206360448201527f616c6c20746869732066756e6374696f6e000000000000000000000000000000606482015260840161061d565b6007546001600160a01b031615610f6b57600754604080517fd2c4693200000000000000000000000000000000000000000000000000000000815290516000926001600160a01b03169163d2c46932916004808301926020929190829003018186803b158015610e8657600080fd5b505afa158015610e9a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ebe9190611ed8565b905060045482610ece9190611f61565b811015610f695760405162461bcd60e51b815260206004820152604360248201527f455243323057697468466565733a206e657720746f74616c20737570706c792060448201527f616d6f756e7420776f756c642065786365656420726573657276652062616c6160648201527f6e63650000000000000000000000000000000000000000000000000000000000608482015260a40161061d565b505b600b54610ae8906001600160a01b031682611d00565b60003381610f8e8261099a565b9050610558828583611592565b3360008181526003602090815260408083206001600160a01b0387168452909152812054909190838110156110385760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f000000000000000000000000000000000000000000000000000000606482015260840161061d565b61104582868684036113a7565b506001949350505050565b600033610558818585611592565b6000546001600160a01b031633146110b85760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161061d565b6001600160a01b0381166111345760405162461bcd60e51b815260206004820152603060248201527f455243323057697468466565733a20636f6c6c656374696f6e2061646472657360448201527f732063616e6e6f74206265207a65726f00000000000000000000000000000000606482015260840161061d565b600a54611149906001600160a01b0316611af9565b600a805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b038316179055610ae881611b81565b6000546001600160a01b031633146111d45760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161061d565b6001805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383169081179091556112116000546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b6000808060001985870985870292508281108382030391505080600014156112925783828161128857634e487b7160e01b600052601260045260246000fd5b0492505050610581565b8084116112e15760405162461bcd60e51b815260206004820152601560248201527f4d6174683a206d756c446976206f766572666c6f770000000000000000000000604482015260640161061d565b60008486880960026001871981018816978890046003810283188082028403028082028403028082028403028082028403028082028403029081029092039091026000889003889004909101858311909403939093029303949094049190911702949350505050565b600080546001600160a01b0383811673ffffffffffffffffffffffffffffffffffffffff19831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b0383166114225760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f7265737300000000000000000000000000000000000000000000000000000000606482015260840161061d565b6001600160a01b03821661149e5760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f7373000000000000000000000000000000000000000000000000000000000000606482015260840161061d565b6001600160a01b0383811660008181526003602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b6001600160a01b03838116600090815260036020908152604080832093861683529290522054600019811461158c578181101561157f5760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e6365000000604482015260640161061d565b61158c84848484036113a7565b50505050565b6001600160a01b03831661160e5760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f6472657373000000000000000000000000000000000000000000000000000000606482015260840161061d565b6001600160a01b03821661168a5760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f6573730000000000000000000000000000000000000000000000000000000000606482015260840161061d565b600081116117005760405162461bcd60e51b815260206004820152602d60248201527f45524332303a207472616e7366657220616d6f756e74206d757374206265206760448201527f726561746572207468616e203000000000000000000000000000000000000000606482015260840161061d565b816001600160a01b0316836001600160a01b031614156117885760405162461bcd60e51b815260206004820152602360248201527f45524332303a2073656c66207472616e73666572206973206e6f7420616c6c6f60448201527f7765640000000000000000000000000000000000000000000000000000000000606482015260840161061d565b611791836118db565b506001600160a01b0383166000908152600260205260409020548111156118205760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e63650000000000000000000000000000000000000000000000000000606482015260840161061d565b6001600160a01b0383166000908152600260205260409020546118449082906120af565b6001600160a01b038416600090815260026020526040902055611866826118db565b506001600160a01b0382166000908152600260205260408120805483929061188f908490611f61565b92505081905550816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516114f391815260200190565b6000806118e7836119b2565b90508015611991576001600160a01b038316600090815260026020526040812080548392906119179084906120af565b9091555050600a546001600160a01b031660009081526002602052604081208054839290611946908490611f61565b9091555050600a546040518281526001600160a01b03918216918516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35b6001600160a01b039290921660009081526008602052604090204290555090565b6001600160a01b03811660009081526002602052604081205415806119ef57506001600160a01b03821660009081526009602052604090205460ff165b156119fc575060006107f8565b600e546001600160a01b038316600090815260086020526040812054909110611a2757600e54611a41565b6001600160a01b0383166000908152600860205260409020545b90506000611a4f82426120af565b9050600d548110611a7b575050506001600160a01b0381166000908152600260205260409020546107f8565b611acb600c5482611a8c9190612090565b6001600160a01b0386166000908152600260205260409020547f000000000000000000000000000000000000000000000000000b342eb7c38000611249565b949350505050565b6001805473ffffffffffffffffffffffffffffffffffffffff19169055610ae88161134a565b6000546001600160a01b03163314611b535760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161061d565b6001600160a01b03166000908152600960209081526040808320805460ff1916905560089091529020429055565b6000546001600160a01b03163314611bdb5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161061d565b6001600160a01b03166000908152600960205260409020805460ff19166001179055565b6001600160a01b03821660009081526002602052604090205481811015611c8e5760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f6365000000000000000000000000000000000000000000000000000000000000606482015260840161061d565b6001600160a01b0383166000908152600260205260408120838303905560048054849290611cbd9084906120af565b90915550506040518281526000906001600160a01b038516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906020016114f3565b8060046000828254611d129190611f61565b90915550506001600160a01b03821660009081526002602052604081208054839290611d3f908490611f61565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b80356001600160a01b03811681146107f857600080fd5b600060208284031215611db1578081fd5b61058182611d89565b60008060408385031215611dcc578081fd5b611dd583611d89565b9150611de360208401611d89565b90509250929050565b600080600060608486031215611e00578081fd5b611e0984611d89565b9250611e1760208501611d89565b9150604084013590509250925092565b60008060408385031215611e39578182fd5b611e4283611d89565b946020939093013593505050565b60008060208385031215611e62578182fd5b823567ffffffffffffffff80821115611e79578384fd5b818501915085601f830112611e8c578384fd5b813581811115611e9a578485fd5b8660208260051b8501011115611eae578485fd5b60209290920196919550909350505050565b600060208284031215611ed1578081fd5b5035919050565b600060208284031215611ee9578081fd5b5051919050565b6000602080835283518082850152825b81811015611f1c57858101830151858201604001528201611f00565b81811115611f2d5783604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b60008219821115611f7457611f7461211c565b500190565b80825b6001808611611f8b5750611fb6565b818704821115611f9d57611f9d61211c565b80861615611faa57918102915b9490941c938002611f7c565b94509492505050565b600061058160001960ff851684600082611fdb57506001610581565b81611fe857506000610581565b8160018114611ffe576002811461200857612035565b6001915050610581565b60ff8411156120195761201961211c565b6001841b91508482111561202f5761202f61211c565b50610581565b5060208310610133831016604e8410600b8410161715612068575081810a838111156120635761206361211c565b610581565b6120758484846001611f79565b8086048211156120875761208761211c565b02949350505050565b60008160001904831182151516156120aa576120aa61211c565b500290565b6000828210156120c1576120c161211c565b500390565b600181811c908216806120da57607f821691505b602082108114156120fb57634e487b7160e01b600052602260045260246000fd5b50919050565b60006000198214156121155761211561211c565b5060010190565b634e487b7160e01b600052601160045260246000fdfea2646970667358221220b4fbfa1399f9b2fd66923280dcf12d134f0e92d64a263212fe44469ed9d4302364736f6c63430008030033

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

00000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000f424000000000000000000000000000000000000000000000000000000000004c4b400000000000000000000000000000000000000000000000000000000000f099c00000000000000000000000005d9b4e268cc65a86a24761c7984b68f5636fcb1300000000000000000000000051a5b99a7d05cf9fee836c4fde12daf46cfe4bfc000000000000000000000000000000000000000000000000000000000000001344656e6172696f2053696c76657220436f696e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034453430000000000000000000000000000000000000000000000000000000000

-----Decoded View---------------
Arg [0] : name_ (string): Denario Silver Coin
Arg [1] : symbol_ (string): DSC
Arg [2] : decimals_ (uint8): 8
Arg [3] : feeRate_ (uint256): 1000000
Arg [4] : maxFee_ (uint256): 5000000
Arg [5] : delayFeeChange_ (uint256): 15768000
Arg [6] : feeCollectionTreasury_ (address): 0x5D9b4E268CC65A86A24761c7984b68F5636fcB13
Arg [7] : minter_ (address): 0x51A5b99a7D05cF9FeE836c4fdE12Daf46cFE4bfc

-----Encoded View---------------
12 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000100
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000140
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000008
Arg [3] : 00000000000000000000000000000000000000000000000000000000000f4240
Arg [4] : 00000000000000000000000000000000000000000000000000000000004c4b40
Arg [5] : 0000000000000000000000000000000000000000000000000000000000f099c0
Arg [6] : 0000000000000000000000005d9b4e268cc65a86a24761c7984b68f5636fcb13
Arg [7] : 00000000000000000000000051a5b99a7d05cf9fee836c4fde12daf46cfe4bfc
Arg [8] : 0000000000000000000000000000000000000000000000000000000000000013
Arg [9] : 44656e6172696f2053696c76657220436f696e00000000000000000000000000
Arg [10] : 0000000000000000000000000000000000000000000000000000000000000003
Arg [11] : 4453430000000000000000000000000000000000000000000000000000000000


Block Transaction Gas Used Reward
view all blocks produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading

OVERVIEW

The RWA token complies with Swiss financial regulations and is fully backed by silver granules, with 1 DSC equaling 1 ounce of silver. The silver is securely stored through an established custodian's vault in Switzerland, ensuring safety and eliminating storage concerns.

Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.