ETH Price: $3,123.73 (+0.01%)

Contract

0x1C98F659C0F293CdF2d7Bc98CaC1f11Ca4e8fB37

Overview

ETH Balance

0 ETH

ETH Value

$0.00

More Info

Private Name Tags

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To

There are no matching entries

Please try again later

Parent Transaction Hash Block From To
View All Internal Transactions

Cross-Chain Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
PoolMath

Compiler Version
v0.8.25+commit.b61c2a91

Optimization Enabled:
Yes with 1 runs

Other Settings:
paris EvmVersion
// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.25;

// Libraries
import { RayMath } from "../libs/RayMath.sol";

// @bw move back into vpool ?

library PoolMath {
  using RayMath for uint256;

  // ======= CONSTANTS ======= //

  uint256 constant YEAR = 365 days;
  uint256 constant RAY = RayMath.RAY;
  uint256 constant MAX_SECONDS_PER_TICK = 1 days;
  uint256 constant FEE_BASE = RAY;
  uint256 constant PERCENTAGE_BASE = 100;
  uint256 constant FULL_CAPACITY = PERCENTAGE_BASE * RAY;

  // ======= STRUCTURES ======= //

  struct Formula {
    uint256 uOptimal;
    uint256 r0;
    uint256 rSlope1;
    uint256 rSlope2;
  }

  // ======= FUNCTIONS ======= //

  /**
   * @notice Computes the premium rate of a cover,
   * the premium rate is the APR cost for a cover  ,
   * these are paid by cover buyer on their cover amount.
   *
   * @param formula The formula of the pool
   * @param utilizationRate_ The utilization rate of the pool
   *
   * @return The premium rate of the cover expressed in rays
   *
   * @dev Not pure since reads self but pure for all practical purposes
   */
  function getPremiumRate(
    Formula calldata formula,
    uint256 utilizationRate_
  ) public pure returns (uint256 /* premiumRate */) {
    if (utilizationRate_ < formula.uOptimal) {
      // Return base rate + proportional slope 1 rate
      return
        formula.r0 +
        formula.rSlope1.rayMul(
          utilizationRate_.rayDiv(formula.uOptimal)
        );
    } else if (utilizationRate_ < FULL_CAPACITY) {
      // Return base rate + slope 1 rate + proportional slope 2 rate
      return
        formula.r0 +
        formula.rSlope1 +
        formula.rSlope2.rayMul(
          (utilizationRate_ - formula.uOptimal).rayDiv(
            FULL_CAPACITY - formula.uOptimal
          )
        );
    } else {
      // Return base rate + slope 1 rate + slope 2 rate
      /**
       * @dev Premium rate is capped because in case of overusage the
       * liquidity providers are exposed to the same risk as 100% usage but
       * cover buyers are not fully covered.
       * This means cover buyers only pay for the effective cover they have.
       */
      return formula.r0 + formula.rSlope1 + formula.rSlope2;
    }
  }

  /**
   * @notice Computes the liquidity index for a given period
   * @param utilizationRate_ The utilization rate
   * @param premiumRate_ The premium rate
   * @param timeSeconds_ The time in seconds
   * @return The liquidity index to add for the given time
   */
  function computeLiquidityIndex(
    uint256 utilizationRate_,
    uint256 premiumRate_,
    uint256 timeSeconds_
  ) public pure returns (uint /* liquidityIndex */) {
    return
      utilizationRate_
        .rayMul(premiumRate_)
        .rayMul(timeSeconds_)
        .rayDiv(YEAR);
  }

  /**
   * @notice Computes the premiums or interests earned by a liquidity position
   * @param userCapital_ The amount of liquidity in the position
   * @param endLiquidityIndex_ The end liquidity index
   * @param startLiquidityIndex_ The start liquidity index
   */
  function getCoverRewards(
    uint256 userCapital_,
    uint256 startLiquidityIndex_,
    uint256 endLiquidityIndex_
  ) public pure returns (uint256) {
    return
      (userCapital_.rayMul(endLiquidityIndex_) -
        userCapital_.rayMul(startLiquidityIndex_)) / 10_000;
  }

  /**
   * @notice Computes the new daily cost of a cover,
   * the emmission rate is the daily cost of a cover  .
   *
   * @param oldDailyCost_ The daily cost of the cover before the change
   * @param oldPremiumRate_ The premium rate of the cover before the change
   * @param newPremiumRate_ The premium rate of the cover after the change
   *
   * @return The new daily cost of the cover expressed in tokens/day
   */
  function getDailyCost(
    uint256 oldDailyCost_,
    uint256 oldPremiumRate_,
    uint256 newPremiumRate_
  ) public pure returns (uint256) {
    return (oldDailyCost_ * newPremiumRate_) / oldPremiumRate_;
  }

  /**
   * @notice Computes the new seconds per tick of a pool,
   * the seconds per tick is the time between two ticks  .
   *
   * @param oldSecondsPerTick_ The seconds per tick before the change
   * @param oldPremiumRate_ The premium rate before the change
   * @param newPremiumRate_ The premium rate after the change
   *
   * @return The new seconds per tick of the pool
   */
  function secondsPerTick(
    uint256 oldSecondsPerTick_,
    uint256 oldPremiumRate_,
    uint256 newPremiumRate_
  ) public pure returns (uint256) {
    return
      oldSecondsPerTick_.rayMul(oldPremiumRate_).rayDiv(
        newPremiumRate_
      );
  }

  /**
   * @notice Computes the updated premium rate of the pool based on utilization.
   * @param formula The formula of the pool
   * @param secondsPerTick_ The seconds per tick of the pool
   * @param coveredCapital_ The amount of covered capital
   * @param totalLiquidity_ The total amount liquidity
   * @param newCoveredCapital_ The new amount of covered capital
   * @param newTotalLiquidity_ The new total amount liquidity
   *
   * @return newPremiumRate The updated premium rate of the pool
   * @return newSecondsPerTick The updated seconds per tick of the pool
   */
  function updatePoolMarket(
    Formula calldata formula,
    uint256 secondsPerTick_,
    uint256 totalLiquidity_,
    uint256 coveredCapital_,
    uint256 newTotalLiquidity_,
    uint256 newCoveredCapital_
  )
    public
    pure
    returns (
      uint256 newPremiumRate,
      uint256 newSecondsPerTick,
      uint256 newUtilizationRate
    )
  {
    uint256 previousPremiumRate = getPremiumRate(
      formula,
      _utilization(coveredCapital_, totalLiquidity_)
    );

    newUtilizationRate = _utilization(
      newCoveredCapital_,
      newTotalLiquidity_
    );

    newPremiumRate = getPremiumRate(formula, newUtilizationRate);

    newSecondsPerTick = secondsPerTick(
      secondsPerTick_,
      previousPremiumRate,
      newPremiumRate
    );
  }

  /**
   * @notice Computes the percentage of the pool's liquidity used for covers.
   * @param coveredCapital_ The amount of covered capital
   * @param liquidity_ The total amount liquidity
   *
   * @return rate The utilization rate of the pool
   *
   * @dev The utilization rate is capped at 100%.
   */
  function _utilization(
    uint256 coveredCapital_,
    uint256 liquidity_
  ) public pure returns (uint256 /* rate */) {
    // If the pool has no liquidity then the utilization rate is 0
    if (liquidity_ == 0) return 0;

    /**
     * @dev Utilization rate is capped at 100% because in case of overusage the
     * liquidity providers are exposed to the same risk as 100% usage but
     * cover buyers are not fully covered.
     * This means cover buyers only pay for the effective cover they have.
     */
    if (liquidity_ < coveredCapital_) return FULL_CAPACITY;

    // Get a base PERCENTAGE_BASE percentage
    return (coveredCapital_ * PERCENTAGE_BASE).rayDiv(liquidity_);
  }
}

