creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "src/dollar/facets/ManagerFacet.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.19;\n\nimport {Modifiers} from \"../libraries/LibAppStorage.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\nimport \"../../dollar/interfaces/IUbiquityDollarToken.sol\";\nimport \"../../dollar/interfaces/ICurveFactory.sol\";\nimport \"../../dollar/interfaces/ICurveStableSwapMetaNG.sol\";\nimport \"../libraries/LibAccessControl.sol\";\n\n/**\n * @notice Facet for setting protocol parameters\n */\ncontract ManagerFacet is Modifiers {\n    /**\n     * @notice Sets Credit token address\n     * @param _creditTokenAddress Credit token address\n     */\n    function setCreditTokenAddress(\n        address _creditTokenAddress\n    ) external onlyAdmin {\n        store.creditTokenAddress = _creditTokenAddress;\n    }\n\n    /**\n     * @notice Sets Dollar token address\n     * @param _dollarTokenAddress Dollar token address\n     */\n    function setDollarTokenAddress(\n        address _dollarTokenAddress\n    ) external onlyAdmin {\n        store.dollarTokenAddress = _dollarTokenAddress;\n    }\n\n    /**\n     * @notice Sets UbiquiStick address\n     * @param _ubiquistickAddress UbiquiStick address\n     */\n    function setUbiquistickAddress(\n        address _ubiquistickAddress\n    ) external onlyAdmin {\n        store.ubiquiStickAddress = _ubiquistickAddress;\n    }\n\n    /**\n     * @notice Sets Credit NFT address\n     * @param _creditNftAddress Credit NFT address\n     */\n    function setCreditNftAddress(address _creditNftAddress) external onlyAdmin {\n        store.creditNftAddress = _creditNftAddress;\n    }\n\n    /**\n     * @notice Sets Governance token address\n     * @param _governanceTokenAddress Governance token address\n     */\n    function setGovernanceTokenAddress(\n        address _governanceTokenAddress\n    ) external onlyAdmin {\n        store.governanceTokenAddress = _governanceTokenAddress;\n    }\n\n    /**\n     * @notice Sets Sushi swap pool address (Dollar-Governance)\n     * @param _sushiSwapPoolAddress Pool address\n     */\n    function setSushiSwapPoolAddress(\n        address _sushiSwapPoolAddress\n    ) external onlyAdmin {\n        store.sushiSwapPoolAddress = _sushiSwapPoolAddress;\n    }\n\n    /**\n     * @notice Sets Dollar mint calculator address\n     * @param _dollarMintCalculatorAddress Dollar mint calculator address\n     */\n    function setDollarMintCalculatorAddress(\n        address _dollarMintCalculatorAddress\n    ) external onlyAdmin {\n        store.dollarMintCalculatorAddress = _dollarMintCalculatorAddress;\n    }\n\n    /**\n     * @notice Sets excess Dollars distributor address\n     * @param creditNftManagerAddress Credit NFT manager address\n     * @param dollarMintExcess Dollar distributor address\n     */\n    function setExcessDollarsDistributor(\n        address creditNftManagerAddress,\n        address dollarMintExcess\n    ) external onlyAdmin {\n        store._excessDollarDistributors[\n            creditNftManagerAddress\n        ] = dollarMintExcess;\n    }\n\n    /**\n     * @notice Sets MasterChef address\n     * @param _masterChefAddress MasterChef address\n     */\n    function setMasterChefAddress(\n        address _masterChefAddress\n    ) external onlyAdmin {\n        store.masterChefAddress = _masterChefAddress;\n    }\n\n    /**\n     * @notice Sets formulas address\n     * @param _formulasAddress Formulas address\n     */\n    function setFormulasAddress(address _formulasAddress) external onlyAdmin {\n        store.formulasAddress = _formulasAddress;\n    }\n\n    /**\n     * @notice Sets staking share address\n     * @param _stakingShareAddress Staking share address\n     */\n    function setStakingShareAddress(\n        address _stakingShareAddress\n    ) external onlyAdmin {\n        store.stakingShareAddress = _stakingShareAddress;\n    }\n\n    /**\n     * @notice Sets Curve Dollar incentive address\n     * @param _curveDollarIncentiveAddress Curve Dollar incentive address\n     */\n    function setCurveDollarIncentiveAddress(\n        address _curveDollarIncentiveAddress\n    ) external onlyAdmin {\n        store.curveDollarIncentiveAddress = _curveDollarIncentiveAddress;\n    }\n\n    /**\n     * @notice Sets Curve Dollar-3CRV MetaPool address\n     * @param _stableSwapMetaPoolAddress Curve Dollar-3CRV MetaPool address\n     */\n    function setStableSwapMetaPoolAddress(\n        address _stableSwapMetaPoolAddress\n    ) external onlyAdmin {\n        store.stableSwapMetaPoolAddress = _stableSwapMetaPoolAddress;\n    }\n\n    /**\n     * @notice Sets Curve's Dollar-Stablecoin plain pool address\n     * @dev `_stableSwapPlainPoolAddress` is used to fetch Dollar price in USD\n     * @param _stableSwapPlainPoolAddress Curve's Dollar-Stablecoin plain pool address\n     */\n    function setStableSwapPlainPoolAddress(\n        address _stableSwapPlainPoolAddress\n    ) external onlyAdmin {\n        store.stableSwapPlainPoolAddress = _stableSwapPlainPoolAddress;\n    }\n\n    /**\n     * @notice Sets staking contract address\n     * @dev Staking contract participants deposit Curve LP tokens\n     * for a certain duration to earn Governance tokens and more Curve LP tokens\n     * @param _stakingContractAddress Staking contract address\n     */\n    function setStakingContractAddress(\n        address _stakingContractAddress\n    ) external onlyAdmin {\n        store.stakingContractAddress = _stakingContractAddress;\n    }\n\n    /**\n     * @notice Sets bonding curve address used for UbiquiStick minting\n     * @param _bondingCurveAddress Bonding curve address\n     */\n    function setBondingCurveAddress(\n        address _bondingCurveAddress\n    ) external onlyAdmin {\n        store.bondingCurveAddress = _bondingCurveAddress;\n    }\n\n    /**\n     * @notice Sets bancor formula address\n     * @dev Implied to be used for UbiquiStick minting\n     * @param _bancorFormulaAddress Bancor formula address\n     */\n    function setBancorFormulaAddress(\n        address _bancorFormulaAddress\n    ) external onlyAdmin {\n        store.bancorFormulaAddress = _bancorFormulaAddress;\n    }\n\n    /**\n     * @notice Sets treasury address\n     * @dev Treasury fund is used to maintain the protocol\n     * @param _treasuryAddress Treasury address\n     */\n    function setTreasuryAddress(address _treasuryAddress) external onlyAdmin {\n        store.treasuryAddress = _treasuryAddress;\n    }\n\n    /**\n     * @notice Sets incentive contract `_incentiveAddress` for `_account` address\n     * @param _account Address for which to set an incentive contract\n     * @param _incentiveAddress Incentive contract address\n     */\n    function setIncentiveToDollar(\n        address _account,\n        address _incentiveAddress\n    ) external onlyAdmin {\n        IUbiquityDollarToken dollar = IUbiquityDollarToken(\n            store.dollarTokenAddress\n        );\n        dollar.setIncentiveContract(_account, _incentiveAddress);\n    }\n\n    /**\n     * @notice Deploys Curve MetaPool [Stablecoin, 3CRV LP]\n     * @dev  From the curve documentation for uncollateralized algorithmic\n     * stablecoins amplification should be 5-10\n     * @param _curveFactory Curve MetaPool factory address\n     * @param _crvBasePool Base pool address for MetaPool\n     * @param _crv3PoolTokenAddress Curve TriPool address\n     * @param _amplificationCoefficient Amplification coefficient. The smaller\n     * it is the closer to a constant product we are.\n     * @param _fee Trade fee, given as an integer with 1e10 precision\n     */\n    function deployStableSwapPool(\n        address _curveFactory,\n        address _crvBasePool,\n        address _crv3PoolTokenAddress,\n        uint256 _amplificationCoefficient,\n        uint256 _fee\n    ) external onlyAdmin {\n        // Create new StableSwap meta pool (Dollar <-> 3Crv)\n        // slither-disable-next-line reentrancy-no-eth\n        address metaPool = ICurveFactory(_curveFactory).deploy_metapool(\n            _crvBasePool,\n            ERC20(store.dollarTokenAddress).name(),\n            ERC20(store.dollarTokenAddress).symbol(),\n            store.dollarTokenAddress,\n            _amplificationCoefficient,\n            _fee\n        );\n        store.stableSwapMetaPoolAddress = metaPool;\n        // Approve the newly-deployed meta pool to transfer this contract's funds\n        uint256 crv3PoolTokenAmount = IERC20(_crv3PoolTokenAddress).balanceOf(\n            address(this)\n        );\n        uint256 dollarTokenAmount = IERC20(store.dollarTokenAddress).balanceOf(\n            address(this)\n        );\n        // safe approve revert if approve from non-zero to non-zero allowance\n        IERC20(_crv3PoolTokenAddress).approve(metaPool, 0);\n        IERC20(_crv3PoolTokenAddress).approve(metaPool, crv3PoolTokenAmount);\n\n        IERC20(store.dollarTokenAddress).approve(metaPool, 0);\n        IERC20(store.dollarTokenAddress).approve(metaPool, dollarTokenAmount);\n\n        // coin at index 0 is Dollar and index 1 is 3CRV\n        require(\n            ICurveStableSwapMetaNG(metaPool).coins(0) ==\n                store.dollarTokenAddress &&\n                ICurveStableSwapMetaNG(metaPool).coins(1) ==\n                _crv3PoolTokenAddress,\n            \"MGR: COIN_ORDER_MISMATCH\"\n        );\n        // Add the initial liquidity to the StableSwap meta pool\n        uint256[2] memory amounts = [\n            IERC20(store.dollarTokenAddress).balanceOf(address(this)),\n            IERC20(_crv3PoolTokenAddress).balanceOf(address(this))\n        ];\n        // set curve 3Pool address\n        store.curve3PoolTokenAddress = _crv3PoolTokenAddress;\n        ICurveStableSwapMetaNG(metaPool).add_liquidity(amounts, 0, msg.sender);\n    }\n\n    /**\n     * @notice Returns Curve TWAP oracle address\n     * @return Curve TWAP oracle address\n     */\n    function twapOracleAddress() external view returns (address) {\n        return address(this);\n    }\n\n    /**\n     * @notice Returns Dollar token address\n     * @return Dollar token address\n     */\n    function dollarTokenAddress() external view returns (address) {\n        return store.dollarTokenAddress;\n    }\n\n    /**\n     * @notice Returns UbiquiStick address\n     * @return UbiquiStick address\n     */\n    function ubiquiStickAddress() external view returns (address) {\n        return store.ubiquiStickAddress;\n    }\n\n    /**\n     * @notice Returns Credit token address\n     * @return Credit token address\n     */\n    function creditTokenAddress() external view returns (address) {\n        return store.creditTokenAddress;\n    }\n\n    /**\n     * @notice Returns Credit NFT address\n     * @return Credit NFT address\n     */\n    function creditNftAddress() external view returns (address) {\n        return store.creditNftAddress;\n    }\n\n    /**\n     * @notice Returns Governance token address\n     * @return Governance token address\n     */\n    function governanceTokenAddress() external view returns (address) {\n        return store.governanceTokenAddress;\n    }\n\n    /**\n     * @notice Returns Sushi swap pool address for Dollar-Governance pair\n     * @return Pool address\n     */\n    function sushiSwapPoolAddress() external view returns (address) {\n        return store.sushiSwapPoolAddress;\n    }\n\n    /**\n     * @notice Returns Credit redemption calculator address\n     * @return Credit redemption calculator address\n     */\n    function creditCalculatorAddress() external view returns (address) {\n        return address(this);\n    }\n\n    /**\n     * @notice Returns Credit NFT redemption calculator address\n     * @return Credit NFT redemption calculator address\n     */\n    function creditNftCalculatorAddress() external view returns (address) {\n        return address(this);\n    }\n\n    /**\n     * @notice Returns Dollar mint calculator address\n     * @return Dollar mint calculator address\n     */\n    function dollarMintCalculatorAddress() external view returns (address) {\n        return store.dollarMintCalculatorAddress;\n    }\n\n    /**\n     * @notice Returns Dollar distributor address\n     * @param _creditNftManagerAddress Credit NFT manager address\n     * @return Dollar distributor address\n     */\n    function excessDollarsDistributor(\n        address _creditNftManagerAddress\n    ) external view returns (address) {\n        return store._excessDollarDistributors[_creditNftManagerAddress];\n    }\n\n    /**\n     * @notice Returns MasterChef address\n     * @return MasterChef address\n     */\n    function masterChefAddress() external view returns (address) {\n        return store.masterChefAddress;\n    }\n\n    /**\n     * @notice Returns formulas address\n     * @return Formulas address\n     */\n    function formulasAddress() external view returns (address) {\n        return store.formulasAddress;\n    }\n\n    /**\n     * @notice Returns staking share address\n     * @return Staking share address\n     */\n    function stakingShareAddress() external view returns (address) {\n        return store.stakingShareAddress;\n    }\n\n    /**\n     * @notice Returns Curve MetaPool address for Dollar-3CRV LP pair\n     * @return Curve MetaPool address\n     */\n    function stableSwapMetaPoolAddress() external view returns (address) {\n        return store.stableSwapMetaPoolAddress;\n    }\n\n    /**\n     * @notice Returns Curve's plain pool address for Dollar-Stablecoin pair\n     * @return Curve's plain pool address for Dollar-Stablecoin pair\n     */\n    function stableSwapPlainPoolAddress() external view returns (address) {\n        return store.stableSwapPlainPoolAddress;\n    }\n\n    /**\n     * @notice Returns staking address\n     * @return Staking address\n     */\n    function stakingContractAddress() external view returns (address) {\n        return store.stakingContractAddress;\n    }\n\n    /**\n     * @notice Returns bonding curve address used for UbiquiStick minting\n     * @return Bonding curve address\n     */\n    function bondingCurveAddress() external view returns (address) {\n        return store.bondingCurveAddress;\n    }\n\n    /**\n     * @notice Returns Bancor formula address\n     * @dev Implied to be used for UbiquiStick minting\n     * @return Bancor formula address\n     */\n    function bancorFormulaAddress() external view returns (address) {\n        return store.bancorFormulaAddress;\n    }\n\n    /**\n     * @notice Returns treasury address\n     * @return Treasury address\n     */\n    function treasuryAddress() external view returns (address) {\n        return store.treasuryAddress;\n    }\n\n    /**\n     * @notice Returns Curve TriPool 3CRV LP token address\n     * @return Curve TriPool 3CRV LP token address\n     */\n    function curve3PoolTokenAddress() external view returns (address) {\n        return store.curve3PoolTokenAddress;\n    }\n}\n"
      },
      "src/dollar/libraries/LibAppStorage.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.19;\n\nimport {LibDiamond} from \"./LibDiamond.sol\";\nimport {LibAccessControl} from \"./LibAccessControl.sol\";\nimport \"./Constants.sol\";\n\n/// @notice Shared struct used as a storage in the `LibAppStorage` library\nstruct AppStorage {\n    // reentrancy guard\n    uint256 reentrancyStatus;\n    // others\n    address dollarTokenAddress;\n    address creditNftAddress;\n    address creditNftCalculatorAddress;\n    address dollarMintCalculatorAddress;\n    address stakingShareAddress;\n    address stakingContractAddress;\n    address stableSwapMetaPoolAddress;\n    address stableSwapPlainPoolAddress;\n    address curve3PoolTokenAddress; // 3CRV\n    address treasuryAddress;\n    address governanceTokenAddress;\n    address sushiSwapPoolAddress; // sushi pool UbiquityDollar-GovernanceToken\n    address masterChefAddress;\n    address formulasAddress;\n    address creditTokenAddress;\n    address creditCalculatorAddress;\n    address ubiquiStickAddress;\n    address bondingCurveAddress;\n    address bancorFormulaAddress;\n    address curveDollarIncentiveAddress;\n    mapping(address => address) _excessDollarDistributors;\n    // pausable\n    bool paused;\n}\n\n/// @notice Library used as a shared storage among all protocol libraries\nlibrary LibAppStorage {\n    /**\n     * @notice Returns `AppStorage` struct used as a shared storage among all libraries\n     * @return ds `AppStorage` struct used as a shared storage\n     */\n    function appStorage() internal pure returns (AppStorage storage ds) {\n        assembly {\n            ds.slot := 0\n        }\n    }\n}\n\n/// @notice Contract includes modifiers shared across all protocol's contracts\ncontract Modifiers {\n    /// @notice Shared struct used as a storage across all protocol's contracts\n    AppStorage internal store;\n\n    /**\n     * @notice Prevents a contract from calling itself, directly or indirectly.\n     * Calling a `nonReentrant` function from another `nonReentrant`\n     * function is not supported. It is possible to prevent this from happening\n     * by making the `nonReentrant` function external, and making it call a\n     * `private` function that does the actual work.\n     *\n     * @dev Works identically to OZ's nonReentrant.\n     * @dev Used to avoid state storage collision within diamond.\n     */\n    modifier nonReentrant() {\n        // On the first call to nonReentrant, _notEntered will be true\n        require(\n            store.reentrancyStatus != _ENTERED,\n            \"ReentrancyGuard: reentrant call\"\n        );\n\n        // Any calls to nonReentrant after this point will fail\n        store.reentrancyStatus = _ENTERED;\n        _;\n\n        // By storing the original value once again, a refund is triggered (see\n        // https://eips.ethereum.org/EIPS/eip-2200)\n        store.reentrancyStatus = _NOT_ENTERED;\n    }\n\n    /// @notice Checks that method is called by a contract owner\n    modifier onlyOwner() {\n        LibDiamond.enforceIsContractOwner();\n        _;\n    }\n\n    /// @notice Checks that method is called by address with the `CREDIT_NFT_MANAGER_ROLE` role\n    modifier onlyCreditNftManager() {\n        require(\n            LibAccessControl.hasRole(CREDIT_NFT_MANAGER_ROLE, msg.sender),\n            \"Caller is not a Credit NFT manager\"\n        );\n        _;\n    }\n\n    /// @notice Checks that method is called by address with the `DEFAULT_ADMIN_ROLE` role\n    modifier onlyAdmin() {\n        require(\n            LibAccessControl.hasRole(DEFAULT_ADMIN_ROLE, msg.sender),\n            \"Manager: Caller is not admin\"\n        );\n        _;\n    }\n\n    /// @notice Checks that method is called by address with the `GOVERNANCE_TOKEN_MINTER_ROLE` role\n    modifier onlyMinter() {\n        require(\n            LibAccessControl.hasRole(GOVERNANCE_TOKEN_MINTER_ROLE, msg.sender),\n            \"Governance token: not minter\"\n        );\n        _;\n    }\n\n    /// @notice Checks that method is called by address with the `GOVERNANCE_TOKEN_BURNER_ROLE` role\n    modifier onlyBurner() {\n        require(\n            LibAccessControl.hasRole(GOVERNANCE_TOKEN_BURNER_ROLE, msg.sender),\n            \"Governance token: not burner\"\n        );\n        _;\n    }\n\n    /// @notice Modifier to make a function callable only when the contract is not paused\n    modifier whenNotPaused() {\n        require(!LibAccessControl.paused(), \"Pausable: paused\");\n        _;\n    }\n\n    /// @notice Modifier to make a function callable only when the contract is paused\n    modifier whenPaused() {\n        require(LibAccessControl.paused(), \"Pausable: not paused\");\n        _;\n    }\n\n    /// @notice Checks that method is called by address with the `STAKING_MANAGER_ROLE` role\n    modifier onlyStakingManager() {\n        require(\n            LibAccessControl.hasRole(STAKING_MANAGER_ROLE, msg.sender),\n            \"not manager\"\n        );\n        _;\n    }\n\n    /// @notice Checks that method is called by address with the `PAUSER_ROLE` role\n    modifier onlyPauser() {\n        require(\n            LibAccessControl.hasRole(PAUSER_ROLE, msg.sender),\n            \"not pauser\"\n        );\n        _;\n    }\n\n    /// @notice Checks that method is called by address with the `GOVERNANCE_TOKEN_MANAGER_ROLE` role\n    modifier onlyTokenManager() {\n        require(\n            LibAccessControl.hasRole(GOVERNANCE_TOKEN_MANAGER_ROLE, msg.sender),\n            \"MasterChef: not Governance Token manager\"\n        );\n        _;\n    }\n\n    /// @notice Checks that method is called by address with the `INCENTIVE_MANAGER_ROLE` role\n    modifier onlyIncentiveAdmin() {\n        require(\n            LibAccessControl.hasRole(INCENTIVE_MANAGER_ROLE, msg.sender),\n            \"CreditCalc: not admin\"\n        );\n        _;\n    }\n\n    /// @notice Checks that method is called by address with the `CURVE_DOLLAR_MANAGER_ROLE` role\n    modifier onlyDollarManager() {\n        require(\n            LibAccessControl.hasRole(CURVE_DOLLAR_MANAGER_ROLE, msg.sender),\n            \"CurveIncentive: Caller is not Ubiquity Dollar\"\n        );\n        _;\n    }\n\n    /// @notice Initializes reentrancy guard on contract deployment\n    function _initReentrancyGuard() internal {\n        store.reentrancyStatus = _NOT_ENTERED;\n    }\n}\n"
      },
      "lib/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.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.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * The default value of {decimals} is 18. To change this, you should override\n * this function so it returns a different value.\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 ERC20 is Context, IERC20, IERC20Metadata {\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     * All two of these values are immutable: they can only be set once during\n     * construction.\n     */\n    constructor(string memory name_, string memory symbol_) {\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 default value returned by this function, unless\n     * it's 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(address from, address to, uint256 amount) 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, allowance(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 = allowance(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 `from` to `to`.\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(address from, address to, uint256 amount) 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            // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by\n            // decrementing then incrementing.\n            _balances[to] += amount;\n        }\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        unchecked {\n            // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.\n            _balances[account] += amount;\n        }\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            // Overflow not possible: amount <= accountBalance <= totalSupply.\n            _totalSupply -= amount;\n        }\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(address owner, address spender, uint256 amount) 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 Updates `owner` s allowance for `spender` based on spent `amount`.\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(address owner, address spender, uint256 amount) 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(address from, address to, uint256 amount) 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(address from, address to, uint256 amount) internal virtual {}\n}\n"
      },
      "lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.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 IERC20 {\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    /**\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(address from, address to, uint256 amount) external returns (bool);\n}\n"
      },
      "src/dollar/interfaces/IUbiquityDollarToken.sol": {
        "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.19;\n\nimport \"./IERC20Ubiquity.sol\";\n\n/**\n * @notice Ubiquity Dollar token interface\n */\ninterface IUbiquityDollarToken is IERC20Ubiquity {\n    /// @notice Emitted on setting an incentive contract for an account\n    event IncentiveContractUpdate(\n        address indexed _incentivized,\n        address indexed _incentiveContract\n    );\n\n    /**\n     * @notice Sets `incentive` contract for `account`\n     * @notice Incentive contracts are applied on Dollar transfers:\n     * - EOA => contract\n     * - contract => EOA\n     * - contract => contract\n     * - any transfer global incentive\n     * @param account Account to incentivize\n     * @param incentive Incentive contract address\n     */\n    function setIncentiveContract(address account, address incentive) external;\n\n    /**\n     * @notice Returns incentive contract address for `account`\n     * @dev Address is 0 if there is no incentive contract for the account\n     * @param account Address for which we should retrieve an incentive contract\n     * @return Incentive contract address\n     */\n    function incentiveContract(address account) external view returns (address);\n}\n"
      },
      "src/dollar/interfaces/ICurveFactory.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// !! THIS FILE WAS AUTOGENERATED BY abi-to-sol. SEE BELOW FOR SOURCE. !!\npragma solidity 0.8.19;\n\n/**\n * @notice Curve Factory interface\n * @notice Permissionless pool deployer and registry\n */\ninterface ICurveFactory {\n    /// @notice Emitted when a new base pool is added\n    event BasePoolAdded(address base_pool, address implementat);\n\n    /// @notice Emitted when a new MetaPool is deployed\n    event MetaPoolDeployed(\n        address coin,\n        address base_pool,\n        uint256 A,\n        uint256 fee,\n        address deployer\n    );\n\n    /**\n     * @notice Finds an available pool for exchanging two coins\n     * @param _from Address of coin to be sent\n     * @param _to Address of coin to be received\n     * @return Pool address\n     */\n    function find_pool_for_coins(\n        address _from,\n        address _to\n    ) external view returns (address);\n\n    /**\n     * @notice Finds an available pool for exchanging two coins\n     * @param _from Address of coin to be sent\n     * @param _to Address of coin to be received\n     * @param i Index value. When multiple pools are available this value is used to return the n'th address.\n     * @return Pool address\n     */\n    function find_pool_for_coins(\n        address _from,\n        address _to,\n        uint256 i\n    ) external view returns (address);\n\n    /**\n     * @notice Get the number of coins in a pool\n     * @param _pool Pool address\n     * @return Number of coins\n     */\n    function get_n_coins(\n        address _pool\n    ) external view returns (uint256, uint256);\n\n    /**\n     * @notice Get the coins within a pool\n     * @param _pool Pool address\n     * @return List of coin addresses\n     */\n    function get_coins(address _pool) external view returns (address[2] memory);\n\n    /**\n     * @notice Get the underlying coins within a pool\n     * @dev Reverts if a pool does not exist or is not a metapool\n     * @param _pool Pool address\n     * @return List of coin addresses\n     */\n    function get_underlying_coins(\n        address _pool\n    ) external view returns (address[8] memory);\n\n    /**\n     * @notice Get decimal places for each coin within a pool\n     * @param _pool Pool address\n     * @return uint256 list of decimals\n     */\n    function get_decimals(\n        address _pool\n    ) external view returns (uint256[2] memory);\n\n    /**\n     * @notice Get decimal places for each underlying coin within a pool\n     * @param _pool Pool address\n     * @return uint256 list of decimals\n     */\n    function get_underlying_decimals(\n        address _pool\n    ) external view returns (uint256[8] memory);\n\n    /**\n     * @notice Get rates for coins within a pool\n     * @param _pool Pool address\n     * @return Rates for each coin, precision normalized to 10**18\n     */\n    function get_rates(address _pool) external view returns (uint256[2] memory);\n\n    /**\n     * @notice Get balances for each coin within a pool\n     * @dev For pools using lending, these are the wrapped coin balances\n     * @param _pool Pool address\n     * @return uint256 list of balances\n     */\n    function get_balances(\n        address _pool\n    ) external view returns (uint256[2] memory);\n\n    /**\n     * @notice Get balances for each underlying coin within a metapool\n     * @param _pool Metapool address\n     * @return uint256 list of underlying balances\n     */\n    function get_underlying_balances(\n        address _pool\n    ) external view returns (uint256[8] memory);\n\n    /**\n     * @notice Get the amplfication co-efficient for a pool\n     * @param _pool Pool address\n     * @return uint256 A\n     */\n    function get_A(address _pool) external view returns (uint256);\n\n    /**\n     * @notice Get the fees for a pool\n     * @dev Fees are expressed as integers\n     * @return Pool fee and admin fee as uint256 with 1e10 precision\n     */\n    function get_fees(address _pool) external view returns (uint256, uint256);\n\n    /**\n     * @notice Get the current admin balances (uncollected fees) for a pool\n     * @param _pool Pool address\n     * @return List of uint256 admin balances\n     */\n    function get_admin_balances(\n        address _pool\n    ) external view returns (uint256[2] memory);\n\n    /**\n     * @notice Convert coin addresses to indices for use with pool methods\n     * @param _pool Pool address\n     * @param _from Coin address to be used as `i` within a pool\n     * @param _to Coin address to be used as `j` within a pool\n     * @return int128 `i`, int128 `j`, boolean indicating if `i` and `j` are underlying coins\n     */\n    function get_coin_indices(\n        address _pool,\n        address _from,\n        address _to\n    ) external view returns (int128, int128, bool);\n\n    /**\n     * @notice Add a base pool to the registry, which may be used in factory metapools\n     * @dev Only callable by admin\n     * @param _base_pool Pool address to add\n     * @param _metapool_implementation Implementation address that can be used with this base pool\n     * @param _fee_receiver Admin fee receiver address for metapools using this base pool\n     */\n    function add_base_pool(\n        address _base_pool,\n        address _metapool_implementation,\n        address _fee_receiver\n    ) external;\n\n    /**\n     * @notice Deploy a new metapool\n     * @param _base_pool Address of the base pool to use within the metapool\n     * @param _name Name of the new metapool\n     * @param _symbol Symbol for the new metapool - will be concatenated with the base pool symbol\n     * @param _coin Address of the coin being used in the metapool\n     * @param _A Amplification co-efficient - a higher value here means\n     *         less tolerance for imbalance within the pool's assets.\n     *         Suggested values include:\n     *          * Uncollateralized algorithmic stablecoins: 5-10\n     *          * Non-redeemable, collateralized assets: 100\n     *          * Redeemable assets: 200-400\n     * @param _fee Trade fee, given as an integer with 1e10 precision. The\n     *           minimum fee is 0.04% (4000000), the maximum is 1% (100000000).\n     *           50% of the fee is distributed to veCRV holders.\n     * @return Address of the deployed pool\n     */\n    function deploy_metapool(\n        address _base_pool,\n        string memory _name,\n        string memory _symbol,\n        address _coin,\n        uint256 _A,\n        uint256 _fee\n    ) external returns (address);\n\n    /**\n     * @notice Transfer ownership of this contract to `addr`\n     * @param addr Address of the new owner\n     */\n    function commit_transfer_ownership(address addr) external;\n\n    /**\n     * @notice Accept a pending ownership transfer\n     * @dev Only callable by the new owner\n     */\n    function accept_transfer_ownership() external;\n\n    /**\n     * @notice Set fee receiver for base and plain pools\n     * @param _base_pool Address of base pool to set fee receiver for. For plain pools, leave as `ZERO_ADDRESS`.\n     * @param _fee_receiver Address that fees are sent to\n     */\n    function set_fee_receiver(\n        address _base_pool,\n        address _fee_receiver\n    ) external;\n\n    /**\n     * @notice Convert the fees of a pool and transfer to the pool's fee receiver\n     * @dev All fees are converted to LP token of base pool\n     */\n    function convert_fees() external returns (bool);\n\n    /**\n     * @notice Returns admin address\n     * @return Admin address\n     */\n    function admin() external view returns (address);\n\n    /**\n     * @notice Returns future admin address\n     * @return Fututre admin address\n     */\n    function future_admin() external view returns (address);\n\n    /**\n     * @notice Returns pool address by index\n     * @param arg0 Pool index\n     * @return Pool address\n     */\n    function pool_list(uint256 arg0) external view returns (address);\n\n    /**\n     * @notice Returns `pool_list` length\n     * @return Pool list length\n     */\n    function pool_count() external view returns (uint256);\n\n    /**\n     * @notice Returns base pool address by index\n     * @param arg0 Base pool index\n     * @return Base pool address\n     */\n    function base_pool_list(uint256 arg0) external view returns (address);\n\n    /**\n     * @notice Returns `base_pool_list` length\n     * @return Base pool list length\n     */\n    function base_pool_count() external view returns (uint256);\n\n    /**\n     * @notice Returns fee reciever by pool address\n     * @param arg0 Pool address\n     * @return Fee receiver\n     */\n    function fee_receiver(address arg0) external view returns (address);\n}\n"
      },
      "src/dollar/interfaces/ICurveStableSwapMetaNG.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.19;\n\nimport {IERC20} from \"@openzeppelin/contracts/interfaces/IERC20.sol\";\n\n/**\n * @notice Curve MetaPool interface\n *\n * @notice **What is Curve MetaPool**\n * @notice The pool that consists of 2 tokens: stable coin and 3CRV LP token.\n * For example the pool may contain Ubiquity Dollar and 3CRV LP token.\n * This allows users to trade between Ubiquity Dollar and any of the tokens\n * from the Curve 3Pool (DAI, USDC, USDT). When user adds liquidity to the pool\n * then he is rewarded with MetaPool LP tokens. 1 Dollar3CRV LP token != 1 stable coin token.\n * @notice Add liquidity example:\n * 1. User sends 100 Ubiquity Dollars to the pool\n * 2. User gets 100 Dollar3CRV LP tokens of the pool\n * @notice Remove liquidity example:\n * 1. User sends 100 Dollar3CRV LP tokens to the pool\n * 2. User gets 100 Dollar/DAI/USDC/USDT (may choose any) tokens\n *\n * @dev Source: https://github.com/curvefi/stableswap-ng/blob/bff1522b30819b7b240af17ccfb72b0effbf6c47/contracts/main/CurveStableSwapMetaNG.vy\n * @dev Docs: https://docs.curve.fi/stableswap-exchange/stableswap-ng/pools/metapool/\n */\ninterface ICurveStableSwapMetaNG is IERC20 {\n    /**\n     * @notice Deposits coins into to the pool and mints new LP tokens\n     * @param _amounts List of amounts of underlying coins to deposit.\n     * Amounts correspond to the tokens at the same index locations within `coins`.\n     * @param _min_mint_amount Minimum amount of LP tokens to mint from the deposit\n     * @param _receiver Optional address that receives the LP tokens. If not specified, they are sent to the caller.\n     * @return The amount of LP tokens that were minted in the deposit\n     */\n    function add_liquidity(\n        uint256[2] memory _amounts,\n        uint256 _min_mint_amount,\n        address _receiver\n    ) external returns (uint256);\n\n    /**\n     * @notice Getter for the current balance of coin `i` within the pool\n     * @param i Coin index\n     * @return Coin balance\n     */\n    function balances(uint256 i) external view returns (uint256);\n\n    /**\n     * @notice Estimates the amount of LP tokens minted or burned based on a deposit or withdrawal\n     *\n     * @notice This calculation accounts for slippage, but not fees. It should be used as a basis for\n     * determining expected amounts when calling `add_liquidity()` or `remove_liquidity_imbalance()`,\n     * but should not be considered to be precise!\n     *\n     * @param _amounts Amount of each coin being deposited. Amounts correspond to the tokens at the\n     * same index locations within `coins()`.\n     * @param _is_deposit Set `True` for deposits, `False` for withdrawals\n     * @return The expected amount of LP tokens minted or burned\n     */\n    function calc_token_amount(\n        uint256[2] memory _amounts,\n        bool _is_deposit\n    ) external view returns (uint256);\n\n    /**\n     * @notice Returns token address by the provided `arg0` index\n     * @param arg0 Token index\n     * @return Token address\n     */\n    function coins(uint256 arg0) external view returns (address);\n\n    /**\n     * @notice Performs an exchange between two tokens. Index values can be found\n     * using the `coins()` public getter method, or `get_coins()` within the factory contract.\n     * @param i Index value of the token to send\n     * @param j Index value of the token to receive\n     * @param dx The amount of `i` being exchanged\n     * @param min_dy The minimum amount of `j` to receive. If the swap would result in less, the transaction will revert.\n     * @return The amount of `j` received in the exchange\n     */\n    function exchange(\n        int128 i,\n        int128 j,\n        uint256 dx,\n        uint256 min_dy\n    ) external returns (uint256);\n\n    /**\n     * @notice Function to calculate the exponential moving average (ema) price for the coin at index value `i`\n     * @param i Index value of coin\n     * @return Price oracle\n     */\n    function price_oracle(uint256 i) external view returns (uint256);\n\n    /**\n     * @notice Withdraws a single asset from the pool\n     * @param _burn_amount Amount of LP tokens to burn in the withdrawal\n     * @param i Index value of the coin to withdraw. Can be found using the `coins()` getter method.\n     * @param _min_received Minimum amount of the coin to receive\n     * @return The amount of the coin received in the withdrawal\n     */\n    function remove_liquidity_one_coin(\n        uint256 _burn_amount,\n        int128 i,\n        uint256 _min_received\n    ) external returns (uint256);\n}\n"
      },
      "src/dollar/libraries/LibAccessControl.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.19;\n\nimport {EnumerableSet} from \"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\";\nimport {AddressUtils} from \"../libraries/AddressUtils.sol\";\nimport {UintUtils} from \"../libraries/UintUtils.sol\";\nimport {LibAppStorage} from \"./LibAppStorage.sol\";\n\n/// @notice Access control library\nlibrary LibAccessControl {\n    using AddressUtils for address;\n    using EnumerableSet for EnumerableSet.AddressSet;\n    using UintUtils for uint256;\n\n    /// @notice Storage slot used to store data for this library\n    bytes32 constant ACCESS_CONTROL_STORAGE_SLOT =\n        bytes32(\n            uint256(keccak256(\"ubiquity.contracts.access.control.storage\")) - 1\n        ) & ~bytes32(uint256(0xff));\n\n    /// @notice Structure to keep all role members with their admin role\n    struct RoleData {\n        EnumerableSet.AddressSet members;\n        bytes32 adminRole;\n    }\n\n    /// @notice Structure to keep all protocol roles\n    struct Layout {\n        mapping(bytes32 => RoleData) roles;\n    }\n\n    /// @notice Emitted when admin role of a role is updated\n    event RoleAdminChanged(\n        bytes32 indexed role,\n        bytes32 indexed previousAdminRole,\n        bytes32 indexed newAdminRole\n    );\n\n    /// @notice Emitted when role is granted to account\n    event RoleGranted(\n        bytes32 indexed role,\n        address indexed account,\n        address indexed sender\n    );\n\n    /// @notice Emitted when role is revoked from account\n    event RoleRevoked(\n        bytes32 indexed role,\n        address indexed account,\n        address indexed sender\n    );\n\n    /// @notice Emitted when the pause is triggered by `account`\n    event Paused(address account);\n\n    /// @notice Emitted when the pause is lifted by `account`\n    event Unpaused(address account);\n\n    /**\n     * @notice Returns struct used as a storage for this library\n     * @return l Struct used as a storage\n     */\n    function accessControlStorage() internal pure returns (Layout storage l) {\n        bytes32 slot = ACCESS_CONTROL_STORAGE_SLOT;\n        assembly {\n            l.slot := slot\n        }\n    }\n\n    /**\n     * @notice Checks that a method can only be called by the provided role\n     * @param role Role name\n     */\n    modifier onlyRole(bytes32 role) {\n        checkRole(role);\n        _;\n    }\n\n    /// @notice Returns true if the contract is paused and false otherwise\n    function paused() internal view returns (bool) {\n        return LibAppStorage.appStorage().paused;\n    }\n\n    /**\n     * @notice Checks whether role is assigned to account\n     * @param role Role to check\n     * @param account Address to check\n     * @return Whether role is assigned to account\n     */\n    function hasRole(\n        bytes32 role,\n        address account\n    ) internal view returns (bool) {\n        return accessControlStorage().roles[role].members.contains(account);\n    }\n\n    /**\n     * @notice Reverts if sender does not have a given role\n     * @param role Role to query\n     */\n    function checkRole(bytes32 role) internal view {\n        checkRole(role, msg.sender);\n    }\n\n    /**\n     * @notice Reverts if given account does not have a given role\n     * @param role Role to query\n     * @param account Address to query\n     */\n    function checkRole(bytes32 role, address account) internal view {\n        if (!hasRole(role, account)) {\n            revert(\n                string(\n                    abi.encodePacked(\n                        \"AccessControl: account \",\n                        account.toString(),\n                        \" is missing role \",\n                        uint256(role).toHexString(32)\n                    )\n                )\n            );\n        }\n    }\n\n    /**\n     * @notice Returns admin role for a given role\n     * @param role Role to query\n     * @return Admin role for a provided role\n     */\n    function getRoleAdmin(bytes32 role) internal view returns (bytes32) {\n        return accessControlStorage().roles[role].adminRole;\n    }\n\n    /**\n     * @notice Sets a new admin role for a provided role\n     * @param role Role for which admin role should be set\n     * @param adminRole Admin role to set\n     */\n    function setRoleAdmin(bytes32 role, bytes32 adminRole) internal {\n        bytes32 previousAdminRole = getRoleAdmin(role);\n        accessControlStorage().roles[role].adminRole = adminRole;\n        emit RoleAdminChanged(role, previousAdminRole, adminRole);\n    }\n\n    /**\n     * @notice Assigns role to a given account\n     * @param role Role to assign\n     * @param account Recipient of role assignment\n     */\n    function grantRole(bytes32 role, address account) internal {\n        accessControlStorage().roles[role].members.add(account);\n        emit RoleGranted(role, account, msg.sender);\n    }\n\n    /**\n     * @notice Unassign role from a given account\n     * @param role Role to unassign\n     * @param account Address from which the provided role should be unassigned\n     */\n    function revokeRole(bytes32 role, address account) internal {\n        accessControlStorage().roles[role].members.remove(account);\n        emit RoleRevoked(role, account, msg.sender);\n    }\n\n    /**\n     * @notice Renounces role\n     * @param role Role to renounce\n     */\n    function renounceRole(bytes32 role) internal {\n        revokeRole(role, msg.sender);\n    }\n\n    /// @notice Pauses the contract\n    function pause() internal {\n        LibAppStorage.appStorage().paused = true;\n        emit Paused(msg.sender);\n    }\n\n    /// @notice Unpauses the contract\n    function unpause() internal {\n        LibAppStorage.appStorage().paused = false;\n        emit Unpaused(msg.sender);\n    }\n}\n"
      },
      "src/dollar/libraries/LibDiamond.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.19;\n\nimport {IDiamondCut} from \"../interfaces/IDiamondCut.sol\";\nimport {IDiamondLoupe} from \"../interfaces/IDiamondLoupe.sol\";\nimport \"@openzeppelin/contracts/interfaces/IERC165.sol\";\nimport {IERC173} from \"../interfaces/IERC173.sol\";\n\n/// @notice Error thrown when `initializeDiamondCut()` fails\nerror InitializationFunctionReverted(\n    address _initializationContractAddress,\n    bytes _calldata\n);\n\n/**\n * @notice Library used for diamond facets and selector modifications\n * @dev Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\n * The loupe functions are required by the EIP2535 Diamonds standard.\n */\nlibrary LibDiamond {\n    /// @notice Storage slot used to store data for this library\n    bytes32 constant DIAMOND_STORAGE_POSITION =\n        bytes32(uint256(keccak256(\"diamond.standard.diamond.storage\")) - 1) &\n            ~bytes32(uint256(0xff));\n\n    /// @notice Struct used as a mapping of facet to function selector position\n    struct FacetAddressAndPosition {\n        address facetAddress;\n        uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\n    }\n\n    /// @notice Struct used as a mapping of facet to function selectors\n    struct FacetFunctionSelectors {\n        bytes4[] functionSelectors;\n        uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\n    }\n\n    /// @notice Struct used as a storage for this library\n    struct DiamondStorage {\n        // maps function selector to the facet address and\n        // the position of the selector in the facetFunctionSelectors.selectors array\n        mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\n        // maps facet addresses to function selectors\n        mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\n        // facet addresses\n        address[] facetAddresses;\n        // Used to query if a contract implements an interface.\n        // Used to implement ERC-165.\n        mapping(bytes4 => bool) supportedInterfaces;\n        // owner of the contract\n        address contractOwner;\n    }\n\n    /**\n     * @notice Returns struct used as a storage for this library\n     * @return ds Struct used as a storage\n     */\n    function diamondStorage()\n        internal\n        pure\n        returns (DiamondStorage storage ds)\n    {\n        bytes32 position = DIAMOND_STORAGE_POSITION;\n        assembly {\n            ds.slot := position\n        }\n    }\n\n    /// @notice Emitted when contract owner is updated\n    event OwnershipTransferred(\n        address indexed previousOwner,\n        address indexed newOwner\n    );\n\n    /**\n     * @notice Updates contract owner\n     * @param _newOwner New contract owner\n     */\n    function setContractOwner(address _newOwner) internal {\n        DiamondStorage storage ds = diamondStorage();\n        address previousOwner = ds.contractOwner;\n        ds.contractOwner = _newOwner;\n        emit OwnershipTransferred(previousOwner, _newOwner);\n    }\n\n    /**\n     * @notice Returns contract owner\n     * @param contractOwner_ Contract owner\n     */\n    function contractOwner() internal view returns (address contractOwner_) {\n        contractOwner_ = diamondStorage().contractOwner;\n    }\n\n    /// @notice Checks that `msg.sender` is a contract owner\n    function enforceIsContractOwner() internal view {\n        require(\n            msg.sender == diamondStorage().contractOwner,\n            \"LibDiamond: Must be contract owner\"\n        );\n    }\n\n    /// @notice Emitted when facet is modified\n    event DiamondCut(\n        IDiamondCut.FacetCut[] _diamondCut,\n        address _init,\n        bytes _calldata\n    );\n\n    /**\n     * @notice Add/replace/remove any number of functions and optionally execute a function with delegatecall\n     * @param _diamondCut Contains the facet addresses and function selectors\n     * @param _init The address of the contract or facet to execute _calldata\n     * @param _calldata A function call, including function selector and arguments\n     * @dev `_calldata` is executed with delegatecall on `_init`\n     */\n    function diamondCut(\n        IDiamondCut.FacetCut[] memory _diamondCut,\n        address _init,\n        bytes memory _calldata\n    ) internal {\n        for (\n            uint256 facetIndex;\n            facetIndex < _diamondCut.length;\n            facetIndex++\n        ) {\n            IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\n            if (action == IDiamondCut.FacetCutAction.Add) {\n                addFunctions(\n                    _diamondCut[facetIndex].facetAddress,\n                    _diamondCut[facetIndex].functionSelectors\n                );\n            } else if (action == IDiamondCut.FacetCutAction.Replace) {\n                replaceFunctions(\n                    _diamondCut[facetIndex].facetAddress,\n                    _diamondCut[facetIndex].functionSelectors\n                );\n            } else if (action == IDiamondCut.FacetCutAction.Remove) {\n                removeFunctions(\n                    _diamondCut[facetIndex].facetAddress,\n                    _diamondCut[facetIndex].functionSelectors\n                );\n            } else {\n                revert(\"LibDiamondCut: Incorrect FacetCutAction\");\n            }\n        }\n        emit DiamondCut(_diamondCut, _init, _calldata);\n        initializeDiamondCut(_init, _calldata);\n    }\n\n    /**\n     * @notice Adds new functions to a facet\n     * @param _facetAddress Facet address\n     * @param _functionSelectors Function selectors to add\n     */\n    function addFunctions(\n        address _facetAddress,\n        bytes4[] memory _functionSelectors\n    ) internal {\n        require(\n            _functionSelectors.length > 0,\n            \"LibDiamondCut: No selectors in facet to cut\"\n        );\n        DiamondStorage storage ds = diamondStorage();\n        require(\n            _facetAddress != address(0),\n            \"LibDiamondCut: Add facet can't be address(0)\"\n        );\n        uint96 selectorPosition = uint96(\n            ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\n        );\n        // add new facet address if it does not exist\n        if (selectorPosition == 0) {\n            addFacet(ds, _facetAddress);\n        }\n        for (\n            uint256 selectorIndex;\n            selectorIndex < _functionSelectors.length;\n            selectorIndex++\n        ) {\n            bytes4 selector = _functionSelectors[selectorIndex];\n            address oldFacetAddress = ds\n                .selectorToFacetAndPosition[selector]\n                .facetAddress;\n            require(\n                oldFacetAddress == address(0),\n                \"LibDiamondCut: Can't add function that already exists\"\n            );\n            addFunction(ds, selector, selectorPosition, _facetAddress);\n            selectorPosition++;\n        }\n    }\n\n    /**\n     * @notice Replaces functions in a facet\n     * @param _facetAddress Facet address\n     * @param _functionSelectors Function selectors to replace with\n     */\n    function replaceFunctions(\n        address _facetAddress,\n        bytes4[] memory _functionSelectors\n    ) internal {\n        require(\n            _functionSelectors.length > 0,\n            \"LibDiamondCut: No selectors in facet to cut\"\n        );\n        DiamondStorage storage ds = diamondStorage();\n        require(\n            _facetAddress != address(0),\n            \"LibDiamondCut: Add facet can't be address(0)\"\n        );\n        uint96 selectorPosition = uint96(\n            ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\n        );\n        // add new facet address if it does not exist\n        if (selectorPosition == 0) {\n            addFacet(ds, _facetAddress);\n        }\n        for (\n            uint256 selectorIndex;\n            selectorIndex < _functionSelectors.length;\n            selectorIndex++\n        ) {\n            bytes4 selector = _functionSelectors[selectorIndex];\n            address oldFacetAddress = ds\n                .selectorToFacetAndPosition[selector]\n                .facetAddress;\n            require(\n                oldFacetAddress != _facetAddress,\n                \"LibDiamondCut: Can't replace function with same function\"\n            );\n            removeFunction(ds, oldFacetAddress, selector);\n            addFunction(ds, selector, selectorPosition, _facetAddress);\n            selectorPosition++;\n        }\n    }\n\n    /**\n     * @notice Removes functions from a facet\n     * @param _facetAddress Facet address\n     * @param _functionSelectors Function selectors to remove\n     */\n    function removeFunctions(\n        address _facetAddress,\n        bytes4[] memory _functionSelectors\n    ) internal {\n        require(\n            _functionSelectors.length > 0,\n            \"LibDiamondCut: No selectors in facet to cut\"\n        );\n        DiamondStorage storage ds = diamondStorage();\n        // if function does not exist then do nothing and return\n        require(\n            _facetAddress == address(0),\n            \"LibDiamondCut: Remove facet address must be address(0)\"\n        );\n        for (\n            uint256 selectorIndex;\n            selectorIndex < _functionSelectors.length;\n            selectorIndex++\n        ) {\n            bytes4 selector = _functionSelectors[selectorIndex];\n            address oldFacetAddress = ds\n                .selectorToFacetAndPosition[selector]\n                .facetAddress;\n            removeFunction(ds, oldFacetAddress, selector);\n        }\n    }\n\n    /**\n     * @notice Adds a new diamond facet\n     * @param ds Struct used as a storage\n     * @param _facetAddress Facet address to add\n     */\n    function addFacet(\n        DiamondStorage storage ds,\n        address _facetAddress\n    ) internal {\n        enforceHasContractCode(\n            _facetAddress,\n            \"LibDiamondCut: New facet has no code\"\n        );\n        ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds\n            .facetAddresses\n            .length;\n        ds.facetAddresses.push(_facetAddress);\n    }\n\n    /**\n     * @notice Adds new function to a facet\n     * @param ds Struct used as a storage\n     * @param _selector Function selector to add\n     * @param _selectorPosition Position in `FacetFunctionSelectors.functionSelectors` array\n     * @param _facetAddress Facet address\n     */\n    function addFunction(\n        DiamondStorage storage ds,\n        bytes4 _selector,\n        uint96 _selectorPosition,\n        address _facetAddress\n    ) internal {\n        ds\n            .selectorToFacetAndPosition[_selector]\n            .functionSelectorPosition = _selectorPosition;\n        ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(\n            _selector\n        );\n        ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\n    }\n\n    /**\n     * @notice Removes function from a facet\n     * @param ds Struct used as a storage\n     * @param _facetAddress Facet address\n     * @param _selector Function selector to add\n     */\n    function removeFunction(\n        DiamondStorage storage ds,\n        address _facetAddress,\n        bytes4 _selector\n    ) internal {\n        require(\n            _facetAddress != address(0),\n            \"LibDiamondCut: Can't remove function that doesn't exist\"\n        );\n        // precomputed diamondCut function selector to save gas\n        // bytes4(keccak256(abi.encodeWithSignature(\"diamondCut((address,uint8,bytes4[])[],address,bytes)\"))) == 0x1f931c1c\n        require(\n            _selector != bytes4(0x1f931c1c),\n            \"LibDiamondCut: Can't remove diamondCut function\"\n        );\n        // an immutable function is a function defined directly in a diamond\n        require(\n            _facetAddress != address(this),\n            \"LibDiamondCut: Can't remove immutable function\"\n        );\n        // replace selector with last selector, then delete last selector\n        uint256 selectorPosition = ds\n            .selectorToFacetAndPosition[_selector]\n            .functionSelectorPosition;\n        uint256 lastSelectorPosition = ds\n            .facetFunctionSelectors[_facetAddress]\n            .functionSelectors\n            .length - 1;\n        // if not the same then replace _selector with lastSelector\n        if (selectorPosition != lastSelectorPosition) {\n            bytes4 lastSelector = ds\n                .facetFunctionSelectors[_facetAddress]\n                .functionSelectors[lastSelectorPosition];\n            ds.facetFunctionSelectors[_facetAddress].functionSelectors[\n                selectorPosition\n            ] = lastSelector;\n            ds\n                .selectorToFacetAndPosition[lastSelector]\n                .functionSelectorPosition = uint96(selectorPosition);\n        }\n        // delete the last selector\n        ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\n        delete ds.selectorToFacetAndPosition[_selector];\n\n        // if no more selectors for facet address then delete the facet address\n        if (lastSelectorPosition == 0) {\n            // replace facet address with last facet address and delete last facet address\n            uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\n            uint256 facetAddressPosition = ds\n                .facetFunctionSelectors[_facetAddress]\n                .facetAddressPosition;\n            if (facetAddressPosition != lastFacetAddressPosition) {\n                address lastFacetAddress = ds.facetAddresses[\n                    lastFacetAddressPosition\n                ];\n                ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\n                ds\n                    .facetFunctionSelectors[lastFacetAddress]\n                    .facetAddressPosition = facetAddressPosition;\n            }\n            ds.facetAddresses.pop();\n            delete ds\n                .facetFunctionSelectors[_facetAddress]\n                .facetAddressPosition;\n        }\n    }\n\n    /**\n     * @notice Function called on diamond cut modification\n     * @param _init The address of the contract or facet to execute _calldata\n     * @param _calldata A function call, including function selector and arguments\n     * @dev `_calldata` is executed with delegatecall on `_init`\n     */\n    function initializeDiamondCut(\n        address _init,\n        bytes memory _calldata\n    ) internal {\n        if (_init == address(0)) {\n            return;\n        }\n        enforceHasContractCode(\n            _init,\n            \"LibDiamondCut: _init address has no code\"\n        );\n        (bool success, bytes memory error) = _init.delegatecall(_calldata);\n        if (!success) {\n            if (error.length > 0) {\n                // bubble up error\n                /// @solidity memory-safe-assembly\n                assembly {\n                    let returndata_size := mload(error)\n                    revert(add(32, error), returndata_size)\n                }\n            } else {\n                revert InitializationFunctionReverted(_init, _calldata);\n            }\n        }\n    }\n\n    /**\n     * @notice Reverts if `_contract` address doesn't have any code\n     * @param _contract Contract address to check for empty code\n     * @param _errorMessage Error message\n     */\n    function enforceHasContractCode(\n        address _contract,\n        string memory _errorMessage\n    ) internal view {\n        uint256 contractSize;\n        assembly {\n            contractSize := extcodesize(_contract)\n        }\n        require(contractSize > 0, _errorMessage);\n    }\n}\n"
      },
      "src/dollar/libraries/Constants.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.19;\n\nimport \"abdk/ABDKMathQuad.sol\";\n\n/// @dev Default admin role name\nbytes32 constant DEFAULT_ADMIN_ROLE = 0x00;\n\n/// @dev Role name for Governance tokens minter\nbytes32 constant GOVERNANCE_TOKEN_MINTER_ROLE = keccak256(\n    \"GOVERNANCE_TOKEN_MINTER_ROLE\"\n);\n\n/// @dev Role name for Governance tokens burner\nbytes32 constant GOVERNANCE_TOKEN_BURNER_ROLE = keccak256(\n    \"GOVERNANCE_TOKEN_BURNER_ROLE\"\n);\n\n/// @dev Role name for staking share minter\nbytes32 constant STAKING_SHARE_MINTER_ROLE = keccak256(\n    \"STAKING_SHARE_MINTER_ROLE\"\n);\n\n/// @dev Role name for staking share burner\nbytes32 constant STAKING_SHARE_BURNER_ROLE = keccak256(\n    \"STAKING_SHARE_BURNER_ROLE\"\n);\n\n/// @dev Role name for Credit tokens minter\nbytes32 constant CREDIT_TOKEN_MINTER_ROLE = keccak256(\n    \"CREDIT_TOKEN_MINTER_ROLE\"\n);\n\n/// @dev Role name for Credit tokens burner\nbytes32 constant CREDIT_TOKEN_BURNER_ROLE = keccak256(\n    \"CREDIT_TOKEN_BURNER_ROLE\"\n);\n\n/// @dev Role name for Dollar tokens minter\nbytes32 constant DOLLAR_TOKEN_MINTER_ROLE = keccak256(\n    \"DOLLAR_TOKEN_MINTER_ROLE\"\n);\n\n/// @dev Role name for Dollar tokens burner\nbytes32 constant DOLLAR_TOKEN_BURNER_ROLE = keccak256(\n    \"DOLLAR_TOKEN_BURNER_ROLE\"\n);\n\n/// @dev Role name for Dollar manager\nbytes32 constant CURVE_DOLLAR_MANAGER_ROLE = keccak256(\n    \"CURVE_DOLLAR_MANAGER_ROLE\"\n);\n\n/// @dev Role name for pauser\nbytes32 constant PAUSER_ROLE = keccak256(\"PAUSER_ROLE\");\n\n/// @dev Role name for Credit NFT manager\nbytes32 constant CREDIT_NFT_MANAGER_ROLE = keccak256(\"CREDIT_NFT_MANAGER_ROLE\");\n\n/// @dev Role name for Staking manager\nbytes32 constant STAKING_MANAGER_ROLE = keccak256(\"STAKING_MANAGER_ROLE\");\n\n/// @dev Role name for inventive manager\nbytes32 constant INCENTIVE_MANAGER_ROLE = keccak256(\"INCENTIVE_MANAGER\");\n\n/// @dev Role name for Governance token manager\nbytes32 constant GOVERNANCE_TOKEN_MANAGER_ROLE = keccak256(\n    \"GOVERNANCE_TOKEN_MANAGER_ROLE\"\n);\n\n/// @dev ETH pseudo address used to distinguish ERC20 tokens and ETH in `LibCollectableDust.sendDust()`\naddress constant ETH_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\n\n/// @dev 1 ETH\nuint256 constant ONE = uint256(1 ether); // 3Crv has 18 decimals\n\n/// @dev Accuracy used in `LibBondingCurve`\nuint256 constant ACCURACY = 10e18;\n/// @dev Max connector weight used in `LibBondingCurve`\nuint32 constant MAX_WEIGHT = 1e6;\n\n/// @dev keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\nbytes32 constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;\n\n/// @dev Reentrancy constant\nuint256 constant _NOT_ENTERED = 1;\n/// @dev Reentrancy constant\nuint256 constant _ENTERED = 2;\n\n/// @dev Ubiquity pool price precision\nuint256 constant UBIQUITY_POOL_PRICE_PRECISION = 1e6;\n"
      },
      "lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20Metadata is IERC20 {\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"
      },
      "lib/openzeppelin-contracts/contracts/utils/Context.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\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 Context {\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"
      },
      "src/dollar/interfaces/IERC20Ubiquity.sol": {
        "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.19;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol\";\n\n/**\n * @notice Interface for ERC20Ubiquity contract\n */\ninterface IERC20Ubiquity is IERC20, IERC20Permit {\n    // ----------- Events -----------\n\n    /// @notice Emitted on tokens minting\n    event Minting(\n        address indexed _to,\n        address indexed _minter,\n        uint256 _amount\n    );\n\n    /// @notice Emitted on tokens burning\n    event Burning(address indexed _burned, uint256 _amount);\n\n    /**\n     * @notice Burns tokens from `msg.sender`\n     * @param amount Amount of tokens to burn\n     */\n    function burn(uint256 amount) external;\n\n    /**\n     * @notice Burns tokens from the `account` address\n     * @param account Address to burn tokens from\n     * @param amount Amount of tokens to burn\n     */\n    function burnFrom(address account, uint256 amount) external;\n\n    /**\n     * @notice Mints tokens to the `account` address\n     * @param account Address to mint tokens to\n     * @param amount Amount of tokens to mint\n     */\n    function mint(address account, uint256 amount) external;\n}\n"
      },
      "lib/openzeppelin-contracts/contracts/interfaces/IERC20.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../token/ERC20/IERC20.sol\";\n"
      },
      "lib/openzeppelin-contracts/contracts/utils/structs/EnumerableSet.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol)\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```solidity\n * contract Example {\n *     // Add the library methods\n *     using EnumerableSet for EnumerableSet.AddressSet;\n *\n *     // Declare a set state variable\n *     EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n *\n * [WARNING]\n * ====\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\n * unusable.\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\n *\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\n * array of EnumerableSet.\n * ====\n */\nlibrary EnumerableSet {\n    // To implement this library for multiple types with as little code\n    // repetition as possible, we write it in terms of a generic Set type with\n    // bytes32 values.\n    // The Set implementation uses private functions, and user-facing\n    // implementations (such as AddressSet) are just wrappers around the\n    // underlying Set.\n    // This means that we can only create new EnumerableSets for types that fit\n    // in bytes32.\n\n    struct Set {\n        // Storage of set values\n        bytes32[] _values;\n        // Position of the value in the `values` array, plus 1 because index 0\n        // means a value is not in the set.\n        mapping(bytes32 => uint256) _indexes;\n    }\n\n    /**\n     * @dev Add a value to a set. O(1).\n     *\n     * Returns true if the value was added to the set, that is if it was not\n     * already present.\n     */\n    function _add(Set storage set, bytes32 value) private returns (bool) {\n        if (!_contains(set, value)) {\n            set._values.push(value);\n            // The value is stored at length-1, but we add 1 to all indexes\n            // and use 0 as a sentinel value\n            set._indexes[value] = set._values.length;\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n    /**\n     * @dev Removes a value from a set. O(1).\n     *\n     * Returns true if the value was removed from the set, that is if it was\n     * present.\n     */\n    function _remove(Set storage set, bytes32 value) private returns (bool) {\n        // We read and store the value's index to prevent multiple reads from the same storage slot\n        uint256 valueIndex = set._indexes[value];\n\n        if (valueIndex != 0) {\n            // Equivalent to contains(set, value)\n            // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n            // the array, and then remove the last element (sometimes called as 'swap and pop').\n            // This modifies the order of the array, as noted in {at}.\n\n            uint256 toDeleteIndex = valueIndex - 1;\n            uint256 lastIndex = set._values.length - 1;\n\n            if (lastIndex != toDeleteIndex) {\n                bytes32 lastValue = set._values[lastIndex];\n\n                // Move the last value to the index where the value to delete is\n                set._values[toDeleteIndex] = lastValue;\n                // Update the index for the moved value\n                set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n            }\n\n            // Delete the slot where the moved value was stored\n            set._values.pop();\n\n            // Delete the index for the deleted slot\n            delete set._indexes[value];\n\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n    /**\n     * @dev Returns true if the value is in the set. O(1).\n     */\n    function _contains(Set storage set, bytes32 value) private view returns (bool) {\n        return set._indexes[value] != 0;\n    }\n\n    /**\n     * @dev Returns the number of values on the set. O(1).\n     */\n    function _length(Set storage set) private view returns (uint256) {\n        return set._values.length;\n    }\n\n    /**\n     * @dev Returns the value stored at position `index` in the set. O(1).\n     *\n     * Note that there are no guarantees on the ordering of values inside the\n     * array, and it may change when more values are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function _at(Set storage set, uint256 index) private view returns (bytes32) {\n        return set._values[index];\n    }\n\n    /**\n     * @dev Return the entire set in an array\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function _values(Set storage set) private view returns (bytes32[] memory) {\n        return set._values;\n    }\n\n    // Bytes32Set\n\n    struct Bytes32Set {\n        Set _inner;\n    }\n\n    /**\n     * @dev Add a value to a set. O(1).\n     *\n     * Returns true if the value was added to the set, that is if it was not\n     * already present.\n     */\n    function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n        return _add(set._inner, value);\n    }\n\n    /**\n     * @dev Removes a value from a set. O(1).\n     *\n     * Returns true if the value was removed from the set, that is if it was\n     * present.\n     */\n    function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n        return _remove(set._inner, value);\n    }\n\n    /**\n     * @dev Returns true if the value is in the set. O(1).\n     */\n    function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n        return _contains(set._inner, value);\n    }\n\n    /**\n     * @dev Returns the number of values in the set. O(1).\n     */\n    function length(Bytes32Set storage set) internal view returns (uint256) {\n        return _length(set._inner);\n    }\n\n    /**\n     * @dev Returns the value stored at position `index` in the set. O(1).\n     *\n     * Note that there are no guarantees on the ordering of values inside the\n     * array, and it may change when more values are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n        return _at(set._inner, index);\n    }\n\n    /**\n     * @dev Return the entire set in an array\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n        bytes32[] memory store = _values(set._inner);\n        bytes32[] memory result;\n\n        /// @solidity memory-safe-assembly\n        assembly {\n            result := store\n        }\n\n        return result;\n    }\n\n    // AddressSet\n\n    struct AddressSet {\n        Set _inner;\n    }\n\n    /**\n     * @dev Add a value to a set. O(1).\n     *\n     * Returns true if the value was added to the set, that is if it was not\n     * already present.\n     */\n    function add(AddressSet storage set, address value) internal returns (bool) {\n        return _add(set._inner, bytes32(uint256(uint160(value))));\n    }\n\n    /**\n     * @dev Removes a value from a set. O(1).\n     *\n     * Returns true if the value was removed from the set, that is if it was\n     * present.\n     */\n    function remove(AddressSet storage set, address value) internal returns (bool) {\n        return _remove(set._inner, bytes32(uint256(uint160(value))));\n    }\n\n    /**\n     * @dev Returns true if the value is in the set. O(1).\n     */\n    function contains(AddressSet storage set, address value) internal view returns (bool) {\n        return _contains(set._inner, bytes32(uint256(uint160(value))));\n    }\n\n    /**\n     * @dev Returns the number of values in the set. O(1).\n     */\n    function length(AddressSet storage set) internal view returns (uint256) {\n        return _length(set._inner);\n    }\n\n    /**\n     * @dev Returns the value stored at position `index` in the set. O(1).\n     *\n     * Note that there are no guarantees on the ordering of values inside the\n     * array, and it may change when more values are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function at(AddressSet storage set, uint256 index) internal view returns (address) {\n        return address(uint160(uint256(_at(set._inner, index))));\n    }\n\n    /**\n     * @dev Return the entire set in an array\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function values(AddressSet storage set) internal view returns (address[] memory) {\n        bytes32[] memory store = _values(set._inner);\n        address[] memory result;\n\n        /// @solidity memory-safe-assembly\n        assembly {\n            result := store\n        }\n\n        return result;\n    }\n\n    // UintSet\n\n    struct UintSet {\n        Set _inner;\n    }\n\n    /**\n     * @dev Add a value to a set. O(1).\n     *\n     * Returns true if the value was added to the set, that is if it was not\n     * already present.\n     */\n    function add(UintSet storage set, uint256 value) internal returns (bool) {\n        return _add(set._inner, bytes32(value));\n    }\n\n    /**\n     * @dev Removes a value from a set. O(1).\n     *\n     * Returns true if the value was removed from the set, that is if it was\n     * present.\n     */\n    function remove(UintSet storage set, uint256 value) internal returns (bool) {\n        return _remove(set._inner, bytes32(value));\n    }\n\n    /**\n     * @dev Returns true if the value is in the set. O(1).\n     */\n    function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n        return _contains(set._inner, bytes32(value));\n    }\n\n    /**\n     * @dev Returns the number of values in the set. O(1).\n     */\n    function length(UintSet storage set) internal view returns (uint256) {\n        return _length(set._inner);\n    }\n\n    /**\n     * @dev Returns the value stored at position `index` in the set. O(1).\n     *\n     * Note that there are no guarantees on the ordering of values inside the\n     * array, and it may change when more values are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n        return uint256(_at(set._inner, index));\n    }\n\n    /**\n     * @dev Return the entire set in an array\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function values(UintSet storage set) internal view returns (uint256[] memory) {\n        bytes32[] memory store = _values(set._inner);\n        uint256[] memory result;\n\n        /// @solidity memory-safe-assembly\n        assembly {\n            result := store\n        }\n\n        return result;\n    }\n}\n"
      },
      "src/dollar/libraries/AddressUtils.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.19;\n\nimport {UintUtils} from \"./UintUtils.sol\";\n\n/**\n * @notice Address utils\n * @dev https://github.com/solidstate-network/solidstate-solidity/blob/master/contracts/utils/AddressUtils.sol\n */\nlibrary AddressUtils {\n    using UintUtils for uint256;\n\n    /// @notice Thrown on insufficient balance\n    error AddressUtils__InsufficientBalance();\n\n    /// @notice Thrown when target address has no code\n    error AddressUtils__NotContract();\n\n    /// @notice Thrown when sending ETH failed\n    error AddressUtils__SendValueFailed();\n\n    /**\n     * @notice Converts address to string\n     * @param account Address to convert\n     * @return String representation of `account`\n     */\n    function toString(address account) internal pure returns (string memory) {\n        return uint256(uint160(account)).toHexString(20);\n    }\n\n    /**\n     * @notice Checks whether `account` has code\n     * @dev NOTICE: NOT SAFE, can be circumvented in the `constructor()`\n     * @param account Address to check\n     * @return Whether `account` has code\n     */\n    function isContract(address account) internal view returns (bool) {\n        uint256 size;\n        assembly {\n            size := extcodesize(account)\n        }\n        return size > 0;\n    }\n\n    /**\n     * @notice Sends ETH to `account`\n     * @param account Address where to send ETH\n     * @param amount Amount of ETH to send\n     */\n    function sendValue(address payable account, uint256 amount) internal {\n        (bool success, ) = account.call{value: amount}(\"\");\n        if (!success) revert AddressUtils__SendValueFailed();\n    }\n\n    /**\n     * @notice Calls `target` with `data`\n     * @param target Target address\n     * @param data Data to pass\n     * @return Response bytes\n     */\n    function functionCall(\n        address target,\n        bytes memory data\n    ) internal returns (bytes memory) {\n        return\n            functionCall(target, data, \"AddressUtils: failed low-level call\");\n    }\n\n    /**\n     * @notice Calls `target` with `data`\n     * @param target Target address\n     * @param data Data to pass\n     * @param error Text error\n     * @return Response bytes\n     */\n    function functionCall(\n        address target,\n        bytes memory data,\n        string memory error\n    ) internal returns (bytes memory) {\n        return _functionCallWithValue(target, data, 0, error);\n    }\n\n    /**\n     * @notice Calls `target` with `data`\n     * @param target Target address\n     * @param data Data to pass\n     * @param value Amount of ETH to send\n     * @return Response bytes\n     */\n    function functionCallWithValue(\n        address target,\n        bytes memory data,\n        uint256 value\n    ) internal returns (bytes memory) {\n        return\n            functionCallWithValue(\n                target,\n                data,\n                value,\n                \"AddressUtils: failed low-level call with value\"\n            );\n    }\n\n    /**\n     * @notice Calls `target` with `data`\n     * @param target Target address\n     * @param data Data to pass\n     * @param value Amount of ETH to send\n     * @param error Text error\n     * @return Response bytes\n     */\n    function functionCallWithValue(\n        address target,\n        bytes memory data,\n        uint256 value,\n        string memory error\n    ) internal returns (bytes memory) {\n        if (value > address(this).balance) {\n            revert AddressUtils__InsufficientBalance();\n        }\n        return _functionCallWithValue(target, data, value, error);\n    }\n\n    /**\n     * @notice Calls `target` with `data`\n     * @param target Target address\n     * @param data Data to pass\n     * @param value Amount of ETH to send\n     * @param error Text error\n     * @return Response bytes\n     */\n    function _functionCallWithValue(\n        address target,\n        bytes memory data,\n        uint256 value,\n        string memory error\n    ) private returns (bytes memory) {\n        if (!isContract(target)) revert AddressUtils__NotContract();\n\n        (bool success, bytes memory returnData) = target.call{value: value}(\n            data\n        );\n\n        if (success) {\n            return returnData;\n        } else if (returnData.length > 0) {\n            assembly {\n                let returnData_size := mload(returnData)\n                revert(add(32, returnData), returnData_size)\n            }\n        } else {\n            revert(error);\n        }\n    }\n}\n"
      },
      "src/dollar/libraries/UintUtils.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.19;\n\n/**\n * @title Utility functions for uint256 operations\n * @dev Derived from https://github.com/OpenZeppelin/openzeppelin-contracts/ (MIT license)\n * @dev https://github.com/solidstate-network/solidstate-solidity/blob/master/contracts/utils/UintUtils.sol\n */\nlibrary UintUtils {\n    /// @notice Thrown on insufficient hex length in `toHexString()`\n    error UintUtils__InsufficientHexLength();\n\n    /// @notice Hex symbols\n    bytes16 private constant HEX_SYMBOLS = \"0123456789abcdef\";\n\n    /**\n     * @notice Returns the addition of two unsigned integers, reverting on\n     * overflow.\n     *\n     * Counterpart to Solidity's `+` operator.\n     *\n     * Requirements:\n     *\n     * - Addition cannot overflow.\n     */\n    function add(uint256 a, int256 b) internal pure returns (uint256) {\n        return b < 0 ? sub(a, -b) : a + uint256(b);\n    }\n\n    /**\n     * @notice Returns the subtraction of two unsigned integers, reverting on\n     * overflow (when the result is negative).\n     *\n     * Counterpart to Solidity's `-` operator.\n     *\n     * Requirements:\n     *\n     * - Subtraction cannot overflow.\n     */\n    function sub(uint256 a, int256 b) internal pure returns (uint256) {\n        return b < 0 ? add(a, -b) : a - uint256(b);\n    }\n\n    /**\n     * @notice Converts a `uint256` to its ASCII `string` decimal representation.\n     */\n    function toString(uint256 value) internal pure returns (string memory) {\n        if (value == 0) {\n            return \"0\";\n        }\n\n        uint256 temp = value;\n        uint256 digits;\n\n        while (temp != 0) {\n            digits++;\n            temp /= 10;\n        }\n\n        bytes memory buffer = new bytes(digits);\n\n        while (value != 0) {\n            digits -= 1;\n            buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n            value /= 10;\n        }\n\n        return string(buffer);\n    }\n\n    /**\n     * @notice Converts a `uint256` to its ASCII `string` decimal representation.\n     */\n    function toHexString(uint256 value) internal pure returns (string memory) {\n        if (value == 0) {\n            return \"0x00\";\n        }\n\n        uint256 length = 0;\n\n        for (uint256 temp = value; temp != 0; temp >>= 8) {\n            unchecked {\n                length++;\n            }\n        }\n\n        return toHexString(value, length);\n    }\n\n    /**\n     * @notice Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n     */\n    function toHexString(\n        uint256 value,\n        uint256 length\n    ) internal pure returns (string memory) {\n        bytes memory buffer = new bytes(2 * length + 2);\n        buffer[0] = \"0\";\n        buffer[1] = \"x\";\n\n        unchecked {\n            for (uint256 i = 2 * length + 1; i > 1; --i) {\n                buffer[i] = HEX_SYMBOLS[value & 0xf];\n                value >>= 4;\n            }\n        }\n\n        if (value != 0) revert UintUtils__InsufficientHexLength();\n\n        return string(buffer);\n    }\n}\n"
      },
      "src/dollar/interfaces/IDiamondCut.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.19;\n\n/// @notice Interface that allows modifications to diamond function selector mapping\ninterface IDiamondCut {\n    /**\n     * @notice Available diamond operations\n     * @dev Add=0, Replace=1, Remove=2\n     */\n    enum FacetCutAction {\n        Add,\n        Replace,\n        Remove\n    }\n\n    /// @notice Struct used as a mapping of facet to function selectors\n    struct FacetCut {\n        address facetAddress;\n        FacetCutAction action;\n        bytes4[] functionSelectors;\n    }\n\n    /**\n     * @notice Add/replace/remove any number of functions and optionally execute a function with delegatecall\n     * @param _diamondCut Contains the facet addresses and function selectors\n     * @param _init The address of the contract or facet to execute _calldata\n     * @param _calldata A function call, including function selector and arguments\n     * @dev `_calldata` is executed with delegatecall on `_init`\n     */\n    function diamondCut(\n        FacetCut[] calldata _diamondCut,\n        address _init,\n        bytes calldata _calldata\n    ) external;\n\n    /// @notice Emitted when facet selectors are modified\n    event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\n}\n"
      },
      "src/dollar/interfaces/IDiamondLoupe.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.19;\n\n/**\n * @notice A loupe is a small magnifying glass used to look at diamonds.\n * These functions look at diamonds.\n * @dev These functions are expected to be called frequently by 3rd party tools.\n */\ninterface IDiamondLoupe {\n    /// @notice Struct used as a mapping of facet to function selectors\n    struct Facet {\n        address facetAddress;\n        bytes4[] functionSelectors;\n    }\n\n    /**\n     * @notice Returns all facet addresses and their four byte function selectors\n     * @return facets_ Facets with function selectors\n     */\n    function facets() external view returns (Facet[] memory facets_);\n\n    /**\n     * @notice Returns all function selectors supported by a specific facet\n     * @param _facet Facet address\n     * @return facetFunctionSelectors_ Function selectors for a particular facet\n     */\n    function facetFunctionSelectors(\n        address _facet\n    ) external view returns (bytes4[] memory facetFunctionSelectors_);\n\n    /**\n     * @notice Returns all facet addresses used by a diamond\n     * @return facetAddresses_ Facet addresses in a diamond\n     */\n    function facetAddresses()\n        external\n        view\n        returns (address[] memory facetAddresses_);\n\n    /**\n     * @notice Returns the facet that supports the given selector\n     * @dev If facet is not found returns `address(0)`\n     * @param _functionSelector Function selector\n     * @return facetAddress_ Facet address\n     */\n    function facetAddress(\n        bytes4 _functionSelector\n    ) external view returns (address facetAddress_);\n}\n"
      },
      "lib/openzeppelin-contracts/contracts/interfaces/IERC165.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/introspection/IERC165.sol\";\n"
      },
      "src/dollar/interfaces/IERC173.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.19;\n\n/**\n * @notice ERC-173 Contract Ownership Standard\n * @dev ERC-165 identifier for this interface is 0x7f5828d0\n */\ninterface IERC173 {\n    /// @notice Emits when ownership of a contract changes\n    event OwnershipTransferred(\n        address indexed previousOwner,\n        address indexed newOwner\n    );\n\n    /**\n     * @notice Returns owner's address\n     * @return owner_ Owner address\n     */\n    function owner() external view returns (address owner_);\n\n    /**\n     * @notice Sets contract's owner to a new address\n     * @dev Set _newOwner to address(0) to renounce any ownership\n     * @param _newOwner The address of the new owner of the contract\n     */\n    function transferOwnership(address _newOwner) external;\n}\n"
      },
      "lib/abdk-libraries-solidity/ABDKMathQuad.sol": {
        "content": "// SPDX-License-Identifier: BSD-4-Clause\n/*\n * ABDK Math Quad Smart Contract Library.  Copyright © 2019 by ABDK Consulting.\n * Author: Mikhail Vladimirov <mikhail.vladimirov@gmail.com>\n */\npragma solidity ^0.8.0;\n\n/**\n * Smart contract library of mathematical functions operating with IEEE 754\n * quadruple-precision binary floating-point numbers (quadruple precision\n * numbers).  As long as quadruple precision numbers are 16-bytes long, they are\n * represented by bytes16 type.\n */\nlibrary ABDKMathQuad {\n  /*\n   * 0.\n   */\n  bytes16 private constant POSITIVE_ZERO = 0x00000000000000000000000000000000;\n\n  /*\n   * -0.\n   */\n  bytes16 private constant NEGATIVE_ZERO = 0x80000000000000000000000000000000;\n\n  /*\n   * +Infinity.\n   */\n  bytes16 private constant POSITIVE_INFINITY = 0x7FFF0000000000000000000000000000;\n\n  /*\n   * -Infinity.\n   */\n  bytes16 private constant NEGATIVE_INFINITY = 0xFFFF0000000000000000000000000000;\n\n  /*\n   * Canonical NaN value.\n   */\n  bytes16 private constant NaN = 0x7FFF8000000000000000000000000000;\n\n  /**\n   * Convert signed 256-bit integer number into quadruple precision number.\n   *\n   * @param x signed 256-bit integer number\n   * @return quadruple precision number\n   */\n  function fromInt (int256 x) internal pure returns (bytes16) {\n    unchecked {\n      if (x == 0) return bytes16 (0);\n      else {\n        // We rely on overflow behavior here\n        uint256 result = uint256 (x > 0 ? x : -x);\n\n        uint256 msb = mostSignificantBit (result);\n        if (msb < 112) result <<= 112 - msb;\n        else if (msb > 112) result >>= msb - 112;\n\n        result = result & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF | 16383 + msb << 112;\n        if (x < 0) result |= 0x80000000000000000000000000000000;\n\n        return bytes16 (uint128 (result));\n      }\n    }\n  }\n\n  /**\n   * Convert quadruple precision number into signed 256-bit integer number\n   * rounding towards zero.  Revert on overflow.\n   *\n   * @param x quadruple precision number\n   * @return signed 256-bit integer number\n   */\n  function toInt (bytes16 x) internal pure returns (int256) {\n    unchecked {\n      uint256 exponent = uint128 (x) >> 112 & 0x7FFF;\n\n      require (exponent <= 16638); // Overflow\n      if (exponent < 16383) return 0; // Underflow\n\n      uint256 result = uint256 (uint128 (x)) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF |\n        0x10000000000000000000000000000;\n\n      if (exponent < 16495) result >>= 16495 - exponent;\n      else if (exponent > 16495) result <<= exponent - 16495;\n\n      if (uint128 (x) >= 0x80000000000000000000000000000000) { // Negative\n        require (result <= 0x8000000000000000000000000000000000000000000000000000000000000000);\n        return -int256 (result); // We rely on overflow behavior here\n      } else {\n        require (result <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);\n        return int256 (result);\n      }\n    }\n  }\n\n  /**\n   * Convert unsigned 256-bit integer number into quadruple precision number.\n   *\n   * @param x unsigned 256-bit integer number\n   * @return quadruple precision number\n   */\n  function fromUInt (uint256 x) internal pure returns (bytes16) {\n    unchecked {\n      if (x == 0) return bytes16 (0);\n      else {\n        uint256 result = x;\n\n        uint256 msb = mostSignificantBit (result);\n        if (msb < 112) result <<= 112 - msb;\n        else if (msb > 112) result >>= msb - 112;\n\n        result = result & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF | 16383 + msb << 112;\n\n        return bytes16 (uint128 (result));\n      }\n    }\n  }\n\n  /**\n   * Convert quadruple precision number into unsigned 256-bit integer number\n   * rounding towards zero.  Revert on underflow.  Note, that negative floating\n   * point numbers in range (-1.0 .. 0.0) may be converted to unsigned integer\n   * without error, because they are rounded to zero.\n   *\n   * @param x quadruple precision number\n   * @return unsigned 256-bit integer number\n   */\n  function toUInt (bytes16 x) internal pure returns (uint256) {\n    unchecked {\n      uint256 exponent = uint128 (x) >> 112 & 0x7FFF;\n\n      if (exponent < 16383) return 0; // Underflow\n\n      require (uint128 (x) < 0x80000000000000000000000000000000); // Negative\n\n      require (exponent <= 16638); // Overflow\n      uint256 result = uint256 (uint128 (x)) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF |\n        0x10000000000000000000000000000;\n\n      if (exponent < 16495) result >>= 16495 - exponent;\n      else if (exponent > 16495) result <<= exponent - 16495;\n\n      return result;\n    }\n  }\n\n  /**\n   * Convert signed 128.128 bit fixed point number into quadruple precision\n   * number.\n   *\n   * @param x signed 128.128 bit fixed point number\n   * @return quadruple precision number\n   */\n  function from128x128 (int256 x) internal pure returns (bytes16) {\n    unchecked {\n      if (x == 0) return bytes16 (0);\n      else {\n        // We rely on overflow behavior here\n        uint256 result = uint256 (x > 0 ? x : -x);\n\n        uint256 msb = mostSignificantBit (result);\n        if (msb < 112) result <<= 112 - msb;\n        else if (msb > 112) result >>= msb - 112;\n\n        result = result & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF | 16255 + msb << 112;\n        if (x < 0) result |= 0x80000000000000000000000000000000;\n\n        return bytes16 (uint128 (result));\n      }\n    }\n  }\n\n  /**\n   * Convert quadruple precision number into signed 128.128 bit fixed point\n   * number.  Revert on overflow.\n   *\n   * @param x quadruple precision number\n   * @return signed 128.128 bit fixed point number\n   */\n  function to128x128 (bytes16 x) internal pure returns (int256) {\n    unchecked {\n      uint256 exponent = uint128 (x) >> 112 & 0x7FFF;\n\n      require (exponent <= 16510); // Overflow\n      if (exponent < 16255) return 0; // Underflow\n\n      uint256 result = uint256 (uint128 (x)) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF |\n        0x10000000000000000000000000000;\n\n      if (exponent < 16367) result >>= 16367 - exponent;\n      else if (exponent > 16367) result <<= exponent - 16367;\n\n      if (uint128 (x) >= 0x80000000000000000000000000000000) { // Negative\n        require (result <= 0x8000000000000000000000000000000000000000000000000000000000000000);\n        return -int256 (result); // We rely on overflow behavior here\n      } else {\n        require (result <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);\n        return int256 (result);\n      }\n    }\n  }\n\n  /**\n   * Convert signed 64.64 bit fixed point number into quadruple precision\n   * number.\n   *\n   * @param x signed 64.64 bit fixed point number\n   * @return quadruple precision number\n   */\n  function from64x64 (int128 x) internal pure returns (bytes16) {\n    unchecked {\n      if (x == 0) return bytes16 (0);\n      else {\n        // We rely on overflow behavior here\n        uint256 result = uint128 (x > 0 ? x : -x);\n\n        uint256 msb = mostSignificantBit (result);\n        if (msb < 112) result <<= 112 - msb;\n        else if (msb > 112) result >>= msb - 112;\n\n        result = result & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF | 16319 + msb << 112;\n        if (x < 0) result |= 0x80000000000000000000000000000000;\n\n        return bytes16 (uint128 (result));\n      }\n    }\n  }\n\n  /**\n   * Convert quadruple precision number into signed 64.64 bit fixed point\n   * number.  Revert on overflow.\n   *\n   * @param x quadruple precision number\n   * @return signed 64.64 bit fixed point number\n   */\n  function to64x64 (bytes16 x) internal pure returns (int128) {\n    unchecked {\n      uint256 exponent = uint128 (x) >> 112 & 0x7FFF;\n\n      require (exponent <= 16446); // Overflow\n      if (exponent < 16319) return 0; // Underflow\n\n      uint256 result = uint256 (uint128 (x)) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF |\n        0x10000000000000000000000000000;\n\n      if (exponent < 16431) result >>= 16431 - exponent;\n      else if (exponent > 16431) result <<= exponent - 16431;\n\n      if (uint128 (x) >= 0x80000000000000000000000000000000) { // Negative\n        require (result <= 0x80000000000000000000000000000000);\n        return -int128 (int256 (result)); // We rely on overflow behavior here\n      } else {\n        require (result <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);\n        return int128 (int256 (result));\n      }\n    }\n  }\n\n  /**\n   * Convert octuple precision number into quadruple precision number.\n   *\n   * @param x octuple precision number\n   * @return quadruple precision number\n   */\n  function fromOctuple (bytes32 x) internal pure returns (bytes16) {\n    unchecked {\n      bool negative = x & 0x8000000000000000000000000000000000000000000000000000000000000000 > 0;\n\n      uint256 exponent = uint256 (x) >> 236 & 0x7FFFF;\n      uint256 significand = uint256 (x) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;\n\n      if (exponent == 0x7FFFF) {\n        if (significand > 0) return NaN;\n        else return negative ? NEGATIVE_INFINITY : POSITIVE_INFINITY;\n      }\n\n      if (exponent > 278526)\n        return negative ? NEGATIVE_INFINITY : POSITIVE_INFINITY;\n      else if (exponent < 245649)\n        return negative ? NEGATIVE_ZERO : POSITIVE_ZERO;\n      else if (exponent < 245761) {\n        significand = (significand | 0x100000000000000000000000000000000000000000000000000000000000) >> 245885 - exponent;\n        exponent = 0;\n      } else {\n        significand >>= 124;\n        exponent -= 245760;\n      }\n\n      uint128 result = uint128 (significand | exponent << 112);\n      if (negative) result |= 0x80000000000000000000000000000000;\n\n      return bytes16 (result);\n    }\n  }\n\n  /**\n   * Convert quadruple precision number into octuple precision number.\n   *\n   * @param x quadruple precision number\n   * @return octuple precision number\n   */\n  function toOctuple (bytes16 x) internal pure returns (bytes32) {\n    unchecked {\n      uint256 exponent = uint128 (x) >> 112 & 0x7FFF;\n\n      uint256 result = uint128 (x) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF;\n\n      if (exponent == 0x7FFF) exponent = 0x7FFFF; // Infinity or NaN\n      else if (exponent == 0) {\n        if (result > 0) {\n          uint256 msb = mostSignificantBit (result);\n          result = result << 236 - msb & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;\n          exponent = 245649 + msb;\n        }\n      } else {\n        result <<= 124;\n        exponent += 245760;\n      }\n\n      result |= exponent << 236;\n      if (uint128 (x) >= 0x80000000000000000000000000000000)\n        result |= 0x8000000000000000000000000000000000000000000000000000000000000000;\n\n      return bytes32 (result);\n    }\n  }\n\n  /**\n   * Convert double precision number into quadruple precision number.\n   *\n   * @param x double precision number\n   * @return quadruple precision number\n   */\n  function fromDouble (bytes8 x) internal pure returns (bytes16) {\n    unchecked {\n      uint256 exponent = uint64 (x) >> 52 & 0x7FF;\n\n      uint256 result = uint64 (x) & 0xFFFFFFFFFFFFF;\n\n      if (exponent == 0x7FF) exponent = 0x7FFF; // Infinity or NaN\n      else if (exponent == 0) {\n        if (result > 0) {\n          uint256 msb = mostSignificantBit (result);\n          result = result << 112 - msb & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF;\n          exponent = 15309 + msb;\n        }\n      } else {\n        result <<= 60;\n        exponent += 15360;\n      }\n\n      result |= exponent << 112;\n      if (x & 0x8000000000000000 > 0)\n        result |= 0x80000000000000000000000000000000;\n\n      return bytes16 (uint128 (result));\n    }\n  }\n\n  /**\n   * Convert quadruple precision number into double precision number.\n   *\n   * @param x quadruple precision number\n   * @return double precision number\n   */\n  function toDouble (bytes16 x) internal pure returns (bytes8) {\n    unchecked {\n      bool negative = uint128 (x) >= 0x80000000000000000000000000000000;\n\n      uint256 exponent = uint128 (x) >> 112 & 0x7FFF;\n      uint256 significand = uint128 (x) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF;\n\n      if (exponent == 0x7FFF) {\n        if (significand > 0) return 0x7FF8000000000000; // NaN\n        else return negative ?\n            bytes8 (0xFFF0000000000000) : // -Infinity\n            bytes8 (0x7FF0000000000000); // Infinity\n      }\n\n      if (exponent > 17406)\n        return negative ?\n            bytes8 (0xFFF0000000000000) : // -Infinity\n            bytes8 (0x7FF0000000000000); // Infinity\n      else if (exponent < 15309)\n        return negative ?\n            bytes8 (0x8000000000000000) : // -0\n            bytes8 (0x0000000000000000); // 0\n      else if (exponent < 15361) {\n        significand = (significand | 0x10000000000000000000000000000) >> 15421 - exponent;\n        exponent = 0;\n      } else {\n        significand >>= 60;\n        exponent -= 15360;\n      }\n\n      uint64 result = uint64 (significand | exponent << 52);\n      if (negative) result |= 0x8000000000000000;\n\n      return bytes8 (result);\n    }\n  }\n\n  /**\n   * Test whether given quadruple precision number is NaN.\n   *\n   * @param x quadruple precision number\n   * @return true if x is NaN, false otherwise\n   */\n  function isNaN (bytes16 x) internal pure returns (bool) {\n    unchecked {\n      return uint128 (x) & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF >\n        0x7FFF0000000000000000000000000000;\n    }\n  }\n\n  /**\n   * Test whether given quadruple precision number is positive or negative\n   * infinity.\n   *\n   * @param x quadruple precision number\n   * @return true if x is positive or negative infinity, false otherwise\n   */\n  function isInfinity (bytes16 x) internal pure returns (bool) {\n    unchecked {\n      return uint128 (x) & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ==\n        0x7FFF0000000000000000000000000000;\n    }\n  }\n\n  /**\n   * Calculate sign of x, i.e. -1 if x is negative, 0 if x if zero, and 1 if x\n   * is positive.  Note that sign (-0) is zero.  Revert if x is NaN. \n   *\n   * @param x quadruple precision number\n   * @return sign of x\n   */\n  function sign (bytes16 x) internal pure returns (int8) {\n    unchecked {\n      uint128 absoluteX = uint128 (x) & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;\n\n      require (absoluteX <= 0x7FFF0000000000000000000000000000); // Not NaN\n\n      if (absoluteX == 0) return 0;\n      else if (uint128 (x) >= 0x80000000000000000000000000000000) return -1;\n      else return 1;\n    }\n  }\n\n  /**\n   * Calculate sign (x - y).  Revert if either argument is NaN, or both\n   * arguments are infinities of the same sign. \n   *\n   * @param x quadruple precision number\n   * @param y quadruple precision number\n   * @return sign (x - y)\n   */\n  function cmp (bytes16 x, bytes16 y) internal pure returns (int8) {\n    unchecked {\n      uint128 absoluteX = uint128 (x) & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;\n\n      require (absoluteX <= 0x7FFF0000000000000000000000000000); // Not NaN\n\n      uint128 absoluteY = uint128 (y) & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;\n\n      require (absoluteY <= 0x7FFF0000000000000000000000000000); // Not NaN\n\n      // Not infinities of the same sign\n      require (x != y || absoluteX < 0x7FFF0000000000000000000000000000);\n\n      if (x == y) return 0;\n      else {\n        bool negativeX = uint128 (x) >= 0x80000000000000000000000000000000;\n        bool negativeY = uint128 (y) >= 0x80000000000000000000000000000000;\n\n        if (negativeX) {\n          if (negativeY) return absoluteX > absoluteY ? -1 : int8 (1);\n          else return -1; \n        } else {\n          if (negativeY) return 1;\n          else return absoluteX > absoluteY ? int8 (1) : -1;\n        }\n      }\n    }\n  }\n\n  /**\n   * Test whether x equals y.  NaN, infinity, and -infinity are not equal to\n   * anything. \n   *\n   * @param x quadruple precision number\n   * @param y quadruple precision number\n   * @return true if x equals to y, false otherwise\n   */\n  function eq (bytes16 x, bytes16 y) internal pure returns (bool) {\n    unchecked {\n      if (x == y) {\n        return uint128 (x) & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF <\n          0x7FFF0000000000000000000000000000;\n      } else return false;\n    }\n  }\n\n  /**\n   * Calculate x + y.  Special values behave in the following way:\n   *\n   * NaN + x = NaN for any x.\n   * Infinity + x = Infinity for any finite x.\n   * -Infinity + x = -Infinity for any finite x.\n   * Infinity + Infinity = Infinity.\n   * -Infinity + -Infinity = -Infinity.\n   * Infinity + -Infinity = -Infinity + Infinity = NaN.\n   *\n   * @param x quadruple precision number\n   * @param y quadruple precision number\n   * @return quadruple precision number\n   */\n  function add (bytes16 x, bytes16 y) internal pure returns (bytes16) {\n    unchecked {\n      uint256 xExponent = uint128 (x) >> 112 & 0x7FFF;\n      uint256 yExponent = uint128 (y) >> 112 & 0x7FFF;\n\n      if (xExponent == 0x7FFF) {\n        if (yExponent == 0x7FFF) { \n          if (x == y) return x;\n          else return NaN;\n        } else return x; \n      } else if (yExponent == 0x7FFF) return y;\n      else {\n        bool xSign = uint128 (x) >= 0x80000000000000000000000000000000;\n        uint256 xSignifier = uint128 (x) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF;\n        if (xExponent == 0) xExponent = 1;\n        else xSignifier |= 0x10000000000000000000000000000;\n\n        bool ySign = uint128 (y) >= 0x80000000000000000000000000000000;\n        uint256 ySignifier = uint128 (y) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF;\n        if (yExponent == 0) yExponent = 1;\n        else ySignifier |= 0x10000000000000000000000000000;\n\n        if (xSignifier == 0) return y == NEGATIVE_ZERO ? POSITIVE_ZERO : y;\n        else if (ySignifier == 0) return x == NEGATIVE_ZERO ? POSITIVE_ZERO : x;\n        else {\n          int256 delta = int256 (xExponent) - int256 (yExponent);\n  \n          if (xSign == ySign) {\n            if (delta > 112) return x;\n            else if (delta > 0) ySignifier >>= uint256 (delta);\n            else if (delta < -112) return y;\n            else if (delta < 0) {\n              xSignifier >>= uint256 (-delta);\n              xExponent = yExponent;\n            }\n  \n            xSignifier += ySignifier;\n  \n            if (xSignifier >= 0x20000000000000000000000000000) {\n              xSignifier >>= 1;\n              xExponent += 1;\n            }\n  \n            if (xExponent == 0x7FFF)\n              return xSign ? NEGATIVE_INFINITY : POSITIVE_INFINITY;\n            else {\n              if (xSignifier < 0x10000000000000000000000000000) xExponent = 0;\n              else xSignifier &= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF;\n  \n              return bytes16 (uint128 (\n                  (xSign ? 0x80000000000000000000000000000000 : 0) |\n                  (xExponent << 112) |\n                  xSignifier)); \n            }\n          } else {\n            if (delta > 0) {\n              xSignifier <<= 1;\n              xExponent -= 1;\n            } else if (delta < 0) {\n              ySignifier <<= 1;\n              xExponent = yExponent - 1;\n            }\n\n            if (delta > 112) ySignifier = 1;\n            else if (delta > 1) ySignifier = (ySignifier - 1 >> uint256 (delta - 1)) + 1;\n            else if (delta < -112) xSignifier = 1;\n            else if (delta < -1) xSignifier = (xSignifier - 1 >> uint256 (-delta - 1)) + 1;\n\n            if (xSignifier >= ySignifier) xSignifier -= ySignifier;\n            else {\n              xSignifier = ySignifier - xSignifier;\n              xSign = ySign;\n            }\n\n            if (xSignifier == 0)\n              return POSITIVE_ZERO;\n\n            uint256 msb = mostSignificantBit (xSignifier);\n\n            if (msb == 113) {\n              xSignifier = xSignifier >> 1 & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF;\n              xExponent += 1;\n            } else if (msb < 112) {\n              uint256 shift = 112 - msb;\n              if (xExponent > shift) {\n                xSignifier = xSignifier << shift & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF;\n                xExponent -= shift;\n              } else {\n                xSignifier <<= xExponent - 1;\n                xExponent = 0;\n              }\n            } else xSignifier &= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF;\n\n            if (xExponent == 0x7FFF)\n              return xSign ? NEGATIVE_INFINITY : POSITIVE_INFINITY;\n            else return bytes16 (uint128 (\n                (xSign ? 0x80000000000000000000000000000000 : 0) |\n                (xExponent << 112) |\n                xSignifier));\n          }\n        }\n      }\n    }\n  }\n\n  /**\n   * Calculate x - y.  Special values behave in the following way:\n   *\n   * NaN - x = NaN for any x.\n   * Infinity - x = Infinity for any finite x.\n   * -Infinity - x = -Infinity for any finite x.\n   * Infinity - -Infinity = Infinity.\n   * -Infinity - Infinity = -Infinity.\n   * Infinity - Infinity = -Infinity - -Infinity = NaN.\n   *\n   * @param x quadruple precision number\n   * @param y quadruple precision number\n   * @return quadruple precision number\n   */\n  function sub (bytes16 x, bytes16 y) internal pure returns (bytes16) {\n    unchecked {\n      return add (x, y ^ 0x80000000000000000000000000000000);\n    }\n  }\n\n  /**\n   * Calculate x * y.  Special values behave in the following way:\n   *\n   * NaN * x = NaN for any x.\n   * Infinity * x = Infinity for any finite positive x.\n   * Infinity * x = -Infinity for any finite negative x.\n   * -Infinity * x = -Infinity for any finite positive x.\n   * -Infinity * x = Infinity for any finite negative x.\n   * Infinity * 0 = NaN.\n   * -Infinity * 0 = NaN.\n   * Infinity * Infinity = Infinity.\n   * Infinity * -Infinity = -Infinity.\n   * -Infinity * Infinity = -Infinity.\n   * -Infinity * -Infinity = Infinity.\n   *\n   * @param x quadruple precision number\n   * @param y quadruple precision number\n   * @return quadruple precision number\n   */\n  function mul (bytes16 x, bytes16 y) internal pure returns (bytes16) {\n    unchecked {\n      uint256 xExponent = uint128 (x) >> 112 & 0x7FFF;\n      uint256 yExponent = uint128 (y) >> 112 & 0x7FFF;\n\n      if (xExponent == 0x7FFF) {\n        if (yExponent == 0x7FFF) {\n          if (x == y) return x ^ y & 0x80000000000000000000000000000000;\n          else if (x ^ y == 0x80000000000000000000000000000000) return x | y;\n          else return NaN;\n        } else {\n          if (y & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0) return NaN;\n          else return x ^ y & 0x80000000000000000000000000000000;\n        }\n      } else if (yExponent == 0x7FFF) {\n          if (x & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0) return NaN;\n          else return y ^ x & 0x80000000000000000000000000000000;\n      } else {\n        uint256 xSignifier = uint128 (x) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF;\n        if (xExponent == 0) xExponent = 1;\n        else xSignifier |= 0x10000000000000000000000000000;\n\n        uint256 ySignifier = uint128 (y) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF;\n        if (yExponent == 0) yExponent = 1;\n        else ySignifier |= 0x10000000000000000000000000000;\n\n        xSignifier *= ySignifier;\n        if (xSignifier == 0)\n          return (x ^ y) & 0x80000000000000000000000000000000 > 0 ?\n              NEGATIVE_ZERO : POSITIVE_ZERO;\n\n        xExponent += yExponent;\n\n        uint256 msb =\n          xSignifier >= 0x200000000000000000000000000000000000000000000000000000000 ? 225 :\n          xSignifier >= 0x100000000000000000000000000000000000000000000000000000000 ? 224 :\n          mostSignificantBit (xSignifier);\n\n        if (xExponent + msb < 16496) { // Underflow\n          xExponent = 0;\n          xSignifier = 0;\n        } else if (xExponent + msb < 16608) { // Subnormal\n          if (xExponent < 16496)\n            xSignifier >>= 16496 - xExponent;\n          else if (xExponent > 16496)\n            xSignifier <<= xExponent - 16496;\n          xExponent = 0;\n        } else if (xExponent + msb > 49373) {\n          xExponent = 0x7FFF;\n          xSignifier = 0;\n        } else {\n          if (msb > 112)\n            xSignifier >>= msb - 112;\n          else if (msb < 112)\n            xSignifier <<= 112 - msb;\n\n          xSignifier &= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF;\n\n          xExponent = xExponent + msb - 16607;\n        }\n\n        return bytes16 (uint128 (uint128 ((x ^ y) & 0x80000000000000000000000000000000) |\n            xExponent << 112 | xSignifier));\n      }\n    }\n  }\n\n  /**\n   * Calculate x / y.  Special values behave in the following way:\n   *\n   * NaN / x = NaN for any x.\n   * x / NaN = NaN for any x.\n   * Infinity / x = Infinity for any finite non-negative x.\n   * Infinity / x = -Infinity for any finite negative x including -0.\n   * -Infinity / x = -Infinity for any finite non-negative x.\n   * -Infinity / x = Infinity for any finite negative x including -0.\n   * x / Infinity = 0 for any finite non-negative x.\n   * x / -Infinity = -0 for any finite non-negative x.\n   * x / Infinity = -0 for any finite non-negative x including -0.\n   * x / -Infinity = 0 for any finite non-negative x including -0.\n   * \n   * Infinity / Infinity = NaN.\n   * Infinity / -Infinity = -NaN.\n   * -Infinity / Infinity = -NaN.\n   * -Infinity / -Infinity = NaN.\n   *\n   * Division by zero behaves in the following way:\n   *\n   * x / 0 = Infinity for any finite positive x.\n   * x / -0 = -Infinity for any finite positive x.\n   * x / 0 = -Infinity for any finite negative x.\n   * x / -0 = Infinity for any finite negative x.\n   * 0 / 0 = NaN.\n   * 0 / -0 = NaN.\n   * -0 / 0 = NaN.\n   * -0 / -0 = NaN.\n   *\n   * @param x quadruple precision number\n   * @param y quadruple precision number\n   * @return quadruple precision number\n   */\n  function div (bytes16 x, bytes16 y) internal pure returns (bytes16) {\n    unchecked {\n      uint256 xExponent = uint128 (x) >> 112 & 0x7FFF;\n      uint256 yExponent = uint128 (y) >> 112 & 0x7FFF;\n\n      if (xExponent == 0x7FFF) {\n        if (yExponent == 0x7FFF) return NaN;\n        else return x ^ y & 0x80000000000000000000000000000000;\n      } else if (yExponent == 0x7FFF) {\n        if (y & 0x0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF != 0) return NaN;\n        else return POSITIVE_ZERO | (x ^ y) & 0x80000000000000000000000000000000;\n      } else if (y & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0) {\n        if (x & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0) return NaN;\n        else return POSITIVE_INFINITY | (x ^ y) & 0x80000000000000000000000000000000;\n      } else {\n        uint256 ySignifier = uint128 (y) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF;\n        if (yExponent == 0) yExponent = 1;\n        else ySignifier |= 0x10000000000000000000000000000;\n\n        uint256 xSignifier = uint128 (x) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF;\n        if (xExponent == 0) {\n          if (xSignifier != 0) {\n            uint shift = 226 - mostSignificantBit (xSignifier);\n\n            xSignifier <<= shift;\n\n            xExponent = 1;\n            yExponent += shift - 114;\n          }\n        }\n        else {\n          xSignifier = (xSignifier | 0x10000000000000000000000000000) << 114;\n        }\n\n        xSignifier = xSignifier / ySignifier;\n        if (xSignifier == 0)\n          return (x ^ y) & 0x80000000000000000000000000000000 > 0 ?\n              NEGATIVE_ZERO : POSITIVE_ZERO;\n\n        assert (xSignifier >= 0x1000000000000000000000000000);\n\n        uint256 msb =\n          xSignifier >= 0x80000000000000000000000000000 ? mostSignificantBit (xSignifier) :\n          xSignifier >= 0x40000000000000000000000000000 ? 114 :\n          xSignifier >= 0x20000000000000000000000000000 ? 113 : 112;\n\n        if (xExponent + msb > yExponent + 16497) { // Overflow\n          xExponent = 0x7FFF;\n          xSignifier = 0;\n        } else if (xExponent + msb + 16380  < yExponent) { // Underflow\n          xExponent = 0;\n          xSignifier = 0;\n        } else if (xExponent + msb + 16268  < yExponent) { // Subnormal\n          if (xExponent + 16380 > yExponent)\n            xSignifier <<= xExponent + 16380 - yExponent;\n          else if (xExponent + 16380 < yExponent)\n            xSignifier >>= yExponent - xExponent - 16380;\n\n          xExponent = 0;\n        } else { // Normal\n          if (msb > 112)\n            xSignifier >>= msb - 112;\n\n          xSignifier &= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF;\n\n          xExponent = xExponent + msb + 16269 - yExponent;\n        }\n\n        return bytes16 (uint128 (uint128 ((x ^ y) & 0x80000000000000000000000000000000) |\n            xExponent << 112 | xSignifier));\n      }\n    }\n  }\n\n  /**\n   * Calculate -x.\n   *\n   * @param x quadruple precision number\n   * @return quadruple precision number\n   */\n  function neg (bytes16 x) internal pure returns (bytes16) {\n    unchecked {\n      return x ^ 0x80000000000000000000000000000000;\n    }\n  }\n\n  /**\n   * Calculate |x|.\n   *\n   * @param x quadruple precision number\n   * @return quadruple precision number\n   */\n  function abs (bytes16 x) internal pure returns (bytes16) {\n    unchecked {\n      return x & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;\n    }\n  }\n\n  /**\n   * Calculate square root of x.  Return NaN on negative x excluding -0.\n   *\n   * @param x quadruple precision number\n   * @return quadruple precision number\n   */\n  function sqrt (bytes16 x) internal pure returns (bytes16) {\n    unchecked {\n      if (uint128 (x) >  0x80000000000000000000000000000000) return NaN;\n      else {\n        uint256 xExponent = uint128 (x) >> 112 & 0x7FFF;\n        if (xExponent == 0x7FFF) return x;\n        else {\n          uint256 xSignifier = uint128 (x) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF;\n          if (xExponent == 0) xExponent = 1;\n          else xSignifier |= 0x10000000000000000000000000000;\n\n          if (xSignifier == 0) return POSITIVE_ZERO;\n\n          bool oddExponent = xExponent & 0x1 == 0;\n          xExponent = xExponent + 16383 >> 1;\n\n          if (oddExponent) {\n            if (xSignifier >= 0x10000000000000000000000000000)\n              xSignifier <<= 113;\n            else {\n              uint256 msb = mostSignificantBit (xSignifier);\n              uint256 shift = (226 - msb) & 0xFE;\n              xSignifier <<= shift;\n              xExponent -= shift - 112 >> 1;\n            }\n          } else {\n            if (xSignifier >= 0x10000000000000000000000000000)\n              xSignifier <<= 112;\n            else {\n              uint256 msb = mostSignificantBit (xSignifier);\n              uint256 shift = (225 - msb) & 0xFE;\n              xSignifier <<= shift;\n              xExponent -= shift - 112 >> 1;\n            }\n          }\n\n          uint256 r = 0x10000000000000000000000000000;\n          r = (r + xSignifier / r) >> 1;\n          r = (r + xSignifier / r) >> 1;\n          r = (r + xSignifier / r) >> 1;\n          r = (r + xSignifier / r) >> 1;\n          r = (r + xSignifier / r) >> 1;\n          r = (r + xSignifier / r) >> 1;\n          r = (r + xSignifier / r) >> 1; // Seven iterations should be enough\n          uint256 r1 = xSignifier / r;\n          if (r1 < r) r = r1;\n\n          return bytes16 (uint128 (xExponent << 112 | r & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF));\n        }\n      }\n    }\n  }\n\n  /**\n   * Calculate binary logarithm of x.  Return NaN on negative x excluding -0.\n   *\n   * @param x quadruple precision number\n   * @return quadruple precision number\n   */\n  function log_2 (bytes16 x) internal pure returns (bytes16) {\n    unchecked {\n      if (uint128 (x) > 0x80000000000000000000000000000000) return NaN;\n      else if (x == 0x3FFF0000000000000000000000000000) return POSITIVE_ZERO; \n      else {\n        uint256 xExponent = uint128 (x) >> 112 & 0x7FFF;\n        if (xExponent == 0x7FFF) return x;\n        else {\n          uint256 xSignifier = uint128 (x) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF;\n          if (xExponent == 0) xExponent = 1;\n          else xSignifier |= 0x10000000000000000000000000000;\n\n          if (xSignifier == 0) return NEGATIVE_INFINITY;\n\n          bool resultNegative;\n          uint256 resultExponent = 16495;\n          uint256 resultSignifier;\n\n          if (xExponent >= 0x3FFF) {\n            resultNegative = false;\n            resultSignifier = xExponent - 0x3FFF;\n            xSignifier <<= 15;\n          } else {\n            resultNegative = true;\n            if (xSignifier >= 0x10000000000000000000000000000) {\n              resultSignifier = 0x3FFE - xExponent;\n              xSignifier <<= 15;\n            } else {\n              uint256 msb = mostSignificantBit (xSignifier);\n              resultSignifier = 16493 - msb;\n              xSignifier <<= 127 - msb;\n            }\n          }\n\n          if (xSignifier == 0x80000000000000000000000000000000) {\n            if (resultNegative) resultSignifier += 1;\n            uint256 shift = 112 - mostSignificantBit (resultSignifier);\n            resultSignifier <<= shift;\n            resultExponent -= shift;\n          } else {\n            uint256 bb = resultNegative ? 1 : 0;\n            while (resultSignifier < 0x10000000000000000000000000000) {\n              resultSignifier <<= 1;\n              resultExponent -= 1;\n  \n              xSignifier *= xSignifier;\n              uint256 b = xSignifier >> 255;\n              resultSignifier += b ^ bb;\n              xSignifier >>= 127 + b;\n            }\n          }\n\n          return bytes16 (uint128 ((resultNegative ? 0x80000000000000000000000000000000 : 0) |\n              resultExponent << 112 | resultSignifier & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF));\n        }\n      }\n    }\n  }\n\n  /**\n   * Calculate natural logarithm of x.  Return NaN on negative x excluding -0.\n   *\n   * @param x quadruple precision number\n   * @return quadruple precision number\n   */\n  function ln (bytes16 x) internal pure returns (bytes16) {\n    unchecked {\n      return mul (log_2 (x), 0x3FFE62E42FEFA39EF35793C7673007E5);\n    }\n  }\n\n  /**\n   * Calculate 2^x.\n   *\n   * @param x quadruple precision number\n   * @return quadruple precision number\n   */\n  function pow_2 (bytes16 x) internal pure returns (bytes16) {\n    unchecked {\n      bool xNegative = uint128 (x) > 0x80000000000000000000000000000000;\n      uint256 xExponent = uint128 (x) >> 112 & 0x7FFF;\n      uint256 xSignifier = uint128 (x) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF;\n\n      if (xExponent == 0x7FFF && xSignifier != 0) return NaN;\n      else if (xExponent > 16397)\n        return xNegative ? POSITIVE_ZERO : POSITIVE_INFINITY;\n      else if (xExponent < 16255)\n        return 0x3FFF0000000000000000000000000000;\n      else {\n        if (xExponent == 0) xExponent = 1;\n        else xSignifier |= 0x10000000000000000000000000000;\n\n        if (xExponent > 16367)\n          xSignifier <<= xExponent - 16367;\n        else if (xExponent < 16367)\n          xSignifier >>= 16367 - xExponent;\n\n        if (xNegative && xSignifier > 0x406E00000000000000000000000000000000)\n          return POSITIVE_ZERO;\n\n        if (!xNegative && xSignifier > 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)\n          return POSITIVE_INFINITY;\n\n        uint256 resultExponent = xSignifier >> 128;\n        xSignifier &= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;\n        if (xNegative && xSignifier != 0) {\n          xSignifier = ~xSignifier;\n          resultExponent += 1;\n        }\n\n        uint256 resultSignifier = 0x80000000000000000000000000000000;\n        if (xSignifier & 0x80000000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x16A09E667F3BCC908B2FB1366EA957D3E >> 128;\n        if (xSignifier & 0x40000000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1306FE0A31B7152DE8D5A46305C85EDEC >> 128;\n        if (xSignifier & 0x20000000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1172B83C7D517ADCDF7C8C50EB14A791F >> 128;\n        if (xSignifier & 0x10000000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x10B5586CF9890F6298B92B71842A98363 >> 128;\n        if (xSignifier & 0x8000000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1059B0D31585743AE7C548EB68CA417FD >> 128;\n        if (xSignifier & 0x4000000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x102C9A3E778060EE6F7CACA4F7A29BDE8 >> 128;\n        if (xSignifier & 0x2000000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x10163DA9FB33356D84A66AE336DCDFA3F >> 128;\n        if (xSignifier & 0x1000000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x100B1AFA5ABCBED6129AB13EC11DC9543 >> 128;\n        if (xSignifier & 0x800000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x10058C86DA1C09EA1FF19D294CF2F679B >> 128;\n        if (xSignifier & 0x400000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1002C605E2E8CEC506D21BFC89A23A00F >> 128;\n        if (xSignifier & 0x200000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x100162F3904051FA128BCA9C55C31E5DF >> 128;\n        if (xSignifier & 0x100000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000B175EFFDC76BA38E31671CA939725 >> 128;\n        if (xSignifier & 0x80000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x100058BA01FB9F96D6CACD4B180917C3D >> 128;\n        if (xSignifier & 0x40000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x10002C5CC37DA9491D0985C348C68E7B3 >> 128;\n        if (xSignifier & 0x20000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000162E525EE054754457D5995292026 >> 128;\n        if (xSignifier & 0x10000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x10000B17255775C040618BF4A4ADE83FC >> 128;\n        if (xSignifier & 0x8000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000058B91B5BC9AE2EED81E9B7D4CFAB >> 128;\n        if (xSignifier & 0x4000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x100002C5C89D5EC6CA4D7C8ACC017B7C9 >> 128;\n        if (xSignifier & 0x2000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x10000162E43F4F831060E02D839A9D16D >> 128;\n        if (xSignifier & 0x1000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x100000B1721BCFC99D9F890EA06911763 >> 128;\n        if (xSignifier & 0x800000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x10000058B90CF1E6D97F9CA14DBCC1628 >> 128;\n        if (xSignifier & 0x400000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000002C5C863B73F016468F6BAC5CA2B >> 128;\n        if (xSignifier & 0x200000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x100000162E430E5A18F6119E3C02282A5 >> 128;\n        if (xSignifier & 0x100000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000B1721835514B86E6D96EFD1BFE >> 128;\n        if (xSignifier & 0x80000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x100000058B90C0B48C6BE5DF846C5B2EF >> 128;\n        if (xSignifier & 0x40000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x10000002C5C8601CC6B9E94213C72737A >> 128;\n        if (xSignifier & 0x20000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000162E42FFF037DF38AA2B219F06 >> 128;\n        if (xSignifier & 0x10000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x10000000B17217FBA9C739AA5819F44F9 >> 128;\n        if (xSignifier & 0x8000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000058B90BFCDEE5ACD3C1CEDC823 >> 128;\n        if (xSignifier & 0x4000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x100000002C5C85FE31F35A6A30DA1BE50 >> 128;\n        if (xSignifier & 0x2000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x10000000162E42FF0999CE3541B9FFFCF >> 128;\n        if (xSignifier & 0x1000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x100000000B17217F80F4EF5AADDA45554 >> 128;\n        if (xSignifier & 0x800000000000000000000000 > 0) resultSignifier = resultSignifier * 0x10000000058B90BFBF8479BD5A81B51AD >> 128;\n        if (xSignifier & 0x400000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000002C5C85FDF84BD62AE30A74CC >> 128;\n        if (xSignifier & 0x200000000000000000000000 > 0) resultSignifier = resultSignifier * 0x100000000162E42FEFB2FED257559BDAA >> 128;\n        if (xSignifier & 0x100000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000B17217F7D5A7716BBA4A9AE >> 128;\n        if (xSignifier & 0x80000000000000000000000 > 0) resultSignifier = resultSignifier * 0x100000000058B90BFBE9DDBAC5E109CCE >> 128;\n        if (xSignifier & 0x40000000000000000000000 > 0) resultSignifier = resultSignifier * 0x10000000002C5C85FDF4B15DE6F17EB0D >> 128;\n        if (xSignifier & 0x20000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000162E42FEFA494F1478FDE05 >> 128;\n        if (xSignifier & 0x10000000000000000000000 > 0) resultSignifier = resultSignifier * 0x10000000000B17217F7D20CF927C8E94C >> 128;\n        if (xSignifier & 0x8000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000058B90BFBE8F71CB4E4B33D >> 128;\n        if (xSignifier & 0x4000000000000000000000 > 0) resultSignifier = resultSignifier * 0x100000000002C5C85FDF477B662B26945 >> 128;\n        if (xSignifier & 0x2000000000000000000000 > 0) resultSignifier = resultSignifier * 0x10000000000162E42FEFA3AE53369388C >> 128;\n        if (xSignifier & 0x1000000000000000000000 > 0) resultSignifier = resultSignifier * 0x100000000000B17217F7D1D351A389D40 >> 128;\n        if (xSignifier & 0x800000000000000000000 > 0) resultSignifier = resultSignifier * 0x10000000000058B90BFBE8E8B2D3D4EDE >> 128;\n        if (xSignifier & 0x400000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000002C5C85FDF4741BEA6E77E >> 128;\n        if (xSignifier & 0x200000000000000000000 > 0) resultSignifier = resultSignifier * 0x100000000000162E42FEFA39FE95583C2 >> 128;\n        if (xSignifier & 0x100000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000B17217F7D1CFB72B45E1 >> 128;\n        if (xSignifier & 0x80000000000000000000 > 0) resultSignifier = resultSignifier * 0x100000000000058B90BFBE8E7CC35C3F0 >> 128;\n        if (xSignifier & 0x40000000000000000000 > 0) resultSignifier = resultSignifier * 0x10000000000002C5C85FDF473E242EA38 >> 128;\n        if (xSignifier & 0x20000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000162E42FEFA39F02B772C >> 128;\n        if (xSignifier & 0x10000000000000000000 > 0) resultSignifier = resultSignifier * 0x10000000000000B17217F7D1CF7D83C1A >> 128;\n        if (xSignifier & 0x8000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000058B90BFBE8E7BDCBE2E >> 128;\n        if (xSignifier & 0x4000000000000000000 > 0) resultSignifier = resultSignifier * 0x100000000000002C5C85FDF473DEA871F >> 128;\n        if (xSignifier & 0x2000000000000000000 > 0) resultSignifier = resultSignifier * 0x10000000000000162E42FEFA39EF44D91 >> 128;\n        if (xSignifier & 0x1000000000000000000 > 0) resultSignifier = resultSignifier * 0x100000000000000B17217F7D1CF79E949 >> 128;\n        if (xSignifier & 0x800000000000000000 > 0) resultSignifier = resultSignifier * 0x10000000000000058B90BFBE8E7BCE544 >> 128;\n        if (xSignifier & 0x400000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000002C5C85FDF473DE6ECA >> 128;\n        if (xSignifier & 0x200000000000000000 > 0) resultSignifier = resultSignifier * 0x100000000000000162E42FEFA39EF366F >> 128;\n        if (xSignifier & 0x100000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000B17217F7D1CF79AFA >> 128;\n        if (xSignifier & 0x80000000000000000 > 0) resultSignifier = resultSignifier * 0x100000000000000058B90BFBE8E7BCD6D >> 128;\n        if (xSignifier & 0x40000000000000000 > 0) resultSignifier = resultSignifier * 0x10000000000000002C5C85FDF473DE6B2 >> 128;\n        if (xSignifier & 0x20000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000162E42FEFA39EF358 >> 128;\n        if (xSignifier & 0x10000000000000000 > 0) resultSignifier = resultSignifier * 0x10000000000000000B17217F7D1CF79AB >> 128;\n        if (xSignifier & 0x8000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000058B90BFBE8E7BCD5 >> 128;\n        if (xSignifier & 0x4000000000000000 > 0) resultSignifier = resultSignifier * 0x100000000000000002C5C85FDF473DE6A >> 128;\n        if (xSignifier & 0x2000000000000000 > 0) resultSignifier = resultSignifier * 0x10000000000000000162E42FEFA39EF34 >> 128;\n        if (xSignifier & 0x1000000000000000 > 0) resultSignifier = resultSignifier * 0x100000000000000000B17217F7D1CF799 >> 128;\n        if (xSignifier & 0x800000000000000 > 0) resultSignifier = resultSignifier * 0x10000000000000000058B90BFBE8E7BCC >> 128;\n        if (xSignifier & 0x400000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000002C5C85FDF473DE5 >> 128;\n        if (xSignifier & 0x200000000000000 > 0) resultSignifier = resultSignifier * 0x100000000000000000162E42FEFA39EF2 >> 128;\n        if (xSignifier & 0x100000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000B17217F7D1CF78 >> 128;\n        if (xSignifier & 0x80000000000000 > 0) resultSignifier = resultSignifier * 0x100000000000000000058B90BFBE8E7BB >> 128;\n        if (xSignifier & 0x40000000000000 > 0) resultSignifier = resultSignifier * 0x10000000000000000002C5C85FDF473DD >> 128;\n        if (xSignifier & 0x20000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000162E42FEFA39EE >> 128;\n        if (xSignifier & 0x10000000000000 > 0) resultSignifier = resultSignifier * 0x10000000000000000000B17217F7D1CF6 >> 128;\n        if (xSignifier & 0x8000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000058B90BFBE8E7A >> 128;\n        if (xSignifier & 0x4000000000000 > 0) resultSignifier = resultSignifier * 0x100000000000000000002C5C85FDF473C >> 128;\n        if (xSignifier & 0x2000000000000 > 0) resultSignifier = resultSignifier * 0x10000000000000000000162E42FEFA39D >> 128;\n        if (xSignifier & 0x1000000000000 > 0) resultSignifier = resultSignifier * 0x100000000000000000000B17217F7D1CE >> 128;\n        if (xSignifier & 0x800000000000 > 0) resultSignifier = resultSignifier * 0x10000000000000000000058B90BFBE8E6 >> 128;\n        if (xSignifier & 0x400000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000002C5C85FDF472 >> 128;\n        if (xSignifier & 0x200000000000 > 0) resultSignifier = resultSignifier * 0x100000000000000000000162E42FEFA38 >> 128;\n        if (xSignifier & 0x100000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000000B17217F7D1B >> 128;\n        if (xSignifier & 0x80000000000 > 0) resultSignifier = resultSignifier * 0x100000000000000000000058B90BFBE8D >> 128;\n        if (xSignifier & 0x40000000000 > 0) resultSignifier = resultSignifier * 0x10000000000000000000002C5C85FDF46 >> 128;\n        if (xSignifier & 0x20000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000000162E42FEFA2 >> 128;\n        if (xSignifier & 0x10000000000 > 0) resultSignifier = resultSignifier * 0x10000000000000000000000B17217F7D0 >> 128;\n        if (xSignifier & 0x8000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000000058B90BFBE7 >> 128;\n        if (xSignifier & 0x4000000000 > 0) resultSignifier = resultSignifier * 0x100000000000000000000002C5C85FDF3 >> 128;\n        if (xSignifier & 0x2000000000 > 0) resultSignifier = resultSignifier * 0x10000000000000000000000162E42FEF9 >> 128;\n        if (xSignifier & 0x1000000000 > 0) resultSignifier = resultSignifier * 0x100000000000000000000000B17217F7C >> 128;\n        if (xSignifier & 0x800000000 > 0) resultSignifier = resultSignifier * 0x10000000000000000000000058B90BFBD >> 128;\n        if (xSignifier & 0x400000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000000002C5C85FDE >> 128;\n        if (xSignifier & 0x200000000 > 0) resultSignifier = resultSignifier * 0x100000000000000000000000162E42FEE >> 128;\n        if (xSignifier & 0x100000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000000000B17217F6 >> 128;\n        if (xSignifier & 0x80000000 > 0) resultSignifier = resultSignifier * 0x100000000000000000000000058B90BFA >> 128;\n        if (xSignifier & 0x40000000 > 0) resultSignifier = resultSignifier * 0x10000000000000000000000002C5C85FC >> 128;\n        if (xSignifier & 0x20000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000000000162E42FD >> 128;\n        if (xSignifier & 0x10000000 > 0) resultSignifier = resultSignifier * 0x10000000000000000000000000B17217E >> 128;\n        if (xSignifier & 0x8000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000000000058B90BE >> 128;\n        if (xSignifier & 0x4000000 > 0) resultSignifier = resultSignifier * 0x100000000000000000000000002C5C85E >> 128;\n        if (xSignifier & 0x2000000 > 0) resultSignifier = resultSignifier * 0x10000000000000000000000000162E42E >> 128;\n        if (xSignifier & 0x1000000 > 0) resultSignifier = resultSignifier * 0x100000000000000000000000000B17216 >> 128;\n        if (xSignifier & 0x800000 > 0) resultSignifier = resultSignifier * 0x10000000000000000000000000058B90A >> 128;\n        if (xSignifier & 0x400000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000000000002C5C84 >> 128;\n        if (xSignifier & 0x200000 > 0) resultSignifier = resultSignifier * 0x100000000000000000000000000162E41 >> 128;\n        if (xSignifier & 0x100000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000000000000B1720 >> 128;\n        if (xSignifier & 0x80000 > 0) resultSignifier = resultSignifier * 0x100000000000000000000000000058B8F >> 128;\n        if (xSignifier & 0x40000 > 0) resultSignifier = resultSignifier * 0x10000000000000000000000000002C5C7 >> 128;\n        if (xSignifier & 0x20000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000000000000162E3 >> 128;\n        if (xSignifier & 0x10000 > 0) resultSignifier = resultSignifier * 0x10000000000000000000000000000B171 >> 128;\n        if (xSignifier & 0x8000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000000000000058B8 >> 128;\n        if (xSignifier & 0x4000 > 0) resultSignifier = resultSignifier * 0x100000000000000000000000000002C5B >> 128;\n        if (xSignifier & 0x2000 > 0) resultSignifier = resultSignifier * 0x10000000000000000000000000000162D >> 128;\n        if (xSignifier & 0x1000 > 0) resultSignifier = resultSignifier * 0x100000000000000000000000000000B16 >> 128;\n        if (xSignifier & 0x800 > 0) resultSignifier = resultSignifier * 0x10000000000000000000000000000058A >> 128;\n        if (xSignifier & 0x400 > 0) resultSignifier = resultSignifier * 0x1000000000000000000000000000002C4 >> 128;\n        if (xSignifier & 0x200 > 0) resultSignifier = resultSignifier * 0x100000000000000000000000000000161 >> 128;\n        if (xSignifier & 0x100 > 0) resultSignifier = resultSignifier * 0x1000000000000000000000000000000B0 >> 128;\n        if (xSignifier & 0x80 > 0) resultSignifier = resultSignifier * 0x100000000000000000000000000000057 >> 128;\n        if (xSignifier & 0x40 > 0) resultSignifier = resultSignifier * 0x10000000000000000000000000000002B >> 128;\n        if (xSignifier & 0x20 > 0) resultSignifier = resultSignifier * 0x100000000000000000000000000000015 >> 128;\n        if (xSignifier & 0x10 > 0) resultSignifier = resultSignifier * 0x10000000000000000000000000000000A >> 128;\n        if (xSignifier & 0x8 > 0) resultSignifier = resultSignifier * 0x100000000000000000000000000000004 >> 128;\n        if (xSignifier & 0x4 > 0) resultSignifier = resultSignifier * 0x100000000000000000000000000000001 >> 128;\n\n        if (!xNegative) {\n          resultSignifier = resultSignifier >> 15 & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF;\n          resultExponent += 0x3FFF;\n        } else if (resultExponent <= 0x3FFE) {\n          resultSignifier = resultSignifier >> 15 & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF;\n          resultExponent = 0x3FFF - resultExponent;\n        } else {\n          resultSignifier = resultSignifier >> resultExponent - 16367;\n          resultExponent = 0;\n        }\n\n        return bytes16 (uint128 (resultExponent << 112 | resultSignifier));\n      }\n    }\n  }\n\n  /**\n   * Calculate e^x.\n   *\n   * @param x quadruple precision number\n   * @return quadruple precision number\n   */\n  function exp (bytes16 x) internal pure returns (bytes16) {\n    unchecked {\n      return pow_2 (mul (x, 0x3FFF71547652B82FE1777D0FFDA0D23A));\n    }\n  }\n\n  /**\n   * Get index of the most significant non-zero bit in binary representation of\n   * x.  Reverts if x is zero.\n   *\n   * @return index of the most significant non-zero bit in binary representation\n   *         of x\n   */\n  function mostSignificantBit (uint256 x) private pure returns (uint256) {\n    unchecked {\n      require (x > 0);\n\n      uint256 result = 0;\n\n      if (x >= 0x100000000000000000000000000000000) { x >>= 128; result += 128; }\n      if (x >= 0x10000000000000000) { x >>= 64; result += 64; }\n      if (x >= 0x100000000) { x >>= 32; result += 32; }\n      if (x >= 0x10000) { x >>= 16; result += 16; }\n      if (x >= 0x100) { x >>= 8; result += 8; }\n      if (x >= 0x10) { x >>= 4; result += 4; }\n      if (x >= 0x4) { x >>= 2; result += 2; }\n      if (x >= 0x2) result += 1; // No need to shift x anymore\n\n      return result;\n    }\n  }\n}\n"
      },
      "lib/openzeppelin-contracts/contracts/token/ERC20/extensions/draft-IERC20Permit.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/draft-IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n// EIP-2612 is Final as of 2022-11-01. This file is deprecated.\n\nimport \"./IERC20Permit.sol\";\n"
      },
      "lib/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n    /**\n     * @dev Returns true if this contract implements the interface defined by\n     * `interfaceId`. See the corresponding\n     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n     * to learn more about how these ids are created.\n     *\n     * This function call must use less than 30 000 gas.\n     */\n    function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n"
      },
      "lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Permit.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20Permit {\n    /**\n     * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n     * given ``owner``'s signed approval.\n     *\n     * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n     * ordering also apply here.\n     *\n     * Emits an {Approval} event.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     * - `deadline` must be a timestamp in the future.\n     * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n     * over the EIP712-formatted function arguments.\n     * - the signature must use ``owner``'s current nonce (see {nonces}).\n     *\n     * For more information on the signature format, see the\n     * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n     * section].\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    ) external;\n\n    /**\n     * @dev Returns the current nonce for `owner`. This value must be\n     * included whenever a signature is generated for {permit}.\n     *\n     * Every successful call to {permit} increases ``owner``'s nonce by one. This\n     * prevents a signature from being used multiple times.\n     */\n    function nonces(address owner) external view returns (uint256);\n\n    /**\n     * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n     */\n    // solhint-disable-next-line func-name-mixedcase\n    function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n"
      }
    },
    "settings": {
      "remappings": [
        "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
        "@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/",
        "forge-std/=lib/forge-std/src/",
        "ds-test/=lib/forge-std/lib/ds-test/src/",
        "solidity-linked-list/=lib/solidity-linked-list/",
        "@uniswap/v2-core/contracts/=lib/Uniswap/v2-core/contracts/",
        "@uniswap/v2-periphery/contracts/=lib/Uniswap/v2-periphery/contracts/",
        "@uniswap/v3-periphery/contracts/=lib/Uniswap/v3-periphery/contracts/",
        "abdk/=lib/abdk-libraries-solidity/",
        "operator-filter-registry/=lib/operator-filter-registry/src/",
        "@chainlink/=lib/chainlink-brownie-contracts/contracts/src/v0.8/",
        "Uniswap/=lib/Uniswap/",
        "abdk-libraries-solidity/=lib/abdk-libraries-solidity/",
        "chainlink-brownie-contracts/=lib/chainlink-brownie-contracts/contracts/src/v0.6/vendor/@arbitrum/nitro-contracts/src/",
        "erc4626-tests/=lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/",
        "openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/",
        "openzeppelin-contracts/=lib/openzeppelin-contracts/",
        "openzeppelin/=lib/openzeppelin-contracts-upgradeable/contracts/"
      ],
      "optimizer": {
        "enabled": true,
        "runs": 20000
      },
      "metadata": {
        "useLiteralContent": false,
        "bytecodeHash": "ipfs",
        "appendCBOR": true
      },
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      },
      "evmVersion": "paris",
      "viaIR": false,
      "libraries": {}
    }
  }}