From 643304a69cdde0fa915ae71181cb6f16d0699bd4 Mon Sep 17 00:00:00 2001 From: Quentin Garchery Date: Fri, 8 Dec 2023 18:54:40 +0100 Subject: [PATCH 1/6] refactor: rename math operations --- src/AdaptiveCurveIrm.sol | 10 ++++----- src/libraries/MathLib.sol | 6 +++-- test/AdaptiveCurveIrmTest.sol | 41 ++++++++++++++--------------------- test/ExpLibTest.sol | 4 ++-- 4 files changed, 27 insertions(+), 34 deletions(-) diff --git a/src/AdaptiveCurveIrm.sol b/src/AdaptiveCurveIrm.sol index 4e769b4b..705089d4 100644 --- a/src/AdaptiveCurveIrm.sol +++ b/src/AdaptiveCurveIrm.sol @@ -114,7 +114,7 @@ contract AdaptiveCurveIrm is IAdaptiveCurveIrm { int256(market.totalSupplyAssets > 0 ? market.totalBorrowAssets.wDivDown(market.totalSupplyAssets) : 0); int256 errNormFactor = utilization > TARGET_UTILIZATION ? WAD - TARGET_UTILIZATION : TARGET_UTILIZATION; - int256 err = (utilization - TARGET_UTILIZATION).wDivDown(errNormFactor); + int256 err = (utilization - TARGET_UTILIZATION).wDiv(errNormFactor); int256 startRateAtTarget = rateAtTarget[id]; @@ -128,7 +128,7 @@ contract AdaptiveCurveIrm is IAdaptiveCurveIrm { } else { // Note that the speed is assumed constant between two interactions, but in theory it increases because of // interests. So the rate will be slightly underestimated. - int256 speed = ADJUSTMENT_SPEED.wMulDown(err); + int256 speed = ADJUSTMENT_SPEED.wMul(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); @@ -168,16 +168,16 @@ contract AdaptiveCurveIrm is IAdaptiveCurveIrm { /// ((C-1)*err + 1) * rateAtTarget else. function _curve(int256 _rateAtTarget, int256 err) private view returns (int256) { // Non negative because 1 - 1/C >= 0, C - 1 >= 0. - int256 coeff = err < 0 ? WAD - WAD.wDivDown(CURVE_STEEPNESS) : CURVE_STEEPNESS - WAD; + int256 coeff = err < 0 ? WAD - WAD.wDiv(CURVE_STEEPNESS) : CURVE_STEEPNESS - WAD; // Non negative if _rateAtTarget >= 0 because if err < 0, coeff <= 1. - return (coeff.wMulDown(err) + WAD).wMulDown(int256(_rateAtTarget)); + return (coeff.wMul(err) + WAD).wMul(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.wMulDown(ExpLib.wExp(linearAdaptation)).bound( + return startRateAtTarget.wMul(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 fb0c7000..15ffd78d 100644 --- a/src/libraries/MathLib.sol +++ b/src/libraries/MathLib.sol @@ -10,11 +10,13 @@ int256 constant WAD_INT = int256(WAD); /// @custom:contact security@morpho.org /// @notice Library to manage fixed-point arithmetic on signed integers. library MathLib { - function wMulDown(int256 a, int256 b) internal pure returns (int256) { + /// @dev Returns the multiplication of `a` by `b` (in WAD) rounded towards 0. + function wMul(int256 a, int256 b) internal pure returns (int256) { return a * b / WAD_INT; } - function wDivDown(int256 a, int256 b) internal pure returns (int256) { + /// @dev Returns the division of `a` by `b` (in WAD) rounded towards 0. + function wDiv(int256 a, int256 b) internal pure returns (int256) { return a * WAD_INT / b; } } diff --git a/test/AdaptiveCurveIrmTest.sol b/test/AdaptiveCurveIrmTest.sol index 4e52a34b..de5e6c63 100644 --- a/test/AdaptiveCurveIrmTest.sol +++ b/test/AdaptiveCurveIrmTest.sol @@ -72,13 +72,13 @@ contract AdaptiveCurveIrmTest is Test { // (exp((50/365)*5) ~= 1.9836. assertApproxEqRel( irm.borrowRateView(marketParams, market), - uint256((INITIAL_RATE_AT_TARGET * 4).wMulDown((1.9836 ether - 1 ether) * WAD / (ADJUSTMENT_SPEED * 5 days))), + uint256((INITIAL_RATE_AT_TARGET * 4).wMul((1.9836 ether - 1 ether) * WAD / (ADJUSTMENT_SPEED * 5 days))), 0.1 ether ); // The average value of exp((50/365)*x) between 0 and 5 is approx. 1.4361. assertApproxEqRel( irm.borrowRateView(marketParams, market), - uint256((INITIAL_RATE_AT_TARGET * 4).wMulDown(1.4361 ether)), + uint256((INITIAL_RATE_AT_TARGET * 4).wMul(1.4361 ether)), 0.1 ether ); // Expected rate: 5.744%. @@ -97,16 +97,12 @@ contract AdaptiveCurveIrmTest is Test { // (exp((-50/365)*5) ~= 0.5041. assertApproxEqRel( irm.borrowRateView(marketParams, market), - uint256( - (INITIAL_RATE_AT_TARGET / 4).wMulDown((0.5041 ether - 1 ether) * WAD / (-ADJUSTMENT_SPEED * 5 days)) - ), + uint256((INITIAL_RATE_AT_TARGET / 4).wMul((0.5041 ether - 1 ether) * WAD / (-ADJUSTMENT_SPEED * 5 days))), 0.1 ether ); // The average value of exp((-50/365*x)) between 0 and 5 is approx. 0.7240. assertApproxEqRel( - irm.borrowRateView(marketParams, market), - uint256((INITIAL_RATE_AT_TARGET / 4).wMulDown(0.724 ether)), - 0.1 ether + irm.borrowRateView(marketParams, market), uint256((INITIAL_RATE_AT_TARGET / 4).wMul(0.724 ether)), 0.1 ether ); // Expected rate: 0.181%. assertApproxEqRel(irm.borrowRateView(marketParams, market), uint256(0.00181 ether) / 365 days, 0.1 ether); @@ -337,11 +333,9 @@ contract AdaptiveCurveIrmTest is Test { market.totalSupplyAssets = 10 ether; assertGe( - irm.borrowRateView(marketParams, market), uint256(ConstantsLib.MIN_RATE_AT_TARGET.wDivDown(CURVE_STEEPNESS)) - ); - assertGe( - irm.borrowRate(marketParams, market), uint256(ConstantsLib.MIN_RATE_AT_TARGET.wDivDown(CURVE_STEEPNESS)) + irm.borrowRateView(marketParams, market), uint256(ConstantsLib.MIN_RATE_AT_TARGET.wDiv(CURVE_STEEPNESS)) ); + assertGe(irm.borrowRate(marketParams, market), uint256(ConstantsLib.MIN_RATE_AT_TARGET.wDiv(CURVE_STEEPNESS))); } function invariantLeMaxRateAtTarget() public { @@ -350,23 +344,21 @@ contract AdaptiveCurveIrmTest is Test { market.totalSupplyAssets = 10 ether; assertLe( - irm.borrowRateView(marketParams, market), uint256(ConstantsLib.MAX_RATE_AT_TARGET.wMulDown(CURVE_STEEPNESS)) - ); - assertLe( - irm.borrowRate(marketParams, market), uint256(ConstantsLib.MAX_RATE_AT_TARGET.wMulDown(CURVE_STEEPNESS)) + irm.borrowRateView(marketParams, market), uint256(ConstantsLib.MAX_RATE_AT_TARGET.wMul(CURVE_STEEPNESS)) ); + assertLe(irm.borrowRate(marketParams, market), uint256(ConstantsLib.MAX_RATE_AT_TARGET.wMul(CURVE_STEEPNESS))); } /* HELPERS */ function _expectedRateAtTarget(Id id, Market memory market) internal view returns (int256) { int256 rateAtTarget = irm.rateAtTarget(id); - int256 speed = ADJUSTMENT_SPEED.wMulDown(_err(market)); + int256 speed = ADJUSTMENT_SPEED.wMul(_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.wMulDown(adaptationMultiplier).bound( + ? rateAtTarget.wMul(adaptationMultiplier).bound( ConstantsLib.MIN_RATE_AT_TARGET, ConstantsLib.MAX_RATE_AT_TARGET ) : INITIAL_RATE_AT_TARGET; @@ -375,7 +367,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 = ADJUSTMENT_SPEED.wMulDown(err); + int256 speed = ADJUSTMENT_SPEED.wMul(err); uint256 elapsed = (rateAtTarget > 0) ? block.timestamp - market.lastUpdate : 0; int256 linearAdaptation = speed * int256(elapsed); int256 endRateAtTarget = int256(_expectedRateAtTarget(id, market)); @@ -386,8 +378,7 @@ contract AdaptiveCurveIrmTest is Test { avgBorrowRate = newBorrowRate; } else { // Safe "unchecked" cast to uint256 because linearAdaptation < 0 <=> newBorrowRate <= borrowRateAfterJump. - avgBorrowRate = - uint256((int256(newBorrowRate) - int256(_curve(rateAtTarget, err))).wDivDown(linearAdaptation)); + avgBorrowRate = uint256((int256(newBorrowRate) - int256(_curve(rateAtTarget, err))).wDiv(linearAdaptation)); } return avgBorrowRate; } @@ -395,9 +386,9 @@ 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.wDivDown(CURVE_STEEPNESS)).wMulDown(err) + WAD).wMulDown(rateAtTarget)); + return uint256(((WAD - WAD.wDiv(CURVE_STEEPNESS)).wMul(err) + WAD).wMul(rateAtTarget)); } else { - return uint256(((CURVE_STEEPNESS - WAD).wMulDown(err) + WAD).wMulDown(rateAtTarget)); + return uint256(((CURVE_STEEPNESS - WAD).wMul(err) + WAD).wMul(rateAtTarget)); } } @@ -407,9 +398,9 @@ contract AdaptiveCurveIrmTest is Test { int256 utilization = int256(market.totalBorrowAssets.wDivDown(market.totalSupplyAssets)); if (utilization > TARGET_UTILIZATION) { - err = (utilization - TARGET_UTILIZATION).wDivDown(WAD - TARGET_UTILIZATION); + err = (utilization - TARGET_UTILIZATION).wDiv(WAD - TARGET_UTILIZATION); } else { - err = (utilization - TARGET_UTILIZATION).wDivDown(TARGET_UTILIZATION); + err = (utilization - TARGET_UTILIZATION).wDiv(TARGET_UTILIZATION); } } } diff --git a/test/ExpLibTest.sol b/test/ExpLibTest.sol index 81e4cd5d..fb28857a 100644 --- a/test/ExpLibTest.sol +++ b/test/ExpLibTest.sol @@ -62,8 +62,8 @@ contract ExpLibTest is Test { assertLe(ExpLib.wExp(x), 1e18); } - function testWExpWMulDownMaxRate() public pure { - ExpLib.wExp(ExpLib.WEXP_UPPER_BOUND).wMulDown(ConstantsLib.MAX_RATE_AT_TARGET); + function testWExpWMulMaxRate() public pure { + ExpLib.wExp(ExpLib.WEXP_UPPER_BOUND).wMul(ConstantsLib.MAX_RATE_AT_TARGET); } function _wExpUnbounded(int256 x) internal pure returns (int256) { From b449f69b678ee5cc2721936cca26610678d2cf33 Mon Sep 17 00:00:00 2001 From: MathisGD Date: Tue, 12 Dec 2023 09:53:46 +0100 Subject: [PATCH 2/6] style: naming --- src/AdaptiveCurveIrm.sol | 10 +++++----- src/libraries/MathLib.sol | 4 ++-- test/AdaptiveCurveIrmTest.sol | 32 ++++++++++++++++---------------- test/ExpLibTest.sol | 2 +- 4 files changed, 24 insertions(+), 24 deletions(-) diff --git a/src/AdaptiveCurveIrm.sol b/src/AdaptiveCurveIrm.sol index 705089d4..6d4167a9 100644 --- a/src/AdaptiveCurveIrm.sol +++ b/src/AdaptiveCurveIrm.sol @@ -114,7 +114,7 @@ contract AdaptiveCurveIrm is IAdaptiveCurveIrm { int256(market.totalSupplyAssets > 0 ? market.totalBorrowAssets.wDivDown(market.totalSupplyAssets) : 0); int256 errNormFactor = utilization > TARGET_UTILIZATION ? WAD - TARGET_UTILIZATION : TARGET_UTILIZATION; - int256 err = (utilization - TARGET_UTILIZATION).wDiv(errNormFactor); + int256 err = (utilization - TARGET_UTILIZATION).wDivTo0(errNormFactor); int256 startRateAtTarget = rateAtTarget[id]; @@ -128,7 +128,7 @@ contract AdaptiveCurveIrm is IAdaptiveCurveIrm { } else { // Note that the speed is assumed constant between two interactions, but in theory it increases because of // interests. So the rate will be slightly underestimated. - int256 speed = ADJUSTMENT_SPEED.wMul(err); + int256 speed = ADJUSTMENT_SPEED.wMulTo0(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); @@ -168,16 +168,16 @@ contract AdaptiveCurveIrm is IAdaptiveCurveIrm { /// ((C-1)*err + 1) * rateAtTarget else. function _curve(int256 _rateAtTarget, int256 err) private view returns (int256) { // Non negative because 1 - 1/C >= 0, C - 1 >= 0. - int256 coeff = err < 0 ? WAD - WAD.wDiv(CURVE_STEEPNESS) : CURVE_STEEPNESS - WAD; + int256 coeff = err < 0 ? WAD - WAD.wDivTo0(CURVE_STEEPNESS) : CURVE_STEEPNESS - WAD; // Non negative if _rateAtTarget >= 0 because if err < 0, coeff <= 1. - return (coeff.wMul(err) + WAD).wMul(int256(_rateAtTarget)); + return (coeff.wMulTo0(err) + WAD).wMulTo0(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.wMul(ExpLib.wExp(linearAdaptation)).bound( + return startRateAtTarget.wMulTo0(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 15ffd78d..413d2f0b 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 wMul(int256 a, int256 b) internal pure returns (int256) { + function wMulTo0(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 wDiv(int256 a, int256 b) internal pure returns (int256) { + function wDivTo0(int256 a, int256 b) internal pure returns (int256) { return a * WAD_INT / b; } } diff --git a/test/AdaptiveCurveIrmTest.sol b/test/AdaptiveCurveIrmTest.sol index de5e6c63..d3dbfb6b 100644 --- a/test/AdaptiveCurveIrmTest.sol +++ b/test/AdaptiveCurveIrmTest.sol @@ -72,13 +72,13 @@ contract AdaptiveCurveIrmTest is Test { // (exp((50/365)*5) ~= 1.9836. assertApproxEqRel( irm.borrowRateView(marketParams, market), - uint256((INITIAL_RATE_AT_TARGET * 4).wMul((1.9836 ether - 1 ether) * WAD / (ADJUSTMENT_SPEED * 5 days))), + uint256((INITIAL_RATE_AT_TARGET * 4).wMulTo0((1.9836 ether - 1 ether) * WAD / (ADJUSTMENT_SPEED * 5 days))), 0.1 ether ); // The average value of exp((50/365)*x) between 0 and 5 is approx. 1.4361. assertApproxEqRel( irm.borrowRateView(marketParams, market), - uint256((INITIAL_RATE_AT_TARGET * 4).wMul(1.4361 ether)), + uint256((INITIAL_RATE_AT_TARGET * 4).wMulTo0(1.4361 ether)), 0.1 ether ); // Expected rate: 5.744%. @@ -97,12 +97,12 @@ contract AdaptiveCurveIrmTest is Test { // (exp((-50/365)*5) ~= 0.5041. assertApproxEqRel( irm.borrowRateView(marketParams, market), - uint256((INITIAL_RATE_AT_TARGET / 4).wMul((0.5041 ether - 1 ether) * WAD / (-ADJUSTMENT_SPEED * 5 days))), + uint256((INITIAL_RATE_AT_TARGET / 4).wMulTo0((0.5041 ether - 1 ether) * WAD / (-ADJUSTMENT_SPEED * 5 days))), 0.1 ether ); // The average value of exp((-50/365*x)) between 0 and 5 is approx. 0.7240. assertApproxEqRel( - irm.borrowRateView(marketParams, market), uint256((INITIAL_RATE_AT_TARGET / 4).wMul(0.724 ether)), 0.1 ether + irm.borrowRateView(marketParams, market), uint256((INITIAL_RATE_AT_TARGET / 4).wMulTo0(0.724 ether)), 0.1 ether ); // Expected rate: 0.181%. assertApproxEqRel(irm.borrowRateView(marketParams, market), uint256(0.00181 ether) / 365 days, 0.1 ether); @@ -333,9 +333,9 @@ contract AdaptiveCurveIrmTest is Test { market.totalSupplyAssets = 10 ether; assertGe( - irm.borrowRateView(marketParams, market), uint256(ConstantsLib.MIN_RATE_AT_TARGET.wDiv(CURVE_STEEPNESS)) + irm.borrowRateView(marketParams, market), uint256(ConstantsLib.MIN_RATE_AT_TARGET.wDivTo0(CURVE_STEEPNESS)) ); - assertGe(irm.borrowRate(marketParams, market), uint256(ConstantsLib.MIN_RATE_AT_TARGET.wDiv(CURVE_STEEPNESS))); + assertGe(irm.borrowRate(marketParams, market), uint256(ConstantsLib.MIN_RATE_AT_TARGET.wDivTo0(CURVE_STEEPNESS))); } function invariantLeMaxRateAtTarget() public { @@ -344,21 +344,21 @@ contract AdaptiveCurveIrmTest is Test { market.totalSupplyAssets = 10 ether; assertLe( - irm.borrowRateView(marketParams, market), uint256(ConstantsLib.MAX_RATE_AT_TARGET.wMul(CURVE_STEEPNESS)) + irm.borrowRateView(marketParams, market), uint256(ConstantsLib.MAX_RATE_AT_TARGET.wMulTo0(CURVE_STEEPNESS)) ); - assertLe(irm.borrowRate(marketParams, market), uint256(ConstantsLib.MAX_RATE_AT_TARGET.wMul(CURVE_STEEPNESS))); + assertLe(irm.borrowRate(marketParams, market), uint256(ConstantsLib.MAX_RATE_AT_TARGET.wMulTo0(CURVE_STEEPNESS))); } /* HELPERS */ function _expectedRateAtTarget(Id id, Market memory market) internal view returns (int256) { int256 rateAtTarget = irm.rateAtTarget(id); - int256 speed = ADJUSTMENT_SPEED.wMul(_err(market)); + int256 speed = ADJUSTMENT_SPEED.wMulTo0(_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.wMul(adaptationMultiplier).bound( + ? rateAtTarget.wMulTo0(adaptationMultiplier).bound( ConstantsLib.MIN_RATE_AT_TARGET, ConstantsLib.MAX_RATE_AT_TARGET ) : INITIAL_RATE_AT_TARGET; @@ -367,7 +367,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 = ADJUSTMENT_SPEED.wMul(err); + int256 speed = ADJUSTMENT_SPEED.wMulTo0(err); uint256 elapsed = (rateAtTarget > 0) ? block.timestamp - market.lastUpdate : 0; int256 linearAdaptation = speed * int256(elapsed); int256 endRateAtTarget = int256(_expectedRateAtTarget(id, market)); @@ -378,7 +378,7 @@ contract AdaptiveCurveIrmTest is Test { avgBorrowRate = newBorrowRate; } else { // Safe "unchecked" cast to uint256 because linearAdaptation < 0 <=> newBorrowRate <= borrowRateAfterJump. - avgBorrowRate = uint256((int256(newBorrowRate) - int256(_curve(rateAtTarget, err))).wDiv(linearAdaptation)); + avgBorrowRate = uint256((int256(newBorrowRate) - int256(_curve(rateAtTarget, err))).wDivTo0(linearAdaptation)); } return avgBorrowRate; } @@ -386,9 +386,9 @@ 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.wDiv(CURVE_STEEPNESS)).wMul(err) + WAD).wMul(rateAtTarget)); + return uint256(((WAD - WAD.wDivTo0(CURVE_STEEPNESS)).wMulTo0(err) + WAD).wMulTo0(rateAtTarget)); } else { - return uint256(((CURVE_STEEPNESS - WAD).wMul(err) + WAD).wMul(rateAtTarget)); + return uint256(((CURVE_STEEPNESS - WAD).wMulTo0(err) + WAD).wMulTo0(rateAtTarget)); } } @@ -398,9 +398,9 @@ contract AdaptiveCurveIrmTest is Test { int256 utilization = int256(market.totalBorrowAssets.wDivDown(market.totalSupplyAssets)); if (utilization > TARGET_UTILIZATION) { - err = (utilization - TARGET_UTILIZATION).wDiv(WAD - TARGET_UTILIZATION); + err = (utilization - TARGET_UTILIZATION).wDivTo0(WAD - TARGET_UTILIZATION); } else { - err = (utilization - TARGET_UTILIZATION).wDiv(TARGET_UTILIZATION); + err = (utilization - TARGET_UTILIZATION).wDivTo0(TARGET_UTILIZATION); } } } diff --git a/test/ExpLibTest.sol b/test/ExpLibTest.sol index fb28857a..eee07127 100644 --- a/test/ExpLibTest.sol +++ b/test/ExpLibTest.sol @@ -63,7 +63,7 @@ contract ExpLibTest is Test { } function testWExpWMulMaxRate() public pure { - ExpLib.wExp(ExpLib.WEXP_UPPER_BOUND).wMul(ConstantsLib.MAX_RATE_AT_TARGET); + ExpLib.wExp(ExpLib.WEXP_UPPER_BOUND).wMulTo0(ConstantsLib.MAX_RATE_AT_TARGET); } function _wExpUnbounded(int256 x) internal pure returns (int256) { From 1516a1c1bf3f3f17693753350ac93f86b5b828e8 Mon Sep 17 00:00:00 2001 From: MathisGD Date: Tue, 12 Dec 2023 10:26:15 +0100 Subject: [PATCH 3/6] chore: fmt --- test/AdaptiveCurveIrmTest.sol | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/test/AdaptiveCurveIrmTest.sol b/test/AdaptiveCurveIrmTest.sol index d3dbfb6b..0acd32c7 100644 --- a/test/AdaptiveCurveIrmTest.sol +++ b/test/AdaptiveCurveIrmTest.sol @@ -102,7 +102,9 @@ 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((INITIAL_RATE_AT_TARGET / 4).wMulTo0(0.724 ether)), 0.1 ether + irm.borrowRateView(marketParams, market), + uint256((INITIAL_RATE_AT_TARGET / 4).wMulTo0(0.724 ether)), + 0.1 ether ); // Expected rate: 0.181%. assertApproxEqRel(irm.borrowRateView(marketParams, market), uint256(0.00181 ether) / 365 days, 0.1 ether); @@ -335,7 +337,9 @@ contract AdaptiveCurveIrmTest is Test { assertGe( irm.borrowRateView(marketParams, market), uint256(ConstantsLib.MIN_RATE_AT_TARGET.wDivTo0(CURVE_STEEPNESS)) ); - assertGe(irm.borrowRate(marketParams, market), uint256(ConstantsLib.MIN_RATE_AT_TARGET.wDivTo0(CURVE_STEEPNESS))); + assertGe( + irm.borrowRate(marketParams, market), uint256(ConstantsLib.MIN_RATE_AT_TARGET.wDivTo0(CURVE_STEEPNESS)) + ); } function invariantLeMaxRateAtTarget() public { @@ -346,7 +350,9 @@ contract AdaptiveCurveIrmTest is Test { assertLe( irm.borrowRateView(marketParams, market), uint256(ConstantsLib.MAX_RATE_AT_TARGET.wMulTo0(CURVE_STEEPNESS)) ); - assertLe(irm.borrowRate(marketParams, market), uint256(ConstantsLib.MAX_RATE_AT_TARGET.wMulTo0(CURVE_STEEPNESS))); + assertLe( + irm.borrowRate(marketParams, market), uint256(ConstantsLib.MAX_RATE_AT_TARGET.wMulTo0(CURVE_STEEPNESS)) + ); } /* HELPERS */ @@ -378,7 +384,8 @@ contract AdaptiveCurveIrmTest is Test { avgBorrowRate = newBorrowRate; } else { // Safe "unchecked" cast to uint256 because linearAdaptation < 0 <=> newBorrowRate <= borrowRateAfterJump. - avgBorrowRate = uint256((int256(newBorrowRate) - int256(_curve(rateAtTarget, err))).wDivTo0(linearAdaptation)); + avgBorrowRate = + uint256((int256(newBorrowRate) - int256(_curve(rateAtTarget, err))).wDivTo0(linearAdaptation)); } return avgBorrowRate; } From 4116ef86e93feee2ae3df62bf0e9dd4c4d7abb6e Mon Sep 17 00:00:00 2001 From: MathisGD Date: Tue, 12 Dec 2023 11:16:48 +0100 Subject: [PATCH 4/6] chore: fix compilation --- test/AdaptiveCurveIrmTest.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/AdaptiveCurveIrmTest.sol b/test/AdaptiveCurveIrmTest.sol index 629ba747..5e889b9b 100644 --- a/test/AdaptiveCurveIrmTest.sol +++ b/test/AdaptiveCurveIrmTest.sol @@ -417,7 +417,7 @@ contract AdaptiveCurveIrmTest is Test { // Safe "unchecked" cast because err >= -1 (in WAD). if (err < 0) { return - uint256(((WAD - WAD.wDivDown(ConstantsLib.CURVE_STEEPNESS)).wMulTo0(err) + WAD).wMulTo0(rateAtTarget)); + uint256(((WAD - WAD.wMulTo0(ConstantsLib.CURVE_STEEPNESS)).wMulTo0(err) + WAD).wMulTo0(rateAtTarget)); } else { return uint256(((ConstantsLib.CURVE_STEEPNESS - WAD).wMulTo0(err) + WAD).wMulTo0(rateAtTarget)); } From e308fa391978d124e1299b18b2b7a678c5a5289f Mon Sep 17 00:00:00 2001 From: MathisGD Date: Tue, 12 Dec 2023 11:39:53 +0100 Subject: [PATCH 5/6] chore: fmt --- test/AdaptiveCurveIrmTest.sol | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/AdaptiveCurveIrmTest.sol b/test/AdaptiveCurveIrmTest.sol index 5e889b9b..1a7aa8b2 100644 --- a/test/AdaptiveCurveIrmTest.sol +++ b/test/AdaptiveCurveIrmTest.sol @@ -416,8 +416,7 @@ 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.wMulTo0(ConstantsLib.CURVE_STEEPNESS)).wMulTo0(err) + WAD).wMulTo0(rateAtTarget)); + return uint256(((WAD - WAD.wMulTo0(ConstantsLib.CURVE_STEEPNESS)).wMulTo0(err) + WAD).wMulTo0(rateAtTarget)); } else { return uint256(((ConstantsLib.CURVE_STEEPNESS - WAD).wMulTo0(err) + WAD).wMulTo0(rateAtTarget)); } From b728864b3691ecb803e7e3a8c520b8291d2c4a2e Mon Sep 17 00:00:00 2001 From: MathisGD Date: Tue, 12 Dec 2023 12:23:41 +0100 Subject: [PATCH 6/6] test: fix test --- test/AdaptiveCurveIrmTest.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/AdaptiveCurveIrmTest.sol b/test/AdaptiveCurveIrmTest.sol index 1a7aa8b2..20a3fe83 100644 --- a/test/AdaptiveCurveIrmTest.sol +++ b/test/AdaptiveCurveIrmTest.sol @@ -416,7 +416,7 @@ 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.wMulTo0(ConstantsLib.CURVE_STEEPNESS)).wMulTo0(err) + WAD).wMulTo0(rateAtTarget)); + return uint256(((WAD - WAD.wDivTo0(ConstantsLib.CURVE_STEEPNESS)).wMulTo0(err) + WAD).wMulTo0(rateAtTarget)); } else { return uint256(((ConstantsLib.CURVE_STEEPNESS - WAD).wMulTo0(err) + WAD).wMulTo0(rateAtTarget)); }