// SPDX-License-Identifier: agpl-3.0
pragma solidity 0.8.25;

/**
 * @title RayMath library
 * @author Aave
 * @dev Provides mul and div function for rays (decimals with 27 digits)
 **/

library RayMath {
  uint256 internal constant RAY = 1e27;
  uint256 internal constant halfRAY = RAY / 2;

  /**
   * @dev Multiplies two ray, rounding half up to the nearest ray
   * @param a Ray
   * @param b Ray
   * @return The result of a*b, in ray
   **/
  function rayMul(
    uint256 a,
    uint256 b
  ) internal pure returns (uint256) {
    return (a * b + halfRAY) / RAY;
  }

  /**
   * @dev Divides two ray, rounding half up to the nearest ray
   * @param a Ray
   * @param b Ray
   * @return The result of a/b, in ray
   **/
  function rayDiv(
    uint256 a,
    uint256 b
  ) internal pure returns (uint256) {
    return ((a * RAY) + (b / 2)) / b;
  }
}

Settings
{
  "optimizer": {
    "enabled": true,
    "runs": 1
  },
  "evmVersion": "paris",
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "libraries": {}
}

Contract Security Audit

Contract ABI

API
[{"inputs":[{"internalType":"uint256","name":"coveredCapital_","type":"uint256"},{"internalType":"uint256","name":"liquidity_","type":"uint256"}],"name":"_utilization","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"utilizationRate_","type":"uint256"},{"internalType":"uint256","name":"premiumRate_","type":"uint256"},{"internalType":"uint256","name":"timeSeconds_","type":"uint256"}],"name":"computeLiquidityIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"userCapital_","type":"uint256"},{"internalType":"uint256","name":"startLiquidityIndex_","type":"uint256"},{"internalType":"uint256","name":"endLiquidityIndex_","type":"uint256"}],"name":"getCoverRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"oldDailyCost_","type":"uint256"},{"internalType":"uint256","name":"oldPremiumRate_","type":"uint256"},{"internalType":"uint256","name":"newPremiumRate_","type":"uint256"}],"name":"getDailyCost","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"uOptimal","type":"uint256"},{"internalType":"uint256","name":"r0","type":"uint256"},{"internalType":"uint256","name":"rSlope1","type":"uint256"},{"internalType":"uint256","name":"rSlope2","type":"uint256"}],"internalType":"struct PoolMath.Formula","name":"formula","type":"tuple"},{"internalType":"uint256","name":"utilizationRate_","type":"uint256"}],"name":"getPremiumRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"oldSecondsPerTick_","type":"uint256"},{"internalType":"uint256","name":"oldPremiumRate_","type":"uint256"},{"internalType":"uint256","name":"newPremiumRate_","type":"uint256"}],"name":"secondsPerTick","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"uOptimal","type":"uint256"},{"internalType":"uint256","name":"r0","type":"uint256"},{"internalType":"uint256","name":"rSlope1","type":"uint256"},{"internalType":"uint256","name":"rSlope2","type":"uint256"}],"internalType":"struct PoolMath.Formula","name":"formula","type":"tuple"},{"internalType":"uint256","name":"secondsPerTick_","type":"uint256"},{"internalType":"uint256","name":"totalLiquidity_","type":"uint256"},{"internalType":"uint256","name":"coveredCapital_","type":"uint256"},{"internalType":"uint256","name":"newTotalLiquidity_","type":"uint256"},{"internalType":"uint256","name":"newCoveredCapital_","type":"uint256"}],"name":"updatePoolMarket","outputs":[{"internalType":"uint256","name":"newPremiumRate","type":"uint256"},{"internalType":"uint256","name":"newSecondsPerTick","type":"uint256"},{"internalType":"uint256","name":"newUtilizationRate","type":"uint256"}],"stateMutability":"pure","type":"function"}]

