Skip to content

Commit e97b3bd

Browse files
authored
Add update_price_feeds_if_fresh_with_funder (#329)
1 parent d7f436a commit e97b3bd

File tree

1 file changed

+93
-0
lines changed

1 file changed

+93
-0
lines changed

aptos/contracts/sources/pyth.move

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,21 @@ module pyth::pyth {
177177
vector::destroy_empty(updates);
178178
}
179179

180+
/// A convenience wrapper around update_price_feeds_if_fresh(), allowing you to conditionally
181+
/// update the price feeds using an entry function.
182+
///
183+
/// If possible, it is recommended to use update_price_feeds_if_fresh() instead, which avoids the need
184+
/// to pass a signer account. update_price_feeds_if_fresh_with_funder() should only be used when
185+
/// you need to call an entry function.
186+
public entry fun update_price_feeds_if_fresh_with_funder(
187+
account: &signer,
188+
vaas: vector<vector<u8>>,
189+
price_identifiers: vector<vector<u8>>,
190+
publish_times: vector<u64>) {
191+
let coins = coin::withdraw<AptosCoin>(account, get_update_fee());
192+
update_price_feeds_if_fresh(vaas, price_identifiers, publish_times, coins);
193+
}
194+
180195
/// Update the cached price feeds with the data in the given VAAs, using
181196
/// update_price_feeds(). However, this function will only have an effect if any of the
182197
/// prices in the update are fresh. The price_identifiers and publish_times parameters
@@ -776,6 +791,47 @@ module pyth::pyth {
776791
cleanup_test(burn_capability, mint_capability);
777792
}
778793

794+
#[test(aptos_framework = @aptos_framework)]
795+
fun test_update_price_feeds_if_fresh_with_funder_fresh_data(aptos_framework: &signer) {
796+
let update_fee = 50;
797+
let initial_balance = 75;
798+
let (burn_capability, mint_capability, coins) = setup_test(aptos_framework, 500, 23, x"5d1f252d5de865279b00c84bce362774c2804294ed53299bc4a0389a5defef92", data_sources_for_test_vaa(), update_fee, initial_balance);
799+
800+
// Create a test funder account and register it to store funds
801+
let funder_addr = @0xbfbffd8e2af9a3e3ce20d2d2b22bd640;
802+
let funder = account::create_account_for_test(funder_addr);
803+
coin::register<AptosCoin>(&funder);
804+
coin::deposit(funder_addr, coins);
805+
806+
assert!(get_update_fee() == update_fee, 1);
807+
assert!(coin::balance<AptosCoin>(signer::address_of(&funder)) == initial_balance, 1);
808+
assert!(coin::balance<AptosCoin>(@pyth) == 0, 1);
809+
810+
// Update the price feeds using the funder
811+
let bytes = TEST_VAAS;
812+
let price_identifiers = vector[
813+
x"c6c75c89f14810ec1c54c03ab8f1864a4c4032791f05747f560faec380a695d1",
814+
x"3b9551a68d01d954d6387aff4df1529027ffb2fee413082e509feb29cc4904fe",
815+
x"33832fad6e36eb05a8972fe5f219b27b5b2bb2230a79ce79beb4c5c5e7ecc76d",
816+
x"21a28b4c6619968bd8c20e95b0aaed7df2187fd310275347e0376a2cd7427db8",
817+
];
818+
let publish_times = vector[
819+
1663680790, 1663680730, 1663680760, 1663680720
820+
];
821+
update_price_feeds_if_fresh_with_funder(&funder, bytes, price_identifiers, publish_times);
822+
823+
// Check that the price feeds are now cached
824+
check_price_feeds_cached(&get_mock_price_infos());
825+
826+
// Check that the funder's balance has decreased by the update_fee amount
827+
assert!(coin::balance<AptosCoin>(signer::address_of(&funder)) == initial_balance - get_update_fee(), 1);
828+
829+
// Check that the amount has been transferred to the Pyth contract
830+
assert!(coin::balance<AptosCoin>(@pyth) == get_update_fee(), 1);
831+
832+
cleanup_test(burn_capability, mint_capability);
833+
}
834+
779835
#[test(aptos_framework = @aptos_framework)]
780836
#[expected_failure(abort_code = 524295)]
781837
fun test_update_price_feeds_if_fresh_stale_data(aptos_framework: &signer) {
@@ -800,4 +856,41 @@ module pyth::pyth {
800856

801857
cleanup_test(burn_capability, mint_capability);
802858
}
859+
860+
#[test(aptos_framework = @aptos_framework)]
861+
#[expected_failure(abort_code = 524295)]
862+
fun test_update_price_feeds_if_fresh_with_funder_stale_data(aptos_framework: &signer) {
863+
let update_fee = 50;
864+
let initial_balance = 75;
865+
let (burn_capability, mint_capability, coins) = setup_test(aptos_framework, 500, 23, x"5d1f252d5de865279b00c84bce362774c2804294ed53299bc4a0389a5defef92", data_sources_for_test_vaa(), update_fee, initial_balance);
866+
867+
// Create a test funder account and register it to store funds
868+
let funder_addr = @0xbfbffd8e2af9a3e3ce20d2d2b22bd640;
869+
let funder = account::create_account_for_test(funder_addr);
870+
coin::register<AptosCoin>(&funder);
871+
coin::deposit(funder_addr, coins);
872+
873+
assert!(get_update_fee() == update_fee, 1);
874+
assert!(coin::balance<AptosCoin>(signer::address_of(&funder)) == initial_balance, 1);
875+
assert!(coin::balance<AptosCoin>(@pyth) == 0, 1);
876+
877+
// First populate the cache
878+
update_cache(get_mock_price_infos());
879+
880+
// Now attempt to update the price feeds with publish_times that are older than those we have cached
881+
// This should abort with error::no_fresh_data()
882+
let bytes = TEST_VAAS;
883+
let price_identifiers = vector[
884+
x"c6c75c89f14810ec1c54c03ab8f1864a4c4032791f05747f560faec380a695d1",
885+
x"3b9551a68d01d954d6387aff4df1529027ffb2fee413082e509feb29cc4904fe",
886+
x"33832fad6e36eb05a8972fe5f219b27b5b2bb2230a79ce79beb4c5c5e7ecc76d",
887+
x"21a28b4c6619968bd8c20e95b0aaed7df2187fd310275347e0376a2cd7427db8",
888+
];
889+
let publish_times = vector[
890+
100, 76, 29, 64
891+
];
892+
update_price_feeds_if_fresh_with_funder(&funder, bytes, price_identifiers, publish_times);
893+
894+
cleanup_test(burn_capability, mint_capability);
895+
}
803896
}

0 commit comments

Comments
 (0)