creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "src/core/TaxModule.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.19;\n\nimport {ProcessParam, RequestData, AssetInfo} from \"./Structs.sol\";\nimport {MathUtil} from \"../utils/MathUtil.sol\";\nimport \"synthetix-v3/utils/core-contracts/contracts/utils/SafeCast.sol\";\nimport {IFyde} from \"src/interfaces/IFyde.sol\";\nimport {Ownable} from \"src/utils/Ownable.sol\";\n\n///@title Tax contract\n///@notice Handle tax logic, for either a deposit or withdraw compute if the action is unabalacing\n/// the protocol\n///        if this is the case, the protocol will compute a tax applied on deposit or withdraw by\n/// reducing the number of shares to mint\n///        or by increasing the number of shares to burn. This tax is then minted to FYDE contract.\n/// The main logic is that for each action, we compute a taxable amount which is the amount that\n/// unbalance the protocol for a given deposit or withdraw,\n/// then we apply the tax on this taxable amount.\n/// For the swap the logic is the same, we compute the tax and incentive for assetIn and that give\n/// the value of assetOut,\n/// for this value we compute the tax and incentive for assetOut.\n/// SwapRate can be greater for assetOut in case there is no tax and some incentives, the same if no\n/// tax no incentive, or lower if there is tax and no incentive.\n\n// 1e20 == 100%,\nstruct TaxParams {\n  uint128 targetConcDeposit;\n  uint128 targetConcWithdraw;\n}\n\nstruct SwapData {\n  uint256 usdValIn;\n  uint256 usdQuoteIn;\n  uint256 usdQuoteOut;\n  uint72 targetIn;\n  uint72 targetOut;\n  int72 incentiveIn;\n  int72 incentiveOut;\n  uint256 usdAmountOut;\n}\n\ncontract TaxModule is Ownable {\n  using SafeCastU256 for uint256;\n  using SafeCastI256 for int256;\n\n  error AssetPriceNotAvailable();\n  error MaxFlatTaxExceeded();\n\n  uint256 constant PREC = 1e18;\n\n  IFyde public immutable FYDE;\n\n  // 100% = 1e9\n  uint32 public taxFactorDeposit = 1e9;\n  uint32 public taxFactorWithdraw = 1e9;\n  uint32 public flatTaxRateDeposit;\n  uint32 public flatTaxRateWithdraw;\n  uint32 public flatTaxRateSwap;\n\n  mapping(address => TaxParams) public taxParams;\n\n  constructor(address _fyde) Ownable(msg.sender) {\n    FYDE = IFyde(_fyde);\n  }\n\n  function setTaxFactorDeposit(uint32 _taxfactor) external onlyOwner {\n    taxFactorDeposit = _taxfactor;\n  }\n\n  function setTaxFactorWithdraw(uint32 _taxfactor) external onlyOwner {\n    taxFactorWithdraw = _taxfactor;\n  }\n\n  function setFlatTaxRate(uint32 _deposit, uint32 _withdraw, uint32 _swap) external onlyOwner {\n    if (_deposit > 1e9 || _withdraw > 1e9 || _swap > 1e9) revert MaxFlatTaxExceeded();\n    flatTaxRateDeposit = _deposit;\n    flatTaxRateWithdraw = _withdraw;\n    flatTaxRateSwap = _swap;\n  }\n\n  function setTaxParams(address[] calldata _assets, TaxParams[] calldata _taxParams)\n    external\n    onlyOwner\n  {\n    for (uint256 i; i < _assets.length; ++i) {\n      taxParams[_assets[i]] = _taxParams[i];\n    }\n  }\n\n  /*//////////////////////////////////////////////////////////////\n                                 MAIN\n    //////////////////////////////////////////////////////////////*/\n\n  function getProcessParamDeposit(RequestData memory _req, uint256 _protocolAUM)\n    external\n    view\n    returns (\n      ProcessParam[] memory processParam,\n      uint256 sharesToMint,\n      uint256 taxInTRSY,\n      uint256 totalUsdDeposit\n    )\n  {\n    uint256 trsySupply = FYDE.totalSupply();\n\n    (processParam, totalUsdDeposit) = _initializeProcessParam(_req, _protocolAUM, trsySupply);\n\n    for (uint256 i; i < processParam.length; i++) {\n      // Get the TaxInUSD\n      processParam[i] = _getDepositTax(\n        processParam[i],\n        _protocolAUM,\n        totalUsdDeposit,\n        uint256(taxFactorDeposit) * 1e11,\n        flatTaxRateDeposit\n      );\n\n      // Apply tax to the deposit\n      processParam[i].sharesAfterTax = _convertToShares(\n        processParam[i].usdValue - processParam[i].taxInUSD, _protocolAUM, trsySupply\n      );\n      sharesToMint += processParam[i].sharesAfterTax;\n      taxInTRSY += processParam[i].sharesBeforeTax - processParam[i].sharesAfterTax;\n    }\n\n    return (processParam, sharesToMint, taxInTRSY, totalUsdDeposit);\n  }\n\n  function getProcessParamWithdraw(RequestData calldata _req, uint256 _protocolAUM)\n    public\n    view\n    returns (\n      ProcessParam[] memory processParam,\n      uint256 totalSharesToBurn,\n      uint256 sharesToBurnBeforeTax,\n      uint256 taxInTRSY,\n      uint256 totalUsdWithdraw\n    )\n  {\n    uint256 trsySupply = FYDE.totalSupply();\n\n    (processParam, totalUsdWithdraw) = _initializeProcessParam(_req, _protocolAUM, trsySupply);\n\n    for (uint256 i; i < processParam.length; i++) {\n      // Get the TaxInUSD\n      processParam[i] = _getWithdrawTax(\n        processParam[i],\n        _protocolAUM,\n        totalUsdWithdraw,\n        uint256(taxFactorWithdraw) * 1e11,\n        flatTaxRateWithdraw\n      );\n\n      // Apply tax to the withdraw\n      taxInTRSY += _convertToShares(processParam[i].taxInUSD, _protocolAUM, trsySupply);\n    }\n\n    sharesToBurnBeforeTax = _convertToShares(totalUsdWithdraw, _protocolAUM, trsySupply);\n    totalSharesToBurn = sharesToBurnBeforeTax + taxInTRSY;\n  }\n\n  ///@notice Return the amountOut for a swap accounting for tax and incentive\n  ///@param _assetIn asset address to swap\n  ///@param _amountIn amount of asset to swap\n  ///@param _assetOut asset address to receive\n  ///@param _protocolAUM AUM given by keeper\n  function getSwapAmountOut(\n    address _assetIn,\n    uint256 _amountIn,\n    address _assetOut,\n    uint256 _protocolAUM\n  ) public view returns (uint256, int256) {\n    // prevent stack too deep struct\n    SwapData memory sd;\n    (sd.usdValIn, sd.usdQuoteIn) = _getUsdValue(_assetIn, _amountIn);\n    (, sd.usdQuoteOut) = _getUsdValue(_assetOut, PREC);\n    if (sd.usdValIn == 0 || sd.usdQuoteOut == 0) return (0, int256(0));\n\n    (sd.incentiveIn, sd.targetIn) = _getIncentiveFactorAndTargetConc(_assetIn);\n\n    ProcessParam memory processParamIn = ProcessParam({\n      targetConc: sd.targetIn,\n      currentConc: _getCurrentConcentration(_assetIn, _protocolAUM, sd.usdQuoteIn),\n      usdValue: sd.usdValIn,\n      sharesBeforeTax: 0,\n      taxableAmount: 0,\n      taxInUSD: 0,\n      sharesAfterTax: 0\n    });\n\n    (sd.incentiveOut, sd.targetOut) = _getIncentiveFactorAndTargetConc(_assetOut);\n\n    ProcessParam memory processParamOut = ProcessParam({\n      targetConc: sd.targetOut,\n      currentConc: _getCurrentConcentration(_assetOut, _protocolAUM, sd.usdQuoteOut),\n      usdValue: 0,\n      sharesBeforeTax: 0,\n      taxableAmount: 0,\n      taxInUSD: 0,\n      sharesAfterTax: 0\n    });\n\n    sd.usdAmountOut =\n      _getSwapRate(processParamIn, processParamOut, sd.incentiveIn, sd.incentiveOut, _protocolAUM);\n\n    return (\n      PREC * sd.usdAmountOut / sd.usdQuoteOut,\n      int256(processParamIn.usdValue) - int256(sd.usdAmountOut)\n    );\n  }\n\n  function _getDepositTax(\n    ProcessParam memory processParam,\n    uint256 protocolAUM,\n    uint256 totalUsdDeposit,\n    uint256 _taxfactor,\n    uint256 _flatTaxRate\n  ) internal pure returns (ProcessParam memory) {\n    if (processParam.targetConc == 0) {\n      processParam.taxInUSD = processParam.usdValue;\n      return processParam;\n    }\n    if (_taxfactor != 0) {\n      processParam = _computeDepositTaxableAmount(processParam, protocolAUM, totalUsdDeposit);\n    }\n\n    if (processParam.taxableAmount != 0) {\n      processParam = _computeDepositTaxInUSD(processParam, protocolAUM, totalUsdDeposit, _taxfactor);\n    }\n\n    return _addFlatTaxInUSD(processParam, _flatTaxRate);\n  }\n\n  function _getWithdrawTax(\n    ProcessParam memory processParam,\n    uint256 protocolAUM,\n    uint256 totalUsdWithdraw,\n    uint256 _taxfactor,\n    uint256 _flatTaxRate\n  ) internal pure returns (ProcessParam memory) {\n    if (_taxfactor != 0) {\n      processParam = _computeWithdrawTaxableAmount(processParam, protocolAUM, totalUsdWithdraw);\n    }\n\n    if (processParam.taxableAmount != 0) {\n      processParam =\n        _computeWithdrawTaxInUSD(processParam, protocolAUM, totalUsdWithdraw, _taxfactor);\n    }\n\n    return _addFlatTaxInUSD(processParam, _flatTaxRate);\n  }\n\n  function _getSwapRate(\n    ProcessParam memory processParamIn,\n    ProcessParam memory processParamOut,\n    int72 incentiveFactorIn,\n    int72 incentiveFactorOut,\n    uint256 protocolAUM\n  ) internal view returns (uint256) {\n    // Compute tax on deposit\n    processParamIn =\n      _getDepositTax(processParamIn, protocolAUM, 0, uint256(taxFactorDeposit) * 1e11, 0);\n\n    int256 valIn = incentiveFactorIn\n      * int256(processParamIn.usdValue - processParamIn.taxableAmount) / int256(1e20);\n\n    // usdValue adjusted with potential tax and incentive\n    uint256 withdrawValOut = valIn >= 0\n      ? processParamIn.usdValue - processParamIn.taxInUSD + valIn.toUint()\n      : processParamIn.usdValue - processParamIn.taxInUSD - (-1 * valIn).toUint();\n\n    processParamOut.usdValue = withdrawValOut;\n    processParamOut = _getWithdrawTax(\n      processParamOut, protocolAUM, 0, uint256(taxFactorWithdraw) * 1e11, flatTaxRateSwap\n    );\n\n    // usdValueOut adjusted with potential tax and incentive\n    int256 valOut =\n      incentiveFactorOut * int256(withdrawValOut - processParamOut.taxableAmount) / 1e20;\n\n    uint256 usdValOut = valOut >= 0\n      ? withdrawValOut - processParamOut.taxInUSD + valOut.toUint()\n      : withdrawValOut - processParamOut.taxInUSD - (-1 * valOut).toUint();\n\n    return usdValOut;\n  }\n\n  /*//////////////////////////////////////////////////////////////\n                                 DEPOSIT\n    //////////////////////////////////////////////////////////////*/\n  function _computeDepositTaxableAmount(\n    ProcessParam memory processParam,\n    uint256 protocolAUM,\n    uint256 totalUsdDeposit\n  ) internal pure returns (ProcessParam memory) {\n    int256 deltaConc = protocolAUM.toInt()\n      * (processParam.currentConc.toInt() - processParam.targetConc.toInt()) / 1e20;\n    int256 targetDeposit = totalUsdDeposit != 0\n      ? processParam.targetConc.toInt() * totalUsdDeposit.toInt() / 1e20\n      : int256(0);\n    int256 tax = processParam.usdValue.toInt() + deltaConc - targetDeposit;\n    processParam.taxableAmount =\n      MathUtil.min(processParam.usdValue.toInt(), MathUtil.max(tax, int256(0))).toUint();\n    return processParam;\n  }\n\n  function _computeDepositTaxInUSD(\n    ProcessParam memory processParam,\n    uint256 protocolAUM,\n    uint256 totalUsdDeposit,\n    uint256 _taxfactor\n  ) internal pure returns (ProcessParam memory) {\n    uint256 numerator = (protocolAUM * processParam.currentConc / 1e20) + processParam.usdValue;\n    uint256 denominator = (protocolAUM + totalUsdDeposit) * processParam.targetConc / 1e20;\n    uint256 eq = (PREC * numerator / denominator) - PREC;\n    uint256 tmpRes = MathUtil.min(eq, PREC);\n    uint256 taxPerc = _taxfactor * tmpRes / 1e20; // 1e20 for applying expressing tax as a\n    // percentage\n    processParam.taxInUSD = processParam.taxableAmount * taxPerc / PREC;\n    return processParam;\n  }\n\n  function _addFlatTaxInUSD(ProcessParam memory processParam, uint256 _flatTaxRate)\n    internal\n    pure\n    returns (ProcessParam memory)\n  {\n    processParam.taxInUSD += (processParam.usdValue - processParam.taxInUSD) * _flatTaxRate / 1e9;\n    return processParam;\n  }\n\n  /*//////////////////////////////////////////////////////////////\n                                 WITHDRAW\n    //////////////////////////////////////////////////////////////*/\n  function _computeWithdrawTaxableAmount(\n    ProcessParam memory processParam,\n    uint256 protocolAUM,\n    uint256 totalUsdWithdraw\n  ) internal pure returns (ProcessParam memory) {\n    int256 deltaConc = protocolAUM.toInt()\n      * (processParam.currentConc.toInt() - processParam.targetConc.toInt()) / 1e20;\n    int256 targetDeposit = processParam.targetConc.toInt() * totalUsdWithdraw.toInt() / 1e20;\n    int256 tax = processParam.usdValue.toInt() - deltaConc - targetDeposit;\n    processParam.taxableAmount =\n      MathUtil.min(processParam.usdValue.toInt(), MathUtil.max(tax, int256(0))).toUint();\n    return processParam;\n  }\n\n  function _computeWithdrawTaxInUSD(\n    ProcessParam memory processParam,\n    uint256 protocolAUM,\n    uint256 totalUsdWithdraw,\n    uint256 _taxfactor\n  ) internal pure returns (ProcessParam memory) {\n    int256 numerator =\n      protocolAUM.toInt() * processParam.currentConc.toInt() / 1e20 - processParam.usdValue.toInt();\n    int256 denominator =\n      processParam.targetConc.toInt() * (protocolAUM.toInt() - totalUsdWithdraw.toInt()) / 1e20;\n    int256 tmpRes = 1e18 - (1e18 * numerator / denominator);\n    uint256 tmpRes2 = MathUtil.min(tmpRes.toUint(), PREC);\n    uint256 taxPerc = _taxfactor * tmpRes2 / 1e20; // 1e20 for applying expressing tax as a\n    // percentage\n    processParam.taxInUSD = processParam.taxableAmount * taxPerc / PREC;\n    return processParam;\n  }\n\n  ///@notice Convert the value of deposit into share of the protocol\n  ///@param _usdValue usd value of the deposit\n  ///@param _usdAUM AUM of the protocol in USD\n  ///@return TSRY share for an USD deposit\n  function _convertToShares(uint256 _usdValue, uint256 _usdAUM, uint256 totalTrsySupply)\n    internal\n    pure\n    returns (uint256)\n  {\n    return totalTrsySupply == 0 ? _usdValue : (_usdValue * totalTrsySupply) / _usdAUM;\n  }\n\n  function _getCurrentConcentration(address _asset, uint256 _protocolAUM, uint256 _usdQuote)\n    internal\n    view\n    returns (uint256)\n  {\n    return _protocolAUM == 0\n      ? 0\n      : (1e20 * FYDE.totalAssetAccounting(_asset) / _protocolAUM * _usdQuote / PREC);\n  }\n\n  function _getTargetConcentrationDeposit(address _asset) internal view returns (uint256) {\n    return uint256(taxParams[_asset].targetConcDeposit);\n  }\n\n  function _getTargetConcentrationWithdraw(address _asset) internal view returns (uint256) {\n    return uint256(taxParams[_asset].targetConcWithdraw);\n  }\n\n  function _getIncentiveFactorAndTargetConc(address _asset) internal view returns (int72, uint72) {\n    AssetInfo memory assetInfo = FYDE.assetInfo(_asset);\n    return (assetInfo.incentiveFactor, assetInfo.targetConcentration);\n  }\n\n  function _getUsdValue(address _asset, uint256 _amount) internal view returns (uint256, uint256) {\n    uint256 usdQuote = FYDE.getQuote(_asset, PREC);\n    uint256 usdVal = _amount * usdQuote / PREC;\n    return (usdVal, usdQuote);\n  }\n\n  function _initializeProcessParam(\n    RequestData memory _req,\n    uint256 _protocolAUM,\n    uint256 _trsySupply\n  ) internal view returns (ProcessParam[] memory processParam, uint256 totalUsdValue) {\n    address[] memory assets = _req.assetIn.length != 0 ? _req.assetIn : _req.assetOut;\n    uint256[] memory amounts = _req.amountIn.length != 0 ? _req.amountIn : _req.amountOut;\n\n    processParam = new ProcessParam[](assets.length);\n\n    for (uint256 i; i < processParam.length; i++) {\n      (uint256 usdVal, uint256 usdQuote) = _getUsdValue(assets[i], amounts[i]);\n\n      totalUsdValue += usdVal;\n\n      uint256 targetConc = _req.assetIn.length != 0\n        ? _getTargetConcentrationDeposit(assets[i])\n        : _getTargetConcentrationWithdraw(assets[i]);\n\n      uint256 sharesBeforeTax =\n        _req.assetIn.length != 0 ? _convertToShares(usdVal, _protocolAUM, _trsySupply) : 0;\n\n      processParam[i] = ProcessParam({\n        targetConc: targetConc,\n        currentConc: _getCurrentConcentration(assets[i], _protocolAUM, usdQuote),\n        usdValue: usdVal,\n        sharesBeforeTax: sharesBeforeTax,\n        taxableAmount: 0,\n        taxInUSD: 0,\n        sharesAfterTax: 0\n      });\n    }\n  }\n}\n"
      },
      "src/core/Structs.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.19;\n\nstruct AssetInfo {\n  uint72 targetConcentration;\n  address uniswapPool;\n  int72 incentiveFactor;\n  uint8 assetDecimals;\n  uint8 quoteTokenDecimals;\n  address uniswapQuoteToken;\n  bool isSupported;\n}\n\nstruct ProtocolData {\n  ///@notice Protocol AUM in USD\n  uint256 aum;\n  ///@notice multiplicator for the tax equation, 100% = 100e18\n  uint72 taxFactor;\n  ///@notice Max deviation allowed between AUM from keeper and registry\n  uint16 maxAumDeviationAllowed; // Default val 200 == 2 %\n  ///@notice block number where AUM was last updated\n  uint48 lastAUMUpdateBlock;\n  ///@notice annual fee on AUM, in % per year 100% = 100e18\n  uint72 managementFee;\n  ///@notice last block.timestamp when fee was collected\n  uint48 lastFeeCollectionTime;\n}\n\nstruct UserRequest {\n  address asset;\n  uint256 amount;\n}\n\nstruct RequestData {\n  uint32 id;\n  address requestor;\n  address[] assetIn;\n  uint256[] amountIn;\n  address[] assetOut;\n  uint256[] amountOut;\n  bool keepGovRights;\n  uint256 slippageChecker;\n}\n\nstruct RequestQ {\n  uint64 start;\n  uint64 end;\n  mapping(uint64 => RequestData) requestData;\n}\n\nstruct ProcessParam {\n  uint256 targetConc;\n  uint256 currentConc;\n  uint256 usdValue;\n  uint256 taxableAmount;\n  uint256 taxInUSD;\n  uint256 sharesBeforeTax;\n  uint256 sharesAfterTax;\n}\n\nstruct RebalanceParam {\n  address asset;\n  uint256 assetTotalAmount;\n  uint256 assetProxyAmount;\n  uint256 assetPrice;\n  uint256 sTrsyTotalSupply;\n  uint256 trsyPrice;\n}\n"
      },
      "src/utils/MathUtil.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/math/Math.sol)\n\npragma solidity 0.8.19;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary MathUtil {\n  /**\n   * @dev Returns the largest of two numbers.\n   */\n  function max(int256 a, int256 b) internal pure returns (int256) {\n    return a >= b ? a : b;\n  }\n\n  /**\n   * @dev Returns the smallest of two numbers.\n   */\n  function min(int256 a, int256 b) internal pure returns (int256) {\n    return a < b ? a : b;\n  }\n\n  /**\n   * @dev Returns the smallest of two numbers.\n   */\n  function min(uint256 a, uint256 b) internal pure returns (uint256) {\n    return a < b ? a : b;\n  }\n}\n"
      },
      "lib/synthetix-v3/utils/core-contracts/contracts/utils/SafeCast.sol": {
        "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.11 <0.9.0;\n\n/**\n * Utilities that convert numeric types avoiding silent overflows.\n */\nimport \"./SafeCast/SafeCastU32.sol\";\nimport \"./SafeCast/SafeCastI32.sol\";\nimport \"./SafeCast/SafeCastI24.sol\";\nimport \"./SafeCast/SafeCastU56.sol\";\nimport \"./SafeCast/SafeCastI56.sol\";\nimport \"./SafeCast/SafeCastU64.sol\";\nimport \"./SafeCast/SafeCastI128.sol\";\nimport \"./SafeCast/SafeCastI256.sol\";\nimport \"./SafeCast/SafeCastU128.sol\";\nimport \"./SafeCast/SafeCastU160.sol\";\nimport \"./SafeCast/SafeCastU256.sol\";\nimport \"./SafeCast/SafeCastAddress.sol\";\nimport \"./SafeCast/SafeCastBytes32.sol\";\n"
      },
      "src/interfaces/IFyde.sol": {
        "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.19;\n\nimport {RequestData, RebalanceParam, ProcessParam, AssetInfo} from \"src/core/Structs.sol\";\n\ninterface IFyde {\n  function protocolData() external view returns (uint256, uint72, uint16, uint48, uint72, uint48);\n\n  function assetInfo(address) external view returns (AssetInfo memory);\n\n  function isAnyNotSupported(address[] calldata _assets) external view returns (address);\n\n  function isSwapAllowed(address[] calldata _assets) external view returns (address);\n\n  function computeProtocolAUM() external view returns (uint256);\n\n  function getProtocolAUM() external view returns (uint256);\n\n  function updateProtocolAUM(uint256) external;\n\n  function processDeposit(uint256, RequestData calldata) external returns (uint256);\n\n  function processWithdraw(uint256, RequestData calldata) external returns (uint256);\n\n  function totalSupply() external view returns (uint256);\n\n  function setOracleModule(address _oracle) external;\n\n  function oracleModule() external view returns (address);\n\n  function setRelayer(address _relayer) external;\n\n  function RELAYER() external view returns (address);\n\n  function totalAssetAccounting(address) external view returns (uint256);\n\n  function proxyAssetAccounting(address) external view returns (uint256);\n\n  function standardAssetAccounting(address) external view returns (uint256);\n\n  function getQuote(address, uint256) external view returns (uint256);\n\n  function getAssetDecimals(address) external view returns (uint8);\n\n  function collectManagementFee() external;\n\n  function getAssetsListLength() external view returns (uint256);\n\n  function assetsList(uint256 index) external view returns (address);\n\n  function processSwap(uint256, RequestData calldata) external returns (int256);\n\n  function owner() external view returns (address);\n\n  function getProcessParamDeposit(RequestData memory _req, uint256 _protocolAUM)\n    external\n    view\n    returns (\n      ProcessParam[] memory processParam,\n      uint256 sharesToMint,\n      uint256 taxInTRSY,\n      uint256 totalUsdDeposit\n    );\n\n  function getProcessParamWithdraw(RequestData calldata _req, uint256 _protocolAUM)\n    external\n    view\n    returns (\n      ProcessParam[] memory processParam,\n      uint256 totalSharesToBurn,\n      uint256 sharesToBurnBeforeTax,\n      uint256 taxInTRSY,\n      uint256 totalUsdWithdraw\n    );\n\n  function acceptOwnership() external;\n\n  // GOVERNANCE ACCESS FUNCTIONS\n\n  function transferAsset(address _asset, address _recipient, uint256 _amount) external;\n\n  function getRebalanceParams(address _asset) external view returns (RebalanceParam memory);\n\n  function updateAssetProxyAmount(address _asset, uint256 _amount) external;\n}\n"
      },
      "src/utils/Ownable.sol": {
        "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.19;\n\n///@title Ownable contract\n/// @notice Simple 2step owner authorization combining solmate and OZ implementation\nabstract contract Ownable {\n  /*//////////////////////////////////////////////////////////////\n                             STORAGE\n    //////////////////////////////////////////////////////////////*/\n\n  ///@notice Address of the owner\n  address public owner;\n\n  ///@notice Address of the pending owner\n  address public pendingOwner;\n\n  /*//////////////////////////////////////////////////////////////\n                                 EVENTS\n    //////////////////////////////////////////////////////////////*/\n\n  event OwnershipTransferred(address indexed user, address indexed newOner);\n  event OwnershipTransferStarted(address indexed user, address indexed newOwner);\n  event OwnershipTransferCanceled(address indexed pendingOwner);\n\n  /*//////////////////////////////////////////////////////////////\n                                 ERROR\n    //////////////////////////////////////////////////////////////*/\n\n  error Unauthorized();\n\n  /*//////////////////////////////////////////////////////////////\n                               CONSTRUCTOR\n    //////////////////////////////////////////////////////////////*/\n\n  constructor(address _owner) {\n    owner = _owner;\n\n    emit OwnershipTransferred(address(0), _owner);\n  }\n\n  /*//////////////////////////////////////////////////////////////\n                             OWNERSHIP LOGIC\n    //////////////////////////////////////////////////////////////*/\n\n  ///@notice Transfer ownership to a new address\n  ///@param newOwner address of the new owner\n  ///@dev newOwner have to acceptOwnership\n  function transferOwnership(address newOwner) external onlyOwner {\n    pendingOwner = newOwner;\n    emit OwnershipTransferStarted(msg.sender, pendingOwner);\n  }\n\n  ///@notice NewOwner accept the ownership, it transfer the ownership to newOwner\n  function acceptOwnership() external {\n    if (msg.sender != pendingOwner) revert Unauthorized();\n    address oldOwner = owner;\n    owner = pendingOwner;\n    delete pendingOwner;\n    emit OwnershipTransferred(oldOwner, owner);\n  }\n\n  ///@notice Cancel the ownership transfer\n  function cancelTransferOwnership() external onlyOwner {\n    emit OwnershipTransferCanceled(pendingOwner);\n    delete pendingOwner;\n  }\n\n  modifier onlyOwner() {\n    if (msg.sender != owner) revert Unauthorized();\n    _;\n  }\n}\n"
      },
      "lib/synthetix-v3/utils/core-contracts/contracts/utils/SafeCast/SafeCastU32.sol": {
        "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.11 <0.9.0;\n\n/**\n * @title See SafeCast.sol.\n */\nlibrary SafeCastU32 {\n    error OverflowUint32ToInt32();\n\n    function toInt(uint32 x) internal pure returns (int32) {\n        // -------------------------------o=========>----------------------\n        // ----------------------<========o========>x----------------------\n        if (x > uint32(type(int32).max)) {\n            revert OverflowUint32ToInt32();\n        }\n\n        return int32(x);\n    }\n\n    function to256(uint32 x) internal pure returns (uint256) {\n        return uint256(x);\n    }\n\n    function to56(uint32 x) internal pure returns (uint56) {\n        return uint56(x);\n    }\n}\n"
      },
      "lib/synthetix-v3/utils/core-contracts/contracts/utils/SafeCast/SafeCastI32.sol": {
        "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.11 <0.9.0;\n\n/**\n * @title See SafeCast.sol.\n */\nlibrary SafeCastI32 {\n    error OverflowInt32ToUint32();\n\n    function toUint(int32 x) internal pure returns (uint32) {\n        // ----------------------<========o========>----------------------\n        // ----------------------xxxxxxxxxo=========>----------------------\n        if (x < 0) {\n            revert OverflowInt32ToUint32();\n        }\n\n        return uint32(x);\n    }\n}\n"
      },
      "lib/synthetix-v3/utils/core-contracts/contracts/utils/SafeCast/SafeCastI24.sol": {
        "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.11 <0.9.0;\n\n/**\n * @title See SafeCast.sol.\n */\nlibrary SafeCastI24 {\n    function to256(int24 x) internal pure returns (int256) {\n        return int256(x);\n    }\n}\n"
      },
      "lib/synthetix-v3/utils/core-contracts/contracts/utils/SafeCast/SafeCastU56.sol": {
        "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.11 <0.9.0;\n\n/**\n * @title See SafeCast.sol.\n */\nlibrary SafeCastU56 {\n    error OverflowUint56ToInt56();\n\n    function toInt(uint56 x) internal pure returns (int56) {\n        // -------------------------------o=========>----------------------\n        // ----------------------<========o========>x----------------------\n        if (x > uint56(type(int56).max)) {\n            revert OverflowUint56ToInt56();\n        }\n\n        return int56(x);\n    }\n}\n"
      },
      "lib/synthetix-v3/utils/core-contracts/contracts/utils/SafeCast/SafeCastI56.sol": {
        "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.11 <0.9.0;\n\n/**\n * @title See SafeCast.sol.\n */\nlibrary SafeCastI56 {\n    error OverflowInt56ToInt24();\n\n    function to24(int56 x) internal pure returns (int24) {\n        // ----------------------<========o========>-----------------------\n        // ----------------------xxx<=====o=====>xxx-----------------------\n        if (x < int(type(int24).min) || x > int(type(int24).max)) {\n            revert OverflowInt56ToInt24();\n        }\n\n        return int24(x);\n    }\n}\n"
      },
      "lib/synthetix-v3/utils/core-contracts/contracts/utils/SafeCast/SafeCastU64.sol": {
        "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.11 <0.9.0;\n\n/**\n * @title See SafeCast.sol.\n */\nlibrary SafeCastU64 {\n    error OverflowUint64ToInt64();\n\n    function toInt(uint64 x) internal pure returns (int64) {\n        // -------------------------------o=========>----------------------\n        // ----------------------<========o========>x----------------------\n        if (x > uint64(type(int64).max)) {\n            revert OverflowUint64ToInt64();\n        }\n\n        return int64(x);\n    }\n}\n"
      },
      "lib/synthetix-v3/utils/core-contracts/contracts/utils/SafeCast/SafeCastI128.sol": {
        "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.11 <0.9.0;\n\n/**\n * @title See SafeCast.sol.\n */\nlibrary SafeCastI128 {\n    error OverflowInt128ToUint128();\n    error OverflowInt128ToInt32();\n\n    function toUint(int128 x) internal pure returns (uint128) {\n        // ----------------<==============o==============>-----------------\n        // ----------------xxxxxxxxxxxxxxxo===============>----------------\n        if (x < 0) {\n            revert OverflowInt128ToUint128();\n        }\n\n        return uint128(x);\n    }\n\n    function to256(int128 x) internal pure returns (int256) {\n        return int256(x);\n    }\n\n    function to32(int128 x) internal pure returns (int32) {\n        // ----------------<==============o==============>-----------------\n        // ----------------xxxxxxxxxxxx<==o==>xxxxxxxxxxxx-----------------\n        if (x < int(type(int32).min) || x > int(type(int32).max)) {\n            revert OverflowInt128ToInt32();\n        }\n\n        return int32(x);\n    }\n\n    function zero() internal pure returns (int128) {\n        return int128(0);\n    }\n}\n"
      },
      "lib/synthetix-v3/utils/core-contracts/contracts/utils/SafeCast/SafeCastI256.sol": {
        "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.11 <0.9.0;\n\n/**\n * @title See SafeCast.sol.\n */\nlibrary SafeCastI256 {\n    error OverflowInt256ToUint256();\n    error OverflowInt256ToInt128();\n    error OverflowInt256ToInt24();\n\n    function to128(int256 x) internal pure returns (int128) {\n        // ----<==========================o===========================>----\n        // ----xxxxxxxxxxxx<==============o==============>xxxxxxxxxxxxx----\n        if (x < int256(type(int128).min) || x > int256(type(int128).max)) {\n            revert OverflowInt256ToInt128();\n        }\n\n        return int128(x);\n    }\n\n    function to24(int256 x) internal pure returns (int24) {\n        // ----<==========================o===========================>----\n        // ----xxxxxxxxxxxxxxxxxxxx<======o=======>xxxxxxxxxxxxxxxxxxxx----\n        if (x < int256(type(int24).min) || x > int256(type(int24).max)) {\n            revert OverflowInt256ToInt24();\n        }\n\n        return int24(x);\n    }\n\n    function toUint(int256 x) internal pure returns (uint256) {\n        // ----<==========================o===========================>----\n        // ----xxxxxxxxxxxxxxxxxxxxxxxxxxxo===============================>\n        if (x < 0) {\n            revert OverflowInt256ToUint256();\n        }\n\n        return uint256(x);\n    }\n\n    function zero() internal pure returns (int256) {\n        return int256(0);\n    }\n}\n"
      },
      "lib/synthetix-v3/utils/core-contracts/contracts/utils/SafeCast/SafeCastU128.sol": {
        "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.11 <0.9.0;\n\n/**\n * @title See SafeCast.sol.\n */\nlibrary SafeCastU128 {\n    error OverflowUint128ToInt128();\n\n    function to256(uint128 x) internal pure returns (uint256) {\n        return uint256(x);\n    }\n\n    function toInt(uint128 x) internal pure returns (int128) {\n        // -------------------------------o===============>----------------\n        // ----------------<==============o==============>x----------------\n        if (x > uint128(type(int128).max)) {\n            revert OverflowUint128ToInt128();\n        }\n\n        return int128(x);\n    }\n\n    function toBytes32(uint128 x) internal pure returns (bytes32) {\n        return bytes32(uint256(x));\n    }\n}\n"
      },
      "lib/synthetix-v3/utils/core-contracts/contracts/utils/SafeCast/SafeCastU160.sol": {
        "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.11 <0.9.0;\n\n/**\n * @title See SafeCast.sol.\n */\nlibrary SafeCastU160 {\n    function to256(uint160 x) internal pure returns (uint256) {\n        return uint256(x);\n    }\n}\n"
      },
      "lib/synthetix-v3/utils/core-contracts/contracts/utils/SafeCast/SafeCastU256.sol": {
        "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.11 <0.9.0;\n\n/**\n * @title See SafeCast.sol.\n */\nlibrary SafeCastU256 {\n    error OverflowUint256ToUint128();\n    error OverflowUint256ToInt256();\n    error OverflowUint256ToUint64();\n    error OverflowUint256ToUint32();\n    error OverflowUint256ToUint160();\n\n    function to128(uint256 x) internal pure returns (uint128) {\n        // -------------------------------o===============================>\n        // -------------------------------o===============>xxxxxxxxxxxxxxxx\n        if (x > type(uint128).max) {\n            revert OverflowUint256ToUint128();\n        }\n\n        return uint128(x);\n    }\n\n    function to64(uint256 x) internal pure returns (uint64) {\n        // -------------------------------o===============================>\n        // -------------------------------o======>xxxxxxxxxxxxxxxxxxxxxxxxx\n        if (x > type(uint64).max) {\n            revert OverflowUint256ToUint64();\n        }\n\n        return uint64(x);\n    }\n\n    function to32(uint256 x) internal pure returns (uint32) {\n        // -------------------------------o===============================>\n        // -------------------------------o===>xxxxxxxxxxxxxxxxxxxxxxxxxxxx\n        if (x > type(uint32).max) {\n            revert OverflowUint256ToUint32();\n        }\n\n        return uint32(x);\n    }\n\n    function to160(uint256 x) internal pure returns (uint160) {\n        // -------------------------------o===============================>\n        // -------------------------------o==================>xxxxxxxxxxxxx\n        if (x > type(uint160).max) {\n            revert OverflowUint256ToUint160();\n        }\n\n        return uint160(x);\n    }\n\n    function toBytes32(uint256 x) internal pure returns (bytes32) {\n        return bytes32(x);\n    }\n\n    function toInt(uint256 x) internal pure returns (int256) {\n        // -------------------------------o===============================>\n        // ----<==========================o===========================>xxxx\n        if (x > uint256(type(int256).max)) {\n            revert OverflowUint256ToInt256();\n        }\n\n        return int256(x);\n    }\n}\n"
      },
      "lib/synthetix-v3/utils/core-contracts/contracts/utils/SafeCast/SafeCastAddress.sol": {
        "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.11 <0.9.0;\n\n/**\n * @title See SafeCast.sol.\n */\nlibrary SafeCastAddress {\n    function toBytes32(address x) internal pure returns (bytes32) {\n        return bytes32(uint256(uint160(x)));\n    }\n}\n"
      },
      "lib/synthetix-v3/utils/core-contracts/contracts/utils/SafeCast/SafeCastBytes32.sol": {
        "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.11 <0.9.0;\n\n/**\n * @title See SafeCast.sol.\n */\nlibrary SafeCastBytes32 {\n    function toAddress(bytes32 x) internal pure returns (address) {\n        return address(uint160(uint256(x)));\n    }\n\n    function toUint(bytes32 x) internal pure returns (uint) {\n        return uint(x);\n    }\n}\n"
      }
    },
    "settings": {
      "remappings": [
        "@uniswap/v3-core/=lib/v3-core/",
        "@uniswap/v3-periphery/=lib/v3-periphery/",
        "openzeppelin-contracts/=lib/openzeppelin-contracts/contracts/",
        "ds-test/=lib/forge-std/lib/ds-test/src/",
        "erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/",
        "forge-std/=lib/forge-std/src/",
        "openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/",
        "openzeppelin/=lib/openzeppelin-contracts/contracts/",
        "solmate/=lib/solmate/src/",
        "synthetix-v3/=lib/synthetix-v3/",
        "v3-core/=lib/v3-core/contracts/",
        "v3-periphery/=lib/v3-periphery/contracts/"
      ],
      "optimizer": {
        "enabled": true,
        "runs": 200
      },
      "metadata": {
        "useLiteralContent": false,
        "bytecodeHash": "ipfs",
        "appendCBOR": true
      },
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      },
      "evmVersion": "paris",
      "libraries": {}
    }
  }}