// SPDX-License-Identifier: Apache-2.0 pragma solidity ^0.8.0; import {IERC20Metadata} from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; import {Policy} from "../Policy.sol"; import {IEToken} from "./IEToken.sol"; import {IRiskModule} from "./IRiskModule.sol"; import {IAccessManager} from "./IAccessManager.sol"; interface IPolicyPool { /** * @dev Event emitted every time a new policy is added to the pool. Contains all the data about the policy that is * later required for doing operations with the policy like resolution or expiration. * * @param riskModule The risk module that created the policy * @param policy The {Policy-PolicyData} struct with all the immutable fields of the policy. */ event NewPolicy(IRiskModule indexed riskModule, Policy.PolicyData policy); /** * @dev Event emitted every time a new policy replaces an old Policy Contains all the data about the policy that is * later required for doing operations with the policy like resolution or expiration. * * @param riskModule The risk module that created the policy * @param oldPolicyId The id of the replaced policy. * @param newPolicyId The id of the new policy. */ event PolicyReplaced(IRiskModule indexed riskModule, uint256 indexed oldPolicyId, uint256 indexed newPolicyId); /** * @dev Event emitted every time a policy is removed from the pool. If the policy expired, the `payout` is 0, * otherwise is the amount transferred to the policyholder. * * @param riskModule The risk module where that created the policy initially. * @param policyId The unique id of the policy * @param payout The payout that has been paid to the policy holder. 0 when the policy expired. */ event PolicyResolved(IRiskModule indexed riskModule, uint256 indexed policyId, uint256 payout); /** * @dev Reference to the main currency (ERC20) used in the protocol * @return The address of the currency (e.g. USDC) token used in the protocol */ function currency() external view returns (IERC20Metadata); /** * @dev Reference to the {AccessManager} contract, this contract manages the access controls. * @return The address of the AccessManager contract */ function access() external view returns (IAccessManager); /** * @dev Address of the treasury, that receives protocol fees. * @return The address of the treasury */ function treasury() external view returns (address); /** * @dev Creates a new Policy. Must be called from an active RiskModule * * Requirements: * - `msg.sender` must be an active RiskModule * - `caller` approved the spending of `currency()` for at least `policy.premium` * - `internalId` must be unique within `policy.riskModule` and not used before * * Events: * - {PolicyPool-NewPolicy}: with all the details about the policy * - {ERC20-Transfer}: does several transfers from caller address to the different receivers of the premium * (see Premium Split in the docs) * * @param policy A policy created with {Policy-initialize} * @param payer The address that will pay for the premium * @param policyHolder The address of the policy holder * @param internalId A unique id within the RiskModule, that will be used to compute the policy id * @return The policy id, identifying the NFT and the policy */ function newPolicy( Policy.PolicyData memory policy, address payer, address policyHolder, uint96 internalId ) external returns (uint256); /** * @dev Replaces a policy with another. Must be called from an active RiskModule * * Requirements: * - `msg.sender` must be an active RiskModule * - `caller` approved the spending of `currency()` for at least `newPolicy_.premium - oldPolicy.premium` * - `internalId` must be unique within `policy.riskModule` and not used before * * Events: * - {PolicyPool-PolicyReplaced}: with all the details about the policy * - {ERC20-Transfer}: does several transfers from caller address to the different receivers of the premium * (see Premium Split in the docs) * * @param oldPolicy A policy created previously and not expired * @param newPolicy_ A policy created with {Policy-initialize} * @param payer The address that will pay for the premium * @param internalId A unique id within the RiskModule, that will be used to compute the policy id * @return The policy id, identifying the NFT and the policy */ function replacePolicy( Policy.PolicyData memory oldPolicy, Policy.PolicyData memory newPolicy_, address payer, uint96 internalId ) external returns (uint256); /** * @dev Resolves a policy with a payout. Must be called from an active RiskModule * * Requirements: * - `policy`: must be a Policy previously created with `newPolicy` (checked with `policy.hash()`) and not * resolved before and not expired (if payout > 0). * - `payout`: must be less than equal to `policy.payout`. * * Events: * - {PolicyPool-PolicyResolved}: with the payout * - {ERC20-Transfer}: to the policyholder with the payout * * @param policy A policy previously created with `newPolicy` * @param payout The amount to paid to the policyholder */ function resolvePolicy(Policy.PolicyData calldata policy, uint256 payout) external; /** * @dev Resolves a policy with a payout that can be either 0 or the maximum payout of the policy * * Requirements: * - `policy`: must be a Policy previously created with `newPolicy` (checked with `policy.hash()`) and not * resolved before and not expired (if customerWon). * * Events: * - {PolicyPool-PolicyResolved}: with the payout * - {ERC20-Transfer}: to the policyholder with the payout * * @param policy A policy previously created with `newPolicy` * @param customerWon Indicated if the payout is zero or the maximum payout */ function resolvePolicyFullPayout(Policy.PolicyData calldata policy, bool customerWon) external; /** * @dev Resolves a policy with a payout 0, unlocking the solvency. Can be called by anyone, but only after * `Policy.expiration`. * * Requirements: * - `policy`: must be a Policy previously created with `newPolicy` (checked with `policy.hash()`) and not resolved * before * - Policy expired: `Policy.expiration` <= block.timestamp * * Events: * - {PolicyPool-PolicyResolved}: with payout == 0 * * @param policy A policy previously created with `newPolicy` */ function expirePolicy(Policy.PolicyData calldata policy) external; /** * @dev Returns whether a policy is active, i.e., it's still in the PolicyPool, not yet resolved or expired. * Be aware that a policy might be active but the `block.timestamp` might be after the expiration date, so it * can't be triggered with a payout. * * @param policyId The id of the policy queried * @return Whether the policy is active or not */ function isActive(uint256 policyId) external view returns (bool); /** * @dev Returns the stored hash of the policy. It's `bytes32(0)` is the policy isn't active. * * @param policyId The id of the policy queried * @return Returns the hash of a given policy id */ function getPolicyHash(uint256 policyId) external view returns (bytes32); /** * @dev Deposits liquidity into an eToken. Forwards the call to {EToken-deposit}, after transferring the funds. * The user will receive etokens for the same amount deposited. * * Requirements: * - `msg.sender` approved the spending of `currency()` for at least `amount` * - `eToken` is an active eToken installed in the pool. * * Events: * - {EToken-Transfer}: from 0x0 to `msg.sender`, reflects the eTokens minted. * - {ERC20-Transfer}: from `msg.sender` to address(eToken) * * @param eToken The address of the eToken to which the user wants to provide liquidity * @param amount The amount to deposit */ function deposit(IEToken eToken, uint256 amount) external; /** * @dev Withdraws an amount from an eToken. Forwards the call to {EToken-withdraw}. * `amount` of eTokens will be burned and the user will receive the same amount in `currency()`. * * Requirements: * - `eToken` is an active (or deprecated) eToken installed in the pool. * * Events: * - {EToken-Transfer}: from `msg.sender` to `0x0`, reflects the eTokens burned. * - {ERC20-Transfer}: from address(eToken) to `msg.sender` * * @param eToken The address of the eToken from where the user wants to withdraw liquidity * @param amount The amount to withdraw. If equal to type(uint256).max, means full withdrawal. * If the balance is not enough or can't be withdrawn (locked as SCR), it withdraws * as much as it can, but doesn't fails. * @return Returns the actual amount withdrawn. */ function withdraw(IEToken eToken, uint256 amount) external returns (uint256); }