@@ -14,16 +14,38 @@ contract PercentageMathFunctions {
1414 function percentDiv (uint256 x , uint256 y ) public pure returns (uint256 ) {
1515 return PercentageMath.percentDiv (x, y);
1616 }
17+
18+ function weightedAvg (
19+ uint256 x ,
20+ uint256 y ,
21+ uint256 percentage
22+ ) public pure returns (uint256 ) {
23+ return PercentageMath.weightedAvg (x, y, percentage);
24+ }
1725}
1826
1927contract PercentageMathFunctionsRef {
28+ error PercentageTooHigh ();
29+
2030 function percentMul (uint256 x , uint256 y ) public pure returns (uint256 ) {
2131 return PercentageMathRef.percentMul (x, y);
2232 }
2333
2434 function percentDiv (uint256 x , uint256 y ) public pure returns (uint256 ) {
2535 return PercentageMathRef.percentDiv (x, y);
2636 }
37+
38+ function weightedAvg (
39+ uint256 x ,
40+ uint256 y ,
41+ uint256 percentage
42+ ) public pure returns (uint256 ) {
43+ if (percentage > PercentageMath.PERCENTAGE_FACTOR) revert PercentageTooHigh ();
44+
45+ return
46+ PercentageMathRef.percentMul (x, PercentageMathRef.PERCENTAGE_FACTOR - percentage) +
47+ PercentageMathRef.percentMul (y, percentage);
48+ }
2749}
2850
2951contract TestPercentageMath is Test {
@@ -75,6 +97,30 @@ contract TestPercentageMath is Test {
7597 PercentageMath.percentDiv (x, y);
7698 }
7799
100+ function testWeightedAvg (
101+ uint256 x ,
102+ uint256 y ,
103+ uint16 percentage
104+ ) public {
105+ vm.assume (percentage <= PERCENTAGE_FACTOR);
106+ if (percentage > 0 ) vm.assume (y <= MAX_UINT256_MINUS_HALF_PERCENTAGE / percentage);
107+ if (percentage < PERCENTAGE_FACTOR)
108+ vm.assume (x <= MAX_UINT256_MINUS_HALF_PERCENTAGE / (PERCENTAGE_FACTOR - percentage));
109+
110+ assertEq (PercentageMath.weightedAvg (x, y, percentage), mathRef.weightedAvg (x, y, percentage));
111+ }
112+
113+ function testWeightedAvgRevertWhenPercentageTooHigh (
114+ uint256 x ,
115+ uint256 y ,
116+ uint256 percentage
117+ ) public {
118+ vm.assume (percentage > PERCENTAGE_FACTOR);
119+
120+ vm.expectRevert (abi.encodeWithSignature ("PercentageTooHigh() " ));
121+ PercentageMath.weightedAvg (x, y, percentage);
122+ }
123+
78124 /// GAS COMPARISONS ///
79125
80126 function testGasPercentageMul () public view {
@@ -86,4 +132,9 @@ contract TestPercentageMath is Test {
86132 math.percentDiv (1 ether, 1_000 );
87133 mathRef.percentDiv (1 ether, 1_000 );
88134 }
135+
136+ function testGasPercentageAvg () public view {
137+ math.weightedAvg (1 ether, 2 ether, 5_000 );
138+ mathRef.weightedAvg (1 ether, 2 ether, 5_000 );
139+ }
89140}
0 commit comments