@@ -1954,7 +1954,7 @@ mod chainlink_precompile {
19541954 use hydradx_traits:: { router:: AssetPair , AggregatedPriceOracle , OraclePeriod } ;
19551955 use pallet_ema_oracle:: Price ;
19561956 use pallet_lbp:: AssetId ;
1957- use primitives:: constants:: chain:: { OMNIPOOL_SOURCE , XYK_SOURCE } ;
1957+ use primitives:: constants:: chain:: { GIGAHDX_SOURCE , OMNIPOOL_SOURCE , XYK_SOURCE } ;
19581958 use primitives:: EvmAddress ;
19591959
19601960 fn assert_prices_are_same ( ema_price : Price , precompile_price : U256 , asset_a_decimals : u8 , asset_b_decimals : u8 ) {
@@ -2692,6 +2692,118 @@ mod chainlink_precompile {
26922692 pretty_assertions:: assert_eq!( r, expected_decimals) ;
26932693 } ) ;
26942694 }
2695+
2696+ const STHDX : AssetId = 670 ;
2697+ const HDX_ID : AssetId = 0 ;
2698+
2699+ fn register_st_hdx ( ) {
2700+ if hydradx_runtime:: AssetRegistry :: decimals ( STHDX ) . is_some ( ) {
2701+ return ;
2702+ }
2703+ assert_ok ! ( hydradx_runtime:: AssetRegistry :: register(
2704+ RuntimeOrigin :: root( ) ,
2705+ Some ( STHDX ) ,
2706+ Some ( b"stHDX" . to_vec( ) . try_into( ) . unwrap( ) ) ,
2707+ pallet_asset_registry:: AssetType :: Token ,
2708+ Some ( 1u128 ) ,
2709+ Some ( b"stHDX" . to_vec( ) . try_into( ) . unwrap( ) ) ,
2710+ Some ( 12u8 ) ,
2711+ None ,
2712+ None ,
2713+ true ,
2714+ ) ) ;
2715+ }
2716+
2717+ fn seed_gigapot_and_supply ( gigapot_hdx : Balance , st_hdx_supply : Balance ) {
2718+ // `total_gigahdx_supply` reads orml-tokens issuance directly.
2719+ orml_tokens:: TotalIssuance :: < Runtime > :: set ( STHDX , st_hdx_supply) ;
2720+ let gigapot = pallet_gigahdx:: Pallet :: < Runtime > :: gigapot_account_id ( ) ;
2721+ assert_ok ! ( Balances :: force_set_balance( RuntimeOrigin :: root( ) , gigapot, gigapot_hdx, ) ) ;
2722+ }
2723+
2724+ fn chainlink_latest_answer ( address : EvmAddress ) -> U256 {
2725+ let data = EvmDataWriter :: new_with_selector ( AggregatorInterface :: LatestAnswer ) . build ( ) ;
2726+ let mut handle = MockHandle {
2727+ input : data,
2728+ context : Context {
2729+ address : evm_address ( ) ,
2730+ caller : address,
2731+ apparent_value : U256 :: from ( 0 ) ,
2732+ } ,
2733+ code_address : address,
2734+ is_static : true ,
2735+ } ;
2736+ let PrecompileOutput { output, exit_status } =
2737+ ChainlinkOraclePrecompile :: < Runtime > :: execute ( & mut handle) . unwrap ( ) ;
2738+ pretty_assertions:: assert_eq!( exit_status, ExitSucceed :: Returned ) ;
2739+ U256 :: from_big_endian ( & output)
2740+ }
2741+
2742+ #[ test]
2743+ fn chainlink_precompile_should_return_gigahdx_exchange_rate_when_source_is_gigahdx ( ) {
2744+ TestNet :: reset ( ) ;
2745+
2746+ Hydra :: execute_with ( || {
2747+ register_st_hdx ( ) ;
2748+ // 110 HDX in gigapot, 100 stHDX issued ⇒ rate = 1.1.
2749+ seed_gigapot_and_supply ( 110 * UNITS , 100 * UNITS ) ;
2750+
2751+ pretty_assertions:: assert_eq!(
2752+ pallet_gigahdx:: Pallet :: <Runtime >:: exchange_rate( ) . cmp( & hydra_dx_math:: ratio:: Ratio :: new( 11 , 10 ) ) ,
2753+ std:: cmp:: Ordering :: Equal
2754+ ) ;
2755+
2756+ let address = encode_oracle_address ( STHDX , HDX_ID , OraclePeriod :: TenMinutes , GIGAHDX_SOURCE ) ;
2757+
2758+ // Pin the canonical mainnet feed address.
2759+ pretty_assertions:: assert_eq!(
2760+ address,
2761+ EvmAddress :: from( hex!( "0000010267696761686478730000029e00000000" ) )
2762+ ) ;
2763+
2764+ pretty_assertions:: assert_eq!( chainlink_latest_answer( address) , U256 :: from( 110_000_000u128 ) ) ;
2765+ } ) ;
2766+ }
2767+
2768+ #[ test]
2769+ fn chainlink_precompile_should_floor_at_one_when_gigahdx_reserves_drained ( ) {
2770+ TestNet :: reset ( ) ;
2771+
2772+ Hydra :: execute_with ( || {
2773+ register_st_hdx ( ) ;
2774+ // Full drain: native rate would be 0 — pallet floor must clamp to 1.0.
2775+ seed_gigapot_and_supply ( 0 , 100 * UNITS ) ;
2776+
2777+ pretty_assertions:: assert_eq!(
2778+ pallet_gigahdx:: Pallet :: <Runtime >:: exchange_rate( ) . cmp( & hydra_dx_math:: ratio:: Ratio :: one( ) ) ,
2779+ std:: cmp:: Ordering :: Equal
2780+ ) ;
2781+
2782+ let address = encode_oracle_address ( STHDX , HDX_ID , OraclePeriod :: TenMinutes , GIGAHDX_SOURCE ) ;
2783+
2784+ pretty_assertions:: assert_eq!( chainlink_latest_answer( address) , U256 :: from( 100_000_000u128 ) ) ;
2785+ } ) ;
2786+ }
2787+
2788+ #[ test]
2789+ fn chainlink_precompile_should_floor_at_one_when_gigahdx_partially_drained ( ) {
2790+ TestNet :: reset ( ) ;
2791+
2792+ Hydra :: execute_with ( || {
2793+ register_st_hdx ( ) ;
2794+ // Partial drain: native rate would be 0.5 — clamp must hit 1.0, not 50_000_000.
2795+ seed_gigapot_and_supply ( 50 * UNITS , 100 * UNITS ) ;
2796+
2797+ pretty_assertions:: assert_eq!(
2798+ pallet_gigahdx:: Pallet :: <Runtime >:: exchange_rate( ) . cmp( & hydra_dx_math:: ratio:: Ratio :: one( ) ) ,
2799+ std:: cmp:: Ordering :: Equal
2800+ ) ;
2801+
2802+ let address = encode_oracle_address ( STHDX , HDX_ID , OraclePeriod :: TenMinutes , GIGAHDX_SOURCE ) ;
2803+
2804+ pretty_assertions:: assert_eq!( chainlink_latest_answer( address) , U256 :: from( 100_000_000u128 ) ) ;
2805+ } ) ;
2806+ }
26952807}
26962808
26972809mod contract_deployment {
0 commit comments