creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "src/facets/AdminFacet.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.22;\n\n// Interfaces\nimport { IERC20 } from \"@openzeppelin/token/ERC20/IERC20.sol\";\nimport { IAdmin } from \"../interfaces/IAdmin.sol\";\n\n// Contracts\nimport { AugustusStorage } from \"../storage/AugustusStorage.sol\";\n\n// Vendor\nimport { LibDiamond } from \"../vendor/libraries/LibDiamond.sol\";\n\n/// @title AdminFacet\n/// @notice A facet for executing admin functions\ncontract AdminFacet is AugustusStorage, IAdmin {\n    /*//////////////////////////////////////////////////////////////\n                               MODIFIERS\n    //////////////////////////////////////////////////////////////*/\n\n    /// @notice Enforce that the caller is the contract owner\n    modifier onlyOwner() {\n        LibDiamond.enforceIsContractOwner();\n        _;\n    }\n\n    /*//////////////////////////////////////////////////////////////\n                                EXTERNAL\n    //////////////////////////////////////////////////////////////*/\n\n    /// @inheritdoc IAdmin\n    function setFeeWallet(address payable _feeWallet) external onlyOwner {\n        // Make sure the fee wallet is not the zero address\n        if (_feeWallet == address(0)) revert InvalidWalletAddress();\n        // Set the fee wallet\n        feeWallet = _feeWallet;\n        // Emit an event\n        emit FeeWalletUpdated(_feeWallet);\n    }\n\n    /// @inheritdoc IAdmin\n    function setFeeWalletDelegate(address payable _feeWalletDelegate) external onlyOwner {\n        // Make sure the fee wallet is not the zero address\n        if (_feeWalletDelegate == address(0)) revert InvalidWalletAddress();\n        // Set the fee wallet\n        feeWalletDelegate = _feeWalletDelegate;\n        // Emit an event\n        emit FeeWalletDelegateUpdated(_feeWalletDelegate);\n    }\n\n    /// @inheritdoc IAdmin\n    function setTokenBlacklisting(IERC20 token, bool isBlacklisted) public onlyOwner {\n        // Set the blacklisting status\n        blacklistedTokens[token] = isBlacklisted;\n        // Emit an event\n        emit TokenBlacklistUpdated(token, isBlacklisted);\n    }\n\n    /// @inheritdoc IAdmin\n    function batchSetTokenBlacklisting(IERC20[] calldata tokens, bool isBlacklisted) external onlyOwner {\n        // Loop through the tokens\n        for (uint256 i = 0; i < tokens.length; i++) {\n            // Set the blacklisting status\n            setTokenBlacklisting(tokens[i], isBlacklisted);\n        }\n    }\n\n    /// @inheritdoc IAdmin\n    function setContractPauseState(bool _isPaused) external onlyOwner {\n        // Set the pause state\n        paused = _isPaused;\n        // Emit an event\n        emit ContractPauseStateUpdated(_isPaused);\n    }\n}\n"
      },
      "lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.20;\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 value of tokens in existence.\n     */\n    function totalSupply() external view returns (uint256);\n\n    /**\n     * @dev Returns the value of tokens owned by `account`.\n     */\n    function balanceOf(address account) external view returns (uint256);\n\n    /**\n     * @dev Moves a `value` amount of 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 value) 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 a `value` amount of tokens as the allowance of `spender` over the\n     * 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 value) external returns (bool);\n\n    /**\n     * @dev Moves a `value` amount of tokens from `from` to `to` using the\n     * allowance mechanism. `value` 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 value) external returns (bool);\n}\n"
      },
      "src/interfaces/IAdmin.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.22;\n\n// Interfaces\nimport { IERC20 } from \"@openzeppelin/token/ERC20/IERC20.sol\";\n\n/// @title IAdmin\n/// @notice Interface for interacting with the AdminFacet contract, which controls the AugustusStorage variables\n/// all functions are callable only by the contract owner set by the ownership facet\ninterface IAdmin {\n    /*//////////////////////////////////////////////////////////////\n                                 ERRORS\n    //////////////////////////////////////////////////////////////*/\n\n    /// @notice Error emitted when the fee wallet is the zero address\n    error InvalidWalletAddress();\n\n    /*//////////////////////////////////////////////////////////////\n                                 EVENTS\n    //////////////////////////////////////////////////////////////*/\n\n    /// @notice Emitted when a token blacklist status is updated\n    /// @param token The token that was updated\n    /// @param isBlacklisted The new blacklisting status\n    event TokenBlacklistUpdated(IERC20 indexed token, bool isBlacklisted);\n\n    /// @notice Emitted when the fee wallet is updated\n    /// @param feeWallet The new fee wallet\n    event FeeWalletUpdated(address indexed feeWallet);\n\n    /// @notice Emitted when the fee wallet delegate is updated\n    /// @param feeWalletDelegate The new second fee wallet\n    event FeeWalletDelegateUpdated(address indexed feeWalletDelegate);\n\n    /// @notice Emitted when the contract is paused\n    event ContractPauseStateUpdated(bool isPaused);\n\n    /*//////////////////////////////////////////////////////////////\n                                EXTERNAL\n    //////////////////////////////////////////////////////////////*/\n\n    /// @notice Set the fee wallet address\n    /// @param _feeWallet The new fee wallet\n    function setFeeWallet(address payable _feeWallet) external;\n\n    /// @notice Set the second fee wallet address\n    /// @param _feeWalletDelegate The new second fee wallet\n    function setFeeWalletDelegate(address payable _feeWalletDelegate) external;\n\n    /// @notice Set the fee blacklisted status of a token\n    /// @param token The token to set the blacklisting status of\n    /// @param isBlacklisted The new blacklisting status\n    function setTokenBlacklisting(IERC20 token, bool isBlacklisted) external;\n\n    /// @notice Batch set the fee blacklisted status of tokens\n    /// @param tokens The tokens to set the blacklisting status of\n    /// @param isBlacklisted The new blacklisting status\n    function batchSetTokenBlacklisting(IERC20[] calldata tokens, bool isBlacklisted) external;\n\n    /// @notice Set the contract pause state\n    /// @param _isPaused The new pause state\n    function setContractPauseState(bool _isPaused) external;\n}\n"
      },
      "src/storage/AugustusStorage.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.22;\n\n// Interfaces\nimport { IERC20 } from \"@openzeppelin/token/ERC20/IERC20.sol\";\n\n// @title AugustusStorage\n// @notice Inherited storage layout for AugustusV6,\n// contracts should inherit this contract to access the storage layout\ncontract AugustusStorage {\n    /*//////////////////////////////////////////////////////////////\n                               FEES\n    //////////////////////////////////////////////////////////////*/\n\n    // @dev Mapping of tokens to boolean indicating if token is blacklisted for fee collection\n    mapping(IERC20 token => bool isBlacklisted) public blacklistedTokens;\n\n    // @dev Fee wallet to directly transfer paraswap share to\n    address payable public feeWallet;\n\n    // @dev Fee wallet address to register the paraswap share to in the fee vault\n    address payable public feeWalletDelegate;\n\n    /*//////////////////////////////////////////////////////////////\n                                CONTROL\n    //////////////////////////////////////////////////////////////*/\n\n    // @dev Contract paused state\n    bool public paused;\n}\n"
      },
      "src/vendor/libraries/LibDiamond.sol": {
        "content": "// SPDX-License-Identifier: MIT\n/**\n * Vendored on October 12, 2023 from:\n * https://github.com/mudgen/diamond-3-hardhat/blob/main/contracts/libraries/LibDiamond.sol\n */\npragma solidity ^0.8.0;\n\n/**\n * \\\n * Author: Nick Mudge <nick@perfectabstractions.com> (https://twitter.com/mudgen)\n * EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\n * /*****************************************************************************\n */\nimport { IDiamondCut } from \"../interfaces/IDiamondCut.sol\";\n\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\n// The loupe functions are required by the EIP2535 Diamonds standard\n\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\n\nlibrary LibDiamond {\n    bytes32 constant DIAMOND_STORAGE_POSITION = keccak256(\"diamond.standard.diamond.storage\");\n\n    struct FacetAddressAndPosition {\n        address facetAddress;\n        uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\n    }\n\n    struct FacetFunctionSelectors {\n        bytes4[] functionSelectors;\n        uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\n    }\n\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    function diamondStorage() internal pure returns (DiamondStorage storage ds) {\n        bytes32 position = DIAMOND_STORAGE_POSITION;\n        assembly {\n            ds.slot := position\n        }\n    }\n\n    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\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    function contractOwner() internal view returns (address contractOwner_) {\n        contractOwner_ = diamondStorage().contractOwner;\n    }\n\n    function enforceIsContractOwner() internal view {\n        require(msg.sender == diamondStorage().contractOwner, \"LibDiamond: Must be contract owner\");\n    }\n\n    event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\n\n    // Internal function version of diamondCut\n    function diamondCut(IDiamondCut.FacetCut[] memory _diamondCut, address _init, bytes memory _calldata) internal {\n        for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\n            IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\n            if (action == IDiamondCut.FacetCutAction.Add) {\n                addFunctions(_diamondCut[facetIndex].facetAddress, _diamondCut[facetIndex].functionSelectors);\n            } else if (action == IDiamondCut.FacetCutAction.Replace) {\n                replaceFunctions(_diamondCut[facetIndex].facetAddress, _diamondCut[facetIndex].functionSelectors);\n            } else if (action == IDiamondCut.FacetCutAction.Remove) {\n                removeFunctions(_diamondCut[facetIndex].facetAddress, _diamondCut[facetIndex].functionSelectors);\n            } else {\n                revert(\"LibDiamondCut: Incorrect FacetCutAction\");\n            }\n        }\n        emit DiamondCut(_diamondCut, _init, _calldata);\n        initializeDiamondCut(_init, _calldata);\n    }\n\n    function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\n        require(_functionSelectors.length > 0, \"LibDiamondCut: No selectors in facet to cut\");\n        DiamondStorage storage ds = diamondStorage();\n        require(_facetAddress != address(0), \"LibDiamondCut: Add facet can't be address(0)\");\n        uint96 selectorPosition = uint96(ds.facetFunctionSelectors[_facetAddress].functionSelectors.length);\n        // add new facet address if it does not exist\n        if (selectorPosition == 0) {\n            addFacet(ds, _facetAddress);\n        }\n        for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\n            bytes4 selector = _functionSelectors[selectorIndex];\n            address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\n            require(oldFacetAddress == address(0), \"LibDiamondCut: Can't add function that already exists\");\n            addFunction(ds, selector, selectorPosition, _facetAddress);\n            selectorPosition++;\n        }\n    }\n\n    function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\n        require(_functionSelectors.length > 0, \"LibDiamondCut: No selectors in facet to cut\");\n        DiamondStorage storage ds = diamondStorage();\n        require(_facetAddress != address(0), \"LibDiamondCut: Add facet can't be address(0)\");\n        uint96 selectorPosition = uint96(ds.facetFunctionSelectors[_facetAddress].functionSelectors.length);\n        // add new facet address if it does not exist\n        if (selectorPosition == 0) {\n            addFacet(ds, _facetAddress);\n        }\n        for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\n            bytes4 selector = _functionSelectors[selectorIndex];\n            address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\n            require(oldFacetAddress != _facetAddress, \"LibDiamondCut: Can't replace function with same function\");\n            removeFunction(ds, oldFacetAddress, selector);\n            addFunction(ds, selector, selectorPosition, _facetAddress);\n            selectorPosition++;\n        }\n    }\n\n    function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\n        require(_functionSelectors.length > 0, \"LibDiamondCut: No selectors in facet to cut\");\n        DiamondStorage storage ds = diamondStorage();\n        // if function does not exist then do nothing and return\n        require(_facetAddress == address(0), \"LibDiamondCut: Remove facet address must be address(0)\");\n        for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\n            bytes4 selector = _functionSelectors[selectorIndex];\n            address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\n            removeFunction(ds, oldFacetAddress, selector);\n        }\n    }\n\n    function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\n        enforceHasContractCode(_facetAddress, \"LibDiamondCut: New facet has no code\");\n        ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\n        ds.facetAddresses.push(_facetAddress);\n    }\n\n    function addFunction(\n        DiamondStorage storage ds,\n        bytes4 _selector,\n        uint96 _selectorPosition,\n        address _facetAddress\n    )\n        internal\n    {\n        ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\n        ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\n        ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\n    }\n\n    function removeFunction(DiamondStorage storage ds, address _facetAddress, bytes4 _selector) internal {\n        require(_facetAddress != address(0), \"LibDiamondCut: Can't remove function that doesn't exist\");\n        // an immutable function is a function defined directly in a diamond\n        require(_facetAddress != address(this), \"LibDiamondCut: Can't remove immutable function\");\n        // replace selector with last selector, then delete last selector\n        uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\n        uint256 lastSelectorPosition = ds.facetFunctionSelectors[_facetAddress].functionSelectors.length - 1;\n        // if not the same then replace _selector with lastSelector\n        if (selectorPosition != lastSelectorPosition) {\n            bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[lastSelectorPosition];\n            ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\n            ds.selectorToFacetAndPosition[lastSelector].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.facetFunctionSelectors[_facetAddress].facetAddressPosition;\n            if (facetAddressPosition != lastFacetAddressPosition) {\n                address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\n                ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\n                ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\n            }\n            ds.facetAddresses.pop();\n            delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\n        }\n    }\n\n    function initializeDiamondCut(address _init, bytes memory _calldata) internal {\n        if (_init == address(0)) {\n            return;\n        }\n        enforceHasContractCode(_init, \"LibDiamondCut: _init address has no code\");\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    function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\n        uint256 contractSize;\n        assembly {\n            contractSize := extcodesize(_contract)\n        }\n        require(contractSize > 0, _errorMessage);\n    }\n}\n"
      },
      "src/vendor/interfaces/IDiamondCut.sol": {
        "content": "// SPDX-License-Identifier: MIT\n/**\n * Vendored on October 12, 2023 from:\n * https://github.com/mudgen/diamond-3-hardhat/blob/main/contracts/interfaces/IDiamondCut.sol\n */\npragma solidity ^0.8.0;\n\n/**\n * \\\n * Author: Nick Mudge (https://twitter.com/mudgen)\n * EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\n * /*****************************************************************************\n */\ninterface IDiamondCut {\n    enum FacetCutAction {\n        Add,\n        Replace,\n        Remove\n    }\n    // Add=0, Replace=1, Remove=2\n\n    struct FacetCut {\n        address facetAddress;\n        FacetCutAction action;\n        bytes4[] functionSelectors;\n    }\n\n    /// @notice Add/replace/remove any number of functions and optionally execute\n    ///         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    ///                  _calldata is executed with delegatecall on _init\n    function diamondCut(FacetCut[] calldata _diamondCut, address _init, bytes calldata _calldata) external;\n\n    event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\n}\n"
      }
    },
    "settings": {
      "remappings": [
        "@prb/test/=lib/prb-test/src/",
        "forge-std/=lib/forge-std/src/",
        "@openzeppelin/=lib/openzeppelin-contracts/contracts/",
        "@solady/=lib/solady/src/",
        "@create3/=lib/create3-factory/src/",
        "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
        "create3-factory/=lib/create3-factory/",
        "ds-test/=lib/forge-std/lib/ds-test/src/",
        "erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/",
        "foundry-huff/=lib/foundry-huff/src/",
        "openzeppelin-contracts/=lib/openzeppelin-contracts/",
        "prb-test/=lib/prb-test/src/",
        "solady/=lib/solady/",
        "solidity-bytes-utils/=lib/solidity-bytes-utils/contracts/",
        "solidity-stringutils/=lib/foundry-huff/lib/solidity-stringutils/",
        "solmate/=lib/create3-factory/lib/solmate/src/",
        "stringutils/=lib/foundry-huff/lib/solidity-stringutils/"
      ],
      "optimizer": {
        "enabled": true,
        "runs": 1000000
      },
      "metadata": {
        "useLiteralContent": false,
        "bytecodeHash": "none",
        "appendCBOR": true
      },
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      },
      "evmVersion": "shanghai",
      "viaIR": true,
      "libraries": {}
    }
  }}