|
1 | 1 | use snforge_std::{
|
2 | 2 | declare, ContractClassTrait, start_prank, stop_prank, CheatTarget, spy_events, SpyOn, EventSpy,
|
3 |
| - EventFetcher, event_name_hash, Event |
| 3 | + EventFetcher, event_name_hash, Event, start_warp, stop_warp |
4 | 4 | };
|
5 | 5 | use pyth::pyth::{
|
6 | 6 | IPythDispatcher, IPythDispatcherTrait, DataSource, Event as PythEvent, PriceFeedUpdated,
|
7 | 7 | WormholeAddressSet, GovernanceDataSourceSet, ContractUpgraded, DataSourcesSet, FeeSet,
|
| 8 | + PriceFeedPublishTime, GetPriceNoOlderThanError, |
8 | 9 | };
|
9 | 10 | use pyth::byte_array::{ByteArray, ByteArrayImpl};
|
10 | 11 | use pyth::util::{array_try_into, UnwrapWithFelt252};
|
@@ -132,6 +133,144 @@ fn update_price_feeds_works() {
|
132 | 133 | assert!(last_ema_price.publish_time == 1712589206);
|
133 | 134 | }
|
134 | 135 |
|
| 136 | +#[test] |
| 137 | +fn test_update_if_necessary_works() { |
| 138 | + let user = 'user'.try_into().unwrap(); |
| 139 | + let wormhole = super::wormhole::deploy_with_test_guardian(); |
| 140 | + let fee_contract = deploy_fee_contract(user); |
| 141 | + let pyth = deploy_default(wormhole.contract_address, fee_contract.contract_address); |
| 142 | + |
| 143 | + start_prank(CheatTarget::One(fee_contract.contract_address), user); |
| 144 | + fee_contract.approve(pyth.contract_address, 10000); |
| 145 | + stop_prank(CheatTarget::One(fee_contract.contract_address)); |
| 146 | + |
| 147 | + let mut spy = spy_events(SpyOn::One(pyth.contract_address)); |
| 148 | + |
| 149 | + let price_id = 0xe62df6c8b4a85fe1a67db44dc12de5db330f7ac66b72dc658afedf0f4a415b43; |
| 150 | + assert!(pyth.get_price_unsafe(price_id).is_err()); |
| 151 | + |
| 152 | + start_prank(CheatTarget::One(pyth.contract_address), user); |
| 153 | + let times = array![PriceFeedPublishTime { price_id, publish_time: 1715769470 }]; |
| 154 | + pyth.update_price_feeds_if_necessary(data::test_price_update1(), times); |
| 155 | + |
| 156 | + let last_price = pyth.get_price_unsafe(price_id).unwrap_with_felt252(); |
| 157 | + assert!(last_price.price == 6281060000000); |
| 158 | + assert!(last_price.publish_time == 1715769470); |
| 159 | + |
| 160 | + spy.fetch_events(); |
| 161 | + assert!(spy.events.len() == 1); |
| 162 | + |
| 163 | + let times = array![PriceFeedPublishTime { price_id, publish_time: 1715769475 }]; |
| 164 | + pyth.update_price_feeds_if_necessary(data::test_price_update2(), times); |
| 165 | + |
| 166 | + let last_price = pyth.get_price_unsafe(price_id).unwrap_with_felt252(); |
| 167 | + assert!(last_price.price == 6281522520745); |
| 168 | + assert!(last_price.publish_time == 1715769475); |
| 169 | + |
| 170 | + spy.fetch_events(); |
| 171 | + assert!(spy.events.len() == 2); |
| 172 | + |
| 173 | + stop_prank(CheatTarget::One(pyth.contract_address)); |
| 174 | +} |
| 175 | + |
| 176 | +#[test] |
| 177 | +#[should_panic(expected: ('no fresh update',))] |
| 178 | +fn test_update_if_necessary_rejects_empty() { |
| 179 | + let user = 'user'.try_into().unwrap(); |
| 180 | + let wormhole = super::wormhole::deploy_with_test_guardian(); |
| 181 | + let fee_contract = deploy_fee_contract(user); |
| 182 | + let pyth = deploy_default(wormhole.contract_address, fee_contract.contract_address); |
| 183 | + |
| 184 | + start_prank(CheatTarget::One(fee_contract.contract_address), user); |
| 185 | + fee_contract.approve(pyth.contract_address, 10000); |
| 186 | + stop_prank(CheatTarget::One(fee_contract.contract_address)); |
| 187 | + |
| 188 | + start_prank(CheatTarget::One(pyth.contract_address), user); |
| 189 | + pyth.update_price_feeds_if_necessary(data::test_price_update1(), array![]); |
| 190 | + stop_prank(CheatTarget::One(pyth.contract_address)); |
| 191 | +} |
| 192 | + |
| 193 | +#[test] |
| 194 | +#[should_panic(expected: ('no fresh update',))] |
| 195 | +fn test_update_if_necessary_rejects_no_fresh() { |
| 196 | + let user = 'user'.try_into().unwrap(); |
| 197 | + let wormhole = super::wormhole::deploy_with_test_guardian(); |
| 198 | + let fee_contract = deploy_fee_contract(user); |
| 199 | + let pyth = deploy_default(wormhole.contract_address, fee_contract.contract_address); |
| 200 | + |
| 201 | + start_prank(CheatTarget::One(fee_contract.contract_address), user); |
| 202 | + fee_contract.approve(pyth.contract_address, 10000); |
| 203 | + stop_prank(CheatTarget::One(fee_contract.contract_address)); |
| 204 | + |
| 205 | + let mut spy = spy_events(SpyOn::One(pyth.contract_address)); |
| 206 | + |
| 207 | + start_prank(CheatTarget::One(pyth.contract_address), user); |
| 208 | + pyth.update_price_feeds_if_necessary(data::test_price_update1(), array![]); |
| 209 | + |
| 210 | + let price_id = 0xe62df6c8b4a85fe1a67db44dc12de5db330f7ac66b72dc658afedf0f4a415b43; |
| 211 | + assert!(pyth.get_price_unsafe(price_id).is_err()); |
| 212 | + spy.fetch_events(); |
| 213 | + assert!(spy.events.len() == 0); |
| 214 | + |
| 215 | + let times = array![PriceFeedPublishTime { price_id, publish_time: 1715769470 }]; |
| 216 | + pyth.update_price_feeds_if_necessary(data::test_price_update1(), times); |
| 217 | + |
| 218 | + let last_price = pyth.get_price_unsafe(price_id).unwrap_with_felt252(); |
| 219 | + assert!(last_price.price == 6281060000000); |
| 220 | + assert!(last_price.publish_time == 1715769470); |
| 221 | + |
| 222 | + spy.fetch_events(); |
| 223 | + assert!(spy.events.len() == 1); |
| 224 | + |
| 225 | + let times = array![PriceFeedPublishTime { price_id, publish_time: 1715769470 }]; |
| 226 | + pyth.update_price_feeds_if_necessary(data::test_price_update2(), times); |
| 227 | +} |
| 228 | + |
| 229 | +#[test] |
| 230 | +fn test_get_no_older_works() { |
| 231 | + let user = 'user'.try_into().unwrap(); |
| 232 | + let wormhole = super::wormhole::deploy_with_mainnet_guardians(); |
| 233 | + let fee_contract = deploy_fee_contract(user); |
| 234 | + let pyth = deploy_default(wormhole.contract_address, fee_contract.contract_address); |
| 235 | + let price_id = 0xe62df6c8b4a85fe1a67db44dc12de5db330f7ac66b72dc658afedf0f4a415b43; |
| 236 | + let err = pyth.get_price_no_older_than(price_id, 100).unwrap_err(); |
| 237 | + assert!(err == GetPriceNoOlderThanError::PriceFeedNotFound); |
| 238 | + let err = pyth.get_ema_price_no_older_than(price_id, 100).unwrap_err(); |
| 239 | + assert!(err == GetPriceNoOlderThanError::PriceFeedNotFound); |
| 240 | + |
| 241 | + start_prank(CheatTarget::One(fee_contract.contract_address), user.try_into().unwrap()); |
| 242 | + fee_contract.approve(pyth.contract_address, 10000); |
| 243 | + stop_prank(CheatTarget::One(fee_contract.contract_address)); |
| 244 | + |
| 245 | + start_prank(CheatTarget::One(pyth.contract_address), user.try_into().unwrap()); |
| 246 | + pyth.update_price_feeds(data::good_update1()); |
| 247 | + stop_prank(CheatTarget::One(pyth.contract_address)); |
| 248 | + |
| 249 | + start_warp(CheatTarget::One(pyth.contract_address), 1712589210); |
| 250 | + let err = pyth.get_price_no_older_than(price_id, 3).unwrap_err(); |
| 251 | + assert!(err == GetPriceNoOlderThanError::StalePrice); |
| 252 | + let err = pyth.get_ema_price_no_older_than(price_id, 3).unwrap_err(); |
| 253 | + assert!(err == GetPriceNoOlderThanError::StalePrice); |
| 254 | + |
| 255 | + start_warp(CheatTarget::One(pyth.contract_address), 1712589208); |
| 256 | + let val = pyth.get_price_no_older_than(price_id, 3).unwrap_with_felt252(); |
| 257 | + assert!(val.publish_time == 1712589206); |
| 258 | + assert!(val.price == 7192002930010); |
| 259 | + let val = pyth.get_ema_price_no_older_than(price_id, 3).unwrap_with_felt252(); |
| 260 | + assert!(val.publish_time == 1712589206); |
| 261 | + assert!(val.price == 7181868900000); |
| 262 | + |
| 263 | + start_warp(CheatTarget::One(pyth.contract_address), 1712589204); |
| 264 | + let val = pyth.get_price_no_older_than(price_id, 3).unwrap_with_felt252(); |
| 265 | + assert!(val.publish_time == 1712589206); |
| 266 | + assert!(val.price == 7192002930010); |
| 267 | + let val = pyth.get_ema_price_no_older_than(price_id, 3).unwrap_with_felt252(); |
| 268 | + assert!(val.publish_time == 1712589206); |
| 269 | + assert!(val.price == 7181868900000); |
| 270 | + |
| 271 | + stop_warp(CheatTarget::One(pyth.contract_address)); |
| 272 | +} |
| 273 | + |
135 | 274 | #[test]
|
136 | 275 | fn test_governance_set_fee_works() {
|
137 | 276 | let user = 'user'.try_into().unwrap();
|
|
0 commit comments