{"file_path":"contracts/BackedAutoFeeTokenImplementation.sol","creation_status":"success","source_code":"/**\r\n * SPDX-License-Identifier: MIT\r\n *\r\n * Copyright (c) 2021-2024 Backed Finance AG\r\n *\r\n * Permission is hereby granted, free of charge, to any person obtaining a copy\r\n * of this software and associated documentation files (the \"Software\"), to deal\r\n * in the Software without restriction, including without limitation the rights\r\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\n * copies of the Software, and to permit persons to whom the Software is\r\n * furnished to do so, subject to the following conditions:\r\n *\r\n * The above copyright notice and this permission notice shall be included in\r\n * copies or substantial portions of the Software.\r\n *\r\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\n * SOFTWARE.\r\n */\r\n\r\n/**\r\n * Disclaimer and Terms of Use\r\n *\r\n * These ERC-20 tokens have not been registered under the U.S. Securities Act of 1933, as\r\n * amended or with any securities regulatory authority of any State or other jurisdiction\r\n * of the United States and (i) may not be offered, sold or delivered within the United States\r\n * to, or for the account or benefit of U.S. Persons, and (ii) may be offered, sold or otherwise\r\n * delivered at any time only to transferees that are Non-United States Persons (as defined by\r\n * the U.S. Commodities Futures Trading Commission).\r\n * For more information and restrictions please refer to the issuer's [Website](https://www.backedassets.fi/legal-documentation)\r\n */\r\n\r\npragma solidity 0.8.9;\r\n\r\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\r\nimport \"./BackedTokenImplementation.sol\";\r\nimport \"./interfaces/IBackedAutoFeeToken.sol\";\r\n\r\n/**\r\n * @dev\r\n *\r\n * This token contract is following the ERC20 standard.\r\n * It inherits BackedTokenImplementation.sol, which is base Backed token implementation. BackedAutoFeeTokenImplementation extends it\r\n * with logic of multiplier, which is used for rebasing logic of the token, thus becoming rebase token itself. Additionally, it contains\r\n * mechanism, which changes this multiplier per configured fee periodically, on defined period length.\r\n * It contains one additional role:\r\n *  - A multiplierUpdater, that can update value of a multiplier.\r\n *\r\n */\r\n\r\ncontract BackedAutoFeeTokenImplementation is BackedTokenImplementation, IBackedAutoFeeToken {\r\n    // Calculating the Delegated Transfer Shares typehash:\r\n    bytes32 constant public DELEGATED_TRANSFER_SHARES_TYPEHASH =\r\n        keccak256(\r\n            \"DELEGATED_TRANSFER_SHARES(address owner,address to,uint256 value,uint256 nonce,uint256 deadline)\"\r\n        );\r\n\r\n    // Roles:\r\n    address public multiplierUpdater;\r\n\r\n    // Management Fee\r\n    uint256 public lastTimeFeeApplied;\r\n    uint256 public feePerPeriod; // in 1e18 precision\r\n    uint256 public periodLength;\r\n\r\n    /**\r\n     * @dev Defines ratio between a single share of a token to balance of a token.\r\n     * Defined in 1e18 precision.\r\n     *\r\n     */\r\n    uint256 public lastMultiplier;\r\n    function multiplier() external view returns (uint256) {\r\n        if(block.timestamp >= newMultiplierActivationTime) {\r\n            return newMultiplier;\r\n        }\r\n        return lastMultiplier;\r\n    }\r\n\r\n    mapping(address => uint256) private _shares;\r\n\r\n    uint256 internal _totalShares;\r\n\r\n    uint256 public lastMultiplierNonce;\r\n    uint256 public newMultiplierNonce;\r\n    uint256 public newMultiplier;\r\n    uint256 public newMultiplierActivationTime;\r\n\r\n    /**\r\n     * @dev Append-only log of *explicit* multiplier updates submitted via\r\n     * `updateMultiplierValue` / `updateMultiplierWithNonce`.\r\n     *\r\n     * Index 0 is a genesis sentinel `{1e18, 1e18, 0}` so that\r\n     * `_storeScheduledMultiplierUpdate` can safely read `length - 1`.\r\n     *\r\n     * Pending future-dated entries are overridden in place: when a new\r\n     * explicit update is submitted while the previous one is still\r\n     * scheduled (activationTime > block.timestamp), the previous entry is\r\n     * popped before the new one is appended. The corresponding\r\n     * `MultiplierScheduled` event from the popped entry remains on chain;\r\n     * the array does not retain it.\r\n     */\r\n    MultiplierUpdate[] public multiplierUpdates;\r\n\r\n    function multiplierNonce() external view returns (uint256) {\r\n        if(block.timestamp >= newMultiplierActivationTime) {\r\n            return newMultiplierNonce;\r\n        }\r\n        return lastMultiplierNonce;\r\n    }\r\n\r\n    // Modifiers:\r\n\r\n    modifier updateMultiplier() {\r\n        (uint256 currentMultiplier, uint256 periodsPassed, uint256 currentMultiplierNonce) = getCurrentMultiplier();\r\n        lastTimeFeeApplied = lastTimeFeeApplied + periodLength * periodsPassed;\r\n        if (lastMultiplier != currentMultiplier) {\r\n            _updateMultiplier(currentMultiplier, currentMultiplierNonce, 0);\r\n        }\r\n        _;\r\n    }\r\n\r\n    modifier onlyMultiplierUpdater() {\r\n        require(\r\n            _msgSender() == multiplierUpdater,\r\n            \"BackedToken: Only multiplier updater\"\r\n        );\r\n        _;\r\n    }\r\n\r\n    modifier onlyUpdatedMultiplier(uint256 oldMultiplier) {\r\n        (uint256 currentMultiplier,,) = getCurrentMultiplier();\r\n        require(\r\n            currentMultiplier == oldMultiplier,\r\n            \"BackedToken: Multiplier changed in the meantime\"\r\n        );\r\n        _;\r\n    }\r\n\r\n    modifier onlyNewerMultiplierNonce(uint256 newMultiplierNonce) {\r\n        (,,uint256 currentMultiplierNonce) = getCurrentMultiplier();\r\n        require(\r\n            currentMultiplierNonce < newMultiplierNonce,\r\n            \"BackedToken: Multiplier nonce is outdated.\"\r\n        );\r\n        _;\r\n    }\r\n    \r\n    // constructor, set lastTimeFeeApplied to lock the implementation instance.\r\n    constructor () {\r\n        lastTimeFeeApplied = 1;\r\n    }\r\n\r\n    // Initializers:\r\n    function initialize(\r\n        string memory name_,\r\n        string memory symbol_\r\n    ) public virtual override(BackedTokenImplementation, IBackedToken) {\r\n        super.initialize(name_, symbol_);\r\n        _initialize_auto_fee(24 * 3600, block.timestamp, 0);\r\n    }\r\n\r\n    function initialize(\r\n        string memory name_,\r\n        string memory symbol_,\r\n        uint256 _periodLength,\r\n        uint256 _lastTimeFeeApplied,\r\n        uint256 _feePerPeriod\r\n    ) external virtual {\r\n        super.initialize(name_, symbol_);\r\n        _initialize_auto_fee(_periodLength, _lastTimeFeeApplied, _feePerPeriod);\r\n    }\r\n\r\n    // Should it be only callable by authorized address?\r\n    function initialize_v2(\r\n        uint256 _periodLength,\r\n        uint256 _lastTimeFeeApplied,\r\n        uint256 _feePerPeriod\r\n    ) external virtual {\r\n        _initialize_auto_fee(_periodLength, _lastTimeFeeApplied, _feePerPeriod);\r\n    }\r\n\r\n    function initialize_v3(\r\n    ) external virtual {\r\n        require(newMultiplier == 0, \"BackedAutoFeeTokenImplementation v3 already initialized\");\r\n        newMultiplier = lastMultiplier;\r\n        newMultiplierNonce = lastMultiplierNonce;\r\n        newMultiplierActivationTime = 0;\r\n    }\r\n\r\n    function initialize_v4(\r\n        MultiplierUpdate [] calldata _pastMultipliersUpdates\r\n    ) external virtual {\r\n        require(multiplierUpdates.length == 0, \"BackedAutoFeeTokenImplementation v4 already initialized\");\r\n        multiplierUpdates.push(MultiplierUpdate({\r\n            previousMultiplier: 1e18,\r\n            newMultiplier: 1e18,\r\n            activationTime: 0\r\n        }));\r\n        for (uint i = 0; i < _pastMultipliersUpdates.length; i++) {\r\n            require(_pastMultipliersUpdates[i].previousMultiplier > 0, \"BackedAutoFeeTokenImplementation: previousMultiplier cannot be zero\");\r\n            multiplierUpdates.push(MultiplierUpdate({\r\n                previousMultiplier: _pastMultipliersUpdates[i].previousMultiplier,\r\n                newMultiplier: _pastMultipliersUpdates[i].newMultiplier,\r\n                activationTime: _pastMultipliersUpdates[i].activationTime\r\n            }));\r\n        }\r\n    }\r\n\r\n    function _initialize_auto_fee(\r\n        uint256 _periodLength,\r\n        uint256 _lastTimeFeeApplied,\r\n        uint256 _feePerPeriod\r\n    ) internal virtual {\r\n        require(lastTimeFeeApplied == 0, \"BackedAutoFeeTokenImplementation already initialized\");\r\n        require(_lastTimeFeeApplied != 0, \"Invalid last time fee applied\");\r\n\r\n        lastMultiplier = 1e18;\r\n        lastMultiplierNonce = 0;\r\n        newMultiplier = 1e18;\r\n        newMultiplierNonce = 0;\r\n        newMultiplierActivationTime = 0;\r\n        periodLength = _periodLength;\r\n        lastTimeFeeApplied = _lastTimeFeeApplied;\r\n        feePerPeriod = _feePerPeriod;\r\n        multiplierUpdates.push(MultiplierUpdate({\r\n            previousMultiplier: 1e18,\r\n            newMultiplier: 1e18,\r\n            activationTime: 0\r\n        }));\r\n    }\r\n\r\n    /**\r\n     * @inheritdoc IERC20MetadataUpgradeable\r\n     */\r\n    function decimals() public view virtual override(BackedTokenImplementation, IBackedToken) returns (uint8) {\r\n        return ERC20Upgradeable.decimals();\r\n    }\r\n\r\n    /**\r\n     * @dev See {IERC20-totalSupply}.\r\n     */\r\n    function totalSupply() public view virtual override returns (uint256) {\r\n        (uint256 currentMultiplier, ,) = getCurrentMultiplier();\r\n        return _getUnderlyingAmountByShares(_totalShares, currentMultiplier);\r\n    }\r\n\r\n    /**\r\n     * @dev See {IERC20-balanceOf}.\r\n     */\r\n    function balanceOf(\r\n        address account\r\n    ) public view virtual override returns (uint256) {\r\n        (uint256 currentMultiplier, ,) = getCurrentMultiplier();\r\n        return _getUnderlyingAmountByShares(sharesOf(account), currentMultiplier);\r\n    }\r\n\r\n    /**\r\n     * @dev Retrieves most up to date value of multiplier\r\n     *\r\n     */\r\n    function getCurrentMultiplier()\r\n        public\r\n        view\r\n        virtual\r\n        returns (uint256 currentMultiplier, uint256 periodsPassed, uint256 currentMultiplierNonce)\r\n    {\r\n        if(block.timestamp < newMultiplierActivationTime) {\r\n            return (lastMultiplier, 0, lastMultiplierNonce);\r\n        }\r\n        periodsPassed = (block.timestamp - lastTimeFeeApplied) / periodLength;\r\n        currentMultiplier = newMultiplier;\r\n        currentMultiplierNonce = newMultiplierNonce;\r\n        if (feePerPeriod > 0) {\r\n            for (uint256 index = 0; index < periodsPassed; index++) {\r\n                currentMultiplier = (currentMultiplier * (1e18 - feePerPeriod)) / 1e18;\r\n            }\r\n            currentMultiplierNonce += periodsPassed;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @dev Returns amount of shares owned by given account\r\n     */\r\n    function sharesOf(address account) public view virtual returns (uint256) {\r\n        return _shares[account];\r\n    }\r\n\r\n    /**\r\n     * @return the amount of shares that corresponds to `_underlyingAmount` underlying amount.\r\n     */\r\n    function getSharesByUnderlyingAmount(\r\n        uint256 _underlyingAmount\r\n    ) external view returns (uint256) {\r\n        (uint256 currentMultiplier, ,) = getCurrentMultiplier();\r\n        return _getSharesByUnderlyingAmount(_underlyingAmount, currentMultiplier);\r\n    }\r\n\r\n    /**\r\n     * @return the amount of underlying that corresponds to `_sharesAmount` token shares.\r\n     */\r\n    function getUnderlyingAmountByShares(\r\n        uint256 _sharesAmount\r\n    ) external view returns (uint256) {\r\n        (uint256 currentMultiplier, ,) = getCurrentMultiplier();\r\n        return _getUnderlyingAmountByShares(_sharesAmount, currentMultiplier);\r\n    }\r\n\r\n    /**\r\n     * @return Length of scheduled multipliers updates array\r\n     */\r\n    function multiplierUpdatesLength() external view returns (uint256) {\r\n        return multiplierUpdates.length;\r\n    }\r\n\r\n    /**\r\n     * @dev Delegated Transfer Shares, transfer shares via a sign message, using erc712.\r\n     */\r\n    function delegatedTransferShares(\r\n        address owner,\r\n        address to,\r\n        uint256 value,\r\n        uint256 deadline,\r\n        uint8 v,\r\n        bytes32 r,\r\n        bytes32 s\r\n    ) external virtual allowedDelegate updateMultiplier {\r\n        require(block.timestamp <= deadline, \"ERC20Permit: expired deadline\");\r\n\r\n        bytes32 structHash = keccak256(\r\n            abi.encode(\r\n                DELEGATED_TRANSFER_SHARES_TYPEHASH,\r\n                owner,\r\n                to,\r\n                value,\r\n                _useNonce(owner),\r\n                deadline\r\n            )\r\n        );\r\n        _checkOwner(owner, structHash, v, r, s);\r\n\r\n        _transferShares(owner, to, value);\r\n    }\r\n\r\n    /**\r\n     * @dev Transfers underlying shares to destination account\r\n     *\r\n     * Requirements:\r\n     *\r\n     * - `to` cannot be the zero address.\r\n     * - the caller must have a balance of at least `sharesAmount`.\r\n     */\r\n    function transferShares(\r\n        address to,\r\n        uint256 sharesAmount\r\n    ) external virtual updateMultiplier returns (bool) {\r\n        address owner = _msgSender();\r\n        _transferShares(owner, to, sharesAmount);\r\n\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * @dev Transfers underlying shares from source account to destination account\r\n     *\r\n     * Requirements:\r\n     *\r\n     * - `from` cannot be the zero address and caller needs to have permission to use it's allowance.\r\n     * - `to` cannot be the zero address.\r\n     * - the caller must have a balance of at least `sharesAmount`.\r\n     */\r\n    function transferSharesFrom(\r\n        address from,\r\n        address to,\r\n        uint256 sharesAmount\r\n    ) external virtual updateMultiplier returns (bool) {\r\n        uint256 amount = _getUnderlyingAmountByShares(sharesAmount, lastMultiplier);\r\n        address spender = _msgSender();\r\n        _spendAllowance(from, spender, amount);\r\n        _transferShares(from, to, sharesAmount, amount);\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * @dev Function to set the new fee. Allowed only for owner\r\n     *\r\n     * @param newFeePerPeriod The new fee per period value\r\n     */\r\n    function updateFeePerPeriod(\r\n        uint256 newFeePerPeriod\r\n    ) external onlyOwner updateMultiplier {\r\n        require(newMultiplierActivationTime == 0, \"Multiplier activation in progress\");\r\n        feePerPeriod = newFeePerPeriod;\r\n    }\r\n\r\n    /**\r\n     * @dev Function to change the contract multiplier updater. Allowed only for owner\r\n     *\r\n     * Emits a { NewMultiplierUpdater } event\r\n     *\r\n     * @param newMultiplierUpdater The address of the new multiplier updater\r\n     */\r\n    function setMultiplierUpdater(\r\n        address newMultiplierUpdater\r\n    ) external onlyOwner {\r\n        multiplierUpdater = newMultiplierUpdater;\r\n        emit NewMultiplierUpdater(newMultiplierUpdater);\r\n    }\r\n\r\n    /**\r\n     * @dev Function to change the time of last fee accrual. Allowed only for owner\r\n     *\r\n     * @param newLastTimeFeeApplied A timestamp of last time fee was applied\r\n     */\r\n    function setLastTimeFeeApplied(\r\n        uint256 newLastTimeFeeApplied\r\n    ) external onlyOwner updateMultiplier {\r\n        require(newMultiplierActivationTime == 0, \"Multiplier activation in progress\");\r\n        require(newLastTimeFeeApplied != 0, \"Invalid last time fee applied\");\r\n        lastTimeFeeApplied = newLastTimeFeeApplied;\r\n    }\r\n\r\n    /**\r\n     * @dev Function to change period length. Allowed only for owner\r\n     *\r\n     * @param newPeriodLength Length of a single accrual period in seconds\r\n     */\r\n    function setPeriodLength(uint256 newPeriodLength) external onlyOwner updateMultiplier {\r\n        require(newMultiplierActivationTime == 0, \"Multiplier activation in progress\");\r\n        periodLength = newPeriodLength;\r\n    }\r\n\r\n    /**\r\n     * @dev Function to change the contract multiplier, only if oldMultiplier did not change in the meantime. Allowed only for multiplierUpdater\r\n     *\r\n     * Emits a { MultiplierChanged } event\r\n     *\r\n     * @param pendingNewMultiplier New multiplier value\r\n     * @param oldMultiplier Old multiplier value\r\n     * @param pendingNewMultiplierActivationTime Time when new multiplier becomes active, which needs to take place before start of the next period\r\n     */\r\n    function updateMultiplierValue(\r\n        uint256 pendingNewMultiplier,\r\n        uint256 oldMultiplier,\r\n        uint256 pendingNewMultiplierActivationTime\r\n    ) public onlyMultiplierUpdater updateMultiplier onlyUpdatedMultiplier(oldMultiplier) {\r\n        _updateMultiplier(pendingNewMultiplier, lastMultiplierNonce + 1, pendingNewMultiplierActivationTime);\r\n        _storeScheduledMultiplierUpdate(oldMultiplier, pendingNewMultiplier, pendingNewMultiplierActivationTime);\r\n    }\r\n\r\n    /**\r\n     * @dev Function to change the contract multiplier with nonce, only if oldMultiplier did not change in the meantime. Allowed only for multiplierUpdater\r\n     *\r\n     * Emits a { MultiplierChanged } event\r\n     *\r\n     * @param newMultiplier New multiplier value\r\n     * @param newMultiplierNonce New multplier nonce\r\n     */\r\n    function updateMultiplierWithNonce(\r\n        uint256 newMultiplier,\r\n        uint256 oldMultiplier,\r\n        uint256 newMultiplierNonce,\r\n        uint256 pendingNewMultiplierActivationTime\r\n    ) external onlyMultiplierUpdater updateMultiplier onlyUpdatedMultiplier(oldMultiplier) onlyNewerMultiplierNonce(newMultiplierNonce){\r\n        _updateMultiplier(newMultiplier, newMultiplierNonce, pendingNewMultiplierActivationTime);\r\n        _storeScheduledMultiplierUpdate(oldMultiplier, newMultiplier, pendingNewMultiplierActivationTime);\r\n    }\r\n\r\n    /**\r\n     * @dev Stores an explicit multiplier update in `multiplierUpdates`.\r\n     *\r\n     * If the previously stored entry is still pending (activationTime in the\r\n     * future), it is overwritten in place — only one scheduled update can be\r\n     * pending at a time — and a `MultiplierScheduleOverridden` event is\r\n     * emitted so off-chain consumers can reconcile the now-stale\r\n     * `MultiplierScheduled` event for the discarded entry.\r\n     *\r\n     * Tolerates an empty array (the not-yet-migrated state between a v4\r\n     * implementation upgrade and an `initialize_v4` call) by falling through\r\n     * to the append path.\r\n     */\r\n    function _storeScheduledMultiplierUpdate(\r\n        uint256 _previousMultiplierValue,\r\n        uint256 _multiplierValue,\r\n        uint256 _multiplierActivationTime\r\n    ) internal {\r\n        MultiplierUpdate memory entry = MultiplierUpdate({\r\n            previousMultiplier: _previousMultiplierValue,\r\n            newMultiplier: _multiplierValue,\r\n            activationTime: _multiplierActivationTime > block.timestamp ? _multiplierActivationTime : block.timestamp\r\n        });\r\n\r\n        uint256 len = multiplierUpdates.length;\r\n        if (len > 0 && multiplierUpdates[len - 1].activationTime > block.timestamp) {\r\n            MultiplierUpdate memory overridden = multiplierUpdates[len - 1];\r\n            multiplierUpdates[len - 1] = entry;\r\n            emit MultiplierScheduleOverridden(\r\n                overridden.newMultiplier,\r\n                overridden.activationTime,\r\n                entry.newMultiplier,\r\n                entry.activationTime\r\n            );\r\n        } else {\r\n            multiplierUpdates.push(entry);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @return the amount of shares that corresponds to `_underlyingAmount` underlying amount.\r\n     */\r\n    function _getSharesByUnderlyingAmount(\r\n        uint256 _underlyingAmount,\r\n        uint256 _multiplier\r\n    ) internal pure returns (uint256) {\r\n        return (_underlyingAmount * 1e18) / _multiplier;\r\n    }\r\n\r\n    /**\r\n     * @return the amount of underlying that corresponds to `_sharesAmount` token shares.\r\n     */\r\n    function _getUnderlyingAmountByShares(\r\n        uint256 _sharesAmount,\r\n        uint256 _multiplier\r\n    ) internal pure returns (uint256) {\r\n        return (_sharesAmount * _multiplier) / 1e18;\r\n    }\r\n\r\n    /**\r\n     * @dev Moves `amount` of tokens from `sender` to `recipient`.\r\n     *\r\n     * This internal function is equivalent to {transfer}, and can be used to\r\n     * e.g. implement automatic token fees, slashing mechanisms, etc.\r\n     * \r\n     * Requirements:\r\n     *\r\n     * - `from` cannot be the zero address.\r\n     * - `to` cannot be the zero address.\r\n     * - `from` must have a balance of at least `amount`.\r\n     */\r\n    function _transfer(\r\n        address from,\r\n        address to,\r\n        uint256 amount\r\n    ) internal virtual override {\r\n        (uint256 multiplier, ,) = getCurrentMultiplier();\r\n        uint256 _sharesAmount = _getSharesByUnderlyingAmount(\r\n            amount,\r\n            multiplier\r\n        );\r\n        _transferShares(from, to, _sharesAmount, amount);\r\n    }\r\n\r\n    /**\r\n     * @dev Moves `shares amount` of tokens from `sender` to `recipient`.\r\n     *\r\n     * Requirements:\r\n     *\r\n     * - `from` cannot be the zero address.\r\n     * - `to` cannot be the zero address.\r\n     * - `from` must have a balance of at least `sharesAmount`.\r\n     */\r\n    function _transferShares(\r\n        address from,\r\n        address to,\r\n        uint256 sharesAmount\r\n    ) internal virtual {\r\n        (uint256 multiplier, ,) = getCurrentMultiplier();\r\n         uint256 amount = _getUnderlyingAmountByShares(\r\n            sharesAmount,\r\n            multiplier\r\n        );\r\n        _transferShares(from, to, sharesAmount, amount);\r\n    }\r\n    \r\n    /**\r\n     * @dev Moves `shares amount` of tokens from `sender` to `recipient`.\r\n     *\r\n     * Emits a {Transfer} event.\r\n     * Emits a {TransferShares} event.\r\n     *\r\n     * Requirements:\r\n     *\r\n     * - `from` cannot be the zero address.\r\n     * - `to` cannot be the zero address.\r\n     * - `from` must have a balance of at least `sharesAmount`.\r\n     */\r\n    function _transferShares(\r\n        address from,\r\n        address to,\r\n        uint256 sharesAmount,\r\n        uint256 tokenAmount\r\n    ) internal virtual {\r\n        require(from != address(0), \"ERC20: transfer from the zero address\");\r\n        require(to != address(0), \"ERC20: transfer to the zero address\");\r\n\r\n        _beforeTokenTransfer(from, to, tokenAmount);\r\n\r\n        uint256 currentSenderShares = _shares[from];\r\n        require(\r\n            currentSenderShares >= sharesAmount,\r\n            \"ERC20: transfer amount exceeds balance\"\r\n        );\r\n\r\n        unchecked {\r\n            _shares[from] = currentSenderShares - (sharesAmount);\r\n        }\r\n        _shares[to] = _shares[to] + (sharesAmount);\r\n\r\n        emit Transfer(from, to, tokenAmount);\r\n        emit TransferShares(from, to, sharesAmount);\r\n\r\n        _afterTokenTransfer(from, to, tokenAmount);\r\n    }\r\n\r\n    /** @dev Creates `amount` tokens and assigns them to `account`, increasing\r\n     * the total supply.\r\n     *\r\n     * Emits a {Transfer} event with `from` set to the zero address.\r\n     * Emits a {TransferShares} event with `from` set to the zero address.\r\n     *\r\n     * Requirements:\r\n     *\r\n     * - `account` cannot be the zero address.\r\n     */\r\n    function _mint(address account, uint256 amount) internal virtual override {\r\n        require(account != address(0), \"ERC20: mint to the zero address\");\r\n\r\n        _beforeTokenTransfer(address(0), account, amount);\r\n        (uint256 multiplier, ,) = getCurrentMultiplier();\r\n        uint256 sharesAmount = _getSharesByUnderlyingAmount(amount, multiplier);\r\n\r\n        _totalShares += sharesAmount;\r\n        _shares[account] += sharesAmount;\r\n        emit Transfer(address(0), account, amount);\r\n        emit TransferShares(address(0), account, sharesAmount);\r\n\r\n        _afterTokenTransfer(address(0), account, amount);\r\n    }\r\n\r\n    /**\r\n     * @dev Destroys `amount` tokens from `account`, reducing the\r\n     * total supply.\r\n     *\r\n     * Emits a {Transfer} event with `to` set to the zero address.\r\n     * Emits a {TransferShares} event with `to` set to the zero address.\r\n     *\r\n     * Requirements:\r\n     *\r\n     * - `account` cannot be the zero address.\r\n     * - `account` must have at least `sharesAmount` token shares.\r\n     */\r\n    function _burn(address account, uint256 amount) internal virtual override {\r\n        require(account != address(0), \"ERC20: burn from the zero address\");\r\n\r\n        _beforeTokenTransfer(account, address(0), amount);\r\n        (uint256 multiplier, ,) = getCurrentMultiplier();\r\n        uint256 sharesAmount = _getSharesByUnderlyingAmount(amount, multiplier);\r\n\r\n        uint256 accountBalance = _shares[account];\r\n        require(\r\n            accountBalance >= sharesAmount,\r\n            \"ERC20: burn amount exceeds balance\"\r\n        );\r\n        unchecked {\r\n            _shares[account] = accountBalance - sharesAmount;\r\n        }\r\n        _totalShares -= sharesAmount;\r\n\r\n        emit Transfer(account, address(0), amount);\r\n        emit TransferShares(account, address(0), sharesAmount);\r\n\r\n        _afterTokenTransfer(account, address(0), amount);\r\n    }\r\n\r\n    /**\r\n     * @dev Updates currently stored multiplier with a new value\r\n     *\r\n     * Emit an {MultiplierUpdated} event.\r\n     */\r\n    function _updateMultiplier(uint256 pendingNewMultiplier, uint256 pendingNewMultiplierNonce, uint256 pendingNewMultiplierActivationTime) internal virtual {\r\n        require(pendingNewMultiplier != 0, \"BackedToken: Multiplier cannot be zero\");\r\n        require(pendingNewMultiplierActivationTime < lastTimeFeeApplied + periodLength, \"BackedToken: Activation time needs to be before next period\");\r\n\r\n        newMultiplier = pendingNewMultiplier;\r\n        newMultiplierNonce = pendingNewMultiplierNonce;\r\n\r\n        if(pendingNewMultiplierActivationTime > block.timestamp) {\r\n            newMultiplierActivationTime = pendingNewMultiplierActivationTime;\r\n            emit MultiplierScheduled(pendingNewMultiplier, pendingNewMultiplierActivationTime);\r\n            // We don't need to update lastMultiplier and lastMultiplierNonce here, as they will be updated in updateMultiplier modifier when calling updateMultiplier method\r\n        } else {\r\n            newMultiplierActivationTime = 0;\r\n            lastMultiplier = pendingNewMultiplier;\r\n            lastMultiplierNonce = pendingNewMultiplierNonce;\r\n            emit MultiplierUpdated(pendingNewMultiplier);\r\n        }\r\n    }\r\n\r\n    // Implement the update multiplier functionality before transfer:\r\n    function _beforeTokenTransfer(\r\n        address from,\r\n        address to,\r\n        uint256 amount\r\n    ) internal virtual override updateMultiplier {\r\n        super._beforeTokenTransfer(from, to, amount);\r\n    }\r\n}\r\n","deployed_bytecode":"0x608060405234801561001057600080fd5b506004361061033d5760003560e01c80637ecebe00116101bb5780637ecebe00146105d85780637f120587146105f85780638038cb581461060d5780638230ef7c146106205780638da5cb5b1461062a5780638fcb4e5b14610632578063944b511c14610645578063944e44691461065857806395d89b411461066b5780639dc29fac146106735780639fd0506d14610686578063a15f84da14610699578063a457c2d7146106ac578063a9059cbb146106bf578063a996d6ce146106d2578063aea77ac3146106e5578063b187bd26146106f8578063b6ca6e1214610705578063bedb86fb14610718578063d1786aab1461072b578063d2ca211514610735578063d50256251461073f578063d505accf14610747578063d9bef6c31461075a578063dd62ed3e1461076d578063deeb8bfd14610780578063ec571c6a14610795578063f00c1dff146107ad578063f2fde38b146107b7578063f5eb42dc146107ca578063f5f68898146107dd578063f7a08958146107f0578063f9e47896146107fa578063fca3b5aa14610802578063ff29130c14610815578063ffa1ad741461082857600080fd5b80630194b09b14610342578063056025011461036c57806306fdde03146103815780630754617214610396578063095ea7b3146103a95780630a4d8a71146103cc57806318160ddd146103df57806318d8ec3c146103f55780631b3ed722146103fd5780631c5633d71461040557806323b872dd1461041857806327810b6e1461042b5780632b63c3001461043e5780632cc5ecd5146104615780632d88af4a1461048457806330adf81f14610497578063313ce567146104ac5780633644e515146104bb57806339509351146104c45780633dfa34cd146104d757806340c10f19146104e1578063430c777c146104f457806344acb51b1461050757806349dc5e8d1461051a5780634cd88b761461052d5780635416d876146105405780635666795d1461054a5780635add8efc146105535780635c575ef314610566578063606380671461057a5780636d7804591461058457806370a0823114610597578063715018a6146105aa5780637544e6b3146105b257806378f86afc146105c5575b600080fd5b61010254610356906001600160a01b031681565b60405161036391906134d3565b60405180910390f35b61037f61037a3660046134e7565b61084c565b005b61038961085c565b6040516103639190613513565b60cb54610356906001600160a01b031681565b6103bc6103b7366004613584565b6108ee565b6040519015158152602001610363565b61037f6103da3660046135ae565b610906565b6103e7610a4f565b604051908152602001610363565b61037f610a71565b6103e7610ae8565b61037f6104133660046135e0565b610b04565b6103bc6104263660046135f9565b610ba7565b60cc54610356906001600160a01b031681565b610446610bcb565b60408051938452602084019290925290820152606001610363565b6103bc61046f366004613635565b60ce6020526000908152604090205460ff1681565b61037f610492366004613635565b610c89565b6103e7600080516020613dd883398151915281565b60405160128152602001610363565b6103e760985481565b6103bc6104d2366004613584565b610d02565b6103e76101035481565b61037f6104ef366004613584565b610d41565b61037f6105023660046135e0565b610dad565b6103e76105153660046135e0565b610e6d565b61037f610528366004613635565b610e8d565b61037f61053b3660046136f2565b610fe1565b6103e761010c5481565b61010d546103e7565b61037f6105613660046135e0565b610ffa565b60cd546103bc90600160a01b900460ff1681565b6103e761010b5481565b6103bc6105923660046135f9565b61109d565b6103e76105a5366004613635565b611120565b61037f611141565b61037f6105c0366004613755565b61117c565b61037f6105d33660046137d3565b611198565b6103e76105e6366004613635565b60976020526000908152604090205481565b6103e7600080516020613d5883398151915281565b61037f61061b3660046134e7565b6111d3565b6103e76101095481565b6103566112ae565b6103bc610640366004613584565b6112bd565b6103e76106533660046135e0565b611321565b61037f61066636600461380f565b61133a565b610389611559565b61037f610681366004613584565b611568565b60cd54610356906001600160a01b031681565b61037f6106a7366004613891565b61163b565b6103bc6106ba366004613584565b6116c2565b6103bc6106cd366004613584565b611754565b61037f6106e0366004613635565b611762565b61037f6106f33660046138ae565b6117db565b60cf546103bc9060ff1681565b61037f610713366004613921565b611836565b61037f610726366004613891565b6118c4565b6103e76101065481565b6103e76101055481565b610389611963565b61037f6107553660046138ae565b6119f1565b6104466107683660046135e0565b611a43565b6103e761077b366004613958565b611a77565b6103e7600080516020613d7883398151915281565b60cf546103569061010090046001600160a01b031681565b6103e76101045481565b61037f6107c5366004613635565b611aa2565b6103e76107d8366004613635565b611b3f565b61037f6107eb366004613635565b611b5b565b6103e761010a5481565b6103e7611bd5565b61037f610810366004613635565b611bf1565b61037f6108233660046138ae565b611c6a565b610389604051806040016040528060058152602001640312e312e360dc1b81525081565b610857838383611e82565b505050565b60606068805461086b9061398b565b80601f01602080910402602001604051908101604052809291908181526020018280546108979061398b565b80156108e45780601f106108b9576101008083540402835291602001916108e4565b820191906000526020600020905b8154815290600101906020018083116108c757829003601f168201915b5050505050905090565b6000336108fc818585611fa2565b5060019392505050565b610102546001600160a01b0316336001600160a01b0316146109435760405162461bcd60e51b815260040161093a906139c6565b60405180910390fd5b6000806000610950610bcb565b92509250925081610105546109659190613a20565b610103546109739190613a3f565b6101035561010654831461098d5761098d838260006120c6565b856000610998610bcb565b505090508181146109bb5760405162461bcd60e51b815260040161093a90613a57565b8660006109c6610bcb565b92505050818110610a2c5760405162461bcd60e51b815260206004820152602a60248201527f4261636b6564546f6b656e3a204d756c7469706c696572206e6f6e63652069736044820152691037baba3230ba32b21760b11b606482015260840161093a565b610a378b8a8a6120c6565b610a428a8c8a612241565b5050505050505050505050565b600080610a5a610bcb565b50509050610a6b610108548261241d565b91505090565b61010b5415610ad05760405162461bcd60e51b81526020600482015260376024820152600080516020613df8833981519152604482015276081d8cc8185b1c9958591e481a5b9a5d1a585b1a5e9959604a1b606482015260840161093a565b6101065461010b556101095461010a55600061010c55565b600061010c544210610afc575061010b5490565b506101065490565b33610b0d6112ae565b6001600160a01b031614610b335760405162461bcd60e51b815260040161093a90613aa6565b6000806000610b40610bcb565b9250925092508161010554610b559190613a20565b61010354610b639190613a3f565b61010355610106548314610b7d57610b7d838260006120c6565b61010c5415610b9e5760405162461bcd60e51b815260040161093a90613adb565b50505061010555565b600033610bb585828561243c565b610bc0858585612523565b506001949350505050565b600080600061010c54421015610bed5750506101065461010954909260009250565b6101055461010354610bff9042613b1c565b610c099190613b33565b915061010b54925061010a5490506000610104541115610c845760005b82811015610c7657670de0b6b3a764000061010454670de0b6b3a7640000610c4e9190613b1c565b610c589086613a20565b610c629190613b33565b935080610c6e81613b55565b915050610c26565b50610c818282613a3f565b90505b909192565b33610c926112ae565b6001600160a01b031614610cb85760405162461bcd60e51b815260040161093a90613aa6565b60cd80546001600160a01b0319166001600160a01b0383169081179091556040517f4f68150eb56c53cc9373649e35bc37dd235a0c86e10aa23b8a835378136ac6a090600090a250565b3360008181526066602090815260408083206001600160a01b03871684529091528120549091906108fc9082908690610d3c908790613a3f565b611fa2565b60cb546001600160a01b0316336001600160a01b031614610d9f5760405162461bcd60e51b81526020600482015260186024820152772130b1b5b2b22a37b5b2b71d1027b7363c9036b4b73a32b960411b604482015260640161093a565b610da9828261254b565b5050565b33610db66112ae565b6001600160a01b031614610ddc5760405162461bcd60e51b815260040161093a90613aa6565b6000806000610de9610bcb565b9250925092508161010554610dfe9190613a20565b61010354610e0c9190613a3f565b61010355610106548314610e2657610e26838260006120c6565b61010c5415610e475760405162461bcd60e51b815260040161093a90613adb565b83610e645760405162461bcd60e51b815260040161093a90613b70565b50505061010355565b600080610e78610bcb565b50509050610e868382612674565b9392505050565b33610e966112ae565b6001600160a01b031614610ebc5760405162461bcd60e51b815260040161093a90613aa6565b60405163df592f7d60e01b81526001600160a01b0382169063df592f7d90610ee89030906004016134d3565b60206040518083038186803b158015610f0057600080fd5b505afa158015610f14573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f389190613ba7565b15610f8f5760405162461bcd60e51b815260206004820152602160248201527f4261636b6564546f6b656e3a2057726f6e67204c69737420696e7465726661636044820152606560f81b606482015260840161093a565b60cf8054610100600160a81b0319166101006001600160a01b038416908102919091179091556040517feff538eaa91b9b5384df4354f3841681487784258ac4b209182aef0755f9e0be90600090a250565b610feb8282611d7a565b610da962015180426000611e82565b336110036112ae565b6001600160a01b0316146110295760405162461bcd60e51b815260040161093a90613aa6565b6000806000611036610bcb565b925092509250816101055461104b9190613a20565b610103546110599190613a3f565b6101035561010654831461107357611073838260006120c6565b61010c54156110945760405162461bcd60e51b815260040161093a90613adb565b50505061010455565b6000806000806110ab610bcb565b92509250925081610105546110c09190613a20565b610103546110ce9190613a3f565b610103556101065483146110e8576110e8838260006120c6565b60006110f7866101065461241d565b90503361110589828461243c565b61111189898985612689565b50600198975050505050505050565b60008061112b610bcb565b50509050610e8661113b84611b3f565b8261241d565b3361114a6112ae565b6001600160a01b0316146111705760405162461bcd60e51b815260040161093a90613aa6565b61117a6000612890565b565b6111868585611d7a565b611191838383611e82565b5050505050565b336111a16112ae565b6001600160a01b0316146111c75760405162461bcd60e51b815260040161093a90613aa6565b6111d0816128e2565b50565b610102546001600160a01b0316336001600160a01b0316146112075760405162461bcd60e51b815260040161093a906139c6565b6000806000611214610bcb565b92509250925081610105546112299190613a20565b610103546112379190613a3f565b6101035561010654831461125157611251838260006120c6565b84600061125c610bcb565b5050905081811461127f5760405162461bcd60e51b815260040161093a90613a57565b611299886101095460016112939190613a3f565b886120c6565b6112a4878988612241565b5050505050505050565b6033546001600160a01b031690565b6000806000806112cb610bcb565b92509250925081610105546112e09190613a20565b610103546112ee9190613a3f565b6101035561010654831461130857611308838260006120c6565b33611314818888612925565b5060019695505050505050565b60008061132c610bcb565b50509050610e86838261241d565b61010d54156113995760405162461bcd60e51b81526020600482015260376024820152600080516020613df8833981519152604482015276081d8d08185b1c9958591e481a5b9a5d1a585b1a5e9959604a1b606482015260840161093a565b60408051606081018252670de0b6b3a764000080825260208201908152600092820183815261010d80546001810182559085529251600080516020613db88339815191526003909402938401559051600080516020613d1883398151915283015551600080516020613e18833981519152909101555b8181101561085757600083838381811061142b5761142b613bc4565b90506060020160000135116114a25760405162461bcd60e51b81526020600482015260436024820152600080516020613df883398151915260448201527f3a2070726576696f75734d756c7469706c6965722063616e6e6f74206265207a60648201526265726f60e81b608482015260a40161093a565b61010d60405180606001604052808585858181106114c2576114c2613bc4565b9050606002016000013581526020018585858181106114e3576114e3613bc4565b90506060020160200135815260200185858581811061150457611504613bc4565b606002919091016040908101359092525082546001808201855560009485526020948590208451600390930201918255938301519381019390935501516002909101558061155181613b55565b91505061140f565b60606069805461086b9061398b565b60cc546001600160a01b0316336001600160a01b0316146115c65760405162461bcd60e51b81526020600482015260186024820152772130b1b5b2b22a37b5b2b71d1027b7363c90313ab93732b960411b604482015260640161093a565b6001600160a01b0382163314806115e557506001600160a01b03821630145b6116315760405162461bcd60e51b815260206004820181905260248201527f4261636b6564546f6b656e3a2043616e6e6f74206275726e206163636f756e74604482015260640161093a565b610da9828261294d565b336116446112ae565b6001600160a01b03161461166a5760405162461bcd60e51b815260040161093a90613aa6565b60cd8054821515600160a01b0260ff60a01b199091161790556040517f238422c0d720060023911dceeb8ba506952801637ad007844edcd4416364fecf906116b790831515815260200190565b60405180910390a150565b3360008181526066602090815260408083206001600160a01b0387168452909152812054909190838110156117475760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b606482015260840161093a565b610bc08286868403611fa2565b6000336108fc818585612523565b3361176b6112ae565b6001600160a01b0316146117915760405162461bcd60e51b815260040161093a90613aa6565b60cc80546001600160a01b0319166001600160a01b0383169081179091556040517f5bb1db06eeb30d85c1e53ae2285b460ce83e4318c623bd1ca51df912f64c45a490600090a250565b60cd54600160a01b900460ff1680611802575033600090815260ce602052604090205460ff165b61181e5760405162461bcd60e51b815260040161093a90613bda565b61182d87878787878787612adc565b50505050505050565b3361183f6112ae565b6001600160a01b0316146118655760405162461bcd60e51b815260040161093a90613aa6565b6001600160a01b038216600081815260ce6020908152604091829020805460ff191685151590811790915591519182527f7459b9d2544fdaf790226b129ff473f8c8ce56bfc10bc3bdbe1c71b9d426a546910160405180910390a25050565b60cd546001600160a01b0316336001600160a01b0316146119225760405162461bcd60e51b81526020600482015260186024820152772130b1b5b2b22a37b5b2b71d1027b7363c903830bab9b2b960411b604482015260640161093a565b60cf805460ff19168215159081179091556040519081527fb9bcdd890b4d4c213bab99cf96dc1adb9ede36bb2a54610c91a86de844b05fb8906020016116b7565b60d080546119709061398b565b80601f016020809104026020016040519081016040528092919081815260200182805461199c9061398b565b80156119e95780601f106119be576101008083540402835291602001916119e9565b820191906000526020600020905b8154815290600101906020018083116119cc57829003601f168201915b505050505081565b60cd54600160a01b900460ff1680611a18575033600090815260ce602052604090205460ff165b611a345760405162461bcd60e51b815260040161093a90613bda565b61182d87878787878787612b5f565b61010d8181548110611a5457600080fd5b600091825260209091206003909102018054600182015460029092015490925083565b6001600160a01b03918216600090815260666020908152604080832093909416825291909152205490565b33611aab6112ae565b6001600160a01b031614611ad15760405162461bcd60e51b815260040161093a90613aa6565b6001600160a01b038116611b365760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161093a565b6111d081612890565b6001600160a01b03166000908152610107602052604090205490565b33611b646112ae565b6001600160a01b031614611b8a5760405162461bcd60e51b815260040161093a90613aa6565b61010280546001600160a01b0319166001600160a01b0383169081179091556040517f352ee13cfd2e4909f0a0c7b78a6079921377f6377d8af594509ff9aaf4f925da90600090a250565b600061010c544210611be9575061010a5490565b506101095490565b33611bfa6112ae565b6001600160a01b031614611c205760405162461bcd60e51b815260040161093a90613aa6565b60cb80546001600160a01b0319166001600160a01b0383169081179091556040517f6adffd5c93085d835dac6f3b40adf7c242ca4b3284048d20c3d8a501748dc97390600090a250565b60cd54600160a01b900460ff1680611c91575033600090815260ce602052604090205460ff165b611cad5760405162461bcd60e51b815260040161093a90613bda565b6000806000611cba610bcb565b9250925092508161010554611ccf9190613a20565b61010354611cdd9190613a3f565b61010355610106548314611cf757611cf7838260006120c6565b86421115611d175760405162461bcd60e51b815260040161093a90613c1c565b6000600080516020613d788339815191528b8b8b611d348f612be2565b8c604051602001611d4a96959493929190613c53565b604051602081830303815290604052805190602001209050611d6f8b82898989612c13565b610a428b8b8b612925565b600054610100900460ff16611d955760005460ff1615611d9d565b611d9d612ccf565b611e005760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840161093a565b600054610100900460ff16158015611e22576000805461ffff19166101011790555b611e2c8383612ce0565b611e34612d11565b611e3c612d40565b611e5d6040518060600160405280602f8152602001613ce9602f91396128e2565b8015610857576000805461ff0019169055505050565b6001600160a01b03163b151590565b6101035415611ede5760405162461bcd60e51b81526020600482015260346024820152600080516020613df883398151915260448201527308185b1c9958591e481a5b9a5d1a585b1a5e995960621b606482015260840161093a565b81611efb5760405162461bcd60e51b815260040161093a90613b70565b670de0b6b3a7640000610106819055600061010981905561010b82905561010a81905561010c819055610105949094556101039290925561010455604080516060810182528281526020810192835290810183815261010d805460018101825594529051600080516020613db8833981519152600394909402938401559051600080516020613d1883398151915283015551600080516020613e1883398151915290910155565b6001600160a01b0383166120045760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b606482015260840161093a565b6001600160a01b0382166120655760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b606482015260840161093a565b6001600160a01b0383811660008181526066602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b826121225760405162461bcd60e51b815260206004820152602660248201527f4261636b6564546f6b656e3a204d756c7469706c6965722063616e6e6f74206260448201526565207a65726f60d01b606482015260840161093a565b61010554610103546121349190613a3f565b81106121a65760405162461bcd60e51b815260206004820152603b60248201527f4261636b6564546f6b656e3a2041637469766174696f6e2074696d65206e656560448201527a191cc81d1bc81899481899599bdc99481b995e1d081c195c9a5bd9602a1b606482015260840161093a565b61010b83905561010a829055428111156121ff5761010c81905560408051848152602081018390527f0fc82f15d800f52869be69bb6dec5615511ff09b246f46c6fe20618c2a845d2091015b60405180910390a1505050565b600061010c556101068390556101098290556040518381527f4dbe4840d7465bd162f67814cea0b519567a2e0e578bcde61e7f4ced361e5a3d906020016121f2565b600060405180606001604052808581526020018481526020014284116122675742612269565b835b905261010d5490915080158015906122af57504261010d61228b600184613b1c565b8154811061229b5761229b613bc4565b906000526020600020906003020160020154115b156123bc57600061010d6122c4600184613b1c565b815481106122d4576122d4613bc4565b9060005260206000209060030201604051806060016040529081600082015481526020016001820154815260200160028201548152505090508261010d60018461231e9190613b1c565b8154811061232e5761232e613bc4565b600091825260209182902083516003909202019081558282015160018201556040928301516002909101558281015183830151918601518684015193517f58b46712c260c156927373112c5a0eac6c69c7b7a8eec19de939fb590a6037f7946123ae94929193845260208401929092526040830152606082015260800190565b60405180910390a150611191565b5061010d80546001810182556000919091528151600080516020613db88339815191526003909202918201556020820151600080516020613d18833981519152820155604090910151600080516020613e1883398151915290910155505050565b6000670de0b6b3a76400006124328385613a20565b610e869190613b33565b60cf5460405163df592f7d60e01b81526101009091046001600160a01b03169063df592f7d906124709085906004016134d3565b60206040518083038186803b15801561248857600080fd5b505afa15801561249c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124c09190613ba7565b156125185760405162461bcd60e51b815260206004820152602260248201527f4261636b6564546f6b656e3a207370656e6465722069732073616e6374696f6e604482015261195960f21b606482015260840161093a565b610857838383612de9565b600061252d610bcb565b50509050600061253d8383612674565b905061119185858386612689565b6001600160a01b0382166125a15760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015260640161093a565b6125ad60008383612e5d565b60006125b7610bcb565b5050905060006125c78383612674565b90508061010860008282546125dc9190613a3f565b90915550506001600160a01b038416600090815261010760205260408120805483929061260a908490613a3f565b90915550506040518381526001600160a01b03851690600090600080516020613d988339815191529060200160405180910390a36040518181526001600160a01b03851690600090600080516020613d388339815191529060200160405180910390a35b50505050565b60008161243284670de0b6b3a7640000613a20565b6001600160a01b0384166126ed5760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b606482015260840161093a565b6001600160a01b03831661274f5760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b606482015260840161093a565b61275a848483612e5d565b6001600160a01b03841660009081526101076020526040902054828110156127d35760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b606482015260840161093a565b6001600160a01b0380861660009081526101076020526040808220868503905591861681522054612805908490613a3f565b6001600160a01b03808616600081815261010760205260409081902093909355915190871690600080516020613d98833981519152906128489086815260200190565b60405180910390a3836001600160a01b0316856001600160a01b0316600080516020613d388339815191528560405161288391815260200190565b60405180910390a3611191565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b80516128f59060d090602084019061343a565b507f9c1e1a17a78053ad78b3801837ad5e515d429987252f2e1371b7b50fa8ff8bec816040516116b79190613513565b600061292f610bcb565b50509050600061293f838361241d565b905061119185858584612689565b6001600160a01b0382166129ad5760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b606482015260840161093a565b6129b982600083612e5d565b60006129c3610bcb565b5050905060006129d38383612674565b6001600160a01b0385166000908152610107602052604090205490915081811015612a4b5760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b606482015260840161093a565b6001600160a01b03851660009081526101076020526040812083830390556101088054849290612a7c908490613b1c565b90915550506040518481526000906001600160a01b03871690600080516020613d988339815191529060200160405180910390a36040518281526000906001600160a01b03871690600080516020613d3883398151915290602001612883565b83421115612afc5760405162461bcd60e51b815260040161093a90613c1c565b6000600080516020613d58833981519152888888612b198c612be2565b89604051602001612b2f96959493929190613c53565b604051602081830303815290604052805190602001209050612b548882868686612c13565b6112a4888888612523565b83421115612b7f5760405162461bcd60e51b815260040161093a90613c1c565b6000600080516020613dd8833981519152888888612b9c8c612be2565b89604051602001612bb296959493929190613c53565b604051602081830303815290604052805190602001209050612bd78882868686612c13565b6112a4888888611fa2565b6001600160a01b0381166000908152609760205260408120805491829190612c0983613b55565b9190505550919050565b6000612c5c6098548660405161190160f01b6020820152602281018390526042810182905260009060620160405160208183030381529060405280519060200120905092915050565b90506000612c6c82868686612eba565b9050866001600160a01b0316816001600160a01b03161461182d5760405162461bcd60e51b815260206004820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e61747572650000604482015260640161093a565b6000612cda30611e73565b15905090565b600054610100900460ff16612d075760405162461bcd60e51b815260040161093a90613c87565b610da98282612ee2565b600054610100900460ff16612d385760405162461bcd60e51b815260040161093a90613c87565b61117a612f30565b7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f612d6961085c565b805160209182012060408051808201825260018152603160f81b90840152805192830193909352918101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160408051601f198184030181529190528051602090910120609855565b6000612df58484611a77565b9050600019811461266e5781811015612e505760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e6365000000604482015260640161093a565b61266e8484848403611fa2565b6000806000612e6a610bcb565b9250925092508161010554612e7f9190613a20565b61010354612e8d9190613a3f565b61010355610106548314612ea757612ea7838260006120c6565b612eb2868686612f60565b505050505050565b6000806000612ecb878787876131a1565b91509150612ed881613284565b5095945050505050565b600054610100900460ff16612f095760405162461bcd60e51b815260040161093a90613c87565b8151612f1c90606890602085019061343a565b50805161085790606990602084019061343a565b600054610100900460ff16612f575760405162461bcd60e51b815260040161093a90613c87565b61117a33612890565b60cf5460ff1615612fc45760405162461bcd60e51b815260206004820152602860248201527f4261636b6564546f6b656e3a20746f6b656e207472616e73666572207768696c60448201526719481c185d5cd95960c21b606482015260840161093a565b6001600160a01b03831615801590612fe457506001600160a01b03821615155b156108575760cf5460405163df592f7d60e01b81526101009091046001600160a01b03169063df592f7d9061301d9086906004016134d3565b60206040518083038186803b15801561303557600080fd5b505afa158015613049573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061306d9190613ba7565b156130c45760405162461bcd60e51b815260206004820152602160248201527f4261636b6564546f6b656e3a2073656e6465722069732073616e6374696f6e656044820152601960fa1b606482015260840161093a565b60cf5460405163df592f7d60e01b81526101009091046001600160a01b03169063df592f7d906130f89085906004016134d3565b60206040518083038186803b15801561311057600080fd5b505afa158015613124573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131489190613ba7565b156108575760405162461bcd60e51b815260206004820152602360248201527f4261636b6564546f6b656e3a2072656365697665722069732073616e6374696f6044820152621b995960ea1b606482015260840161093a565b6000806fa2a8918ca85bafe22016d0b997e4df60600160ff1b038311156131ce575060009050600361327b565b8460ff16601b141580156131e657508460ff16601c14155b156131f7575060009050600461327b565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801561324b573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166132745760006001925092505061327b565b9150600090505b94509492505050565b600081600481111561329857613298613cd2565b14156132a15750565b60018160048111156132b5576132b5613cd2565b14156132fe5760405162461bcd60e51b815260206004820152601860248201527745434453413a20696e76616c6964207369676e617475726560401b604482015260640161093a565b600281600481111561331257613312613cd2565b14156133605760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e67746800604482015260640161093a565b600381600481111561337457613374613cd2565b14156133cd5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b606482015260840161093a565b60048160048111156133e1576133e1613cd2565b14156111d05760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b606482015260840161093a565b8280546134469061398b565b90600052602060002090601f01602090048101928261346857600085556134ae565b82601f1061348157805160ff19168380011785556134ae565b828001600101855582156134ae579182015b828111156134ae578251825591602001919060010190613493565b506134ba9291506134be565b5090565b5b808211156134ba57600081556001016134bf565b6001600160a01b0391909116815260200190565b6000806000606084860312156134fc57600080fd5b505081359360208301359350604090920135919050565b600060208083528351808285015260005b8181101561354057858101830151858201604001528201613524565b81811115613552576000604083870101525b50601f01601f1916929092016040019392505050565b80356001600160a01b038116811461357f57600080fd5b919050565b6000806040838503121561359757600080fd5b6135a083613568565b946020939093013593505050565b600080600080608085870312156135c457600080fd5b5050823594602084013594506040840135936060013592509050565b6000602082840312156135f257600080fd5b5035919050565b60008060006060848603121561360e57600080fd5b61361784613568565b925061362560208501613568565b9150604084013590509250925092565b60006020828403121561364757600080fd5b610e8682613568565b634e487b7160e01b600052604160045260246000fd5b600082601f83011261367757600080fd5b81356001600160401b038082111561369157613691613650565b604051601f8301601f19908116603f011681019082821181831017156136b9576136b9613650565b816040528381528660208588010111156136d257600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000806040838503121561370557600080fd5b82356001600160401b038082111561371c57600080fd5b61372886838701613666565b9350602085013591508082111561373e57600080fd5b5061374b85828601613666565b9150509250929050565b600080600080600060a0868803121561376d57600080fd5b85356001600160401b038082111561378457600080fd5b61379089838a01613666565b965060208801359150808211156137a657600080fd5b506137b388828901613666565b959895975050505060408401359360608101359360809091013592509050565b6000602082840312156137e557600080fd5b81356001600160401b038111156137fb57600080fd5b61380784828501613666565b949350505050565b6000806020838503121561382257600080fd5b82356001600160401b038082111561383957600080fd5b818501915085601f83011261384d57600080fd5b81358181111561385c57600080fd5b86602060608302850101111561387157600080fd5b60209290920196919550909350505050565b80151581146111d057600080fd5b6000602082840312156138a357600080fd5b8135610e8681613883565b600080600080600080600060e0888a0312156138c957600080fd5b6138d288613568565b96506138e060208901613568565b95506040880135945060608801359350608088013560ff8116811461390457600080fd5b9699959850939692959460a0840135945060c09093013592915050565b6000806040838503121561393457600080fd5b61393d83613568565b9150602083013561394d81613883565b809150509250929050565b6000806040838503121561396b57600080fd5b61397483613568565b915061398260208401613568565b90509250929050565b600181811c9082168061399f57607f821691505b602082108114156139c057634e487b7160e01b600052602260045260246000fd5b50919050565b60208082526024908201527f4261636b6564546f6b656e3a204f6e6c79206d756c7469706c6965722075706460408201526330ba32b960e11b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b6000816000190483118215151615613a3a57613a3a613a0a565b500290565b60008219821115613a5257613a52613a0a565b500190565b6020808252602f908201527f4261636b6564546f6b656e3a204d756c7469706c696572206368616e6765642060408201526e696e20746865206d65616e74696d6560881b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526021908201527f4d756c7469706c6965722061637469766174696f6e20696e2070726f677265736040820152607360f81b606082015260800190565b600082821015613b2e57613b2e613a0a565b500390565b600082613b5057634e487b7160e01b600052601260045260246000fd5b500490565b6000600019821415613b6957613b69613a0a565b5060010190565b6020808252601d908201527f496e76616c6964206c6173742074696d6520666565206170706c696564000000604082015260600190565b600060208284031215613bb957600080fd5b8151610e8681613883565b634e487b7160e01b600052603260045260246000fd5b60208082526022908201527f4261636b6564546f6b656e3a20556e617574686f72697a65642064656c656761604082015261746560f01b606082015260800190565b6020808252601d908201527f45524332305065726d69743a206578706972656420646561646c696e65000000604082015260600190565b9586526001600160a01b0394851660208701529290931660408501526060840152608083019190915260a082015260c00190565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b634e487b7160e01b600052602160045260246000fdfe68747470733a2f2f7777772e6261636b65646173736574732e66692f6c6567616c2d646f63756d656e746174696f6ed37d5aab611bd3c946977441ea77c3eceb623a7966962fbc75015048e8640bfc9d9c909296d9c674451c0c24f02cb64981eb3b727f99865939192f880a755dcb4eba51a08f56c21035fcbda11b779f91748d3ae295b24c3e032d1eeff84edc2e9e94967fdaa8d9ec120d5cd909b051117451405dec84a6cd95bb12f2eb37bf75ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efd37d5aab611bd3c946977441ea77c3eceb623a7966962fbc75015048e8640bfb6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c94261636b65644175746f466565546f6b656e496d706c656d656e746174696f6ed37d5aab611bd3c946977441ea77c3eceb623a7966962fbc75015048e8640bfda264697066735822122004eee7102fd5a9ded1ab4329a0519a96171fe102a65a8781bff6ddb878f31d9f64736f6c63430008090033","optimization_enabled":true,"verified_twin_address_hash":null,"is_verified":true,"compiler_settings":{"evmVersion":"london","libraries":{},"metadata":{"bytecodeHash":"ipfs"},"optimizer":{"enabled":true,"runs":10},"outputSelection":{"*":{"":["*"],"*":["*"]}}},"optimization_runs":10,"sourcify_repo_url":null,"decoded_constructor_args":null,"compiler_version":"v0.8.9+commit.e5eed63a","is_verified_via_verifier_alliance":true,"verified_at":"2026-06-24T15:04:11.928985Z","implementations":[],"proxy_type":null,"external_libraries":[],"creation_bytecode":"0x60806040523480156200001157600080fd5b50620000746040518060400160405280601b81526020017f4261636b656420546f6b656e20496d706c656d656e746174696f6e00000000008152506040518060400160405280600381526020016242544960e81b8152506200008060201b60201c565b600161010355620007f2565b620000978282620000ac60201b62001d7a1760201c565b620000a862015180426000620001bb565b5050565b600054610100900460ff16620000c95760005460ff1615620000d3565b620000d362000360565b6200013c5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b600054610100900460ff161580156200015f576000805461ffff19166101011790555b6200016b83836200037e565b62000175620003b4565b6200017f620003ea565b620001a36040518060600160405280602f81526020016200466f602f913962000495565b8015620001b6576000805461ff00191690555b505050565b6101035415620002345760405162461bcd60e51b815260206004820152603460248201527f4261636b65644175746f466565546f6b656e496d706c656d656e746174696f6e60448201527f20616c726561647920696e697469616c697a6564000000000000000000000000606482015260840162000133565b81620002835760405162461bcd60e51b815260206004820152601d60248201527f496e76616c6964206c6173742074696d6520666565206170706c696564000000604482015260640162000133565b670de0b6b3a7640000610106819055600061010981905561010b82905561010a81905561010c819055610105949094556101039290925561010455604080516060810182528281526020810192835290810183815261010d8054600181018255945290517fd37d5aab611bd3c946977441ea77c3eceb623a7966962fbc75015048e8640bfb6003949094029384015590517fd37d5aab611bd3c946977441ea77c3eceb623a7966962fbc75015048e8640bfc830155517fd37d5aab611bd3c946977441ea77c3eceb623a7966962fbc75015048e8640bfd90910155565b60006200037830620004e760201b62001e731760201c565b15905090565b600054610100900460ff16620003a85760405162461bcd60e51b8152600401620001339062000712565b620000a88282620004f6565b600054610100900460ff16620003de5760405162461bcd60e51b8152600401620001339062000712565b620003e86200054b565b565b7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6200041562000580565b805160209182012060408051808201825260018152603160f81b90840152805192830193909352918101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160408051601f198184030181529190528051602090910120609855565b8051620004aa9060d09060208401906200066c565b507f9c1e1a17a78053ad78b3801837ad5e515d429987252f2e1371b7b50fa8ff8bec81604051620004dc91906200075d565b60405180910390a150565b6001600160a01b03163b151590565b600054610100900460ff16620005205760405162461bcd60e51b8152600401620001339062000712565b8151620005359060689060208501906200066c565b508051620001b69060699060208401906200066c565b600054610100900460ff16620005755760405162461bcd60e51b8152600401620001339062000712565b620003e8336200061a565b6060606880546200059190620007b5565b80601f0160208091040260200160405190810160405280929190818152602001828054620005bf90620007b5565b8015620006105780601f10620005e45761010080835404028352916020019162000610565b820191906000526020600020905b815481529060010190602001808311620005f257829003601f168201915b5050505050905090565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b8280546200067a90620007b5565b90600052602060002090601f0160209004810192826200069e5760008555620006e9565b82601f10620006b957805160ff1916838001178555620006e9565b82800160010185558215620006e9579182015b82811115620006e9578251825591602001919060010190620006cc565b50620006f7929150620006fb565b5090565b5b80821115620006f75760008155600101620006fc565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b600060208083528351808285015260005b818110156200078c578581018301518582016040015282016200076e565b818111156200079f576000604083870101525b50601f01601f1916929092016040019392505050565b600181811c90821680620007ca57607f821691505b60208210811415620007ec57634e487b7160e01b600052602260045260246000fd5b50919050565b613e6d80620008026000396000f3fe608060405234801561001057600080fd5b506004361061033d5760003560e01c80637ecebe00116101bb5780637ecebe00146105d85780637f120587146105f85780638038cb581461060d5780638230ef7c146106205780638da5cb5b1461062a5780638fcb4e5b14610632578063944b511c14610645578063944e44691461065857806395d89b411461066b5780639dc29fac146106735780639fd0506d14610686578063a15f84da14610699578063a457c2d7146106ac578063a9059cbb146106bf578063a996d6ce146106d2578063aea77ac3146106e5578063b187bd26146106f8578063b6ca6e1214610705578063bedb86fb14610718578063d1786aab1461072b578063d2ca211514610735578063d50256251461073f578063d505accf14610747578063d9bef6c31461075a578063dd62ed3e1461076d578063deeb8bfd14610780578063ec571c6a14610795578063f00c1dff146107ad578063f2fde38b146107b7578063f5eb42dc146107ca578063f5f68898146107dd578063f7a08958146107f0578063f9e47896146107fa578063fca3b5aa14610802578063ff29130c14610815578063ffa1ad741461082857600080fd5b80630194b09b14610342578063056025011461036c57806306fdde03146103815780630754617214610396578063095ea7b3146103a95780630a4d8a71146103cc57806318160ddd146103df57806318d8ec3c146103f55780631b3ed722146103fd5780631c5633d71461040557806323b872dd1461041857806327810b6e1461042b5780632b63c3001461043e5780632cc5ecd5146104615780632d88af4a1461048457806330adf81f14610497578063313ce567146104ac5780633644e515146104bb57806339509351146104c45780633dfa34cd146104d757806340c10f19146104e1578063430c777c146104f457806344acb51b1461050757806349dc5e8d1461051a5780634cd88b761461052d5780635416d876146105405780635666795d1461054a5780635add8efc146105535780635c575ef314610566578063606380671461057a5780636d7804591461058457806370a0823114610597578063715018a6146105aa5780637544e6b3146105b257806378f86afc146105c5575b600080fd5b61010254610356906001600160a01b031681565b60405161036391906134d3565b60405180910390f35b61037f61037a3660046134e7565b61084c565b005b61038961085c565b6040516103639190613513565b60cb54610356906001600160a01b031681565b6103bc6103b7366004613584565b6108ee565b6040519015158152602001610363565b61037f6103da3660046135ae565b610906565b6103e7610a4f565b604051908152602001610363565b61037f610a71565b6103e7610ae8565b61037f6104133660046135e0565b610b04565b6103bc6104263660046135f9565b610ba7565b60cc54610356906001600160a01b031681565b610446610bcb565b60408051938452602084019290925290820152606001610363565b6103bc61046f366004613635565b60ce6020526000908152604090205460ff1681565b61037f610492366004613635565b610c89565b6103e7600080516020613dd883398151915281565b60405160128152602001610363565b6103e760985481565b6103bc6104d2366004613584565b610d02565b6103e76101035481565b61037f6104ef366004613584565b610d41565b61037f6105023660046135e0565b610dad565b6103e76105153660046135e0565b610e6d565b61037f610528366004613635565b610e8d565b61037f61053b3660046136f2565b610fe1565b6103e761010c5481565b61010d546103e7565b61037f6105613660046135e0565b610ffa565b60cd546103bc90600160a01b900460ff1681565b6103e761010b5481565b6103bc6105923660046135f9565b61109d565b6103e76105a5366004613635565b611120565b61037f611141565b61037f6105c0366004613755565b61117c565b61037f6105d33660046137d3565b611198565b6103e76105e6366004613635565b60976020526000908152604090205481565b6103e7600080516020613d5883398151915281565b61037f61061b3660046134e7565b6111d3565b6103e76101095481565b6103566112ae565b6103bc610640366004613584565b6112bd565b6103e76106533660046135e0565b611321565b61037f61066636600461380f565b61133a565b610389611559565b61037f610681366004613584565b611568565b60cd54610356906001600160a01b031681565b61037f6106a7366004613891565b61163b565b6103bc6106ba366004613584565b6116c2565b6103bc6106cd366004613584565b611754565b61037f6106e0366004613635565b611762565b61037f6106f33660046138ae565b6117db565b60cf546103bc9060ff1681565b61037f610713366004613921565b611836565b61037f610726366004613891565b6118c4565b6103e76101065481565b6103e76101055481565b610389611963565b61037f6107553660046138ae565b6119f1565b6104466107683660046135e0565b611a43565b6103e761077b366004613958565b611a77565b6103e7600080516020613d7883398151915281565b60cf546103569061010090046001600160a01b031681565b6103e76101045481565b61037f6107c5366004613635565b611aa2565b6103e76107d8366004613635565b611b3f565b61037f6107eb366004613635565b611b5b565b6103e761010a5481565b6103e7611bd5565b61037f610810366004613635565b611bf1565b61037f6108233660046138ae565b611c6a565b610389604051806040016040528060058152602001640312e312e360dc1b81525081565b610857838383611e82565b505050565b60606068805461086b9061398b565b80601f01602080910402602001604051908101604052809291908181526020018280546108979061398b565b80156108e45780601f106108b9576101008083540402835291602001916108e4565b820191906000526020600020905b8154815290600101906020018083116108c757829003601f168201915b5050505050905090565b6000336108fc818585611fa2565b5060019392505050565b610102546001600160a01b0316336001600160a01b0316146109435760405162461bcd60e51b815260040161093a906139c6565b60405180910390fd5b6000806000610950610bcb565b92509250925081610105546109659190613a20565b610103546109739190613a3f565b6101035561010654831461098d5761098d838260006120c6565b856000610998610bcb565b505090508181146109bb5760405162461bcd60e51b815260040161093a90613a57565b8660006109c6610bcb565b92505050818110610a2c5760405162461bcd60e51b815260206004820152602a60248201527f4261636b6564546f6b656e3a204d756c7469706c696572206e6f6e63652069736044820152691037baba3230ba32b21760b11b606482015260840161093a565b610a378b8a8a6120c6565b610a428a8c8a612241565b5050505050505050505050565b600080610a5a610bcb565b50509050610a6b610108548261241d565b91505090565b61010b5415610ad05760405162461bcd60e51b81526020600482015260376024820152600080516020613df8833981519152604482015276081d8cc8185b1c9958591e481a5b9a5d1a585b1a5e9959604a1b606482015260840161093a565b6101065461010b556101095461010a55600061010c55565b600061010c544210610afc575061010b5490565b506101065490565b33610b0d6112ae565b6001600160a01b031614610b335760405162461bcd60e51b815260040161093a90613aa6565b6000806000610b40610bcb565b9250925092508161010554610b559190613a20565b61010354610b639190613a3f565b61010355610106548314610b7d57610b7d838260006120c6565b61010c5415610b9e5760405162461bcd60e51b815260040161093a90613adb565b50505061010555565b600033610bb585828561243c565b610bc0858585612523565b506001949350505050565b600080600061010c54421015610bed5750506101065461010954909260009250565b6101055461010354610bff9042613b1c565b610c099190613b33565b915061010b54925061010a5490506000610104541115610c845760005b82811015610c7657670de0b6b3a764000061010454670de0b6b3a7640000610c4e9190613b1c565b610c589086613a20565b610c629190613b33565b935080610c6e81613b55565b915050610c26565b50610c818282613a3f565b90505b909192565b33610c926112ae565b6001600160a01b031614610cb85760405162461bcd60e51b815260040161093a90613aa6565b60cd80546001600160a01b0319166001600160a01b0383169081179091556040517f4f68150eb56c53cc9373649e35bc37dd235a0c86e10aa23b8a835378136ac6a090600090a250565b3360008181526066602090815260408083206001600160a01b03871684529091528120549091906108fc9082908690610d3c908790613a3f565b611fa2565b60cb546001600160a01b0316336001600160a01b031614610d9f5760405162461bcd60e51b81526020600482015260186024820152772130b1b5b2b22a37b5b2b71d1027b7363c9036b4b73a32b960411b604482015260640161093a565b610da9828261254b565b5050565b33610db66112ae565b6001600160a01b031614610ddc5760405162461bcd60e51b815260040161093a90613aa6565b6000806000610de9610bcb565b9250925092508161010554610dfe9190613a20565b61010354610e0c9190613a3f565b61010355610106548314610e2657610e26838260006120c6565b61010c5415610e475760405162461bcd60e51b815260040161093a90613adb565b83610e645760405162461bcd60e51b815260040161093a90613b70565b50505061010355565b600080610e78610bcb565b50509050610e868382612674565b9392505050565b33610e966112ae565b6001600160a01b031614610ebc5760405162461bcd60e51b815260040161093a90613aa6565b60405163df592f7d60e01b81526001600160a01b0382169063df592f7d90610ee89030906004016134d3565b60206040518083038186803b158015610f0057600080fd5b505afa158015610f14573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f389190613ba7565b15610f8f5760405162461bcd60e51b815260206004820152602160248201527f4261636b6564546f6b656e3a2057726f6e67204c69737420696e7465726661636044820152606560f81b606482015260840161093a565b60cf8054610100600160a81b0319166101006001600160a01b038416908102919091179091556040517feff538eaa91b9b5384df4354f3841681487784258ac4b209182aef0755f9e0be90600090a250565b610feb8282611d7a565b610da962015180426000611e82565b336110036112ae565b6001600160a01b0316146110295760405162461bcd60e51b815260040161093a90613aa6565b6000806000611036610bcb565b925092509250816101055461104b9190613a20565b610103546110599190613a3f565b6101035561010654831461107357611073838260006120c6565b61010c54156110945760405162461bcd60e51b815260040161093a90613adb565b50505061010455565b6000806000806110ab610bcb565b92509250925081610105546110c09190613a20565b610103546110ce9190613a3f565b610103556101065483146110e8576110e8838260006120c6565b60006110f7866101065461241d565b90503361110589828461243c565b61111189898985612689565b50600198975050505050505050565b60008061112b610bcb565b50509050610e8661113b84611b3f565b8261241d565b3361114a6112ae565b6001600160a01b0316146111705760405162461bcd60e51b815260040161093a90613aa6565b61117a6000612890565b565b6111868585611d7a565b611191838383611e82565b5050505050565b336111a16112ae565b6001600160a01b0316146111c75760405162461bcd60e51b815260040161093a90613aa6565b6111d0816128e2565b50565b610102546001600160a01b0316336001600160a01b0316146112075760405162461bcd60e51b815260040161093a906139c6565b6000806000611214610bcb565b92509250925081610105546112299190613a20565b610103546112379190613a3f565b6101035561010654831461125157611251838260006120c6565b84600061125c610bcb565b5050905081811461127f5760405162461bcd60e51b815260040161093a90613a57565b611299886101095460016112939190613a3f565b886120c6565b6112a4878988612241565b5050505050505050565b6033546001600160a01b031690565b6000806000806112cb610bcb565b92509250925081610105546112e09190613a20565b610103546112ee9190613a3f565b6101035561010654831461130857611308838260006120c6565b33611314818888612925565b5060019695505050505050565b60008061132c610bcb565b50509050610e86838261241d565b61010d54156113995760405162461bcd60e51b81526020600482015260376024820152600080516020613df8833981519152604482015276081d8d08185b1c9958591e481a5b9a5d1a585b1a5e9959604a1b606482015260840161093a565b60408051606081018252670de0b6b3a764000080825260208201908152600092820183815261010d80546001810182559085529251600080516020613db88339815191526003909402938401559051600080516020613d1883398151915283015551600080516020613e18833981519152909101555b8181101561085757600083838381811061142b5761142b613bc4565b90506060020160000135116114a25760405162461bcd60e51b81526020600482015260436024820152600080516020613df883398151915260448201527f3a2070726576696f75734d756c7469706c6965722063616e6e6f74206265207a60648201526265726f60e81b608482015260a40161093a565b61010d60405180606001604052808585858181106114c2576114c2613bc4565b9050606002016000013581526020018585858181106114e3576114e3613bc4565b90506060020160200135815260200185858581811061150457611504613bc4565b606002919091016040908101359092525082546001808201855560009485526020948590208451600390930201918255938301519381019390935501516002909101558061155181613b55565b91505061140f565b60606069805461086b9061398b565b60cc546001600160a01b0316336001600160a01b0316146115c65760405162461bcd60e51b81526020600482015260186024820152772130b1b5b2b22a37b5b2b71d1027b7363c90313ab93732b960411b604482015260640161093a565b6001600160a01b0382163314806115e557506001600160a01b03821630145b6116315760405162461bcd60e51b815260206004820181905260248201527f4261636b6564546f6b656e3a2043616e6e6f74206275726e206163636f756e74604482015260640161093a565b610da9828261294d565b336116446112ae565b6001600160a01b03161461166a5760405162461bcd60e51b815260040161093a90613aa6565b60cd8054821515600160a01b0260ff60a01b199091161790556040517f238422c0d720060023911dceeb8ba506952801637ad007844edcd4416364fecf906116b790831515815260200190565b60405180910390a150565b3360008181526066602090815260408083206001600160a01b0387168452909152812054909190838110156117475760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b606482015260840161093a565b610bc08286868403611fa2565b6000336108fc818585612523565b3361176b6112ae565b6001600160a01b0316146117915760405162461bcd60e51b815260040161093a90613aa6565b60cc80546001600160a01b0319166001600160a01b0383169081179091556040517f5bb1db06eeb30d85c1e53ae2285b460ce83e4318c623bd1ca51df912f64c45a490600090a250565b60cd54600160a01b900460ff1680611802575033600090815260ce602052604090205460ff165b61181e5760405162461bcd60e51b815260040161093a90613bda565b61182d87878787878787612adc565b50505050505050565b3361183f6112ae565b6001600160a01b0316146118655760405162461bcd60e51b815260040161093a90613aa6565b6001600160a01b038216600081815260ce6020908152604091829020805460ff191685151590811790915591519182527f7459b9d2544fdaf790226b129ff473f8c8ce56bfc10bc3bdbe1c71b9d426a546910160405180910390a25050565b60cd546001600160a01b0316336001600160a01b0316146119225760405162461bcd60e51b81526020600482015260186024820152772130b1b5b2b22a37b5b2b71d1027b7363c903830bab9b2b960411b604482015260640161093a565b60cf805460ff19168215159081179091556040519081527fb9bcdd890b4d4c213bab99cf96dc1adb9ede36bb2a54610c91a86de844b05fb8906020016116b7565b60d080546119709061398b565b80601f016020809104026020016040519081016040528092919081815260200182805461199c9061398b565b80156119e95780601f106119be576101008083540402835291602001916119e9565b820191906000526020600020905b8154815290600101906020018083116119cc57829003601f168201915b505050505081565b60cd54600160a01b900460ff1680611a18575033600090815260ce602052604090205460ff165b611a345760405162461bcd60e51b815260040161093a90613bda565b61182d87878787878787612b5f565b61010d8181548110611a5457600080fd5b600091825260209091206003909102018054600182015460029092015490925083565b6001600160a01b03918216600090815260666020908152604080832093909416825291909152205490565b33611aab6112ae565b6001600160a01b031614611ad15760405162461bcd60e51b815260040161093a90613aa6565b6001600160a01b038116611b365760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161093a565b6111d081612890565b6001600160a01b03166000908152610107602052604090205490565b33611b646112ae565b6001600160a01b031614611b8a5760405162461bcd60e51b815260040161093a90613aa6565b61010280546001600160a01b0319166001600160a01b0383169081179091556040517f352ee13cfd2e4909f0a0c7b78a6079921377f6377d8af594509ff9aaf4f925da90600090a250565b600061010c544210611be9575061010a5490565b506101095490565b33611bfa6112ae565b6001600160a01b031614611c205760405162461bcd60e51b815260040161093a90613aa6565b60cb80546001600160a01b0319166001600160a01b0383169081179091556040517f6adffd5c93085d835dac6f3b40adf7c242ca4b3284048d20c3d8a501748dc97390600090a250565b60cd54600160a01b900460ff1680611c91575033600090815260ce602052604090205460ff165b611cad5760405162461bcd60e51b815260040161093a90613bda565b6000806000611cba610bcb565b9250925092508161010554611ccf9190613a20565b61010354611cdd9190613a3f565b61010355610106548314611cf757611cf7838260006120c6565b86421115611d175760405162461bcd60e51b815260040161093a90613c1c565b6000600080516020613d788339815191528b8b8b611d348f612be2565b8c604051602001611d4a96959493929190613c53565b604051602081830303815290604052805190602001209050611d6f8b82898989612c13565b610a428b8b8b612925565b600054610100900460ff16611d955760005460ff1615611d9d565b611d9d612ccf565b611e005760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840161093a565b600054610100900460ff16158015611e22576000805461ffff19166101011790555b611e2c8383612ce0565b611e34612d11565b611e3c612d40565b611e5d6040518060600160405280602f8152602001613ce9602f91396128e2565b8015610857576000805461ff0019169055505050565b6001600160a01b03163b151590565b6101035415611ede5760405162461bcd60e51b81526020600482015260346024820152600080516020613df883398151915260448201527308185b1c9958591e481a5b9a5d1a585b1a5e995960621b606482015260840161093a565b81611efb5760405162461bcd60e51b815260040161093a90613b70565b670de0b6b3a7640000610106819055600061010981905561010b82905561010a81905561010c819055610105949094556101039290925561010455604080516060810182528281526020810192835290810183815261010d805460018101825594529051600080516020613db8833981519152600394909402938401559051600080516020613d1883398151915283015551600080516020613e1883398151915290910155565b6001600160a01b0383166120045760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b606482015260840161093a565b6001600160a01b0382166120655760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b606482015260840161093a565b6001600160a01b0383811660008181526066602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b826121225760405162461bcd60e51b815260206004820152602660248201527f4261636b6564546f6b656e3a204d756c7469706c6965722063616e6e6f74206260448201526565207a65726f60d01b606482015260840161093a565b61010554610103546121349190613a3f565b81106121a65760405162461bcd60e51b815260206004820152603b60248201527f4261636b6564546f6b656e3a2041637469766174696f6e2074696d65206e656560448201527a191cc81d1bc81899481899599bdc99481b995e1d081c195c9a5bd9602a1b606482015260840161093a565b61010b83905561010a829055428111156121ff5761010c81905560408051848152602081018390527f0fc82f15d800f52869be69bb6dec5615511ff09b246f46c6fe20618c2a845d2091015b60405180910390a1505050565b600061010c556101068390556101098290556040518381527f4dbe4840d7465bd162f67814cea0b519567a2e0e578bcde61e7f4ced361e5a3d906020016121f2565b600060405180606001604052808581526020018481526020014284116122675742612269565b835b905261010d5490915080158015906122af57504261010d61228b600184613b1c565b8154811061229b5761229b613bc4565b906000526020600020906003020160020154115b156123bc57600061010d6122c4600184613b1c565b815481106122d4576122d4613bc4565b9060005260206000209060030201604051806060016040529081600082015481526020016001820154815260200160028201548152505090508261010d60018461231e9190613b1c565b8154811061232e5761232e613bc4565b600091825260209182902083516003909202019081558282015160018201556040928301516002909101558281015183830151918601518684015193517f58b46712c260c156927373112c5a0eac6c69c7b7a8eec19de939fb590a6037f7946123ae94929193845260208401929092526040830152606082015260800190565b60405180910390a150611191565b5061010d80546001810182556000919091528151600080516020613db88339815191526003909202918201556020820151600080516020613d18833981519152820155604090910151600080516020613e1883398151915290910155505050565b6000670de0b6b3a76400006124328385613a20565b610e869190613b33565b60cf5460405163df592f7d60e01b81526101009091046001600160a01b03169063df592f7d906124709085906004016134d3565b60206040518083038186803b15801561248857600080fd5b505afa15801561249c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124c09190613ba7565b156125185760405162461bcd60e51b815260206004820152602260248201527f4261636b6564546f6b656e3a207370656e6465722069732073616e6374696f6e604482015261195960f21b606482015260840161093a565b610857838383612de9565b600061252d610bcb565b50509050600061253d8383612674565b905061119185858386612689565b6001600160a01b0382166125a15760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015260640161093a565b6125ad60008383612e5d565b60006125b7610bcb565b5050905060006125c78383612674565b90508061010860008282546125dc9190613a3f565b90915550506001600160a01b038416600090815261010760205260408120805483929061260a908490613a3f565b90915550506040518381526001600160a01b03851690600090600080516020613d988339815191529060200160405180910390a36040518181526001600160a01b03851690600090600080516020613d388339815191529060200160405180910390a35b50505050565b60008161243284670de0b6b3a7640000613a20565b6001600160a01b0384166126ed5760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b606482015260840161093a565b6001600160a01b03831661274f5760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b606482015260840161093a565b61275a848483612e5d565b6001600160a01b03841660009081526101076020526040902054828110156127d35760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b606482015260840161093a565b6001600160a01b0380861660009081526101076020526040808220868503905591861681522054612805908490613a3f565b6001600160a01b03808616600081815261010760205260409081902093909355915190871690600080516020613d98833981519152906128489086815260200190565b60405180910390a3836001600160a01b0316856001600160a01b0316600080516020613d388339815191528560405161288391815260200190565b60405180910390a3611191565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b80516128f59060d090602084019061343a565b507f9c1e1a17a78053ad78b3801837ad5e515d429987252f2e1371b7b50fa8ff8bec816040516116b79190613513565b600061292f610bcb565b50509050600061293f838361241d565b905061119185858584612689565b6001600160a01b0382166129ad5760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b606482015260840161093a565b6129b982600083612e5d565b60006129c3610bcb565b5050905060006129d38383612674565b6001600160a01b0385166000908152610107602052604090205490915081811015612a4b5760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b606482015260840161093a565b6001600160a01b03851660009081526101076020526040812083830390556101088054849290612a7c908490613b1c565b90915550506040518481526000906001600160a01b03871690600080516020613d988339815191529060200160405180910390a36040518281526000906001600160a01b03871690600080516020613d3883398151915290602001612883565b83421115612afc5760405162461bcd60e51b815260040161093a90613c1c565b6000600080516020613d58833981519152888888612b198c612be2565b89604051602001612b2f96959493929190613c53565b604051602081830303815290604052805190602001209050612b548882868686612c13565b6112a4888888612523565b83421115612b7f5760405162461bcd60e51b815260040161093a90613c1c565b6000600080516020613dd8833981519152888888612b9c8c612be2565b89604051602001612bb296959493929190613c53565b604051602081830303815290604052805190602001209050612bd78882868686612c13565b6112a4888888611fa2565b6001600160a01b0381166000908152609760205260408120805491829190612c0983613b55565b9190505550919050565b6000612c5c6098548660405161190160f01b6020820152602281018390526042810182905260009060620160405160208183030381529060405280519060200120905092915050565b90506000612c6c82868686612eba565b9050866001600160a01b0316816001600160a01b03161461182d5760405162461bcd60e51b815260206004820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e61747572650000604482015260640161093a565b6000612cda30611e73565b15905090565b600054610100900460ff16612d075760405162461bcd60e51b815260040161093a90613c87565b610da98282612ee2565b600054610100900460ff16612d385760405162461bcd60e51b815260040161093a90613c87565b61117a612f30565b7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f612d6961085c565b805160209182012060408051808201825260018152603160f81b90840152805192830193909352918101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160408051601f198184030181529190528051602090910120609855565b6000612df58484611a77565b9050600019811461266e5781811015612e505760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e6365000000604482015260640161093a565b61266e8484848403611fa2565b6000806000612e6a610bcb565b9250925092508161010554612e7f9190613a20565b61010354612e8d9190613a3f565b61010355610106548314612ea757612ea7838260006120c6565b612eb2868686612f60565b505050505050565b6000806000612ecb878787876131a1565b91509150612ed881613284565b5095945050505050565b600054610100900460ff16612f095760405162461bcd60e51b815260040161093a90613c87565b8151612f1c90606890602085019061343a565b50805161085790606990602084019061343a565b600054610100900460ff16612f575760405162461bcd60e51b815260040161093a90613c87565b61117a33612890565b60cf5460ff1615612fc45760405162461bcd60e51b815260206004820152602860248201527f4261636b6564546f6b656e3a20746f6b656e207472616e73666572207768696c60448201526719481c185d5cd95960c21b606482015260840161093a565b6001600160a01b03831615801590612fe457506001600160a01b03821615155b156108575760cf5460405163df592f7d60e01b81526101009091046001600160a01b03169063df592f7d9061301d9086906004016134d3565b60206040518083038186803b15801561303557600080fd5b505afa158015613049573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061306d9190613ba7565b156130c45760405162461bcd60e51b815260206004820152602160248201527f4261636b6564546f6b656e3a2073656e6465722069732073616e6374696f6e656044820152601960fa1b606482015260840161093a565b60cf5460405163df592f7d60e01b81526101009091046001600160a01b03169063df592f7d906130f89085906004016134d3565b60206040518083038186803b15801561311057600080fd5b505afa158015613124573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131489190613ba7565b156108575760405162461bcd60e51b815260206004820152602360248201527f4261636b6564546f6b656e3a2072656365697665722069732073616e6374696f6044820152621b995960ea1b606482015260840161093a565b6000806fa2a8918ca85bafe22016d0b997e4df60600160ff1b038311156131ce575060009050600361327b565b8460ff16601b141580156131e657508460ff16601c14155b156131f7575060009050600461327b565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801561324b573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166132745760006001925092505061327b565b9150600090505b94509492505050565b600081600481111561329857613298613cd2565b14156132a15750565b60018160048111156132b5576132b5613cd2565b14156132fe5760405162461bcd60e51b815260206004820152601860248201527745434453413a20696e76616c6964207369676e617475726560401b604482015260640161093a565b600281600481111561331257613312613cd2565b14156133605760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e67746800604482015260640161093a565b600381600481111561337457613374613cd2565b14156133cd5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b606482015260840161093a565b60048160048111156133e1576133e1613cd2565b14156111d05760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b606482015260840161093a565b8280546134469061398b565b90600052602060002090601f01602090048101928261346857600085556134ae565b82601f1061348157805160ff19168380011785556134ae565b828001600101855582156134ae579182015b828111156134ae578251825591602001919060010190613493565b506134ba9291506134be565b5090565b5b808211156134ba57600081556001016134bf565b6001600160a01b0391909116815260200190565b6000806000606084860312156134fc57600080fd5b505081359360208301359350604090920135919050565b600060208083528351808285015260005b8181101561354057858101830151858201604001528201613524565b81811115613552576000604083870101525b50601f01601f1916929092016040019392505050565b80356001600160a01b038116811461357f57600080fd5b919050565b6000806040838503121561359757600080fd5b6135a083613568565b946020939093013593505050565b600080600080608085870312156135c457600080fd5b5050823594602084013594506040840135936060013592509050565b6000602082840312156135f257600080fd5b5035919050565b60008060006060848603121561360e57600080fd5b61361784613568565b925061362560208501613568565b9150604084013590509250925092565b60006020828403121561364757600080fd5b610e8682613568565b634e487b7160e01b600052604160045260246000fd5b600082601f83011261367757600080fd5b81356001600160401b038082111561369157613691613650565b604051601f8301601f19908116603f011681019082821181831017156136b9576136b9613650565b816040528381528660208588010111156136d257600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000806040838503121561370557600080fd5b82356001600160401b038082111561371c57600080fd5b61372886838701613666565b9350602085013591508082111561373e57600080fd5b5061374b85828601613666565b9150509250929050565b600080600080600060a0868803121561376d57600080fd5b85356001600160401b038082111561378457600080fd5b61379089838a01613666565b965060208801359150808211156137a657600080fd5b506137b388828901613666565b959895975050505060408401359360608101359360809091013592509050565b6000602082840312156137e557600080fd5b81356001600160401b038111156137fb57600080fd5b61380784828501613666565b949350505050565b6000806020838503121561382257600080fd5b82356001600160401b038082111561383957600080fd5b818501915085601f83011261384d57600080fd5b81358181111561385c57600080fd5b86602060608302850101111561387157600080fd5b60209290920196919550909350505050565b80151581146111d057600080fd5b6000602082840312156138a357600080fd5b8135610e8681613883565b600080600080600080600060e0888a0312156138c957600080fd5b6138d288613568565b96506138e060208901613568565b95506040880135945060608801359350608088013560ff8116811461390457600080fd5b9699959850939692959460a0840135945060c09093013592915050565b6000806040838503121561393457600080fd5b61393d83613568565b9150602083013561394d81613883565b809150509250929050565b6000806040838503121561396b57600080fd5b61397483613568565b915061398260208401613568565b90509250929050565b600181811c9082168061399f57607f821691505b602082108114156139c057634e487b7160e01b600052602260045260246000fd5b50919050565b60208082526024908201527f4261636b6564546f6b656e3a204f6e6c79206d756c7469706c6965722075706460408201526330ba32b960e11b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b6000816000190483118215151615613a3a57613a3a613a0a565b500290565b60008219821115613a5257613a52613a0a565b500190565b6020808252602f908201527f4261636b6564546f6b656e3a204d756c7469706c696572206368616e6765642060408201526e696e20746865206d65616e74696d6560881b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526021908201527f4d756c7469706c6965722061637469766174696f6e20696e2070726f677265736040820152607360f81b606082015260800190565b600082821015613b2e57613b2e613a0a565b500390565b600082613b5057634e487b7160e01b600052601260045260246000fd5b500490565b6000600019821415613b6957613b69613a0a565b5060010190565b6020808252601d908201527f496e76616c6964206c6173742074696d6520666565206170706c696564000000604082015260600190565b600060208284031215613bb957600080fd5b8151610e8681613883565b634e487b7160e01b600052603260045260246000fd5b60208082526022908201527f4261636b6564546f6b656e3a20556e617574686f72697a65642064656c656761604082015261746560f01b606082015260800190565b6020808252601d908201527f45524332305065726d69743a206578706972656420646561646c696e65000000604082015260600190565b9586526001600160a01b0394851660208701529290931660408501526060840152608083019190915260a082015260c00190565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b634e487b7160e01b600052602160045260246000fdfe68747470733a2f2f7777772e6261636b65646173736574732e66692f6c6567616c2d646f63756d656e746174696f6ed37d5aab611bd3c946977441ea77c3eceb623a7966962fbc75015048e8640bfc9d9c909296d9c674451c0c24f02cb64981eb3b727f99865939192f880a755dcb4eba51a08f56c21035fcbda11b779f91748d3ae295b24c3e032d1eeff84edc2e9e94967fdaa8d9ec120d5cd909b051117451405dec84a6cd95bb12f2eb37bf75ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efd37d5aab611bd3c946977441ea77c3eceb623a7966962fbc75015048e8640bfb6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c94261636b65644175746f466565546f6b656e496d706c656d656e746174696f6ed37d5aab611bd3c946977441ea77c3eceb623a7966962fbc75015048e8640bfda264697066735822122004eee7102fd5a9ded1ab4329a0519a96171fe102a65a8781bff6ddb878f31d9f64736f6c6343000809003368747470733a2f2f7777772e6261636b65646173736574732e66692f6c6567616c2d646f63756d656e746174696f6e","name":"BackedAutoFeeTokenImplementation","is_blueprint":false,"license_type":"none","is_fully_verified":true,"is_verified_via_eth_bytecode_db":true,"language":"solidity","evm_version":"london","can_be_visualized_via_sol2uml":true,"is_verified_via_sourcify":false,"additional_sources":[{"file_path":"@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary StringsUpgradeable {\n    bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n    /**\n     * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n     */\n    function toString(uint256 value) internal pure returns (string memory) {\n        // Inspired by OraclizeAPI's implementation - MIT licence\n        // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n        if (value == 0) {\n            return \"0\";\n        }\n        uint256 temp = value;\n        uint256 digits;\n        while (temp != 0) {\n            digits++;\n            temp /= 10;\n        }\n        bytes memory buffer = new bytes(digits);\n        while (value != 0) {\n            digits -= 1;\n            buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n            value /= 10;\n        }\n        return string(buffer);\n    }\n\n    /**\n     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n     */\n    function toHexString(uint256 value) internal pure returns (string memory) {\n        if (value == 0) {\n            return \"0x00\";\n        }\n        uint256 temp = value;\n        uint256 length = 0;\n        while (temp != 0) {\n            length++;\n            temp >>= 8;\n        }\n        return toHexString(value, length);\n    }\n\n    /**\n     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n     */\n    function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n        bytes memory buffer = new bytes(2 * length + 2);\n        buffer[0] = \"0\";\n        buffer[1] = \"x\";\n        for (uint256 i = 2 * length + 1; i > 1; --i) {\n            buffer[i] = _HEX_SYMBOLS[value & 0xf];\n            value >>= 4;\n        }\n        require(value == 0, \"Strings: hex length insufficient\");\n        return string(buffer);\n    }\n}\n"},{"file_path":"@openzeppelin/contracts-upgradeable/utils/cryptography/ECDSAUpgradeable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../StringsUpgradeable.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSAUpgradeable {\n    enum RecoverError {\n        NoError,\n        InvalidSignature,\n        InvalidSignatureLength,\n        InvalidSignatureS,\n        InvalidSignatureV\n    }\n\n    function _throwError(RecoverError error) private pure {\n        if (error == RecoverError.NoError) {\n            return; // no error: do nothing\n        } else if (error == RecoverError.InvalidSignature) {\n            revert(\"ECDSA: invalid signature\");\n        } else if (error == RecoverError.InvalidSignatureLength) {\n            revert(\"ECDSA: invalid signature length\");\n        } else if (error == RecoverError.InvalidSignatureS) {\n            revert(\"ECDSA: invalid signature 's' value\");\n        } else if (error == RecoverError.InvalidSignatureV) {\n            revert(\"ECDSA: invalid signature 'v' value\");\n        }\n    }\n\n    /**\n     * @dev Returns the address that signed a hashed message (`hash`) with\n     * `signature` or error string. This address can then be used for verification purposes.\n     *\n     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n     * this function rejects them by requiring the `s` value to be in the lower\n     * half order, and the `v` value to be either 27 or 28.\n     *\n     * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n     * verification to be secure: it is possible to craft signatures that\n     * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n     * this is by receiving a hash of the original message (which may otherwise\n     * be too long), and then calling {toEthSignedMessageHash} on it.\n     *\n     * Documentation for signature generation:\n     * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n     * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n     *\n     * _Available since v4.3._\n     */\n    function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n        // Check the signature length\n        // - case 65: r,s,v signature (standard)\n        // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n        if (signature.length == 65) {\n            bytes32 r;\n            bytes32 s;\n            uint8 v;\n            // ecrecover takes the signature parameters, and the only way to get them\n            // currently is to use assembly.\n            assembly {\n                r := mload(add(signature, 0x20))\n                s := mload(add(signature, 0x40))\n                v := byte(0, mload(add(signature, 0x60)))\n            }\n            return tryRecover(hash, v, r, s);\n        } else if (signature.length == 64) {\n            bytes32 r;\n            bytes32 vs;\n            // ecrecover takes the signature parameters, and the only way to get them\n            // currently is to use assembly.\n            assembly {\n                r := mload(add(signature, 0x20))\n                vs := mload(add(signature, 0x40))\n            }\n            return tryRecover(hash, r, vs);\n        } else {\n            return (address(0), RecoverError.InvalidSignatureLength);\n        }\n    }\n\n    /**\n     * @dev Returns the address that signed a hashed message (`hash`) with\n     * `signature`. This address can then be used for verification purposes.\n     *\n     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n     * this function rejects them by requiring the `s` value to be in the lower\n     * half order, and the `v` value to be either 27 or 28.\n     *\n     * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n     * verification to be secure: it is possible to craft signatures that\n     * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n     * this is by receiving a hash of the original message (which may otherwise\n     * be too long), and then calling {toEthSignedMessageHash} on it.\n     */\n    function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n        (address recovered, RecoverError error) = tryRecover(hash, signature);\n        _throwError(error);\n        return recovered;\n    }\n\n    /**\n     * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n     *\n     * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n     *\n     * _Available since v4.3._\n     */\n    function tryRecover(\n        bytes32 hash,\n        bytes32 r,\n        bytes32 vs\n    ) internal pure returns (address, RecoverError) {\n        bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n        uint8 v = uint8((uint256(vs) >> 255) + 27);\n        return tryRecover(hash, v, r, s);\n    }\n\n    /**\n     * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n     *\n     * _Available since v4.2._\n     */\n    function recover(\n        bytes32 hash,\n        bytes32 r,\n        bytes32 vs\n    ) internal pure returns (address) {\n        (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n        _throwError(error);\n        return recovered;\n    }\n\n    /**\n     * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n     * `r` and `s` signature fields separately.\n     *\n     * _Available since v4.3._\n     */\n    function tryRecover(\n        bytes32 hash,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) internal pure returns (address, RecoverError) {\n        // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n        // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n        // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n        // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n        //\n        // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n        // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n        // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n        // these malleable signatures as well.\n        if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n            return (address(0), RecoverError.InvalidSignatureS);\n        }\n        if (v != 27 && v != 28) {\n            return (address(0), RecoverError.InvalidSignatureV);\n        }\n\n        // If the signature is valid (and not malleable), return the signer address\n        address signer = ecrecover(hash, v, r, s);\n        if (signer == address(0)) {\n            return (address(0), RecoverError.InvalidSignature);\n        }\n\n        return (signer, RecoverError.NoError);\n    }\n\n    /**\n     * @dev Overload of {ECDSA-recover} that receives the `v`,\n     * `r` and `s` signature fields separately.\n     */\n    function recover(\n        bytes32 hash,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) internal pure returns (address) {\n        (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n        _throwError(error);\n        return recovered;\n    }\n\n    /**\n     * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n     * produces hash corresponding to the one signed with the\n     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n     * JSON-RPC method as part of EIP-191.\n     *\n     * See {recover}.\n     */\n    function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n        // 32 is the length in bytes of hash,\n        // enforced by the type signature above\n        return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n    }\n\n    /**\n     * @dev Returns an Ethereum Signed Message, created from `s`. This\n     * produces hash corresponding to the one signed with the\n     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n     * JSON-RPC method as part of EIP-191.\n     *\n     * See {recover}.\n     */\n    function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n        return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", StringsUpgradeable.toString(s.length), s));\n    }\n\n    /**\n     * @dev Returns an Ethereum Signed Typed Data, created from a\n     * `domainSeparator` and a `structHash`. This produces hash corresponding\n     * to the one signed with the\n     * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n     * JSON-RPC method as part of EIP-712.\n     *\n     * See {recover}.\n     */\n    function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n        return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n    }\n}\n"},{"file_path":"contracts/BackedTokenImplementation.sol","source_code":"/**\r\n * SPDX-License-Identifier: MIT\r\n *\r\n * Copyright (c) 2021-2022 Backed Finance AG\r\n *\r\n * Permission is hereby granted, free of charge, to any person obtaining a copy\r\n * of this software and associated documentation files (the \"Software\"), to deal\r\n * in the Software without restriction, including without limitation the rights\r\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\n * copies of the Software, and to permit persons to whom the Software is\r\n * furnished to do so, subject to the following conditions:\r\n *\r\n * The above copyright notice and this permission notice shall be included in\r\n * copies or substantial portions of the Software.\r\n *\r\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\n * SOFTWARE.\r\n */\r\n\r\n/**\r\n * Disclaimer and Terms of Use\r\n *\r\n * These ERC-20 tokens have not been registered under the U.S. Securities Act of 1933, as\r\n * amended or with any securities regulatory authority of any State or other jurisdiction\r\n * of the United States and (i) may not be offered, sold or delivered within the United States\r\n * to, or for the account or benefit of U.S. Persons, and (ii) may be offered, sold or otherwise\r\n * delivered at any time only to transferees that are Non-United States Persons (as defined by \r\n * the U.S. Commodities Futures Trading Commission). \r\n * For more information and restrictions please refer to the issuer's [Website](https://www.backedassets.fi/legal-documentation)\r\n */\r\n\r\npragma solidity 0.8.9;\r\n\r\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\r\nimport \"./ERC20PermitDelegateTransfer.sol\";\r\nimport \"./SanctionsList.sol\";\r\nimport \"./interfaces/IBackedToken.sol\";\r\n\r\n/**\r\n * @dev\r\n *\r\n * This token contract is following the ERC20 standard.\r\n * It inherits ERC20PermitDelegateTransfer.sol, which extends the basic ERC20 to also allow permit and delegateTransfer EIP-712 functionality.\r\n * Enforces Sanctions List via the Chainalysis standard interface.\r\n * The contract contains three roles:\r\n *  - A minter, that can mint new tokens.\r\n *  - A burner, that can burn its own tokens, or contract's tokens.\r\n *  - A pauser, that can pause or restore all transfers in the contract.\r\n *  - An owner, that can set the three above, and also the sanctionsList pointer.\r\n * The owner can also set who can use the EIP-712 functionality, either specific accounts via a whitelist, or everyone.\r\n * \r\n */\r\n\r\ncontract BackedTokenImplementation is OwnableUpgradeable, ERC20PermitDelegateTransfer, IBackedToken {\r\n    string constant public VERSION = \"1.1.0\";\r\n\r\n    // Roles:\r\n    address public minter;\r\n    address public burner;\r\n    address public pauser;\r\n\r\n    // EIP-712 Delegate Functionality:\r\n    bool public delegateMode;\r\n    mapping(address => bool) public delegateWhitelist;\r\n\r\n    // Pause:\r\n    bool public isPaused;\r\n\r\n    // SanctionsList:\r\n    SanctionsList public sanctionsList;\r\n\r\n    // Terms:\r\n    string public terms;\r\n\r\n    modifier allowedDelegate {\r\n        require(delegateMode || delegateWhitelist[_msgSender()], \"BackedToken: Unauthorized delegate\");\r\n        _;\r\n    }\r\n\r\n\r\n    // constructor, call initializer to lock the implementation instance.\r\n    constructor () {\r\n        initialize(\"Backed Token Implementation\", \"BTI\");\r\n    }\r\n\r\n    function initialize(string memory name_, string memory symbol_) public virtual initializer {\r\n        __ERC20_init(name_, symbol_);\r\n        __Ownable_init();\r\n        _buildDomainSeparator();\r\n        _setTerms(\"https://www.backedassets.fi/legal-documentation\"); // Default Terms\r\n    }\r\n\r\n    /**\r\n     * @dev Update allowance with a signed permit. Allowed only if\r\n     *  the sender is whitelisted, or the delegateMode is set to true\r\n     *\r\n     * @param owner       Token owner's address (Authorizer)\r\n     * @param spender     Spender's address\r\n     * @param value       Amount of allowance\r\n     * @param deadline    Expiration time, seconds since the epoch\r\n     * @param v           v part of the signature\r\n     * @param r           r part of the signature\r\n     * @param s           s part of the signature\r\n     */\r\n    function permit(\r\n        address owner,\r\n        address spender,\r\n        uint256 value,\r\n        uint256 deadline,\r\n        uint8 v,\r\n        bytes32 r,\r\n        bytes32 s\r\n    ) public override allowedDelegate {\r\n        super.permit(owner, spender, value, deadline, v, r, s);\r\n    }\r\n\r\n    /**\r\n     * @dev Perform an intended transfer on one account's behalf, from another account,\r\n     *  who actually pays fees for the transaction. Allowed only if the sender\r\n     *  is whitelisted, or the delegateMode is set to true\r\n     *\r\n     * @param owner       The account that provided the signature and from which the tokens will be taken\r\n     * @param to          The account that will receive the tokens\r\n     * @param value       The amount of tokens to transfer\r\n     * @param deadline    Expiration time, seconds since the epoch\r\n     * @param v           v part of the signature\r\n     * @param r           r part of the signature\r\n     * @param s           s part of the signature\r\n     */\r\n    function delegatedTransfer(\r\n        address owner,\r\n        address to,\r\n        uint256 value,\r\n        uint256 deadline,\r\n        uint8 v,\r\n        bytes32 r,\r\n        bytes32 s\r\n    ) public virtual override allowedDelegate {\r\n        super.delegatedTransfer(owner, to, value, deadline, v, r, s);\r\n    }\r\n\r\n    function decimals() public view virtual override(ERC20Upgradeable, IBackedToken) returns (uint8) {\r\n        return super.decimals();\r\n    }\r\n\r\n    /**\r\n     * @dev Function to mint tokens. Allowed only for minter\r\n     *\r\n     * @param account   The address that will receive the minted tokens\r\n     * @param amount    The amount of tokens to mint\r\n     */\r\n    function mint(address account, uint256 amount) virtual external {\r\n        require(_msgSender() == minter, \"BackedToken: Only minter\");\r\n        _mint(account, amount);\r\n    }\r\n\r\n\r\n    /**\r\n     * @dev Function to burn tokens. Allowed only for burner. The burned tokens\r\n     *  must be from the burner (msg.sender), or from the contract itself\r\n     *\r\n     * @param account   The account from which the tokens will be burned\r\n     * @param amount    The amount of tokens to be burned\r\n     */\r\n    function burn(address account, uint256 amount) virtual external {\r\n        require(_msgSender() == burner, \"BackedToken: Only burner\");\r\n        require(account == _msgSender() || account == address(this), \"BackedToken: Cannot burn account\");\r\n        _burn(account, amount);\r\n    }\r\n\r\n\r\n    /**\r\n     * @dev Function to set the pause in order to block or restore all\r\n     *  transfers. Allowed only for pauser\r\n     *\r\n     * Emits a { PauseModeChange } event\r\n     *\r\n     * @param newPauseMode The new pause mode\r\n     */\r\n    function setPause(bool newPauseMode) external {\r\n        require(_msgSender() == pauser, \"BackedToken: Only pauser\");\r\n        isPaused = newPauseMode;\r\n        emit PauseModeChange(newPauseMode);\r\n    }\r\n\r\n    /**\r\n     * @dev Function to change the contract minter. Allowed only for owner\r\n     *\r\n     * Emits a { NewMinter } event\r\n     *\r\n     * @param newMinter The address of the new minter\r\n     */\r\n    function setMinter(address newMinter) external onlyOwner {\r\n        minter = newMinter;\r\n        emit NewMinter(newMinter);\r\n    }\r\n\r\n    /**\r\n     * @dev Function to change the contract burner. Allowed only for owner\r\n     *\r\n     * Emits a { NewBurner } event\r\n     *\r\n     * @param newBurner The address of the new burner\r\n     */\r\n    function setBurner(address newBurner) external onlyOwner {\r\n        burner = newBurner;\r\n        emit NewBurner(newBurner);\r\n    }\r\n\r\n    /**\r\n     * @dev Function to change the contract pauser. Allowed only for owner\r\n     *\r\n     * Emits a { NewPauser } event\r\n     *\r\n     * @param newPauser The address of the new pauser\r\n     */\r\n    function setPauser(address newPauser) external onlyOwner {\r\n        pauser = newPauser;\r\n        emit NewPauser(newPauser);\r\n    }\r\n\r\n    /**\r\n     * @dev Function to change the contract Senctions List. Allowed only for owner\r\n     *\r\n     * Emits a { NewSanctionsList } event\r\n     *\r\n     * @param newSanctionsList The address of the new Senctions List following the Chainalysis standard\r\n     */\r\n    function setSanctionsList(address newSanctionsList) external onlyOwner {\r\n        // Check the proposed sanctions list contract has the right interface:\r\n        require(!SanctionsList(newSanctionsList).isSanctioned(address(this)), \"BackedToken: Wrong List interface\");\r\n\r\n        sanctionsList = SanctionsList(newSanctionsList);\r\n        emit NewSanctionsList(newSanctionsList);\r\n    }\r\n\r\n\r\n    /**\r\n     * @dev EIP-712 Function to change the delegate status of account.\r\n     *  Allowed only for owner\r\n     *\r\n     * Emits a { DelegateWhitelistChange } event\r\n     *\r\n     * @param whitelistAddress  The address for which to change the delegate status\r\n     * @param status            The new delegate status\r\n     */\r\n    function setDelegateWhitelist(address whitelistAddress, bool status) external onlyOwner {\r\n        delegateWhitelist[whitelistAddress] = status;\r\n        emit DelegateWhitelistChange(whitelistAddress, status);\r\n    }\r\n\r\n    /**\r\n     * @dev EIP-712 Function to change the contract delegate mode. Allowed\r\n     *  only for owner\r\n     *\r\n     * Emits a { DelegateModeChange } event\r\n     *\r\n     * @param _delegateMode The new delegate mode for the contract\r\n     */\r\n    function setDelegateMode(bool _delegateMode) external onlyOwner {\r\n        delegateMode = _delegateMode;\r\n\r\n        emit DelegateModeChange(_delegateMode);\r\n    }\r\n\r\n    /**\r\n     * @dev Function to change the contract terms. Allowed only for owner\r\n     *\r\n     * Emits a { NewTerms } event\r\n     *\r\n     * @param newTerms A string with the terms. Usually a web or IPFS link.\r\n     */\r\n    function setTerms(string memory newTerms) external onlyOwner {\r\n        _setTerms(newTerms);\r\n    }\r\n\r\n    // Implement setTerms, tp allow also to use from initializer:\r\n    function _setTerms(string memory newTerms) internal virtual {\r\n        terms = newTerms;\r\n        emit NewTerms(newTerms);\r\n    }\r\n\r\n    // Implement the pause and SanctionsList functionality before transfer:\r\n    function _beforeTokenTransfer(\r\n        address from,\r\n        address to,\r\n        uint256 amount\r\n    ) internal virtual override {\r\n        // Check not paused:\r\n        require(!isPaused, \"BackedToken: token transfer while paused\");\r\n\r\n        // Check Sanctions List, but do not prevent minting burning:\r\n        if (from != address(0) && to != address(0)) {\r\n            require(!sanctionsList.isSanctioned(from), \"BackedToken: sender is sanctioned\");\r\n            require(!sanctionsList.isSanctioned(to), \"BackedToken: receiver is sanctioned\");\r\n        }\r\n\r\n        super._beforeTokenTransfer(from, to, amount);\r\n    }\r\n\r\n    // Implement the SanctionsList functionality for spender:\r\n    function _spendAllowance(\r\n        address owner,\r\n        address spender,\r\n        uint256 amount\r\n    ) internal virtual override {\r\n        require(!sanctionsList.isSanctioned(spender), \"BackedToken: spender is sanctioned\");\r\n\r\n        super._spendAllowance(owner, spender, amount);\r\n    }\r\n    /**\r\n     * @dev This empty reserved space is put in place to allow future versions to add new\r\n     * variables without shifting down storage in the inheritance chain.\r\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\r\n     */\r\n    uint256[49] private __gap;\r\n}\r\n"},{"file_path":"contracts/ERC20PermitDelegateTransfer.sol","source_code":"/**\n * SPDX-License-Identifier: MIT\n *\n * Copyright (c) 2021-2022 Backed Finance AG\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\npragma solidity 0.8.9;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/cryptography/ECDSAUpgradeable.sol\";\n\n/**\n * @dev \n *\n * This contract is a based (copy-paste with changes) on OpenZeppelin's draft-ERC20Permit.sol (token/ERC20/extensions/draft-ERC20Permit.sol).\n * \n * The changes are:\n *  - Adding also delegated transfer functionality, that is similar to permit, but doing the actual transfer and not approval.\n *  - Cutting some of the generalities to make the contacts more straight forward for this case (e.g. removing the counters library). \n *\n*/\n\ncontract ERC20PermitDelegateTransfer is ERC20Upgradeable {\n    mapping(address => uint256) public nonces;\n\n    // Calculating the Permit typehash:\n    bytes32 public constant PERMIT_TYPEHASH =\n        keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n\n    // Calculating the Delegated Transfer typehash:\n    bytes32 public constant DELEGATED_TRANSFER_TYPEHASH =\n        keccak256(\"DELEGATED_TRANSFER(address owner,address to,uint256 value,uint256 nonce,uint256 deadline)\");\n\n    // Immutable variable for Domain Separator:\n    // solhint-disable-next-line var-name-mixedcase\n    bytes32 public DOMAIN_SEPARATOR;\n\n    // A version number:\n    // solhint-disable-next-line var-name-mixedcase\n    string internal constant DOMAIN_SEPARATOR_VERSION = \"1\";\n\n    /**\n     * @dev Permit, approve via a sign message, using erc712.\n     */\n    function permit(\n        address owner,\n        address spender,\n        uint256 value,\n        uint256 deadline,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) public virtual {\n        require(block.timestamp <= deadline, \"ERC20Permit: expired deadline\");\n\n        bytes32 structHash = keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));\n\n        _checkOwner(owner, structHash, v, r, s);\n\n        _approve(owner, spender, value);\n    }\n\n    /**\n     * @dev Delegated Transfer, transfer via a sign message, using erc712.\n     */\n    function delegatedTransfer(\n        address owner,\n        address to,\n        uint256 value,\n        uint256 deadline,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) public virtual {\n        require(block.timestamp <= deadline, \"ERC20Permit: expired deadline\");\n\n        bytes32 structHash = keccak256(abi.encode(DELEGATED_TRANSFER_TYPEHASH, owner, to, value, _useNonce(owner), deadline));\n\n        _checkOwner(owner, structHash, v, r, s);\n\n        _transfer(owner, to, value);\n    }\n\n    /**\n     * @dev \"Consume a nonce\": return the current value and increment.\n     */\n    function _useNonce(address owner) internal virtual returns (uint256 current) {\n        current = nonces[owner];\n        nonces[owner]++;\n    }\n\n    function _checkOwner(address owner, bytes32 structHash, uint8 v, bytes32 r, bytes32 s) internal view {\n        bytes32 hash = ECDSAUpgradeable.toTypedDataHash(DOMAIN_SEPARATOR, structHash);\n\n        address signer = ECDSAUpgradeable.recover(hash, v, r, s);\n        require(signer == owner, \"ERC20Permit: invalid signature\");\n    }\n\n    function _buildDomainSeparator() internal {\n        DOMAIN_SEPARATOR = keccak256(\n            abi.encode(\n                keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"),\n                keccak256(bytes(name())),\n                keccak256(bytes(DOMAIN_SEPARATOR_VERSION)),\n                block.chainid,\n                address(this)\n            )\n        );\n    }\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n    uint256[50] private __gap;\n}\n"},{"file_path":"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n    address private _owner;\n\n    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n    /**\n     * @dev Initializes the contract setting the deployer as the initial owner.\n     */\n    function __Ownable_init() internal onlyInitializing {\n        __Ownable_init_unchained();\n    }\n\n    function __Ownable_init_unchained() internal onlyInitializing {\n        _transferOwnership(_msgSender());\n    }\n\n    /**\n     * @dev Returns the address of the current owner.\n     */\n    function owner() public view virtual returns (address) {\n        return _owner;\n    }\n\n    /**\n     * @dev Throws if called by any account other than the owner.\n     */\n    modifier onlyOwner() {\n        require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n        _;\n    }\n\n    /**\n     * @dev Leaves the contract without owner. It will not be possible to call\n     * `onlyOwner` functions anymore. Can only be called by the current owner.\n     *\n     * NOTE: Renouncing ownership will leave the contract without an owner,\n     * thereby removing any functionality that is only available to the owner.\n     */\n    function renounceOwnership() public virtual onlyOwner {\n        _transferOwnership(address(0));\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Can only be called by the current owner.\n     */\n    function transferOwnership(address newOwner) public virtual onlyOwner {\n        require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n        _transferOwnership(newOwner);\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Internal function without access restriction.\n     */\n    function _transferOwnership(address newOwner) internal virtual {\n        address oldOwner = _owner;\n        _owner = newOwner;\n        emit OwnershipTransferred(oldOwner, newOwner);\n    }\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n    uint256[49] private __gap;\n}\n"},{"file_path":"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To initialize the implementation contract, you can either invoke the\n * initializer manually, or you can include a constructor to automatically mark it as initialized when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() initializer {}\n * ```\n * ====\n */\nabstract contract Initializable {\n    /**\n     * @dev Indicates that the contract has been initialized.\n     */\n    bool private _initialized;\n\n    /**\n     * @dev Indicates that the contract is in the process of being initialized.\n     */\n    bool private _initializing;\n\n    /**\n     * @dev Modifier to protect an initializer function from being invoked twice.\n     */\n    modifier initializer() {\n        // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n        // inheritance patterns, but we only do this in the context of a constructor, because in other contexts the\n        // contract may have been reentered.\n        require(_initializing ? _isConstructor() : !_initialized, \"Initializable: contract is already initialized\");\n\n        bool isTopLevelCall = !_initializing;\n        if (isTopLevelCall) {\n            _initializing = true;\n            _initialized = true;\n        }\n\n        _;\n\n        if (isTopLevelCall) {\n            _initializing = false;\n        }\n    }\n\n    /**\n     * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n     * {initializer} modifier, directly or indirectly.\n     */\n    modifier onlyInitializing() {\n        require(_initializing, \"Initializable: contract is not initializing\");\n        _;\n    }\n\n    function _isConstructor() private view returns (bool) {\n        return !AddressUpgradeable.isContract(address(this));\n    }\n}\n"},{"file_path":"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20Upgradeable.sol\";\nimport \"./extensions/IERC20MetadataUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {\n    mapping(address => uint256) private _balances;\n\n    mapping(address => mapping(address => uint256)) private _allowances;\n\n    uint256 private _totalSupply;\n\n    string private _name;\n    string private _symbol;\n\n    /**\n     * @dev Sets the values for {name} and {symbol}.\n     *\n     * The default value of {decimals} is 18. To select a different value for\n     * {decimals} you should overload it.\n     *\n     * All two of these values are immutable: they can only be set once during\n     * construction.\n     */\n    function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {\n        __ERC20_init_unchained(name_, symbol_);\n    }\n\n    function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n        _name = name_;\n        _symbol = symbol_;\n    }\n\n    /**\n     * @dev Returns the name of the token.\n     */\n    function name() public view virtual override returns (string memory) {\n        return _name;\n    }\n\n    /**\n     * @dev Returns the symbol of the token, usually a shorter version of the\n     * name.\n     */\n    function symbol() public view virtual override returns (string memory) {\n        return _symbol;\n    }\n\n    /**\n     * @dev Returns the number of decimals used to get its user representation.\n     * For example, if `decimals` equals `2`, a balance of `505` tokens should\n     * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n     *\n     * Tokens usually opt for a value of 18, imitating the relationship between\n     * Ether and Wei. This is the value {ERC20} uses, unless this function is\n     * overridden;\n     *\n     * NOTE: This information is only used for _display_ purposes: it in\n     * no way affects any of the arithmetic of the contract, including\n     * {IERC20-balanceOf} and {IERC20-transfer}.\n     */\n    function decimals() public view virtual override returns (uint8) {\n        return 18;\n    }\n\n    /**\n     * @dev See {IERC20-totalSupply}.\n     */\n    function totalSupply() public view virtual override returns (uint256) {\n        return _totalSupply;\n    }\n\n    /**\n     * @dev See {IERC20-balanceOf}.\n     */\n    function balanceOf(address account) public view virtual override returns (uint256) {\n        return _balances[account];\n    }\n\n    /**\n     * @dev See {IERC20-transfer}.\n     *\n     * Requirements:\n     *\n     * - `to` cannot be the zero address.\n     * - the caller must have a balance of at least `amount`.\n     */\n    function transfer(address to, uint256 amount) public virtual override returns (bool) {\n        address owner = _msgSender();\n        _transfer(owner, to, amount);\n        return true;\n    }\n\n    /**\n     * @dev See {IERC20-allowance}.\n     */\n    function allowance(address owner, address spender) public view virtual override returns (uint256) {\n        return _allowances[owner][spender];\n    }\n\n    /**\n     * @dev See {IERC20-approve}.\n     *\n     * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n     * `transferFrom`. This is semantically equivalent to an infinite approval.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     */\n    function approve(address spender, uint256 amount) public virtual override returns (bool) {\n        address owner = _msgSender();\n        _approve(owner, spender, amount);\n        return true;\n    }\n\n    /**\n     * @dev See {IERC20-transferFrom}.\n     *\n     * Emits an {Approval} event indicating the updated allowance. This is not\n     * required by the EIP. See the note at the beginning of {ERC20}.\n     *\n     * NOTE: Does not update the allowance if the current allowance\n     * is the maximum `uint256`.\n     *\n     * Requirements:\n     *\n     * - `from` and `to` cannot be the zero address.\n     * - `from` must have a balance of at least `amount`.\n     * - the caller must have allowance for ``from``'s tokens of at least\n     * `amount`.\n     */\n    function transferFrom(\n        address from,\n        address to,\n        uint256 amount\n    ) public virtual override returns (bool) {\n        address spender = _msgSender();\n        _spendAllowance(from, spender, amount);\n        _transfer(from, to, amount);\n        return true;\n    }\n\n    /**\n     * @dev Atomically increases the allowance granted to `spender` by the caller.\n     *\n     * This is an alternative to {approve} that can be used as a mitigation for\n     * problems described in {IERC20-approve}.\n     *\n     * Emits an {Approval} event indicating the updated allowance.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     */\n    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n        address owner = _msgSender();\n        _approve(owner, spender, _allowances[owner][spender] + addedValue);\n        return true;\n    }\n\n    /**\n     * @dev Atomically decreases the allowance granted to `spender` by the caller.\n     *\n     * This is an alternative to {approve} that can be used as a mitigation for\n     * problems described in {IERC20-approve}.\n     *\n     * Emits an {Approval} event indicating the updated allowance.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     * - `spender` must have allowance for the caller of at least\n     * `subtractedValue`.\n     */\n    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n        address owner = _msgSender();\n        uint256 currentAllowance = _allowances[owner][spender];\n        require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n        unchecked {\n            _approve(owner, spender, currentAllowance - subtractedValue);\n        }\n\n        return true;\n    }\n\n    /**\n     * @dev Moves `amount` of tokens from `sender` to `recipient`.\n     *\n     * This internal function is equivalent to {transfer}, and can be used to\n     * e.g. implement automatic token fees, slashing mechanisms, etc.\n     *\n     * Emits a {Transfer} event.\n     *\n     * Requirements:\n     *\n     * - `from` cannot be the zero address.\n     * - `to` cannot be the zero address.\n     * - `from` must have a balance of at least `amount`.\n     */\n    function _transfer(\n        address from,\n        address to,\n        uint256 amount\n    ) internal virtual {\n        require(from != address(0), \"ERC20: transfer from the zero address\");\n        require(to != address(0), \"ERC20: transfer to the zero address\");\n\n        _beforeTokenTransfer(from, to, amount);\n\n        uint256 fromBalance = _balances[from];\n        require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n        unchecked {\n            _balances[from] = fromBalance - amount;\n        }\n        _balances[to] += amount;\n\n        emit Transfer(from, to, amount);\n\n        _afterTokenTransfer(from, to, amount);\n    }\n\n    /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n     * the total supply.\n     *\n     * Emits a {Transfer} event with `from` set to the zero address.\n     *\n     * Requirements:\n     *\n     * - `account` cannot be the zero address.\n     */\n    function _mint(address account, uint256 amount) internal virtual {\n        require(account != address(0), \"ERC20: mint to the zero address\");\n\n        _beforeTokenTransfer(address(0), account, amount);\n\n        _totalSupply += amount;\n        _balances[account] += amount;\n        emit Transfer(address(0), account, amount);\n\n        _afterTokenTransfer(address(0), account, amount);\n    }\n\n    /**\n     * @dev Destroys `amount` tokens from `account`, reducing the\n     * total supply.\n     *\n     * Emits a {Transfer} event with `to` set to the zero address.\n     *\n     * Requirements:\n     *\n     * - `account` cannot be the zero address.\n     * - `account` must have at least `amount` tokens.\n     */\n    function _burn(address account, uint256 amount) internal virtual {\n        require(account != address(0), \"ERC20: burn from the zero address\");\n\n        _beforeTokenTransfer(account, address(0), amount);\n\n        uint256 accountBalance = _balances[account];\n        require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n        unchecked {\n            _balances[account] = accountBalance - amount;\n        }\n        _totalSupply -= amount;\n\n        emit Transfer(account, address(0), amount);\n\n        _afterTokenTransfer(account, address(0), amount);\n    }\n\n    /**\n     * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n     *\n     * This internal function is equivalent to `approve`, and can be used to\n     * e.g. set automatic allowances for certain subsystems, etc.\n     *\n     * Emits an {Approval} event.\n     *\n     * Requirements:\n     *\n     * - `owner` cannot be the zero address.\n     * - `spender` cannot be the zero address.\n     */\n    function _approve(\n        address owner,\n        address spender,\n        uint256 amount\n    ) internal virtual {\n        require(owner != address(0), \"ERC20: approve from the zero address\");\n        require(spender != address(0), \"ERC20: approve to the zero address\");\n\n        _allowances[owner][spender] = amount;\n        emit Approval(owner, spender, amount);\n    }\n\n    /**\n     * @dev Spend `amount` form the allowance of `owner` toward `spender`.\n     *\n     * Does not update the allowance amount in case of infinite allowance.\n     * Revert if not enough allowance is available.\n     *\n     * Might emit an {Approval} event.\n     */\n    function _spendAllowance(\n        address owner,\n        address spender,\n        uint256 amount\n    ) internal virtual {\n        uint256 currentAllowance = allowance(owner, spender);\n        if (currentAllowance != type(uint256).max) {\n            require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n            unchecked {\n                _approve(owner, spender, currentAllowance - amount);\n            }\n        }\n    }\n\n    /**\n     * @dev Hook that is called before any transfer of tokens. This includes\n     * minting and burning.\n     *\n     * Calling conditions:\n     *\n     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n     * will be transferred to `to`.\n     * - when `from` is zero, `amount` tokens will be minted for `to`.\n     * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n     * - `from` and `to` are never both zero.\n     *\n     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n     */\n    function _beforeTokenTransfer(\n        address from,\n        address to,\n        uint256 amount\n    ) internal virtual {}\n\n    /**\n     * @dev Hook that is called after any transfer of tokens. This includes\n     * minting and burning.\n     *\n     * Calling conditions:\n     *\n     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n     * has been transferred to `to`.\n     * - when `from` is zero, `amount` tokens have been minted for `to`.\n     * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n     * - `from` and `to` are never both zero.\n     *\n     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n     */\n    function _afterTokenTransfer(\n        address from,\n        address to,\n        uint256 amount\n    ) internal virtual {}\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n    uint256[45] private __gap;\n}\n"},{"file_path":"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20Upgradeable {\n    /**\n     * @dev Returns the amount of tokens in existence.\n     */\n    function totalSupply() external view returns (uint256);\n\n    /**\n     * @dev Returns the amount of tokens owned by `account`.\n     */\n    function balanceOf(address account) external view returns (uint256);\n\n    /**\n     * @dev Moves `amount` tokens from the caller's account to `to`.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transfer(address to, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Returns the remaining number of tokens that `spender` will be\n     * allowed to spend on behalf of `owner` through {transferFrom}. This is\n     * zero by default.\n     *\n     * This value changes when {approve} or {transferFrom} are called.\n     */\n    function allowance(address owner, address spender) external view returns (uint256);\n\n    /**\n     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * IMPORTANT: Beware that changing an allowance with this method brings the risk\n     * that someone may use both the old and the new allowance by unfortunate\n     * transaction ordering. One possible solution to mitigate this race\n     * condition is to first reduce the spender's allowance to 0 and set the\n     * desired value afterwards:\n     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n     *\n     * Emits an {Approval} event.\n     */\n    function approve(address spender, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Moves `amount` tokens from `from` to `to` using the\n     * allowance mechanism. `amount` is then deducted from the caller's\n     * allowance.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transferFrom(\n        address from,\n        address to,\n        uint256 amount\n    ) external returns (bool);\n\n    /**\n     * @dev Emitted when `value` tokens are moved from one account (`from`) to\n     * another (`to`).\n     *\n     * Note that `value` may be zero.\n     */\n    event Transfer(address indexed from, address indexed to, uint256 value);\n\n    /**\n     * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n     * a call to {approve}. `value` is the new allowance.\n     */\n    event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n"},{"file_path":"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20Upgradeable.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20MetadataUpgradeable is IERC20Upgradeable {\n    /**\n     * @dev Returns the name of the token.\n     */\n    function name() external view returns (string memory);\n\n    /**\n     * @dev Returns the symbol of the token.\n     */\n    function symbol() external view returns (string memory);\n\n    /**\n     * @dev Returns the decimals places of the token.\n     */\n    function decimals() external view returns (uint8);\n}\n"},{"file_path":"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n    /**\n     * @dev Returns true if `account` is a contract.\n     *\n     * [IMPORTANT]\n     * ====\n     * It is unsafe to assume that an address for which this function returns\n     * false is an externally-owned account (EOA) and not a contract.\n     *\n     * Among others, `isContract` will return false for the following\n     * types of addresses:\n     *\n     *  - an externally-owned account\n     *  - a contract in construction\n     *  - an address where a contract will be created\n     *  - an address where a contract lived, but was destroyed\n     * ====\n     *\n     * [IMPORTANT]\n     * ====\n     * You shouldn't rely on `isContract` to protect against flash loan attacks!\n     *\n     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n     * constructor.\n     * ====\n     */\n    function isContract(address account) internal view returns (bool) {\n        // This method relies on extcodesize/address.code.length, which returns 0\n        // for contracts in construction, since the code is only stored at the end\n        // of the constructor execution.\n\n        return account.code.length > 0;\n    }\n\n    /**\n     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n     * `recipient`, forwarding all available gas and reverting on errors.\n     *\n     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n     * of certain opcodes, possibly making contracts go over the 2300 gas limit\n     * imposed by `transfer`, making them unable to receive funds via\n     * `transfer`. {sendValue} removes this limitation.\n     *\n     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n     *\n     * IMPORTANT: because control is transferred to `recipient`, care must be\n     * taken to not create reentrancy vulnerabilities. Consider using\n     * {ReentrancyGuard} or the\n     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n     */\n    function sendValue(address payable recipient, uint256 amount) internal {\n        require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n        (bool success, ) = recipient.call{value: amount}(\"\");\n        require(success, \"Address: unable to send value, recipient may have reverted\");\n    }\n\n    /**\n     * @dev Performs a Solidity function call using a low level `call`. A\n     * plain `call` is an unsafe replacement for a function call: use this\n     * function instead.\n     *\n     * If `target` reverts with a revert reason, it is bubbled up by this\n     * function (like regular Solidity function calls).\n     *\n     * Returns the raw returned data. To convert to the expected return value,\n     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n     *\n     * Requirements:\n     *\n     * - `target` must be a contract.\n     * - calling `target` with `data` must not revert.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n        return functionCall(target, data, \"Address: low-level call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n     * `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, 0, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but also transferring `value` wei to `target`.\n     *\n     * Requirements:\n     *\n     * - the calling contract must have an ETH balance of at least `value`.\n     * - the called Solidity function must be `payable`.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(\n        address target,\n        bytes memory data,\n        uint256 value\n    ) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n     * with `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(\n        address target,\n        bytes memory data,\n        uint256 value,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        require(address(this).balance >= value, \"Address: insufficient balance for call\");\n        require(isContract(target), \"Address: call to non-contract\");\n\n        (bool success, bytes memory returndata) = target.call{value: value}(data);\n        return verifyCallResult(success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a static call.\n     *\n     * _Available since v3.3._\n     */\n    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n        return functionStaticCall(target, data, \"Address: low-level static call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n     * but performing a static call.\n     *\n     * _Available since v3.3._\n     */\n    function functionStaticCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal view returns (bytes memory) {\n        require(isContract(target), \"Address: static call to non-contract\");\n\n        (bool success, bytes memory returndata) = target.staticcall(data);\n        return verifyCallResult(success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n     * revert reason using the provided one.\n     *\n     * _Available since v4.3._\n     */\n    function verifyCallResult(\n        bool success,\n        bytes memory returndata,\n        string memory errorMessage\n    ) internal pure returns (bytes memory) {\n        if (success) {\n            return returndata;\n        } else {\n            // Look for revert reason and bubble it up if present\n            if (returndata.length > 0) {\n                // The easiest way to bubble the revert reason is using memory via assembly\n\n                assembly {\n                    let returndata_size := mload(returndata)\n                    revert(add(32, returndata), returndata_size)\n                }\n            } else {\n                revert(errorMessage);\n            }\n        }\n    }\n}\n"},{"file_path":"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n    function __Context_init() internal onlyInitializing {\n    }\n\n    function __Context_init_unchained() internal onlyInitializing {\n    }\n    function _msgSender() internal view virtual returns (address) {\n        return msg.sender;\n    }\n\n    function _msgData() internal view virtual returns (bytes calldata) {\n        return msg.data;\n    }\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n    uint256[50] private __gap;\n}\n"},{"file_path":"contracts/SanctionsList.sol","source_code":"pragma solidity 0.8.9;\n\n/**\n * SPDX-License-Identifier: MIT\n *\n * Copyright (c) 2021-2022 Backed Finance AG\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\ninterface SanctionsList {\n    function isSanctioned(address addr) external view returns (bool);\n}"},{"file_path":"contracts/interfaces/IBackedAutoFeeToken.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nimport \"../SanctionsList.sol\";\nimport \"./IBackedToken.sol\";\n\n/**\n * @title IBackedAutoFeeToken\n * @dev Interface for the BackedAutoFeeToken, a rebasing ERC20 token with automatic fee accrual\n *\n * This token implements a share-based rebasing mechanism where:\n * - Users hold shares that represent their portion of the total supply\n * - A multiplier converts shares to underlying token amounts\n * - Fees are automatically applied by decreasing the multiplier over time\n * - The multiplier can be updated by an authorized multiplierUpdater address\n */\ninterface IBackedAutoFeeToken is IBackedToken {\n    /**\n     * @dev Struct representing multiplier update\n     * @param previousMultiplier The multiplier value before this update\n     * @param newMultiplier The multiplier value after this update\n     * @param activationTime The Unix timestamp when this update was/will be activated\n     */\n    struct MultiplierUpdate {\n        uint256 previousMultiplier;\n        uint256 newMultiplier;\n        uint256 activationTime;\n    }\n\n    // Events\n\n    /**\n     * @dev Emitted when the multiplier updater address is changed\n     * @param newMultiplierUpdater The address of the new multiplier updater\n     */\n    event NewMultiplierUpdater(address indexed newMultiplierUpdater);\n\n    /**\n     * @dev Emitted when shares are transferred between addresses\n     * @param from The address shares are transferred from\n     * @param to The address shares are transferred to\n     * @param value The amount of shares transferred\n     */\n    event TransferShares(address indexed from, address indexed to, uint256 value);\n\n    /**\n     * @dev Emitted when the multiplier value is updated and activated\n     * @param value The new multiplier value (in 1e18 precision)\n     */\n    event MultiplierUpdated(uint256 value);\n\n    /**\n     * @dev Emitted when a multiplier is scheduled for future activation\n     * @param newMultiplier The new multiplier value that will be activated (in 1e18 precision)\n     * @param activationTime The Unix timestamp when the multiplier will become active\n     */\n    event MultiplierScheduled(uint256 newMultiplier, uint256 activationTime);\n\n    /**\n     * @dev Emitted when a previously scheduled multiplier update is replaced\n     * before its activationTime is reached. The overridden entry is removed\n     * from `multiplierUpdates` in place and replaced by the new one.\n     *\n     * Off-chain consumers reconstructing state from events should drop any\n     * earlier `MultiplierScheduled(overriddenMultiplier, overriddenActivationTime)`\n     * upon seeing this event.\n     *\n     * @param overriddenMultiplier The newMultiplier of the pending entry that\n     *        was discarded (the one previously announced via MultiplierScheduled)\n     * @param overriddenActivationTime The activationTime of the discarded entry\n     * @param newMultiplier The newMultiplier that replaces it (already announced\n     *        in this same transaction via MultiplierScheduled or MultiplierUpdated)\n     * @param newActivationTime The activationTime stored for the replacement\n     */\n    event MultiplierScheduleOverridden(\n        uint256 overriddenMultiplier,\n        uint256 overriddenActivationTime,\n        uint256 newMultiplier,\n        uint256 newActivationTime\n    );\n\n    // View functions - EIP-712 and Roles\n\n    /**\n     * @dev Returns the address authorized to update the multiplier\n     * @return The multiplier updater address\n     */\n    function multiplierUpdater() external view returns (address);\n\n    // View functions - Fee Configuration\n\n    /**\n     * @dev Returns the timestamp when the fee was last applied\n     * @return The Unix timestamp of the last fee application\n     */\n    function lastTimeFeeApplied() external view returns (uint256);\n\n    /**\n     * @dev Returns the fee rate applied per period\n     * @return The fee per period in 1e18 precision (e.g., 1e15 = 0.1% fee)\n     */\n    function feePerPeriod() external view returns (uint256);\n\n    /**\n     * @dev Returns the length of each fee accrual period in seconds\n     * @return The period length in seconds (e.g., 86400 for daily fees)\n     */\n    function periodLength() external view returns (uint256);\n\n    // View functions - Multiplier State\n\n    /**\n     * @dev Returns the last activated multiplier value\n     * @return The last multiplier value in 1e18 precision\n     */\n    function lastMultiplier() external view returns (uint256);\n\n    /**\n     * @dev Returns the current active multiplier, considering pending activations\n     * @return The currently active multiplier value in 1e18 precision\n     */\n    function multiplier() external view returns (uint256);\n\n    /**\n     * @dev Returns the nonce of the last activated multiplier\n     * @return The last multiplier nonce\n     */\n    function lastMultiplierNonce() external view returns (uint256);\n\n    /**\n     * @dev Returns the nonce of the pending/new multiplier\n     * @return The new multiplier nonce\n     */\n    function newMultiplierNonce() external view returns (uint256);\n\n    /**\n     * @dev Returns the value of the pending/new multiplier\n     * @return The new multiplier value in 1e18 precision\n     */\n    function newMultiplier() external view returns (uint256);\n\n    /**\n     * @dev Returns the timestamp when the new multiplier becomes active\n     * @return The Unix timestamp of activation (0 if no pending activation)\n     */\n    function newMultiplierActivationTime() external view returns (uint256);\n\n    /**\n     * @dev Returns the current multiplier nonce, considering pending activations\n     * @return The current active multiplier nonce\n     */\n    function multiplierNonce() external view returns (uint256);\n\n    /**\n     * @dev Calculates and returns the current multiplier with fees applied\n     * @return currentMultiplier The multiplier value with all accrued fees applied\n     * @return periodsPassed The number of fee periods that have passed\n     * @return currentMultiplierNonce The nonce including periods passed\n     */\n    function getCurrentMultiplier() external view returns (uint256 currentMultiplier, uint256 periodsPassed, uint256 currentMultiplierNonce);\n\n    // View functions - Token Shares\n\n    /**\n     * @dev Returns the share balance of an account\n     * @param account The address to query\n     * @return The number of shares owned by the account\n     */\n    function sharesOf(address account) external view returns (uint256);\n\n    /**\n     * @dev Converts an underlying token amount to shares\n     * @param _underlyingAmount The amount of tokens to convert\n     * @return The equivalent amount of shares\n     */\n    function getSharesByUnderlyingAmount(uint256 _underlyingAmount) external view returns (uint256);\n\n    /**\n     * @dev Converts shares to underlying token amount\n     * @param _sharesAmount The amount of shares to convert\n     * @return The equivalent amount of tokens\n     */\n    function getUnderlyingAmountByShares(uint256 _sharesAmount) external view returns (uint256);\n\n    /**\n     * @dev Returns the length of the multiplierUpdates array.\n     *\n     * The array records *explicit* multiplier updates only (those submitted\n     * via `updateMultiplierValue` / `updateMultiplierWithNonce`). Automatic\n     * per-period fee decay is NOT appended. See `multiplierUpdates` for the\n     * full semantics.\n     *\n     * @return The number of explicit multiplier updates stored\n     *         (including the genesis sentinel at index 0).\n     */\n    function multiplierUpdatesLength() external view returns (uint256);\n\n    /**\n     * @dev Returns a specific explicit multiplier update by index.\n     *\n     * This array is an append-only log of *explicit* multiplier updates only;\n     * automatic per-period fee decay is applied lazily to `lastMultiplier`\n     * without appending here. As a result `previousMultiplier` at index `i`\n     * is the fee-decayed value at the time of the i-th explicit update and\n     * is typically less than `newMultiplier` at index `i-1` — the gap is the\n     * accrual that happened in between.\n     *\n     * Index 0 is a genesis sentinel `{1e18, 1e18, 0}`. A future-dated entry\n     * that is overridden before activation is popped from this array; the\n     * `MultiplierScheduled` event for the popped entry remains on chain.\n     *\n     * @param index The index in the multiplierUpdates array\n     * @return previousMultiplier The (possibly fee-decayed) multiplier value\n     *         immediately before this explicit update was applied\n     * @return newMultiplier The multiplier value after this update\n     * @return activationTime The Unix timestamp when this update was/will be\n     *         activated; equals `block.timestamp` at recording time for\n     *         immediate updates, or the requested future timestamp for\n     *         scheduled ones\n     */\n    function multiplierUpdates(uint256 index) external view returns (uint256 previousMultiplier, uint256 newMultiplier, uint256 activationTime);\n\n    // State-changing functions - Share Transfers\n\n    /**\n     * @dev Executes a delegated share transfer using EIP-712 signature\n     * @param owner The address that owns the shares\n     * @param to The address to transfer shares to\n     * @param value The amount of shares to transfer\n     * @param deadline The deadline timestamp for the signature\n     * @param v The recovery byte of the signature\n     * @param r Half of the ECDSA signature pair\n     * @param s Half of the ECDSA signature pair\n     */\n    function delegatedTransferShares(address owner, address to, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external;\n\n    /**\n     * @dev Transfers shares from the caller to another address\n     * @param to The address to transfer shares to\n     * @param sharesAmount The amount of shares to transfer\n     * @return success True if the transfer succeeded\n     */\n    function transferShares(address to, uint256 sharesAmount) external returns (bool);\n\n    /**\n     * @dev Transfers shares from one address to another using allowance\n     * @param from The address to transfer shares from\n     * @param to The address to transfer shares to\n     * @param sharesAmount The amount of shares to transfer\n     * @return success True if the transfer succeeded\n     */\n    function transferSharesFrom(address from, address to, uint256 sharesAmount) external returns (bool);\n\n    // State-changing functions - Fee Configuration (Owner only)\n\n    /**\n     * @dev Updates the fee rate per period\n     * Can only be called by the owner\n     * Cannot be called when a multiplier activation is pending\n     * @param newFeePerPeriod The new fee rate in 1e18 precision\n     */\n    function updateFeePerPeriod(uint256 newFeePerPeriod) external;\n\n    /**\n     * @dev Updates the multiplier updater address\n     * Can only be called by the owner\n     * @param newMultiplierUpdater The address of the new multiplier updater\n     */\n    function setMultiplierUpdater(address newMultiplierUpdater) external;\n\n    /**\n     * @dev Updates the timestamp of last fee application\n     * Can only be called by the owner\n     * Cannot be called when a multiplier activation is pending\n     * @param newLastTimeFeeApplied The new timestamp (must be non-zero)\n     */\n    function setLastTimeFeeApplied(uint256 newLastTimeFeeApplied) external;\n\n    /**\n     * @dev Updates the length of each fee period\n     * Can only be called by the owner\n     * Cannot be called when a multiplier activation is pending\n     * @param newPeriodLength The new period length in seconds\n     */\n    function setPeriodLength(uint256 newPeriodLength) external;\n\n    // State-changing functions - Multiplier Updates (Multiplier Updater only)\n\n    /**\n     * @dev Updates the multiplier value with automatic nonce increment\n     * Can only be called by the multiplier updater\n     * Validates that the oldMultiplier matches the current value\n     * @param pendingNewMultiplier The new multiplier value in 1e18 precision\n     * @param oldMultiplier The expected current multiplier for validation\n     * @param pendingNewMultiplierActivationTime When to activate (0 for immediate, future timestamp for delayed)\n     */\n    function updateMultiplierValue(uint256 pendingNewMultiplier, uint256 oldMultiplier, uint256 pendingNewMultiplierActivationTime) external;\n\n    /**\n     * @dev Updates the multiplier value with explicit nonce\n     * Can only be called by the multiplier updater\n     * Validates that the oldMultiplier matches and nonce is newer\n     * @param newMultiplier The new multiplier value in 1e18 precision\n     * @param oldMultiplier The expected current multiplier for validation\n     * @param newMultiplierNonce The explicit nonce for this update\n     * @param pendingNewMultiplierActivationTime When to activate (0 for immediate, future timestamp for delayed)\n     */\n    function updateMultiplierWithNonce(uint256 newMultiplier, uint256 oldMultiplier, uint256 newMultiplierNonce, uint256 pendingNewMultiplierActivationTime) external;\n}"},{"file_path":"contracts/interfaces/IBackedToken.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nimport \"../SanctionsList.sol\";\n\n/**\n * @title IBackedToken\n * @dev Interface for BackedTokenImplementation, an ERC20 token with EIP-712\n *      permit and delegated-transfer support, role-based mint/burn/pause\n *      controls, a Chainalysis-compatible sanctions list, and a settable\n *      terms-of-service link.\n *\n * The contract exposes four roles:\n *  - minter: can mint new tokens.\n *  - burner: can burn its own tokens or tokens held by the contract itself.\n *  - pauser: can pause or unpause all transfers.\n *  - owner: can configure the three roles above, the sanctions list, the\n *           delegate-mode flags, and the terms string.\n */\ninterface IBackedToken {\n    /**\n     * @dev Returns the decimals places of the token.\n     */\n    function decimals() external view returns (uint8);\n\n    // View functions - Roles\n\n    /**\n     * @dev Returns the address authorized to mint tokens.\n     */\n    function minter() external view returns (address);\n\n    /**\n     * @dev Returns the address authorized to burn tokens.\n     */\n    function burner() external view returns (address);\n\n    /**\n     * @dev Returns the address authorized to pause/unpause transfers.\n     */\n    function pauser() external view returns (address);\n\n    // View functions - Delegate Mode\n\n    /**\n     * @dev Returns whether anyone is allowed to relay `permit` and\n     *      `delegatedTransfer` calls. When false, only addresses present in\n     *      `delegateWhitelist` are allowed.\n     */\n    function delegateMode() external view returns (bool);\n\n    /**\n     * @dev Returns whether `account` is whitelisted to relay `permit` and\n     *      `delegatedTransfer` calls.\n     * @param account The address to query.\n     */\n    function delegateWhitelist(address account) external view returns (bool);\n\n    // View functions - Pause\n\n    /**\n     * @dev Returns whether all token transfers are currently paused.\n     */\n    function isPaused() external view returns (bool);\n\n    // View functions - Sanctions List and Terms\n\n    /**\n     * @dev Returns the sanctions list contract used to gate transfers and\n     *      allowance spends. Follows the Chainalysis interface.\n     */\n    function sanctionsList() external view returns (SanctionsList);\n\n    /**\n     * @dev Returns the current terms-of-service string (typically a web or\n     *      IPFS link).\n     */\n    function terms() external view returns (string memory);\n\n    // State-changing functions - Initialization\n\n    /**\n     * @dev Initializes the token. Can only be called once per proxy.\n     * @param name_   The ERC20 token name.\n     * @param symbol_ The ERC20 token symbol.\n     */\n    function initialize(string memory name_, string memory symbol_) external;\n\n    // State-changing functions - Mint and Burn\n\n    /**\n     * @dev Mint new tokens. Callable only by `minter`.\n     * @param account Recipient of the minted tokens.\n     * @param amount  Amount to mint.\n     */\n    function mint(address account, uint256 amount) external;\n\n    /**\n     * @dev Burn tokens. Callable only by `burner`. The burned tokens must\n     *      come from the burner itself or from this contract.\n     * @param account Account from which the tokens will be burned.\n     * @param amount  Amount to burn.\n     */\n    function burn(address account, uint256 amount) external;\n\n    // State-changing functions - Pause\n\n    /**\n     * @dev Pause or unpause all token transfers. Callable only by `pauser`.\n     * @param newPauseMode True to pause, false to resume.\n     */\n    function setPause(bool newPauseMode) external;\n\n    // State-changing functions - Owner Configuration\n\n    /**\n     * @dev Set the address authorized to mint tokens. Owner only.\n     * @param newMinter The new minter address.\n     */\n    function setMinter(address newMinter) external;\n\n    /**\n     * @dev Set the address authorized to burn tokens. Owner only.\n     * @param newBurner The new burner address.\n     */\n    function setBurner(address newBurner) external;\n\n    /**\n     * @dev Set the address authorized to pause transfers. Owner only.\n     * @param newPauser The new pauser address.\n     */\n    function setPauser(address newPauser) external;\n\n    /**\n     * @dev Point the contract at a new sanctions-list contract. Owner only.\n     *      The new contract must implement the Chainalysis interface; the\n     *      call probes `isSanctioned(address(this))` to verify.\n     * @param newSanctionsList The new sanctions list address.\n     */\n    function setSanctionsList(address newSanctionsList) external;\n\n    /**\n     * @dev Toggle the delegate-relay whitelist status of an address. Owner only.\n     * @param whitelistAddress The address whose status is changing.\n     * @param status           True to whitelist, false to remove.\n     */\n    function setDelegateWhitelist(address whitelistAddress, bool status) external;\n\n    /**\n     * @dev Toggle global delegate mode. When true, anyone may relay `permit`\n     *      and `delegatedTransfer` calls. Owner only.\n     * @param _delegateMode The new delegate-mode flag.\n     */\n    function setDelegateMode(bool _delegateMode) external;\n\n    /**\n     * @dev Set the terms-of-service string. Owner only.\n     * @param newTerms The new terms (typically a web or IPFS link).\n     */\n    function setTerms(string memory newTerms) external;\n\n    // Events\n\n    event NewMinter(address indexed newMinter);\n    event NewBurner(address indexed newBurner);\n    event NewPauser(address indexed newPauser);\n    event NewSanctionsList(address indexed newSanctionsList);\n    event DelegateWhitelistChange(address indexed whitelistAddress, bool status);\n    event DelegateModeChange(bool delegateMode);\n    event PauseModeChange(bool pauseMode);\n    event NewTerms(string newTerms);\n}\n"}],"certified":false,"conflicting_implementations":null,"abi":[{"inputs":[],"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":"bool","name":"delegateMode","type":"bool"}],"name":"DelegateModeChange","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"whitelistAddress","type":"address"},{"indexed":false,"internalType":"bool","name":"status","type":"bool"}],"name":"DelegateWhitelistChange","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"overriddenMultiplier","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"overriddenActivationTime","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newMultiplier","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newActivationTime","type":"uint256"}],"name":"MultiplierScheduleOverridden","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newMultiplier","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"activationTime","type":"uint256"}],"name":"MultiplierScheduled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"MultiplierUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newBurner","type":"address"}],"name":"NewBurner","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newMinter","type":"address"}],"name":"NewMinter","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newMultiplierUpdater","type":"address"}],"name":"NewMultiplierUpdater","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newPauser","type":"address"}],"name":"NewPauser","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newSanctionsList","type":"address"}],"name":"NewSanctionsList","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"newTerms","type":"string"}],"name":"NewTerms","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":"bool","name":"pauseMode","type":"bool"}],"name":"PauseModeChange","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"TransferShares","type":"event"},{"inputs":[],"name":"DELEGATED_TRANSFER_SHARES_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DELEGATED_TRANSFER_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PERMIT_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VERSION","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","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"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"burner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","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":"delegateMode","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"delegateWhitelist","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"delegatedTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"delegatedTransferShares","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"feePerPeriod","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCurrentMultiplier","outputs":[{"internalType":"uint256","name":"currentMultiplier","type":"uint256"},{"internalType":"uint256","name":"periodsPassed","type":"uint256"},{"internalType":"uint256","name":"currentMultiplierNonce","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_underlyingAmount","type":"uint256"}],"name":"getSharesByUnderlyingAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_sharesAmount","type":"uint256"}],"name":"getUnderlyingAmountByShares","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":[{"internalType":"string","name":"name_","type":"string"},{"internalType":"string","name":"symbol_","type":"string"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"name_","type":"string"},{"internalType":"string","name":"symbol_","type":"string"},{"internalType":"uint256","name":"_periodLength","type":"uint256"},{"internalType":"uint256","name":"_lastTimeFeeApplied","type":"uint256"},{"internalType":"uint256","name":"_feePerPeriod","type":"uint256"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_periodLength","type":"uint256"},{"internalType":"uint256","name":"_lastTimeFeeApplied","type":"uint256"},{"internalType":"uint256","name":"_feePerPeriod","type":"uint256"}],"name":"initialize_v2","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"initialize_v3","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"previousMultiplier","type":"uint256"},{"internalType":"uint256","name":"newMultiplier","type":"uint256"},{"internalType":"uint256","name":"activationTime","type":"uint256"}],"internalType":"struct IBackedAutoFeeToken.MultiplierUpdate[]","name":"_pastMultipliersUpdates","type":"tuple[]"}],"name":"initialize_v4","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"isPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastMultiplier","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastMultiplierNonce","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastTimeFeeApplied","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"minter","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"multiplier","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"multiplierNonce","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"multiplierUpdater","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"multiplierUpdates","outputs":[{"internalType":"uint256","name":"previousMultiplier","type":"uint256"},{"internalType":"uint256","name":"newMultiplier","type":"uint256"},{"internalType":"uint256","name":"activationTime","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"multiplierUpdatesLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"newMultiplier","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"newMultiplierActivationTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"newMultiplierNonce","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pauser","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"periodLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"sanctionsList","outputs":[{"internalType":"contract SanctionsList","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newBurner","type":"address"}],"name":"setBurner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_delegateMode","type":"bool"}],"name":"setDelegateMode","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"whitelistAddress","type":"address"},{"internalType":"bool","name":"status","type":"bool"}],"name":"setDelegateWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newLastTimeFeeApplied","type":"uint256"}],"name":"setLastTimeFeeApplied","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newMinter","type":"address"}],"name":"setMinter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newMultiplierUpdater","type":"address"}],"name":"setMultiplierUpdater","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"newPauseMode","type":"bool"}],"name":"setPause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newPauser","type":"address"}],"name":"setPauser","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newPeriodLength","type":"uint256"}],"name":"setPeriodLength","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newSanctionsList","type":"address"}],"name":"setSanctionsList","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"newTerms","type":"string"}],"name":"setTerms","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"sharesOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"terms","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":"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":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"sharesAmount","type":"uint256"}],"name":"transferShares","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":"sharesAmount","type":"uint256"}],"name":"transferSharesFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newFeePerPeriod","type":"uint256"}],"name":"updateFeePerPeriod","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"pendingNewMultiplier","type":"uint256"},{"internalType":"uint256","name":"oldMultiplier","type":"uint256"},{"internalType":"uint256","name":"pendingNewMultiplierActivationTime","type":"uint256"}],"name":"updateMultiplierValue","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newMultiplier","type":"uint256"},{"internalType":"uint256","name":"oldMultiplier","type":"uint256"},{"internalType":"uint256","name":"newMultiplierNonce","type":"uint256"},{"internalType":"uint256","name":"pendingNewMultiplierActivationTime","type":"uint256"}],"name":"updateMultiplierWithNonce","outputs":[],"stateMutability":"nonpayable","type":"function"}],"is_changed_bytecode":false,"is_partially_verified":false,"constructor_args":null}