6104db610039600b82828239805160001a607314602c57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600436106100775760003560e01c806313717b121461007c5780634eb1fe9b146100a25780635b521a78146100b5578063b76920b8146100e3578063bf4a9186146100f6578063d344572d14610109578063ecc6776d1461011c575b600080fd5b61008f61008a366004610352565b61012f565b6040519081526020015b60405180910390f35b61008f6100b0366004610352565b61015b565b6100c86100c3366004610396565b610188565b60408051938452602084019290925290820152606001610099565b61008f6100f1366004610352565b6101d0565b61008f6101043660046103e3565b6101dd565b61008f610117366004610405565b61022c565b61008f61012a366004610352565b6102ec565b60006101536301e1338061014d8461014788886102f8565b906102f8565b9061032f565b949350505050565b600061271061016a85856102f8565b61017486856102f8565b61017e9190610446565b6101539190610459565b60008060008061019c8a610117898b6101dd565b90506101a885876101dd565b91506101b48a8361022c565b93506101c18982866102ec565b92505096509650969350505050565b60008261017e838661047b565b6000816000036101ef57506000610226565b828210156102145761020d676765c793fa10079d601b1b606461047b565b9050610226565b6102238261014d60648661047b565b90505b92915050565b6000823582101561025e5761025061024583853561032f565b6040850135906102f8565b61020d906020850135610492565b610274676765c793fa10079d601b1b606461047b565b8210156102d5576102b96102ae8435610299676765c793fa10079d601b1b606461047b565b6102a39190610446565b61014d863586610446565b6060850135906102f8565b6102cb60408501356020860135610492565b61020d9190610492565b60608301356102cb60408501356020860135610492565b60006101538261014d86865b6000676765c793fa10079d601b1b610311600282610459565b61031b848661047b565b6103259190610492565b6102239190610459565b60008161033d600282610459565b61031b676765c793fa10079d601b1b8661047b565b60008060006060848603121561036757600080fd5b505081359360208301359350604090920135919050565b60006080828403121561039057600080fd5b50919050565b60008060008060008061012087890312156103b057600080fd5b6103ba888861037e565b986080880135985060a08801359760c0810135975060e081013596506101000135945092505050565b600080604083850312156103f657600080fd5b50508035926020909101359150565b60008060a0838503121561041857600080fd5b610422848461037e565b946080939093013593505050565b634e487b7160e01b600052601160045260246000fd5b8181038181111561022657610226610430565b60008261047657634e487b7160e01b600052601260045260246000fd5b500490565b808202811582820484141761022657610226610430565b808201808211156102265761022661043056fea2646970667358221220e5f184439776e3184c0dfba3351802be636636050140f403d3b4d6535494e34d64736f6c63430008190033

