diff --git a/src/AdaptiveCurveIrm.sol b/src/AdaptiveCurveIrm.sol index 166b3ad4..f19ec822 100644 --- a/src/AdaptiveCurveIrm.sol +++ b/src/AdaptiveCurveIrm.sol @@ -81,7 +81,7 @@ contract AdaptiveCurveIrm is IAdaptiveCurveIrm { int256 errNormFactor = utilization > ConstantsLib.TARGET_UTILIZATION ? WAD - ConstantsLib.TARGET_UTILIZATION : ConstantsLib.TARGET_UTILIZATION; - int256 err = (utilization - ConstantsLib.TARGET_UTILIZATION).wDivTo0(errNormFactor); + int256 err = (utilization - ConstantsLib.TARGET_UTILIZATION).wDivToZero(errNormFactor); int256 startRateAtTarget = rateAtTarget[id]; @@ -95,7 +95,7 @@ contract AdaptiveCurveIrm is IAdaptiveCurveIrm { } else { // The speed is assumed constant between two updates, but it is in fact not constant because of interest. // So the rate is always underestimated. - int256 speed = ConstantsLib.ADJUSTMENT_SPEED.wMulTo0(err); + int256 speed = ConstantsLib.ADJUSTMENT_SPEED.wMulToZero(err); // market.lastUpdate != 0 because it is not the first interaction with this market. // Safe "unchecked" cast because block.timestamp - market.lastUpdate <= block.timestamp <= type(int256).max. int256 elapsed = int256(block.timestamp - market.lastUpdate); @@ -135,16 +135,16 @@ contract AdaptiveCurveIrm is IAdaptiveCurveIrm { /// ((C-1)*err + 1) * rateAtTarget else. function _curve(int256 _rateAtTarget, int256 err) private pure returns (int256) { // Non negative because 1 - 1/C >= 0, C - 1 >= 0. - int256 coeff = err < 0 ? WAD - WAD.wDivTo0(ConstantsLib.CURVE_STEEPNESS) : ConstantsLib.CURVE_STEEPNESS - WAD; + int256 coeff = err < 0 ? WAD - WAD.wDivToZero(ConstantsLib.CURVE_STEEPNESS) : ConstantsLib.CURVE_STEEPNESS - WAD; // Non negative if _rateAtTarget >= 0 because if err < 0, coeff <= 1. - return (coeff.wMulTo0(err) + WAD).wMulTo0(int256(_rateAtTarget)); + return (coeff.wMulToZero(err) + WAD).wMulToZero(int256(_rateAtTarget)); } /// @dev Returns the new rate at target, for a given `startRateAtTarget` and a given `linearAdaptation`. /// The formula is: max(min(startRateAtTarget * exp(linearAdaptation), maxRateAtTarget), minRateAtTarget). function _newRateAtTarget(int256 startRateAtTarget, int256 linearAdaptation) private pure returns (int256) { // Non negative because MIN_RATE_AT_TARGET > 0. - return startRateAtTarget.wMulTo0(ExpLib.wExp(linearAdaptation)).bound( + return startRateAtTarget.wMulToZero(ExpLib.wExp(linearAdaptation)).bound( ConstantsLib.MIN_RATE_AT_TARGET, ConstantsLib.MAX_RATE_AT_TARGET ); } diff --git a/src/libraries/MathLib.sol b/src/libraries/MathLib.sol index 413d2f0b..3e3dbd51 100644 --- a/src/libraries/MathLib.sol +++ b/src/libraries/MathLib.sol @@ -11,12 +11,12 @@ int256 constant WAD_INT = int256(WAD); /// @notice Library to manage fixed-point arithmetic on signed integers. library MathLib { /// @dev Returns the multiplication of `a` by `b` (in WAD) rounded towards 0. - function wMulTo0(int256 a, int256 b) internal pure returns (int256) { + function wMulToZero(int256 a, int256 b) internal pure returns (int256) { return a * b / WAD_INT; } /// @dev Returns the division of `a` by `b` (in WAD) rounded towards 0. - function wDivTo0(int256 a, int256 b) internal pure returns (int256) { + function wDivToZero(int256 a, int256 b) internal pure returns (int256) { return a * WAD_INT / b; } } diff --git a/test/forge/AdaptiveCurveIrmTest.sol b/test/forge/AdaptiveCurveIrmTest.sol index 5bf27c99..8d821340 100644 --- a/test/forge/AdaptiveCurveIrmTest.sol +++ b/test/forge/AdaptiveCurveIrmTest.sol @@ -73,7 +73,7 @@ contract AdaptiveCurveIrmTest is Test { assertApproxEqRel( irm.borrowRateView(marketParams, market), uint256( - (ConstantsLib.INITIAL_RATE_AT_TARGET * 4).wMulTo0( + (ConstantsLib.INITIAL_RATE_AT_TARGET * 4).wMulToZero( (1.9836 ether - 1 ether) * WAD / (ConstantsLib.ADJUSTMENT_SPEED * 5 days) ) ), @@ -82,7 +82,7 @@ contract AdaptiveCurveIrmTest is Test { // The average value of exp((50/365)*x) between 0 and 5 is approx. 1.4361. assertApproxEqRel( irm.borrowRateView(marketParams, market), - uint256((ConstantsLib.INITIAL_RATE_AT_TARGET * 4).wMulTo0(1.4361 ether)), + uint256((ConstantsLib.INITIAL_RATE_AT_TARGET * 4).wMulToZero(1.4361 ether)), 0.1 ether ); // Expected rate: 22.976%. @@ -104,7 +104,7 @@ contract AdaptiveCurveIrmTest is Test { assertApproxEqRel( irm.borrowRateView(marketParams, market), uint256( - (ConstantsLib.INITIAL_RATE_AT_TARGET / 4).wMulTo0( + (ConstantsLib.INITIAL_RATE_AT_TARGET / 4).wMulToZero( (0.5041 ether - 1 ether) * WAD / (-ConstantsLib.ADJUSTMENT_SPEED * 5 days) ) ), @@ -113,7 +113,7 @@ contract AdaptiveCurveIrmTest is Test { // The average value of exp((-50/365*x)) between 0 and 5 is approx. 0.7240. assertApproxEqRel( irm.borrowRateView(marketParams, market), - uint256((ConstantsLib.INITIAL_RATE_AT_TARGET / 4).wMulTo0(0.724 ether)), + uint256((ConstantsLib.INITIAL_RATE_AT_TARGET / 4).wMulToZero(0.724 ether)), 0.1 ether ); // Expected rate: 0.7240%. @@ -344,11 +344,11 @@ contract AdaptiveCurveIrmTest is Test { assertGe( irm.borrowRateView(marketParams, market), - uint256(ConstantsLib.MIN_RATE_AT_TARGET.wDivTo0(ConstantsLib.CURVE_STEEPNESS)) + uint256(ConstantsLib.MIN_RATE_AT_TARGET.wDivToZero(ConstantsLib.CURVE_STEEPNESS)) ); assertGe( irm.borrowRate(marketParams, market), - uint256(ConstantsLib.MIN_RATE_AT_TARGET.wDivTo0(ConstantsLib.CURVE_STEEPNESS)) + uint256(ConstantsLib.MIN_RATE_AT_TARGET.wDivToZero(ConstantsLib.CURVE_STEEPNESS)) ); } @@ -359,11 +359,11 @@ contract AdaptiveCurveIrmTest is Test { assertLe( irm.borrowRateView(marketParams, market), - uint256(ConstantsLib.MAX_RATE_AT_TARGET.wMulTo0(ConstantsLib.CURVE_STEEPNESS)) + uint256(ConstantsLib.MAX_RATE_AT_TARGET.wMulToZero(ConstantsLib.CURVE_STEEPNESS)) ); assertLe( irm.borrowRate(marketParams, market), - uint256(ConstantsLib.MAX_RATE_AT_TARGET.wMulTo0(ConstantsLib.CURVE_STEEPNESS)) + uint256(ConstantsLib.MAX_RATE_AT_TARGET.wMulToZero(ConstantsLib.CURVE_STEEPNESS)) ); } @@ -382,12 +382,12 @@ contract AdaptiveCurveIrmTest is Test { function _expectedRateAtTarget(Id id, Market memory market) internal view returns (int256) { int256 rateAtTarget = irm.rateAtTarget(id); - int256 speed = ConstantsLib.ADJUSTMENT_SPEED.wMulTo0(_err(market)); + int256 speed = ConstantsLib.ADJUSTMENT_SPEED.wMulToZero(_err(market)); uint256 elapsed = (rateAtTarget > 0) ? block.timestamp - market.lastUpdate : 0; int256 linearAdaptation = speed * int256(elapsed); int256 adaptationMultiplier = ExpLib.wExp(linearAdaptation); return (rateAtTarget > 0) - ? rateAtTarget.wMulTo0(adaptationMultiplier).bound( + ? rateAtTarget.wMulToZero(adaptationMultiplier).bound( ConstantsLib.MIN_RATE_AT_TARGET, ConstantsLib.MAX_RATE_AT_TARGET ) : ConstantsLib.INITIAL_RATE_AT_TARGET; @@ -396,7 +396,7 @@ contract AdaptiveCurveIrmTest is Test { function _expectedAvgRate(Id id, Market memory market) internal view returns (uint256) { int256 rateAtTarget = irm.rateAtTarget(id); int256 err = _err(market); - int256 speed = ConstantsLib.ADJUSTMENT_SPEED.wMulTo0(err); + int256 speed = ConstantsLib.ADJUSTMENT_SPEED.wMulToZero(err); uint256 elapsed = (rateAtTarget > 0) ? block.timestamp - market.lastUpdate : 0; int256 linearAdaptation = speed * int256(elapsed); int256 endRateAtTarget = int256(_expectedRateAtTarget(id, market)); @@ -408,7 +408,7 @@ contract AdaptiveCurveIrmTest is Test { } else { // Safe "unchecked" cast to uint256 because linearAdaptation < 0 <=> newBorrowRate <= borrowRateAfterJump. avgBorrowRate = - uint256((int256(newBorrowRate) - int256(_curve(rateAtTarget, err))).wDivTo0(linearAdaptation)); + uint256((int256(newBorrowRate) - int256(_curve(rateAtTarget, err))).wDivToZero(linearAdaptation)); } return avgBorrowRate; } @@ -416,9 +416,11 @@ contract AdaptiveCurveIrmTest is Test { function _curve(int256 rateAtTarget, int256 err) internal pure returns (uint256) { // Safe "unchecked" cast because err >= -1 (in WAD). if (err < 0) { - return uint256(((WAD - WAD.wDivTo0(ConstantsLib.CURVE_STEEPNESS)).wMulTo0(err) + WAD).wMulTo0(rateAtTarget)); + return uint256( + ((WAD - WAD.wDivToZero(ConstantsLib.CURVE_STEEPNESS)).wMulToZero(err) + WAD).wMulToZero(rateAtTarget) + ); } else { - return uint256(((ConstantsLib.CURVE_STEEPNESS - WAD).wMulTo0(err) + WAD).wMulTo0(rateAtTarget)); + return uint256(((ConstantsLib.CURVE_STEEPNESS - WAD).wMulToZero(err) + WAD).wMulToZero(rateAtTarget)); } } @@ -428,9 +430,9 @@ contract AdaptiveCurveIrmTest is Test { int256 utilization = int256(market.totalBorrowAssets.wDivDown(market.totalSupplyAssets)); if (utilization > ConstantsLib.TARGET_UTILIZATION) { - err = (utilization - ConstantsLib.TARGET_UTILIZATION).wDivTo0(WAD - ConstantsLib.TARGET_UTILIZATION); + err = (utilization - ConstantsLib.TARGET_UTILIZATION).wDivToZero(WAD - ConstantsLib.TARGET_UTILIZATION); } else { - err = (utilization - ConstantsLib.TARGET_UTILIZATION).wDivTo0(ConstantsLib.TARGET_UTILIZATION); + err = (utilization - ConstantsLib.TARGET_UTILIZATION).wDivToZero(ConstantsLib.TARGET_UTILIZATION); } } } diff --git a/test/forge/ExpLibTest.sol b/test/forge/ExpLibTest.sol index e378b0d7..ee61ce06 100644 --- a/test/forge/ExpLibTest.sol +++ b/test/forge/ExpLibTest.sol @@ -63,7 +63,7 @@ contract ExpLibTest is Test { } function testWExpWMulMaxRate() public pure { - ExpLib.wExp(ExpLib.WEXP_UPPER_BOUND).wMulTo0(ConstantsLib.MAX_RATE_AT_TARGET); + ExpLib.wExp(ExpLib.WEXP_UPPER_BOUND).wMulToZero(ConstantsLib.MAX_RATE_AT_TARGET); } function _wExpUnbounded(int256 x) internal pure returns (int256) {