creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "contracts/lib/Oracle/contracts/oracles/ZunEthOracle.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity ^0.8.23;\n\nimport '../../interfaces/IOracle.sol';\nimport '../../libraries/ScaledMath.sol';\n\ninterface ICurvePriceOracleNG {\n    function price_oracle(uint256 i) external view returns (uint256);\n}\n\ncontract ZunEthOracle is IOracle {\n    using ScaledMath for uint256;\n\n    // Tokens\n    address internal constant _ZUNETH = address(0xc2e660C62F72c2ad35AcE6DB78a616215E2F2222);\n    address internal constant _FRXETH = address(0x5E8422345238F34275888049021821E8E08CAa1f);\n\n    // Curve pools\n    address internal constant _ZUNETH_FRXETH = address(0x3A65cbaebBFecbeA5D0CB523ab56fDbda7fF9aAA);\n\n    IOracle internal immutable _genericOracle;\n\n    constructor(address genericOracle_) {\n        _genericOracle = IOracle(genericOracle_);\n    }\n\n    function getUSDPrice(address token_) external view override returns (uint256) {\n        require(isTokenSupported(token_), 'token not supported');\n        return _getZunUSDPriceForCurvePool(_ZUNETH_FRXETH, _FRXETH);\n    }\n\n    function isTokenSupported(address token_) public pure override returns (bool) {\n        return token_ == _ZUNETH;\n    }\n\n    function _getZunUSDPriceForCurvePool(\n        address curvePool_,\n        address token_\n    ) internal view returns (uint256) {\n        uint256 tokenPrice_ = _genericOracle.getUSDPrice(token_);\n        uint256 tokenPerZunETH_ = ICurvePriceOracleNG(curvePool_).price_oracle(0);\n\n        return tokenPrice_.mulDown(tokenPerZunETH_);\n    }\n}\n"
      },
      "contracts/lib/Oracle/interfaces/IOracle.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity ^0.8.23;\n\ninterface IOracle {\n    /// @notice returns the price in USD of symbol.\n    function getUSDPrice(address token) external view returns (uint256);\n\n    /// @notice returns if the given token is supported for pricing.\n    function isTokenSupported(address token) external view returns (bool);\n}\n"
      },
      "contracts/lib/Oracle/libraries/ScaledMath.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity ^0.8.23;\n\nlibrary ScaledMath {\n    uint256 internal constant DECIMALS = 18;\n    uint256 internal constant ONE = 10 ** DECIMALS;\n\n    function mulDown(uint256 a, uint256 b) internal pure returns (uint256) {\n        return (a * b) / ONE;\n    }\n\n    function mulDown(uint256 a, uint256 b, uint256 decimals) internal pure returns (uint256) {\n        return (a * b) / (10 ** decimals);\n    }\n\n    function divDown(uint256 a, uint256 b) internal pure returns (uint256) {\n        return (a * ONE) / b;\n    }\n\n    function divDown(uint256 a, uint256 b, uint256 decimals) internal pure returns (uint256) {\n        return (a * 10 ** decimals) / b;\n    }\n\n    function divUp(uint256 a, uint256 b) internal pure returns (uint256) {\n        if (a == 0) {\n            return 0;\n        }\n        return ((a * ONE) - 1) / b + 1;\n    }\n\n    function mulDown(int256 a, int256 b) internal pure returns (int256) {\n        return (a * b) / int256(ONE);\n    }\n\n    function mulDownUint128(uint128 a, uint128 b) internal pure returns (uint128) {\n        return (a * b) / uint128(ONE);\n    }\n\n    function mulDown(int256 a, int256 b, uint256 decimals) internal pure returns (int256) {\n        return (a * b) / int256(10 ** decimals);\n    }\n\n    function divDown(int256 a, int256 b) internal pure returns (int256) {\n        return (a * int256(ONE)) / b;\n    }\n\n    function divDownUint128(uint128 a, uint128 b) internal pure returns (uint128) {\n        return (a * uint128(ONE)) / b;\n    }\n\n    function divDown(int256 a, int256 b, uint256 decimals) internal pure returns (int256) {\n        return (a * int256(10 ** decimals)) / b;\n    }\n\n    function convertScale(\n        uint256 a,\n        uint8 fromDecimals,\n        uint8 toDecimals\n    ) internal pure returns (uint256) {\n        if (fromDecimals == toDecimals) return a;\n        if (fromDecimals > toDecimals) return downscale(a, fromDecimals, toDecimals);\n        return upscale(a, fromDecimals, toDecimals);\n    }\n\n    function convertScale(\n        int256 a,\n        uint8 fromDecimals,\n        uint8 toDecimals\n    ) internal pure returns (int256) {\n        if (fromDecimals == toDecimals) return a;\n        if (fromDecimals > toDecimals) return downscale(a, fromDecimals, toDecimals);\n        return upscale(a, fromDecimals, toDecimals);\n    }\n\n    function upscale(\n        uint256 a,\n        uint8 fromDecimals,\n        uint8 toDecimals\n    ) internal pure returns (uint256) {\n        return a * (10 ** (toDecimals - fromDecimals));\n    }\n\n    function downscale(\n        uint256 a,\n        uint8 fromDecimals,\n        uint8 toDecimals\n    ) internal pure returns (uint256) {\n        return a / (10 ** (fromDecimals - toDecimals));\n    }\n\n    function upscale(\n        int256 a,\n        uint8 fromDecimals,\n        uint8 toDecimals\n    ) internal pure returns (int256) {\n        return a * int256(10 ** (toDecimals - fromDecimals));\n    }\n\n    function downscale(\n        int256 a,\n        uint8 fromDecimals,\n        uint8 toDecimals\n    ) internal pure returns (int256) {\n        return a / int256(10 ** (fromDecimals - toDecimals));\n    }\n\n    function intPow(uint256 a, uint256 n) internal pure returns (uint256) {\n        uint256 result = ONE;\n        for (uint256 i; i < n; ) {\n            result = mulDown(result, a);\n            unchecked {\n                ++i;\n            }\n        }\n        return result;\n    }\n\n    function absSub(uint256 a, uint256 b) internal pure returns (uint256) {\n        unchecked {\n            return a >= b ? a - b : b - a;\n        }\n    }\n}\n"
      }
    },
    "settings": {
      "optimizer": {
        "enabled": true,
        "runs": 200
      },
      "evmVersion": "paris",
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      },
      "metadata": {
        "useLiteralContent": true
      },
      "libraries": {}
    }
  }}