creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "src/core/Pythia.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.2 <0.9.0;\n\nimport {RiskData} from \"../interfaces/RiskData.sol\";\n\n/// @title Pythia Contract for Risk Data Signature Verification\n/// @author bprotocol\n/// @notice This contract is designed to manage and verify signatures for risk data, using EIP712 typed data standard.\n/// @dev It uses EIP712 domain and type hashes for structuring and verifying data,\n///      providing a function to easily recover the signer's address from signed risk data.\ncontract Pythia {\n  struct EIP712Domain {\n    string name;\n    string version;\n    uint256 chainId;\n    address verifyingContract;\n  }\n\n  /// @notice Type hash for the EIP712 domain, used in constructing the domain separator.\n  bytes32 public constant EIP712DOMAIN_TYPEHASH =\n    keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\");\n\n  /// @notice Type hash for RiskData, used in the EIP712 typed data signing process.\n  bytes32 public constant RISKDATA_TYPEHASH =\n    keccak256(\n      \"RiskData(address collateralAsset,address debtAsset,uint256 liquidity,uint256 volatility,uint256 liquidationBonus,uint256 lastUpdate,uint256 chainId)\"\n    );\n\n  /// @notice Immutable EIP712 domain separator, unique to this contract and its deployment environment.\n  bytes32 public immutable DOMAIN_SEPARATOR;\n\n  /// @notice The chain ID on which this contract is deployed, immutable and set at contract deployment.\n  uint256 public immutable chainId;\n\n  /// @notice Initializes the contract, setting up the domain separator with the contract's details.\n  constructor() {\n    chainId = block.chainid;\n\n    EIP712Domain memory domain = EIP712Domain({\n      name: \"SPythia\",\n      version: \"0.0.1\",\n      chainId: chainId,\n      verifyingContract: address(this)\n    });\n    DOMAIN_SEPARATOR = keccak256(\n      abi.encode(\n        EIP712DOMAIN_TYPEHASH,\n        keccak256(bytes(domain.name)),\n        keccak256(bytes(domain.version)),\n        domain.chainId,\n        domain.verifyingContract\n      )\n    );\n  }\n\n  /// @notice Hashes a RiskData struct using the EIP712 risk data type hash.\n  /// @param data The RiskData struct to be hashed.\n  /// @return The keccak256 hash of the encoded RiskData struct.\n  function hashStruct(RiskData memory data) public pure returns (bytes32) {\n    return\n      keccak256(\n        abi.encode(\n          RISKDATA_TYPEHASH,\n          data.collateralAsset,\n          data.debtAsset,\n          data.liquidity,\n          data.volatility,\n          data.liquidationBonus,\n          data.lastUpdate,\n          data.chainId\n        )\n      );\n  }\n\n  /// @notice Recovers the signer's address from the provided EIP712 signature and RiskData.\n  /// @dev Uses the EIP712 standard for typed data signing to recover the address.\n  /// @param data The signed RiskData struct.\n  /// @param v The recovery byte of the signature.\n  /// @param r Half of the ECDSA signature pair.\n  /// @param s Half of the ECDSA signature pair.\n  /// @return The address of the signer who signed the provided RiskData.\n  function getSigner(RiskData memory data, uint8 v, bytes32 r, bytes32 s) public view returns (address) {\n    bytes32 digest = keccak256(abi.encodePacked(\"\\x19\\x01\", DOMAIN_SEPARATOR, hashStruct(data)));\n    return ecrecover(digest, v, r, s);\n  }\n}\n"
      },
      "src/interfaces/RiskData.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.2 <0.9.0;\n\nstruct Signature {\n  uint8 v;\n  bytes32 r;\n  bytes32 s;\n}\n\nstruct RiskData {\n  address collateralAsset;\n  address debtAsset;\n  uint256 liquidity;\n  uint256 volatility;\n  uint256 liquidationBonus;\n  uint256 lastUpdate;\n  uint256 chainId;\n}\n\nstruct SignedRiskData {\n  RiskData riskData;\n  uint8 v;\n  bytes32 r;\n  bytes32 s;\n}\n"
      }
    },
    "settings": {
      "remappings": [
        "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
        "core/=scripts/core/",
        "ds-test/=lib/forge-std/lib/ds-test/src/",
        "erc4626-tests/=lib/metamorpho/lib/erc4626-tests/",
        "forge-std/=lib/forge-std/src/",
        "goerli/=scripts/goerli/",
        "metamorpho/=lib/metamorpho/src/",
        "morpho-blue/=lib/metamorpho/lib/morpho-blue/src/",
        "morpho/=scripts/morpho/",
        "murky/=lib/metamorpho/lib/universal-rewards-distributor/lib/murky/src/",
        "openzeppelin-contracts/=lib/openzeppelin-contracts/",
        "openzeppelin/=lib/metamorpho/lib/universal-rewards-distributor/lib/openzeppelin-contracts/contracts/",
        "solmate/=lib/metamorpho/lib/universal-rewards-distributor/lib/solmate/src/",
        "universal-rewards-distributor/=lib/metamorpho/lib/universal-rewards-distributor/src/"
      ],
      "optimizer": {
        "enabled": true,
        "runs": 200
      },
      "metadata": {
        "useLiteralContent": false,
        "bytecodeHash": "ipfs",
        "appendCBOR": true
      },
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      },
      "evmVersion": "paris",
      "viaIR": false,
      "libraries": {}
    }
  }}