@@ -44,7 +44,7 @@ contract ReservoirPriceOracleTest is BaseTest {
4444 // writes the cached prices, for easy testing
4545 function _writePriceCache (address aToken0 , address aToken1 , uint256 aPrice ) internal {
4646 require (aToken0 < aToken1, "tokens unsorted " );
47- require (bytes32 ( aPrice) & bytes2 ( 0xffff ) == 0 , "PRICE WILL OVERLAP FLAG " );
47+ require (aPrice <= Constants.MAX_SUPPORTED_PRICE , "price too large " );
4848
4949 vm.record ();
5050 _oracle.priceCache (aToken0, aToken1);
@@ -98,7 +98,7 @@ contract ReservoirPriceOracleTest is BaseTest {
9898 _writePriceCache (address (_tokenB), address (_tokenC), lPrice);
9999
100100 // assert
101- (uint256 lQueriedPrice ,) = _oracle.priceCache (address (_tokenB), address (_tokenC));
101+ (uint256 lQueriedPrice ,, ) = _oracle.priceCache (address (_tokenB), address (_tokenC));
102102 assertEq (lQueriedPrice, lPrice);
103103 }
104104
@@ -124,7 +124,7 @@ contract ReservoirPriceOracleTest is BaseTest {
124124
125125 // arrange
126126 _writePriceCache (address (_tokenA), address (_tokenB), lPrice);
127- (uint256 lQueriedPrice ,) = _oracle.priceCache (address (_tokenA), address (_tokenB));
127+ (uint256 lQueriedPrice ,, ) = _oracle.priceCache (address (_tokenA), address (_tokenB));
128128 assertEq (lQueriedPrice, lPrice);
129129
130130 // act
@@ -219,11 +219,11 @@ contract ReservoirPriceOracleTest is BaseTest {
219219 lRoute[2 ] = address (lTokenC);
220220
221221 {
222- uint16 [] memory lBpDiffForMaxReward = new uint16 [](2 );
223- lBpDiffForMaxReward[0 ] = lBpDiffForMaxReward[1 ] = Constants.BP_SCALE;
224- _oracle.setRoute (address (lTokenA), address (lTokenC), lRoute, lBpDiffForMaxReward);
225- _writePriceCache (address (lTokenA), address (lTokenB), 1e18 );
226- _writePriceCache (address (lTokenC), address (lTokenB), 1e18 );
222+ uint16 [] memory lBpDiffForMaxReward = new uint16 [](2 );
223+ lBpDiffForMaxReward[0 ] = lBpDiffForMaxReward[1 ] = Constants.BP_SCALE;
224+ _oracle.setRoute (address (lTokenA), address (lTokenC), lRoute, lBpDiffForMaxReward);
225+ _writePriceCache (address (lTokenA), address (lTokenB), 1e18 );
226+ _writePriceCache (address (lTokenC), address (lTokenB), 1e18 );
227227 }
228228
229229 // act
@@ -415,6 +415,17 @@ contract ReservoirPriceOracleTest is BaseTest {
415415 assertEq (lAmtOut / 1e12 , lAmtIn * lRate / 1e18 );
416416 }
417417
418+ function testPriceCache_Inverted () external {
419+ // arrange
420+ _writePriceCache (address (_tokenA), address (_tokenB), 1e18 );
421+
422+ // act
423+ (uint256 lPrice ,,) = _oracle.priceCache (address (_tokenB), address (_tokenA));
424+
425+ // assert
426+ assertEq (lPrice, 0 );
427+ }
428+
418429 function testUpdateTwapPeriod (uint256 aNewPeriod ) external {
419430 // assume
420431 uint64 lNewPeriod = uint64 (bound (aNewPeriod, 1 , 1 hours));
@@ -439,9 +450,9 @@ contract ReservoirPriceOracleTest is BaseTest {
439450 assertEq (_oracle.rewardGasAmount (), lNewRewardMultiplier);
440451 }
441452
442- function testUpdatePrice_FirstUpdate () external {
453+ function testUpdatePrice_FirstUpdate () public {
443454 // sanity
444- (uint256 lPrice ,) = _oracle.priceCache (address (_tokenA), address (_tokenB));
455+ (uint256 lPrice ,, ) = _oracle.priceCache (address (_tokenA), address (_tokenB));
445456 assertEq (lPrice, 0 );
446457
447458 // arrange
@@ -450,23 +461,41 @@ contract ReservoirPriceOracleTest is BaseTest {
450461 skip (1 );
451462 _pair.sync ();
452463 skip (_oracle.twapPeriod () * 2 );
453- _tokenA.mint (address (_pair), 2e18 );
454- _pair.swap (2e18 , true , address (this ), "" );
464+ _pair.sync ();
455465
456466 // act
457467 _oracle.updatePrice (address (_tokenB), address (_tokenA), address (this ));
458468
459469 // assert
460- (lPrice,) = _oracle.priceCache (address (_tokenA), address (_tokenB));
470+ (lPrice,, ) = _oracle.priceCache (address (_tokenA), address (_tokenB));
461471 assertEq (lPrice, 98_918_868_099_219_913_512 );
462- (lPrice,) = _oracle.priceCache (address (_tokenB), address (_tokenA));
472+ (lPrice,, ) = _oracle.priceCache (address (_tokenB), address (_tokenA));
463473 assertEq (lPrice, 0 );
464474 assertEq (address (this ).balance, 0 ); // there should be no reward for the first price update
465475 }
466476
467- function testUpdatePrice_WithinThreshold () external {
477+ function testUpdatePrice_NoPriceChange () external {
468478 // arrange
469- _writePriceCache (address (_tokenA), address (_tokenB), 98.9223e18 );
479+ testUpdatePrice_FirstUpdate ();
480+ uint256 lExpectedPrice = 98_918_868_099_219_913_512 ;
481+ (uint256 lPrice ,,) = _oracle.priceCache (address (_tokenA), address (_tokenB));
482+ assertEq (lPrice, lExpectedPrice); // ensure that there is a price to begin with
483+ skip (_oracle.twapPeriod () * 2 );
484+ _pair.sync ();
485+
486+ // act
487+ _oracle.updatePrice (address (_tokenA), address (_tokenB), address (this ));
488+
489+ // assert
490+ (lPrice,,) = _oracle.priceCache (address (_tokenA), address (_tokenB));
491+ assertEq (lPrice, lExpectedPrice);
492+ assertEq (address (this ).balance, 0 ); // no reward as the price did not change at all
493+ }
494+
495+ function testUpdatePrice_BelowMaxReward () external {
496+ // arrange
497+ uint256 lOriginalPrice = 98.9223e18 ;
498+ _writePriceCache (address (_tokenA), address (_tokenB), lOriginalPrice);
470499 deal (address (_oracle), 1 ether);
471500
472501 skip (1 );
@@ -479,14 +508,14 @@ contract ReservoirPriceOracleTest is BaseTest {
479508 _oracle.updatePrice (address (_tokenB), address (_tokenA), address (this ));
480509
481510 // assert
482- (uint256 lPrice ,) = _oracle.priceCache (address (_tokenA), address (_tokenB));
511+ (uint256 lPrice ,, ) = _oracle.priceCache (address (_tokenA), address (_tokenB));
483512 assertEq (lPrice, 98_918_868_099_219_913_512 );
484- (lPrice,) = _oracle. priceCache ( address (_tokenB), address (_tokenA));
485- assertEq (lPrice, 0 ) ;
486- assertEq (address (this ).balance, 0 ); // no reward since price is within threshold
513+ uint256 lExpectedRewardReceived =
514+ block . basefee * _oracle. rewardGasAmount () * lOriginalPrice. calcPercentageDiff (lPrice) / 1e18 ;
515+ assertEq (address (this ).balance, lExpectedRewardReceived ); // some reward received but is less than max possible reward
487516 }
488517
489- function testUpdatePrice_BeyondThreshold () external {
518+ function testUpdatePrice_BeyondMaxReward () external {
490519 // arrange
491520 _writePriceCache (address (_tokenA), address (_tokenB), 5e18 );
492521 deal (address (_oracle), 1 ether);
@@ -501,15 +530,16 @@ contract ReservoirPriceOracleTest is BaseTest {
501530 _oracle.updatePrice (address (_tokenB), address (_tokenA), address (this ));
502531
503532 // assert
504- (uint256 lPrice ,) = _oracle.priceCache (address (_tokenA), address (_tokenB));
533+ (uint256 lPrice ,, ) = _oracle.priceCache (address (_tokenA), address (_tokenB));
505534 assertEq (lPrice, 98_918_868_099_219_913_512 );
506- (lPrice,) = _oracle.priceCache (address (_tokenB), address (_tokenA));
535+ (lPrice,, ) = _oracle.priceCache (address (_tokenB), address (_tokenA));
507536 assertEq (lPrice, 0 );
508- assertEq (address (this ).balance, block .basefee * _oracle.rewardGasAmount ());
509- assertEq (address (_oracle).balance, 1 ether - block .basefee * _oracle.rewardGasAmount ());
537+ uint256 lExpectedRewardReceived = block .basefee * _oracle.rewardGasAmount ();
538+ assertEq (address (this ).balance, lExpectedRewardReceived);
539+ assertEq (address (_oracle).balance, 1 ether - lExpectedRewardReceived);
510540 }
511541
512- function testUpdatePrice_BeyondThreshold_InsufficientReward (uint256 aRewardAvailable ) external {
542+ function testUpdatePrice_RewardEligible_InsufficientReward (uint256 aRewardAvailable ) external {
513543 // assume
514544 uint256 lRewardAvailable = bound (aRewardAvailable, 1 , block .basefee * _oracle.rewardGasAmount () - 1 );
515545
@@ -526,11 +556,13 @@ contract ReservoirPriceOracleTest is BaseTest {
526556 // act
527557 _oracle.updatePrice (address (_tokenA), address (_tokenB), address (this ));
528558
529- // assert
530- assertEq (address (this ).balance, 0 ); // no reward as there's insufficient ether in the contract
559+ // assert - no reward as there's insufficient ether in the contract, but price cache updated nonetheless
560+ (uint256 lPrice ,,) = _oracle.priceCache (address (_tokenA), address (_tokenB));
561+ assertNotEq (lPrice, 5e18 );
562+ assertEq (address (this ).balance, 0 );
531563 }
532564
533- function testUpdatePrice_BeyondThreshold_ZeroRecipient () external {
565+ function testUpdatePrice_RewardEligible_ZeroRecipient () external {
534566 // arrange
535567 uint256 lBalance = 10 ether ;
536568 deal (address (_oracle), lBalance);
@@ -545,7 +577,9 @@ contract ReservoirPriceOracleTest is BaseTest {
545577 // act
546578 _oracle.updatePrice (address (_tokenA), address (_tokenB), address (0 ));
547579
548- // assert - no change to balance
580+ // assert - no change to balance, but price cache updated nonetheless
581+ (uint256 lPrice ,,) = _oracle.priceCache (address (_tokenA), address (_tokenB));
582+ assertNotEq (lPrice, 5e18 );
549583 assertEq (address (_oracle).balance, lBalance);
550584 }
551585
@@ -595,10 +629,10 @@ contract ReservoirPriceOracleTest is BaseTest {
595629 _oracle.updatePrice (address (_tokenA), address (_tokenB), address (this ));
596630
597631 // assert
598- (uint256 lPriceAC ,) = _oracle.priceCache (lStart, lIntermediate1);
599- (uint256 lPriceCD ,) = _oracle.priceCache (lIntermediate1, lIntermediate2);
600- (uint256 lPriceBD ,) = _oracle.priceCache (lEnd, lIntermediate2);
601- (uint256 lPriceAB ,) = _oracle.priceCache (lStart, lEnd);
632+ (uint256 lPriceAC ,, ) = _oracle.priceCache (lStart, lIntermediate1);
633+ (uint256 lPriceCD ,, ) = _oracle.priceCache (lIntermediate1, lIntermediate2);
634+ (uint256 lPriceBD ,, ) = _oracle.priceCache (lEnd, lIntermediate2);
635+ (uint256 lPriceAB ,, ) = _oracle.priceCache (lStart, lEnd);
602636 assertApproxEqRel (lPriceAC, 0.5e18 , 0.0001e18 );
603637 assertApproxEqRel (lPriceCD, 2e18 , 0.0001e18 );
604638 assertApproxEqRel (lPriceBD, 2e18 , 0.0001e18 );
@@ -623,7 +657,7 @@ contract ReservoirPriceOracleTest is BaseTest {
623657 // assert
624658 address [] memory lQueriedRoute = _oracle.route (lToken0, lToken1);
625659 assertEq (lQueriedRoute, lRoute);
626- (, int256 lDecimalDiff ) = _oracle.priceCache (lToken0, lToken1);
660+ (, int256 lDecimalDiff , ) = _oracle.priceCache (lToken0, lToken1);
627661 int256 lActualDiff = int256 (uint256 (IERC20 (lToken1).decimals ())) - int256 (uint256 (IERC20 (lToken0).decimals ()));
628662 assertEq (lDecimalDiff, lActualDiff);
629663 }
@@ -720,7 +754,7 @@ contract ReservoirPriceOracleTest is BaseTest {
720754 // assert
721755 lQueriedRoute = _oracle.route (lToken0, lToken1);
722756 assertEq (lQueriedRoute, new address [](0 ));
723- (uint256 lPrice ,) = _oracle.priceCache (lToken0, lToken1);
757+ (uint256 lPrice ,, ) = _oracle.priceCache (lToken0, lToken1);
724758 assertEq (lPrice, 0 );
725759 }
726760
0 commit comments