@@ -44,7 +44,7 @@ contract ReservoirPriceOracleTest is BaseTest {
44
44
// writes the cached prices, for easy testing
45
45
function _writePriceCache (address aToken0 , address aToken1 , uint256 aPrice ) internal {
46
46
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 " );
48
48
49
49
vm.record ();
50
50
_oracle.priceCache (aToken0, aToken1);
@@ -98,7 +98,7 @@ contract ReservoirPriceOracleTest is BaseTest {
98
98
_writePriceCache (address (_tokenB), address (_tokenC), lPrice);
99
99
100
100
// assert
101
- (uint256 lQueriedPrice ,) = _oracle.priceCache (address (_tokenB), address (_tokenC));
101
+ (uint256 lQueriedPrice ,, ) = _oracle.priceCache (address (_tokenB), address (_tokenC));
102
102
assertEq (lQueriedPrice, lPrice);
103
103
}
104
104
@@ -124,7 +124,7 @@ contract ReservoirPriceOracleTest is BaseTest {
124
124
125
125
// arrange
126
126
_writePriceCache (address (_tokenA), address (_tokenB), lPrice);
127
- (uint256 lQueriedPrice ,) = _oracle.priceCache (address (_tokenA), address (_tokenB));
127
+ (uint256 lQueriedPrice ,, ) = _oracle.priceCache (address (_tokenA), address (_tokenB));
128
128
assertEq (lQueriedPrice, lPrice);
129
129
130
130
// act
@@ -219,11 +219,11 @@ contract ReservoirPriceOracleTest is BaseTest {
219
219
lRoute[2 ] = address (lTokenC);
220
220
221
221
{
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 );
227
227
}
228
228
229
229
// act
@@ -415,6 +415,17 @@ contract ReservoirPriceOracleTest is BaseTest {
415
415
assertEq (lAmtOut / 1e12 , lAmtIn * lRate / 1e18 );
416
416
}
417
417
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
+
418
429
function testUpdateTwapPeriod (uint256 aNewPeriod ) external {
419
430
// assume
420
431
uint64 lNewPeriod = uint64 (bound (aNewPeriod, 1 , 1 hours));
@@ -439,9 +450,9 @@ contract ReservoirPriceOracleTest is BaseTest {
439
450
assertEq (_oracle.rewardGasAmount (), lNewRewardMultiplier);
440
451
}
441
452
442
- function testUpdatePrice_FirstUpdate () external {
453
+ function testUpdatePrice_FirstUpdate () public {
443
454
// sanity
444
- (uint256 lPrice ,) = _oracle.priceCache (address (_tokenA), address (_tokenB));
455
+ (uint256 lPrice ,, ) = _oracle.priceCache (address (_tokenA), address (_tokenB));
445
456
assertEq (lPrice, 0 );
446
457
447
458
// arrange
@@ -450,23 +461,41 @@ contract ReservoirPriceOracleTest is BaseTest {
450
461
skip (1 );
451
462
_pair.sync ();
452
463
skip (_oracle.twapPeriod () * 2 );
453
- _tokenA.mint (address (_pair), 2e18 );
454
- _pair.swap (2e18 , true , address (this ), "" );
464
+ _pair.sync ();
455
465
456
466
// act
457
467
_oracle.updatePrice (address (_tokenB), address (_tokenA), address (this ));
458
468
459
469
// assert
460
- (lPrice,) = _oracle.priceCache (address (_tokenA), address (_tokenB));
470
+ (lPrice,, ) = _oracle.priceCache (address (_tokenA), address (_tokenB));
461
471
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));
463
473
assertEq (lPrice, 0 );
464
474
assertEq (address (this ).balance, 0 ); // there should be no reward for the first price update
465
475
}
466
476
467
- function testUpdatePrice_WithinThreshold () external {
477
+ function testUpdatePrice_NoPriceChange () external {
468
478
// 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);
470
499
deal (address (_oracle), 1 ether);
471
500
472
501
skip (1 );
@@ -479,14 +508,14 @@ contract ReservoirPriceOracleTest is BaseTest {
479
508
_oracle.updatePrice (address (_tokenB), address (_tokenA), address (this ));
480
509
481
510
// assert
482
- (uint256 lPrice ,) = _oracle.priceCache (address (_tokenA), address (_tokenB));
511
+ (uint256 lPrice ,, ) = _oracle.priceCache (address (_tokenA), address (_tokenB));
483
512
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
487
516
}
488
517
489
- function testUpdatePrice_BeyondThreshold () external {
518
+ function testUpdatePrice_BeyondMaxReward () external {
490
519
// arrange
491
520
_writePriceCache (address (_tokenA), address (_tokenB), 5e18 );
492
521
deal (address (_oracle), 1 ether);
@@ -501,15 +530,16 @@ contract ReservoirPriceOracleTest is BaseTest {
501
530
_oracle.updatePrice (address (_tokenB), address (_tokenA), address (this ));
502
531
503
532
// assert
504
- (uint256 lPrice ,) = _oracle.priceCache (address (_tokenA), address (_tokenB));
533
+ (uint256 lPrice ,, ) = _oracle.priceCache (address (_tokenA), address (_tokenB));
505
534
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));
507
536
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);
510
540
}
511
541
512
- function testUpdatePrice_BeyondThreshold_InsufficientReward (uint256 aRewardAvailable ) external {
542
+ function testUpdatePrice_RewardEligible_InsufficientReward (uint256 aRewardAvailable ) external {
513
543
// assume
514
544
uint256 lRewardAvailable = bound (aRewardAvailable, 1 , block .basefee * _oracle.rewardGasAmount () - 1 );
515
545
@@ -526,11 +556,13 @@ contract ReservoirPriceOracleTest is BaseTest {
526
556
// act
527
557
_oracle.updatePrice (address (_tokenA), address (_tokenB), address (this ));
528
558
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 );
531
563
}
532
564
533
- function testUpdatePrice_BeyondThreshold_ZeroRecipient () external {
565
+ function testUpdatePrice_RewardEligible_ZeroRecipient () external {
534
566
// arrange
535
567
uint256 lBalance = 10 ether ;
536
568
deal (address (_oracle), lBalance);
@@ -545,7 +577,9 @@ contract ReservoirPriceOracleTest is BaseTest {
545
577
// act
546
578
_oracle.updatePrice (address (_tokenA), address (_tokenB), address (0 ));
547
579
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 );
549
583
assertEq (address (_oracle).balance, lBalance);
550
584
}
551
585
@@ -595,10 +629,10 @@ contract ReservoirPriceOracleTest is BaseTest {
595
629
_oracle.updatePrice (address (_tokenA), address (_tokenB), address (this ));
596
630
597
631
// 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);
602
636
assertApproxEqRel (lPriceAC, 0.5e18 , 0.0001e18 );
603
637
assertApproxEqRel (lPriceCD, 2e18 , 0.0001e18 );
604
638
assertApproxEqRel (lPriceBD, 2e18 , 0.0001e18 );
@@ -623,7 +657,7 @@ contract ReservoirPriceOracleTest is BaseTest {
623
657
// assert
624
658
address [] memory lQueriedRoute = _oracle.route (lToken0, lToken1);
625
659
assertEq (lQueriedRoute, lRoute);
626
- (, int256 lDecimalDiff ) = _oracle.priceCache (lToken0, lToken1);
660
+ (, int256 lDecimalDiff , ) = _oracle.priceCache (lToken0, lToken1);
627
661
int256 lActualDiff = int256 (uint256 (IERC20 (lToken1).decimals ())) - int256 (uint256 (IERC20 (lToken0).decimals ()));
628
662
assertEq (lDecimalDiff, lActualDiff);
629
663
}
@@ -720,7 +754,7 @@ contract ReservoirPriceOracleTest is BaseTest {
720
754
// assert
721
755
lQueriedRoute = _oracle.route (lToken0, lToken1);
722
756
assertEq (lQueriedRoute, new address [](0 ));
723
- (uint256 lPrice ,) = _oracle.priceCache (lToken0, lToken1);
757
+ (uint256 lPrice ,, ) = _oracle.priceCache (lToken0, lToken1);
724
758
assertEq (lPrice, 0 );
725
759
}
726
760
0 commit comments