@@ -374,37 +374,6 @@ contract AaveV3Horizon_PriceFeed_20260404_Test is ProtocolV3HorizonTestBase {
374374 _assertCapBounded (oracle, AaveV3EthereumHorizonAssets.USDC_UNDERLYING, usdcAdapter, 'USDC ' );
375375 }
376376
377- function _assertCapBounded (
378- IAaveOracle oracle ,
379- address underlying ,
380- IPriceCapAdapterStable adapter ,
381- string memory label
382- ) internal {
383- int256 priceCap = adapter.getPriceCap ();
384- int256 spike = priceCap + int256 (1e7 ); // $0.10 above cap
385-
386- address underlyingFeed = adapter.ASSET_TO_USD_AGGREGATOR ();
387- vm.mockCall (
388- underlyingFeed,
389- abi.encodeWithSelector (AggregatorInterface.latestAnswer.selector ),
390- abi.encode (spike)
391- );
392- vm.mockCall (
393- underlyingFeed,
394- abi.encodeWithSelector (AggregatorInterface.latestRoundData.selector ),
395- abi.encode (uint80 (1 ), spike, block .timestamp , block .timestamp , uint80 (1 ))
396- );
397-
398- uint256 priceFromPool = oracle.getAssetPrice (underlying);
399- assertEq (
400- priceFromPool,
401- uint256 (priceCap),
402- string .concat (label, ': pool oracle price not clamped to cap on upstream spike ' )
403- );
404-
405- vm.clearMockedCalls ();
406- }
407-
408377 /// @dev when the underlying feed reports a price below the cap, the pool oracle must pass it through uncapped
409378 function test_priceFlowsThrough_belowCap_viaPool_after () public virtual {
410379 _executePayload ();
@@ -446,38 +415,6 @@ contract AaveV3Horizon_PriceFeed_20260404_Test is ProtocolV3HorizonTestBase {
446415 }
447416 }
448417
449- function _assertPriceFlowsThrough (
450- IAaveOracle oracle ,
451- address underlying ,
452- IPriceCapAdapterStable adapter ,
453- string memory label
454- ) internal {
455- int256 priceCap = adapter.getPriceCap ();
456- int256 belowCap = priceCap - int256 (1e6 ); // $0.01 below cap in 8-decimal precision
457- require (belowCap > 0 , 'belowCap should be positive ' );
458-
459- address underlyingFeed = adapter.ASSET_TO_USD_AGGREGATOR ();
460- vm.mockCall (
461- underlyingFeed,
462- abi.encodeWithSelector (AggregatorInterface.latestAnswer.selector ),
463- abi.encode (belowCap)
464- );
465- vm.mockCall (
466- underlyingFeed,
467- abi.encodeWithSelector (AggregatorInterface.latestRoundData.selector ),
468- abi.encode (uint80 (1 ), belowCap, block .timestamp , block .timestamp , uint80 (1 ))
469- );
470-
471- uint256 priceFromPool = oracle.getAssetPrice (underlying);
472- assertEq (
473- priceFromPool,
474- uint256 (belowCap),
475- string .concat (label, ': pool oracle should pass through underlying when below cap ' )
476- );
477-
478- vm.clearMockedCalls ();
479- }
480-
481418 /// @dev `setPriceCap` only callable by `CallerIsNotRiskOrPoolAdmin`
482419 function test_setPriceCap_unauthorized_reverts () public virtual {
483420 address randomUser = makeAddr ('randomUser ' );
@@ -586,16 +523,67 @@ contract AaveV3Horizon_PriceFeed_20260404_Test is ProtocolV3HorizonTestBase {
586523 _executeHorizonPayload (address (proposal));
587524 }
588525
589- /// @dev Override expected price feeds so the snapshot validator in defaultTest accepts the new oracles.
590- /// Returns the proposal's `NEW_*_ORACLE` constants as literals to keep this `pure` (matching the base helper).
591- function _expectedPriceFeed (address underlying ) internal pure override returns (address ) {
592- if (underlying == AaveV3EthereumHorizonAssets.RLUSD_UNDERLYING) {
593- return 0x9E7c31e9b3C76Ea759D9f7464210353862F0c957 ; // NEW_RLUSD_ORACLE
594- }
595- if (underlying == AaveV3EthereumHorizonAssets.USDC_UNDERLYING) {
596- return 0x46f94aff8cF7DdC8557eF69f7276087b01C8f363 ; // NEW_USDC_ORACLE
597- }
598- return super ._expectedPriceFeed (underlying);
526+ function _assertCapBounded (
527+ IAaveOracle oracle ,
528+ address underlying ,
529+ IPriceCapAdapterStable adapter ,
530+ string memory label
531+ ) internal {
532+ int256 priceCap = adapter.getPriceCap ();
533+ int256 spike = priceCap + int256 (1e7 ); // $0.10 above cap
534+
535+ address underlyingFeed = adapter.ASSET_TO_USD_AGGREGATOR ();
536+ vm.mockCall (
537+ underlyingFeed,
538+ abi.encodeWithSelector (AggregatorInterface.latestAnswer.selector ),
539+ abi.encode (spike)
540+ );
541+ vm.mockCall (
542+ underlyingFeed,
543+ abi.encodeWithSelector (AggregatorInterface.latestRoundData.selector ),
544+ abi.encode (uint80 (1 ), spike, block .timestamp , block .timestamp , uint80 (1 ))
545+ );
546+
547+ uint256 priceFromPool = oracle.getAssetPrice (underlying);
548+ assertEq (
549+ priceFromPool,
550+ uint256 (priceCap),
551+ string .concat (label, ': pool oracle price not clamped to cap on upstream spike ' )
552+ );
553+
554+ vm.clearMockedCalls ();
555+ }
556+
557+ function _assertPriceFlowsThrough (
558+ IAaveOracle oracle ,
559+ address underlying ,
560+ IPriceCapAdapterStable adapter ,
561+ string memory label
562+ ) internal {
563+ int256 priceCap = adapter.getPriceCap ();
564+ int256 belowCap = priceCap - int256 (1e6 ); // $0.01 below cap in 8-decimal precision
565+ require (belowCap > 0 , 'belowCap should be positive ' );
566+
567+ address underlyingFeed = adapter.ASSET_TO_USD_AGGREGATOR ();
568+ vm.mockCall (
569+ underlyingFeed,
570+ abi.encodeWithSelector (AggregatorInterface.latestAnswer.selector ),
571+ abi.encode (belowCap)
572+ );
573+ vm.mockCall (
574+ underlyingFeed,
575+ abi.encodeWithSelector (AggregatorInterface.latestRoundData.selector ),
576+ abi.encode (uint80 (1 ), belowCap, block .timestamp , block .timestamp , uint80 (1 ))
577+ );
578+
579+ uint256 priceFromPool = oracle.getAssetPrice (underlying);
580+ assertEq (
581+ priceFromPool,
582+ uint256 (belowCap),
583+ string .concat (label, ': pool oracle should pass through underlying when below cap ' )
584+ );
585+
586+ vm.clearMockedCalls ();
599587 }
600588
601589 function _assertFuzzedBounded (
@@ -623,4 +611,16 @@ contract AaveV3Horizon_PriceFeed_20260404_Test is ProtocolV3HorizonTestBase {
623611
624612 vm.clearMockedCalls ();
625613 }
614+
615+ /// @dev Override expected price feeds so the snapshot validator in defaultTest accepts the new oracles.
616+ /// Returns the proposal's `NEW_*_ORACLE` constants as literals to keep this `pure` (matching the base helper).
617+ function _expectedPriceFeed (address underlying ) internal pure override returns (address ) {
618+ if (underlying == AaveV3EthereumHorizonAssets.RLUSD_UNDERLYING) {
619+ return 0x9E7c31e9b3C76Ea759D9f7464210353862F0c957 ; // NEW_RLUSD_ORACLE
620+ }
621+ if (underlying == AaveV3EthereumHorizonAssets.USDC_UNDERLYING) {
622+ return 0x46f94aff8cF7DdC8557eF69f7276087b01C8f363 ; // NEW_USDC_ORACLE
623+ }
624+ return super ._expectedPriceFeed (underlying);
625+ }
626626}
0 commit comments