Source Code
Overview
ETH Balance
0 ETH
ETH Value
$0.00
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
Contract Source Code (Solidity Standard Json-Input format)
// 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;
}
}{
"optimizer": {
"enabled": true,
"runs": 1
},
"evmVersion": "paris",
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
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"}]Contract Creation Code
6104db610039600b82828239805160001a607314602c57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600436106100775760003560e01c806313717b121461007c5780634eb1fe9b146100a25780635b521a78146100b5578063b76920b8146100e3578063bf4a9186146100f6578063d344572d14610109578063ecc6776d1461011c575b600080fd5b61008f61008a366004610352565b61012f565b6040519081526020015b60405180910390f35b61008f6100b0366004610352565b61015b565b6100c86100c3366004610396565b610188565b60408051938452602084019290925290820152606001610099565b61008f6100f1366004610352565b6101d0565b61008f6101043660046103e3565b6101dd565b61008f610117366004610405565b61022c565b61008f61012a366004610352565b6102ec565b60006101536301e1338061014d8461014788886102f8565b906102f8565b9061032f565b949350505050565b600061271061016a85856102f8565b61017486856102f8565b61017e9190610446565b6101539190610459565b60008060008061019c8a610117898b6101dd565b90506101a885876101dd565b91506101b48a8361022c565b93506101c18982866102ec565b92505096509650969350505050565b60008261017e838661047b565b6000816000036101ef57506000610226565b828210156102145761020d676765c793fa10079d601b1b606461047b565b9050610226565b6102238261014d60648661047b565b90505b92915050565b6000823582101561025e5761025061024583853561032f565b6040850135906102f8565b61020d906020850135610492565b610274676765c793fa10079d601b1b606461047b565b8210156102d5576102b96102ae8435610299676765c793fa10079d601b1b606461047b565b6102a39190610446565b61014d863586610446565b6060850135906102f8565b6102cb60408501356020860135610492565b61020d9190610492565b60608301356102cb60408501356020860135610492565b60006101538261014d86865b6000676765c793fa10079d601b1b610311600282610459565b61031b848661047b565b6103259190610492565b6102239190610459565b60008161033d600282610459565b61031b676765c793fa10079d601b1b8661047b565b60008060006060848603121561036757600080fd5b505081359360208301359350604090920135919050565b60006080828403121561039057600080fd5b50919050565b60008060008060008061012087890312156103b057600080fd5b6103ba888861037e565b986080880135985060a08801359760c0810135975060e081013596506101000135945092505050565b600080604083850312156103f657600080fd5b50508035926020909101359150565b60008060a0838503121561041857600080fd5b610422848461037e565b946080939093013593505050565b634e487b7160e01b600052601160045260246000fd5b8181038181111561022657610226610430565b60008261047657634e487b7160e01b600052601260045260246000fd5b500490565b808202811582820484141761022657610226610430565b808201808211156102265761022661043056fea2646970667358221220e5f184439776e3184c0dfba3351802be636636050140f403d3b4d6535494e34d64736f6c63430008190033
Deployed Bytecode
0x731c98f659c0f293cdf2d7bc98cac1f11ca4e8fb3730146080604052600436106100775760003560e01c806313717b121461007c5780634eb1fe9b146100a25780635b521a78146100b5578063b76920b8146100e3578063bf4a9186146100f6578063d344572d14610109578063ecc6776d1461011c575b600080fd5b61008f61008a366004610352565b61012f565b6040519081526020015b60405180910390f35b61008f6100b0366004610352565b61015b565b6100c86100c3366004610396565b610188565b60408051938452602084019290925290820152606001610099565b61008f6100f1366004610352565b6101d0565b61008f6101043660046103e3565b6101dd565b61008f610117366004610405565b61022c565b61008f61012a366004610352565b6102ec565b60006101536301e1338061014d8461014788886102f8565b906102f8565b9061032f565b949350505050565b600061271061016a85856102f8565b61017486856102f8565b61017e9190610446565b6101539190610459565b60008060008061019c8a610117898b6101dd565b90506101a885876101dd565b91506101b48a8361022c565b93506101c18982866102ec565b92505096509650969350505050565b60008261017e838661047b565b6000816000036101ef57506000610226565b828210156102145761020d676765c793fa10079d601b1b606461047b565b9050610226565b6102238261014d60648661047b565b90505b92915050565b6000823582101561025e5761025061024583853561032f565b6040850135906102f8565b61020d906020850135610492565b610274676765c793fa10079d601b1b606461047b565b8210156102d5576102b96102ae8435610299676765c793fa10079d601b1b606461047b565b6102a39190610446565b61014d863586610446565b6060850135906102f8565b6102cb60408501356020860135610492565b61020d9190610492565b60608301356102cb60408501356020860135610492565b60006101538261014d86865b6000676765c793fa10079d601b1b610311600282610459565b61031b848661047b565b6103259190610492565b6102239190610459565b60008161033d600282610459565b61031b676765c793fa10079d601b1b8661047b565b60008060006060848603121561036757600080fd5b505081359360208301359350604090920135919050565b60006080828403121561039057600080fd5b50919050565b60008060008060008061012087890312156103b057600080fd5b6103ba888861037e565b986080880135985060a08801359760c0810135975060e081013596506101000135945092505050565b600080604083850312156103f657600080fd5b50508035926020909101359150565b60008060a0838503121561041857600080fd5b610422848461037e565b946080939093013593505050565b634e487b7160e01b600052601160045260246000fd5b8181038181111561022657610226610430565b60008261047657634e487b7160e01b600052601260045260246000fd5b500490565b808202811582820484141761022657610226610430565b808201808211156102265761022661043056fea2646970667358221220e5f184439776e3184c0dfba3351802be636636050140f403d3b4d6535494e34d64736f6c63430008190033
Loading...
Loading
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 34 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
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.