creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "/contracts/periphery/EthStrategyLens.sol": {
        "content": "// SPDX-License-Identifier: MIT\r\npragma solidity ^0.8.0;\r\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\r\nimport \"../interfaces/ISubStrategy.sol\";\r\nimport \"../subStrategies/interfaces/IWstETH.sol\";\r\nimport \"../subStrategies/interfaces/ICurve.sol\";\r\nimport \"../subStrategies/interfaces/IBalancer.sol\";\r\ncontract EthStrategyLens{\r\n    address public immutable ethVault;\r\n    address public immutable EthStrategy;\r\n    address public immutable curvePool;\r\n    address public immutable awstETH;\r\n    address public immutable aDebtETH;\r\n    address public immutable wstETH;\r\n    address public immutable balancerFee;\r\n    constructor(address _vault,address _strategy,address _curvePool,address _awstEth,address _aDebtEth,address _wstEth,address _balancerFee){\r\n        ethVault = _vault;\r\n        EthStrategy = _strategy;\r\n        curvePool = _curvePool;\r\n        awstETH = _awstEth;\r\n        aDebtETH = _aDebtEth;\r\n        wstETH = _wstEth;\r\n        balancerFee = _balancerFee;\r\n    }\r\n    function getDepositOut(uint256 assets) external view returns (uint256) {\r\n        uint256 totalAsset = ISubStrategy(EthStrategy).totalAssets();\r\n        if (totalAsset == 0){\r\n            return assets;\r\n        }\r\n        uint256 balDebtETH = IERC20(aDebtETH).balanceOf(address(EthStrategy));\r\n        uint256 supply = IERC20(ethVault).totalSupply();\r\n        uint256 debt =  balDebtETH*assets/totalAsset;\r\n        uint256 swapOut = ICurve(curvePool).get_dy(0, 1, debt+assets);\r\n        uint256 flashFee = IBalancer(balancerFee).getFlashLoanFeePercentage();\r\n        if(swapOut<debt+assets){\r\n            swapOut=debt+assets;\r\n        }\r\n        return (swapOut-(debt*1e18+flashFee)/1e18)*supply/totalAsset;\r\n    }\r\n\r\n    function getRedeemOut(uint256 shares) external view returns (uint256) {\r\n        uint256 supply = IERC20(ethVault).totalSupply();\r\n        if (supply == 0){\r\n            return shares;\r\n        }\r\n        uint256 balWstETH = IERC20(awstETH).balanceOf(address(EthStrategy));\r\n        uint256 balDebtETH = IERC20(aDebtETH).balanceOf(address(EthStrategy));        \r\n        uint256 collateral =  IWstETH(wstETH).getStETHByWstETH(balWstETH)*shares/supply;\r\n        uint256 debt =  balDebtETH*shares/supply;\r\n        uint256 swapOut = ICurve(curvePool).get_dy(1, 0, collateral);\r\n        uint256 flashFee = IBalancer(balancerFee).getFlashLoanFeePercentage();\r\n        return swapOut-(debt*1e18+flashFee)/1e18;\r\n    }\r\n\r\n}"
      },
      "/contracts/subStrategies/interfaces/IWstETH.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface IWstETH {\n    function wrap(uint256 _stETHAmount) external returns (uint256);\n    function unwrap(uint256 _wstETHAmount) external returns (uint256);\n    function getWstETHByStETH(uint256 _stETHAmount) external view returns (uint256);\n    function getStETHByWstETH(uint256 _wstETHAmount) external view returns (uint256);\n\n}\n"
      },
      "/contracts/subStrategies/interfaces/ICurve.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface ICurve {\n    function get_dy(\n        int128 i,\n        int128 j,\n        uint256 dx\n    ) external view returns (uint256);\n    function exchange(\n        int128 i,\n        int128 j,\n        uint256 dx,\n        uint256 min_dy\n    ) external payable returns (uint256);\n}\n"
      },
      "/contracts/subStrategies/interfaces/IBalancer.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface IBalancer {\n    function flashLoan(\n        address recipient,\n        address[] calldata tokens,\n        uint256[] calldata amounts,\n        bytes calldata userData\n    ) external;\n\n    function getFlashLoanFeePercentage() external view returns (uint256); //18 decimal\n}\n"
      },
      "/contracts/interfaces/ISubStrategy.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface ISubStrategy {\n    function totalAssets() external view returns (uint256);\n\n    function deposit(uint256 _amount) external returns (uint256);\n\n    function withdraw(uint256 _amount) external returns (uint256);\n\n    function maxDeposit() external view returns (uint256);\n\n    function withdrawable(uint256 _amount) external view returns (uint256);\n\n}\n"
      },
      "@openzeppelin/contracts/token/ERC20/IERC20.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.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(\n        address from,\n        address to,\n        uint256 amount\n    ) external returns (bool);\n}\n"
      }
    },
    "settings": {
      "remappings": [],
      "optimizer": {
        "enabled": true,
        "runs": 200
      },
      "evmVersion": "london",
      "libraries": {},
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      }
    }
  }}