|
|
@@ -1,10 +1,11 @@
|
|
|
use snforge_std::{
|
|
|
declare, ContractClassTrait, start_prank, stop_prank, CheatTarget, spy_events, SpyOn, EventSpy,
|
|
|
- EventFetcher, event_name_hash, Event
|
|
|
+ EventFetcher, event_name_hash, Event, start_warp, stop_warp
|
|
|
};
|
|
|
use pyth::pyth::{
|
|
|
IPythDispatcher, IPythDispatcherTrait, DataSource, Event as PythEvent, PriceFeedUpdated,
|
|
|
WormholeAddressSet, GovernanceDataSourceSet, ContractUpgraded, DataSourcesSet, FeeSet,
|
|
|
+ PriceFeedPublishTime, GetPriceNoOlderThanError,
|
|
|
};
|
|
|
use pyth::byte_array::{ByteArray, ByteArrayImpl};
|
|
|
use pyth::util::{array_try_into, UnwrapWithFelt252};
|
|
|
@@ -132,6 +133,144 @@ fn update_price_feeds_works() {
|
|
|
assert!(last_ema_price.publish_time == 1712589206);
|
|
|
}
|
|
|
|
|
|
+#[test]
|
|
|
+fn test_update_if_necessary_works() {
|
|
|
+ let user = 'user'.try_into().unwrap();
|
|
|
+ let wormhole = super::wormhole::deploy_with_test_guardian();
|
|
|
+ let fee_contract = deploy_fee_contract(user);
|
|
|
+ let pyth = deploy_default(wormhole.contract_address, fee_contract.contract_address);
|
|
|
+
|
|
|
+ start_prank(CheatTarget::One(fee_contract.contract_address), user);
|
|
|
+ fee_contract.approve(pyth.contract_address, 10000);
|
|
|
+ stop_prank(CheatTarget::One(fee_contract.contract_address));
|
|
|
+
|
|
|
+ let mut spy = spy_events(SpyOn::One(pyth.contract_address));
|
|
|
+
|
|
|
+ let price_id = 0xe62df6c8b4a85fe1a67db44dc12de5db330f7ac66b72dc658afedf0f4a415b43;
|
|
|
+ assert!(pyth.get_price_unsafe(price_id).is_err());
|
|
|
+
|
|
|
+ start_prank(CheatTarget::One(pyth.contract_address), user);
|
|
|
+ let times = array![PriceFeedPublishTime { price_id, publish_time: 1715769470 }];
|
|
|
+ pyth.update_price_feeds_if_necessary(data::test_price_update1(), times);
|
|
|
+
|
|
|
+ let last_price = pyth.get_price_unsafe(price_id).unwrap_with_felt252();
|
|
|
+ assert!(last_price.price == 6281060000000);
|
|
|
+ assert!(last_price.publish_time == 1715769470);
|
|
|
+
|
|
|
+ spy.fetch_events();
|
|
|
+ assert!(spy.events.len() == 1);
|
|
|
+
|
|
|
+ let times = array![PriceFeedPublishTime { price_id, publish_time: 1715769475 }];
|
|
|
+ pyth.update_price_feeds_if_necessary(data::test_price_update2(), times);
|
|
|
+
|
|
|
+ let last_price = pyth.get_price_unsafe(price_id).unwrap_with_felt252();
|
|
|
+ assert!(last_price.price == 6281522520745);
|
|
|
+ assert!(last_price.publish_time == 1715769475);
|
|
|
+
|
|
|
+ spy.fetch_events();
|
|
|
+ assert!(spy.events.len() == 2);
|
|
|
+
|
|
|
+ stop_prank(CheatTarget::One(pyth.contract_address));
|
|
|
+}
|
|
|
+
|
|
|
+#[test]
|
|
|
+#[should_panic(expected: ('no fresh update',))]
|
|
|
+fn test_update_if_necessary_rejects_empty() {
|
|
|
+ let user = 'user'.try_into().unwrap();
|
|
|
+ let wormhole = super::wormhole::deploy_with_test_guardian();
|
|
|
+ let fee_contract = deploy_fee_contract(user);
|
|
|
+ let pyth = deploy_default(wormhole.contract_address, fee_contract.contract_address);
|
|
|
+
|
|
|
+ start_prank(CheatTarget::One(fee_contract.contract_address), user);
|
|
|
+ fee_contract.approve(pyth.contract_address, 10000);
|
|
|
+ stop_prank(CheatTarget::One(fee_contract.contract_address));
|
|
|
+
|
|
|
+ start_prank(CheatTarget::One(pyth.contract_address), user);
|
|
|
+ pyth.update_price_feeds_if_necessary(data::test_price_update1(), array![]);
|
|
|
+ stop_prank(CheatTarget::One(pyth.contract_address));
|
|
|
+}
|
|
|
+
|
|
|
+#[test]
|
|
|
+#[should_panic(expected: ('no fresh update',))]
|
|
|
+fn test_update_if_necessary_rejects_no_fresh() {
|
|
|
+ let user = 'user'.try_into().unwrap();
|
|
|
+ let wormhole = super::wormhole::deploy_with_test_guardian();
|
|
|
+ let fee_contract = deploy_fee_contract(user);
|
|
|
+ let pyth = deploy_default(wormhole.contract_address, fee_contract.contract_address);
|
|
|
+
|
|
|
+ start_prank(CheatTarget::One(fee_contract.contract_address), user);
|
|
|
+ fee_contract.approve(pyth.contract_address, 10000);
|
|
|
+ stop_prank(CheatTarget::One(fee_contract.contract_address));
|
|
|
+
|
|
|
+ let mut spy = spy_events(SpyOn::One(pyth.contract_address));
|
|
|
+
|
|
|
+ start_prank(CheatTarget::One(pyth.contract_address), user);
|
|
|
+ pyth.update_price_feeds_if_necessary(data::test_price_update1(), array![]);
|
|
|
+
|
|
|
+ let price_id = 0xe62df6c8b4a85fe1a67db44dc12de5db330f7ac66b72dc658afedf0f4a415b43;
|
|
|
+ assert!(pyth.get_price_unsafe(price_id).is_err());
|
|
|
+ spy.fetch_events();
|
|
|
+ assert!(spy.events.len() == 0);
|
|
|
+
|
|
|
+ let times = array![PriceFeedPublishTime { price_id, publish_time: 1715769470 }];
|
|
|
+ pyth.update_price_feeds_if_necessary(data::test_price_update1(), times);
|
|
|
+
|
|
|
+ let last_price = pyth.get_price_unsafe(price_id).unwrap_with_felt252();
|
|
|
+ assert!(last_price.price == 6281060000000);
|
|
|
+ assert!(last_price.publish_time == 1715769470);
|
|
|
+
|
|
|
+ spy.fetch_events();
|
|
|
+ assert!(spy.events.len() == 1);
|
|
|
+
|
|
|
+ let times = array![PriceFeedPublishTime { price_id, publish_time: 1715769470 }];
|
|
|
+ pyth.update_price_feeds_if_necessary(data::test_price_update2(), times);
|
|
|
+}
|
|
|
+
|
|
|
+#[test]
|
|
|
+fn test_get_no_older_works() {
|
|
|
+ let user = 'user'.try_into().unwrap();
|
|
|
+ let wormhole = super::wormhole::deploy_with_mainnet_guardians();
|
|
|
+ let fee_contract = deploy_fee_contract(user);
|
|
|
+ let pyth = deploy_default(wormhole.contract_address, fee_contract.contract_address);
|
|
|
+ let price_id = 0xe62df6c8b4a85fe1a67db44dc12de5db330f7ac66b72dc658afedf0f4a415b43;
|
|
|
+ let err = pyth.get_price_no_older_than(price_id, 100).unwrap_err();
|
|
|
+ assert!(err == GetPriceNoOlderThanError::PriceFeedNotFound);
|
|
|
+ let err = pyth.get_ema_price_no_older_than(price_id, 100).unwrap_err();
|
|
|
+ assert!(err == GetPriceNoOlderThanError::PriceFeedNotFound);
|
|
|
+
|
|
|
+ start_prank(CheatTarget::One(fee_contract.contract_address), user.try_into().unwrap());
|
|
|
+ fee_contract.approve(pyth.contract_address, 10000);
|
|
|
+ stop_prank(CheatTarget::One(fee_contract.contract_address));
|
|
|
+
|
|
|
+ start_prank(CheatTarget::One(pyth.contract_address), user.try_into().unwrap());
|
|
|
+ pyth.update_price_feeds(data::good_update1());
|
|
|
+ stop_prank(CheatTarget::One(pyth.contract_address));
|
|
|
+
|
|
|
+ start_warp(CheatTarget::One(pyth.contract_address), 1712589210);
|
|
|
+ let err = pyth.get_price_no_older_than(price_id, 3).unwrap_err();
|
|
|
+ assert!(err == GetPriceNoOlderThanError::StalePrice);
|
|
|
+ let err = pyth.get_ema_price_no_older_than(price_id, 3).unwrap_err();
|
|
|
+ assert!(err == GetPriceNoOlderThanError::StalePrice);
|
|
|
+
|
|
|
+ start_warp(CheatTarget::One(pyth.contract_address), 1712589208);
|
|
|
+ let val = pyth.get_price_no_older_than(price_id, 3).unwrap_with_felt252();
|
|
|
+ assert!(val.publish_time == 1712589206);
|
|
|
+ assert!(val.price == 7192002930010);
|
|
|
+ let val = pyth.get_ema_price_no_older_than(price_id, 3).unwrap_with_felt252();
|
|
|
+ assert!(val.publish_time == 1712589206);
|
|
|
+ assert!(val.price == 7181868900000);
|
|
|
+
|
|
|
+ start_warp(CheatTarget::One(pyth.contract_address), 1712589204);
|
|
|
+ let val = pyth.get_price_no_older_than(price_id, 3).unwrap_with_felt252();
|
|
|
+ assert!(val.publish_time == 1712589206);
|
|
|
+ assert!(val.price == 7192002930010);
|
|
|
+ let val = pyth.get_ema_price_no_older_than(price_id, 3).unwrap_with_felt252();
|
|
|
+ assert!(val.publish_time == 1712589206);
|
|
|
+ assert!(val.price == 7181868900000);
|
|
|
+
|
|
|
+ stop_warp(CheatTarget::One(pyth.contract_address));
|
|
|
+}
|
|
|
+
|
|
|
#[test]
|
|
|
fn test_governance_set_fee_works() {
|
|
|
let user = 'user'.try_into().unwrap();
|