53 lines
1.8 KiB
Solidity
53 lines
1.8 KiB
Solidity
|
|
// SPDX-License-Identifier: MIT
|
|||
|
|
pragma solidity ^0.8.20;
|
|||
|
|
|
|||
|
|
import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @title PolicyMath
|
|||
|
|
* @notice Deterministic GRU M0/M1 rules: 1.2× reserves on M0; ≤5× M1 vs M0 per line.
|
|||
|
|
* @dev Must match docs/hybx-omnl/HYBX_OMNL_POLICY_SPEC.md
|
|||
|
|
*/
|
|||
|
|
library PolicyMath {
|
|||
|
|
uint256 internal constant M0_NUM = 12;
|
|||
|
|
uint256 internal constant M0_DEN = 10;
|
|||
|
|
uint256 internal constant M1_CAP_NUM = 5;
|
|||
|
|
uint256 internal constant M1_CAP_DEN = 1;
|
|||
|
|
|
|||
|
|
/// @notice Minimum reserves R required to back S0 units of M0 (ceil(1.2 * S0)).
|
|||
|
|
function minReservesForM0(uint256 s0) internal pure returns (uint256) {
|
|||
|
|
return Math.mulDiv(s0, M0_NUM, M0_DEN, Math.Rounding.Ceil);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// @notice Maximum M1 supply allowed for S0 units of M0 (5 * S0).
|
|||
|
|
function maxM1ForM0(uint256 s0) internal pure returns (uint256) {
|
|||
|
|
return Math.mulDiv(s0, M1_CAP_NUM, M1_CAP_DEN);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function m0BackingOk(uint256 s0, uint256 r) internal pure returns (bool) {
|
|||
|
|
return r >= minReservesForM0(s0);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function m1ExpansionOk(uint256 s0, uint256 s1) internal pure returns (bool) {
|
|||
|
|
return s1 <= maxM1ForM0(s0);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function isCompliant(uint256 s0, uint256 s1, uint256 r) internal pure returns (bool) {
|
|||
|
|
return m0BackingOk(s0, r) && m1ExpansionOk(s0, s1);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function canMintM0(uint256 s0Before, uint256 mintAmount, uint256 r) internal pure returns (bool) {
|
|||
|
|
unchecked {
|
|||
|
|
uint256 s0After = s0Before + mintAmount;
|
|||
|
|
return m0BackingOk(s0After, r);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function canMintM1(uint256 s0, uint256 s1Before, uint256 mintAmount) internal pure returns (bool) {
|
|||
|
|
unchecked {
|
|||
|
|
uint256 s1After = s1Before + mintAmount;
|
|||
|
|
return m1ExpansionOk(s0, s1After);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|