Deployed Bytecode

0x731c98f659c0f293cdf2d7bc98cac1f11ca4e8fb3730146080604052600436106100775760003560e01c806313717b121461007c5780634eb1fe9b146100a25780635b521a78146100b5578063b76920b8146100e3578063bf4a9186146100f6578063d344572d14610109578063ecc6776d1461011c575b600080fd5b61008f61008a366004610352565b61012f565b6040519081526020015b60405180910390f35b61008f6100b0366004610352565b61015b565b6100c86100c3366004610396565b610188565b60408051938452602084019290925290820152606001610099565b61008f6100f1366004610352565b6101d0565b61008f6101043660046103e3565b6101dd565b61008f610117366004610405565b61022c565b61008f61012a366004610352565b6102ec565b60006101536301e1338061014d8461014788886102f8565b906102f8565b9061032f565b949350505050565b600061271061016a85856102f8565b61017486856102f8565b61017e9190610446565b6101539190610459565b60008060008061019c8a610117898b6101dd565b90506101a885876101dd565b91506101b48a8361022c565b93506101c18982866102ec565b92505096509650969350505050565b60008261017e838661047b565b6000816000036101ef57506000610226565b828210156102145761020d676765c793fa10079d601b1b606461047b565b9050610226565b6102238261014d60648661047b565b90505b92915050565b6000823582101561025e5761025061024583853561032f565b6040850135906102f8565b61020d906020850135610492565b610274676765c793fa10079d601b1b606461047b565b8210156102d5576102b96102ae8435610299676765c793fa10079d601b1b606461047b565b6102a39190610446565b61014d863586610446565b6060850135906102f8565b6102cb60408501356020860135610492565b61020d9190610492565b60608301356102cb60408501356020860135610492565b60006101538261014d86865b6000676765c793fa10079d601b1b610311600282610459565b61031b848661047b565b6103259190610492565b6102239190610459565b60008161033d600282610459565b61031b676765c793fa10079d601b1b8661047b565b60008060006060848603121561036757600080fd5b505081359360208301359350604090920135919050565b60006080828403121561039057600080fd5b50919050565b60008060008060008061012087890312156103b057600080fd5b6103ba888861037e565b986080880135985060a08801359760c0810135975060e081013596506101000135945092505050565b600080604083850312156103f657600080fd5b50508035926020909101359150565b60008060a0838503121561041857600080fd5b610422848461037e565b946080939093013593505050565b634e487b7160e01b600052601160045260246000fd5b8181038181111561022657610226610430565b60008261047657634e487b7160e01b600052601260045260246000fd5b500490565b808202811582820484141761022657610226610430565b808201808211156102265761022661043056fea2646970667358221220e5f184439776e3184c0dfba3351802be636636050140f403d3b4d6535494e34d64736f6c63430008190033

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.