@@ -205,14 +205,14 @@ module aave_oracle::oracle {
205205
206206 match (cap_info.type) {
207207 AdapterType::SUSDE => {
208- let (assets_prices, _) = get_asset_prices_and_timestamps_internal (
209- vector [asset, *option::borrow (&cap_info.mapped_asset_ratio_multiplier)]
210- );
208+ // Get sUSDe/USDe exchange rate (already in 18 decimals) WITHOUT capping —
209+ // this is the adapter’s internal ratio, not a capped quote.
210+ let (underlying_asset_price, _) = get_asset_price_internal (asset);
211+
212+ // Get the mapped base asset (e.g., USDT) price THROUGH the capped path.
213+ let mapped = *option::borrow (&cap_info.mapped_asset_ratio_multiplier);
214+ let (asset_base_ratio, _) = get_asset_price_and_timestamp (mapped);
211215
212- // It means "underlying_asset_price" is the price of sUSDe/USDe exchange rate
213- // expressed in 18 decimals already
214- let underlying_asset_price = assets_prices[0 ]; // sUSDe/USDe exchange rate
215- let asset_base_ratio = assets_prices[1 ]; // USDT price
216216 let (_, is_capped) = get_capped_susde_price (
217217 underlying_asset_price, asset_base_ratio, &cap_info
218218 );
@@ -304,13 +304,17 @@ module aave_oracle::oracle {
304304
305305 match (cap_info.type) {
306306 AdapterType::SUSDE => {
307- let (assets_prices, assets_timestamps) = get_asset_prices_and_timestamps_internal (
308- vector [asset, *option::borrow (&cap_info.mapped_asset_ratio_multiplier)]
307+ // sUSDe/USDe exchange rate (18 decimals), from the adapter’s raw (uncapped) internal path
308+ let (underlying_asset_price, underlying_asset_timestamp) = get_asset_price_internal (
309+ asset
310+ );
311+
312+ // Mapped base asset (e.g., USDT) fetched through the capped path
313+ let mapped = *option::borrow (&cap_info.mapped_asset_ratio_multiplier);
314+ let (asset_base_ratio, asset_base_timestamp) = get_asset_price_and_timestamp (
315+ mapped
309316 );
310- let underlying_asset_price = assets_prices[0 ];
311- let asset_base_ratio = assets_prices[1 ];
312- let underlying_asset_timestamp = assets_timestamps[0 ];
313- let asset_base_timestamp = assets_timestamps[1 ];
317+
314318 let (underlying_asset_capped_price, _) = get_capped_susde_price (
315319 underlying_asset_price, asset_base_ratio, &cap_info
316320 );
@@ -564,11 +568,32 @@ module aave_oracle::oracle {
564568 only_asset_listing_or_pool_admin (account);
565569 assert !(custom_price > 0 , error_config::get_ezero_asset_custom_price ());
566570 if (is_asset_price_capped (asset)) {
567- let (capped_price, _) = get_asset_price_and_timestamp (asset);
568- assert !(
569- custom_price <= capped_price,
570- error_config::get_ecustom_price_above_price_cap ()
571- );
571+ // Inspect the adapter type so we compare apples-to-apples.
572+ let pod = borrow_global <PriceOracleData >(oracle_address ());
573+ if (smart_table::contains (&pod.capped_assets_data, asset)) {
574+ let cap_info = *smart_table::borrow (&pod.capped_assets_data, asset);
575+
576+ match (cap_info.type) {
577+ // For STABLE: `custom_price` is a USD-denominated price → compare to USD capped price.
578+ AdapterType::STABLE => {
579+ let (capped_price, _) = get_asset_price_and_timestamp (asset);
580+ assert !(
581+ custom_price <= capped_price,
582+ error_config::get_ecustom_price_above_price_cap ()
583+ );
584+ },
585+
586+ // For SUSDE: `custom_price` is a *ratio* (sUSDe/USDe, 18 dp).
587+ // Compare directly to the max allowed ratio (unit-consistent), NOT to the USD price.
588+ AdapterType::SUSDE => {
589+ let max_ratio = get_max_allowed_susde_ratio (&cap_info);
590+ assert !(
591+ custom_price <= max_ratio,
592+ error_config::get_ecustom_price_above_price_cap ()
593+ );
594+ }
595+ }
596+ }
572597 };
573598 update_asset_custom_price (asset, custom_price);
574599 }
@@ -694,6 +719,20 @@ module aave_oracle::oracle {
694719 (prices, timestamps)
695720 }
696721
722+ /// Max allowed sUSDe/USDe ratio given the snapshot and growth parameters.
723+ /// Assumes parameters were validated in `set_susde_price_adapter`.
724+ /// @param cap Capped asset data
725+ /// @return The max allowed sUSDe/USDe ratio in 18 decimals
726+ fun get_max_allowed_susde_ratio (cap: &CappedAssetData ): u256 {
727+ let snapshot_ratio = *option::borrow (&cap.snapshot_ratio);
728+ let snapshot_ts = *option::borrow (&cap.snapshot_timestamp);
729+ let growth_per_s = *option::borrow (&cap.max_ratio_growth_per_second);
730+ let now = timestamp::now_seconds () as u256 ;
731+
732+ // Saturating behavior not needed because params are pre-validated against overflow
733+ snapshot_ratio + growth_per_s * (now - snapshot_ts)
734+ }
735+
697736 // Private helper functions
698737 /// @notice Applies stable price capping logic to a base price
699738 /// @param base_price The original asset price before capping
0 commit comments