From 8a116260e5a407273682966e133c95ce515d15b9 Mon Sep 17 00:00:00 2001 From: Alin Cruceat Date: Fri, 4 Oct 2024 12:22:22 +0300 Subject: [PATCH 01/13] add more events to PriceAggregator --- contracts/core/price-aggregator/src/events.rs | 16 ++++++++++++++++ contracts/core/price-aggregator/src/lib.rs | 7 ++++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/contracts/core/price-aggregator/src/events.rs b/contracts/core/price-aggregator/src/events.rs index d485e622db..14be0dc7c3 100644 --- a/contracts/core/price-aggregator/src/events.rs +++ b/contracts/core/price-aggregator/src/events.rs @@ -43,4 +43,20 @@ pub trait EventsModule { #[indexed] epoch: u64, new_round_event: &NewRoundEvent, ); + + #[event("discard_round")] + fn discard_round_event( + &self, + #[indexed] from: &ManagedBuffer, + #[indexed] to: &ManagedBuffer, + #[indexed] epoch: u64, + ); + + #[event("add_submission")] + fn add_submission_event( + &self, + #[indexed] caller: &ManagedAddress, + #[indexed] price: &BigUint, + #[indexed] epoch: u64, + ); } diff --git a/contracts/core/price-aggregator/src/lib.rs b/contracts/core/price-aggregator/src/lib.rs index 1dbed54848..6fba1bb1ef 100644 --- a/contracts/core/price-aggregator/src/lib.rs +++ b/contracts/core/price-aggregator/src/lib.rs @@ -183,10 +183,12 @@ pub trait PriceAggregator: let accepted = !submissions.contains_key(&caller) && (is_first_submission || submission_timestamp >= first_submission_timestamp); if accepted { - submissions.insert(caller, price); + submissions.insert(caller.clone(), price.clone()); last_sub_time_mapper.set(current_timestamp); self.create_new_round(token_pair, submissions, decimals); + let epoch = self.blockchain().get_block_epoch(); + self.add_submission_event(&caller, &price, epoch); } self.oracle_status() @@ -282,6 +284,9 @@ pub trait PriceAggregator: .get() .push(&price_feed); self.emit_new_round_event(&token_pair, &price_feed); + } else { + let epoch = self.blockchain().get_block_epoch(); + self.discard_round_event(&token_pair.from.clone(), &token_pair.to.clone(), epoch); } } From 5517ef0f9dd2d5b93d5ae16972fa03ff16b703db Mon Sep 17 00:00:00 2001 From: Alin Cruceat Date: Fri, 4 Oct 2024 12:29:42 +0300 Subject: [PATCH 02/13] set round in event in stead of epoch --- contracts/core/price-aggregator/src/events.rs | 4 ++-- contracts/core/price-aggregator/src/lib.rs | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/contracts/core/price-aggregator/src/events.rs b/contracts/core/price-aggregator/src/events.rs index 14be0dc7c3..71bf623ab5 100644 --- a/contracts/core/price-aggregator/src/events.rs +++ b/contracts/core/price-aggregator/src/events.rs @@ -49,7 +49,7 @@ pub trait EventsModule { &self, #[indexed] from: &ManagedBuffer, #[indexed] to: &ManagedBuffer, - #[indexed] epoch: u64, + #[indexed] round: u64, ); #[event("add_submission")] @@ -57,6 +57,6 @@ pub trait EventsModule { &self, #[indexed] caller: &ManagedAddress, #[indexed] price: &BigUint, - #[indexed] epoch: u64, + #[indexed] round: u64, ); } diff --git a/contracts/core/price-aggregator/src/lib.rs b/contracts/core/price-aggregator/src/lib.rs index 6fba1bb1ef..0b665f7596 100644 --- a/contracts/core/price-aggregator/src/lib.rs +++ b/contracts/core/price-aggregator/src/lib.rs @@ -187,8 +187,8 @@ pub trait PriceAggregator: last_sub_time_mapper.set(current_timestamp); self.create_new_round(token_pair, submissions, decimals); - let epoch = self.blockchain().get_block_epoch(); - self.add_submission_event(&caller, &price, epoch); + let round = self.blockchain().get_block_round(); + self.add_submission_event(&caller, &price, round); } self.oracle_status() @@ -285,8 +285,8 @@ pub trait PriceAggregator: .push(&price_feed); self.emit_new_round_event(&token_pair, &price_feed); } else { - let epoch = self.blockchain().get_block_epoch(); - self.discard_round_event(&token_pair.from.clone(), &token_pair.to.clone(), epoch); + let round = self.blockchain().get_block_round(); + self.discard_round_event(&token_pair.from.clone(), &token_pair.to.clone(), round); } } From 075bfbd37c08d0d47fc3ab42f202fb48fa82623b Mon Sep 17 00:00:00 2001 From: Alin Cruceat Date: Fri, 4 Oct 2024 12:48:35 +0300 Subject: [PATCH 03/13] sc round --- contracts/core/price-aggregator/src/events.rs | 4 ++-- contracts/core/price-aggregator/src/lib.rs | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/contracts/core/price-aggregator/src/events.rs b/contracts/core/price-aggregator/src/events.rs index 71bf623ab5..ef93ba449b 100644 --- a/contracts/core/price-aggregator/src/events.rs +++ b/contracts/core/price-aggregator/src/events.rs @@ -49,7 +49,7 @@ pub trait EventsModule { &self, #[indexed] from: &ManagedBuffer, #[indexed] to: &ManagedBuffer, - #[indexed] round: u64, + #[indexed] round: usize, ); #[event("add_submission")] @@ -57,6 +57,6 @@ pub trait EventsModule { &self, #[indexed] caller: &ManagedAddress, #[indexed] price: &BigUint, - #[indexed] round: u64, + #[indexed] round: usize, ); } diff --git a/contracts/core/price-aggregator/src/lib.rs b/contracts/core/price-aggregator/src/lib.rs index 0b665f7596..c9972957c2 100644 --- a/contracts/core/price-aggregator/src/lib.rs +++ b/contracts/core/price-aggregator/src/lib.rs @@ -186,9 +186,9 @@ pub trait PriceAggregator: submissions.insert(caller.clone(), price.clone()); last_sub_time_mapper.set(current_timestamp); - self.create_new_round(token_pair, submissions, decimals); - let round = self.blockchain().get_block_round(); - self.add_submission_event(&caller, &price, round); + self.create_new_round(token_pair.clone(), submissions, decimals); + let round_id = self.rounds().get(&token_pair).unwrap().len(); + self.add_submission_event(&caller, &price, round_id); } self.oracle_status() @@ -285,8 +285,8 @@ pub trait PriceAggregator: .push(&price_feed); self.emit_new_round_event(&token_pair, &price_feed); } else { - let round = self.blockchain().get_block_round(); - self.discard_round_event(&token_pair.from.clone(), &token_pair.to.clone(), round); + let round_id = self.rounds().get(&token_pair).unwrap().len(); + self.discard_round_event(&token_pair.from.clone(), &token_pair.to.clone(), round_id); } } From 980745f30d62063a5c503c5e0a92b06d27bb2ac1 Mon Sep 17 00:00:00 2001 From: Alin Cruceat Date: Fri, 4 Oct 2024 13:04:21 +0300 Subject: [PATCH 04/13] fix unwrap error --- contracts/core/price-aggregator/src/lib.rs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/contracts/core/price-aggregator/src/lib.rs b/contracts/core/price-aggregator/src/lib.rs index c9972957c2..f75da9316b 100644 --- a/contracts/core/price-aggregator/src/lib.rs +++ b/contracts/core/price-aggregator/src/lib.rs @@ -187,7 +187,11 @@ pub trait PriceAggregator: last_sub_time_mapper.set(current_timestamp); self.create_new_round(token_pair.clone(), submissions, decimals); - let round_id = self.rounds().get(&token_pair).unwrap().len(); + let wrapped_rounds = self.rounds().get(&token_pair); + let mut round_id = 0; + if wrapped_rounds.is_some() { + round_id = wrapped_rounds.unwrap().len(); + } self.add_submission_event(&caller, &price, round_id); } @@ -285,7 +289,11 @@ pub trait PriceAggregator: .push(&price_feed); self.emit_new_round_event(&token_pair, &price_feed); } else { - let round_id = self.rounds().get(&token_pair).unwrap().len(); + let wrapped_rounds = self.rounds().get(&token_pair); + let mut round_id = 0; + if wrapped_rounds.is_some() { + round_id = wrapped_rounds.unwrap().len(); + } self.discard_round_event(&token_pair.from.clone(), &token_pair.to.clone(), round_id); } } From af7764588df0476a3f164a58ddce5c864e4d45a1 Mon Sep 17 00:00:00 2001 From: Alin Cruceat Date: Fri, 4 Oct 2024 13:21:06 +0300 Subject: [PATCH 05/13] changes from mx-contracts-rs --- contracts/core/price-aggregator/src/lib.rs | 8 +++++--- contracts/core/price-aggregator/src/median.rs | 1 - 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/contracts/core/price-aggregator/src/lib.rs b/contracts/core/price-aggregator/src/lib.rs index f75da9316b..a52ceb578e 100644 --- a/contracts/core/price-aggregator/src/lib.rs +++ b/contracts/core/price-aggregator/src/lib.rs @@ -390,9 +390,11 @@ pub trait PriceAggregator: #[only_owner] #[endpoint(setPairDecimals)] fn set_pair_decimals(&self, from: ManagedBuffer, to: ManagedBuffer, decimals: u8) { - self.require_paused(); - - self.pair_decimals(&from, &to).set(Some(decimals)); + let pair_decimals_mapper = self.pair_decimals(&from, &to); + if !pair_decimals_mapper.is_empty() { + self.require_paused(); + } + pair_decimals_mapper.set(Some(decimals)); let pair = TokenPair { from, to }; self.clear_submissions(&pair); } diff --git a/contracts/core/price-aggregator/src/median.rs b/contracts/core/price-aggregator/src/median.rs index 714acf9632..53227bc9d7 100644 --- a/contracts/core/price-aggregator/src/median.rs +++ b/contracts/core/price-aggregator/src/median.rs @@ -1,5 +1,4 @@ multiversx_sc::imports!(); -multiversx_sc::derive_imports!(); /// Returns the sorted middle, or the average of the two middle indexed items if the /// vector has an even number of elements. From 520a5435c27d210a166fad94a8d20bd7fe25c5fd Mon Sep 17 00:00:00 2001 From: dragosrebegea Date: Fri, 4 Oct 2024 13:25:49 +0300 Subject: [PATCH 06/13] uniform price aggregator events --- contracts/core/price-aggregator/src/events.rs | 10 ++++++---- contracts/core/price-aggregator/src/lib.rs | 16 ++++++---------- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/contracts/core/price-aggregator/src/events.rs b/contracts/core/price-aggregator/src/events.rs index ef93ba449b..15c0b64511 100644 --- a/contracts/core/price-aggregator/src/events.rs +++ b/contracts/core/price-aggregator/src/events.rs @@ -18,13 +18,14 @@ pub trait EventsModule { fn emit_new_round_event( &self, token_pair: &TokenPair, + round_id: usize, price_feed: &TimestampedPrice, ) { let epoch = self.blockchain().get_block_epoch(); self.new_round_event( &token_pair.from.clone(), &token_pair.to.clone(), - epoch, + round_id, &NewRoundEvent { price: price_feed.price.clone(), timestamp: price_feed.timestamp, @@ -40,7 +41,7 @@ pub trait EventsModule { &self, #[indexed] from: &ManagedBuffer, #[indexed] to: &ManagedBuffer, - #[indexed] epoch: u64, + #[indexed] round: usize, new_round_event: &NewRoundEvent, ); @@ -55,8 +56,9 @@ pub trait EventsModule { #[event("add_submission")] fn add_submission_event( &self, - #[indexed] caller: &ManagedAddress, - #[indexed] price: &BigUint, + #[indexed] from: &ManagedBuffer, + #[indexed] to: &ManagedBuffer, #[indexed] round: usize, + price: &BigUint, ); } diff --git a/contracts/core/price-aggregator/src/lib.rs b/contracts/core/price-aggregator/src/lib.rs index f75da9316b..194426748c 100644 --- a/contracts/core/price-aggregator/src/lib.rs +++ b/contracts/core/price-aggregator/src/lib.rs @@ -186,13 +186,13 @@ pub trait PriceAggregator: submissions.insert(caller.clone(), price.clone()); last_sub_time_mapper.set(current_timestamp); - self.create_new_round(token_pair.clone(), submissions, decimals); - let wrapped_rounds = self.rounds().get(&token_pair); let mut round_id = 0; + let wrapped_rounds = self.rounds().get(&token_pair); if wrapped_rounds.is_some() { - round_id = wrapped_rounds.unwrap().len(); + round_id = wrapped_rounds.unwrap().len() + 1; } - self.add_submission_event(&caller, &price, round_id); + self.create_new_round(token_pair.clone(), round_id, submissions, decimals); + self.add_submission_event(&token_pair.from.clone(), &token_pair.to.clone(), round_id, &price); } self.oracle_status() @@ -254,6 +254,7 @@ pub trait PriceAggregator: fn create_new_round( &self, token_pair: TokenPair, + round_id: usize, mut submissions: MapMapper, decimals: u8, ) { @@ -287,13 +288,8 @@ pub trait PriceAggregator: .or_default() .get() .push(&price_feed); - self.emit_new_round_event(&token_pair, &price_feed); + self.emit_new_round_event(&token_pair, round_id, &price_feed); } else { - let wrapped_rounds = self.rounds().get(&token_pair); - let mut round_id = 0; - if wrapped_rounds.is_some() { - round_id = wrapped_rounds.unwrap().len(); - } self.discard_round_event(&token_pair.from.clone(), &token_pair.to.clone(), round_id); } } From f0f5a4114269f60e7bb51cc705b4e100b0225b92 Mon Sep 17 00:00:00 2001 From: Alin Cruceat Date: Fri, 4 Oct 2024 13:56:53 +0300 Subject: [PATCH 07/13] upgrade --- contracts/core/price-aggregator/src/lib.rs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/contracts/core/price-aggregator/src/lib.rs b/contracts/core/price-aggregator/src/lib.rs index 6477006fcf..e2936365ba 100644 --- a/contracts/core/price-aggregator/src/lib.rs +++ b/contracts/core/price-aggregator/src/lib.rs @@ -47,6 +47,11 @@ pub trait PriceAggregator: self.set_paused(true); } + #[upgrade] + fn upgrade(&self) { + self.set_paused(true); + } + #[only_owner] #[endpoint(changeAmounts)] fn change_amounts(&self, staking_amount: BigUint, slash_amount: BigUint) { @@ -192,7 +197,12 @@ pub trait PriceAggregator: round_id = wrapped_rounds.unwrap().len() + 1; } self.create_new_round(token_pair.clone(), round_id, submissions, decimals); - self.add_submission_event(&token_pair.from.clone(), &token_pair.to.clone(), round_id, &price); + self.add_submission_event( + &token_pair.from.clone(), + &token_pair.to.clone(), + round_id, + &price, + ); } self.oracle_status() From c3c2b8110c3cf9fa7adbfa76ba11d5d887b40c05 Mon Sep 17 00:00:00 2001 From: Alin Cruceat Date: Fri, 4 Oct 2024 14:32:04 +0300 Subject: [PATCH 08/13] regen proxies --- .../tests/price_aggregator_proxy.rs | 19 +++++++++++++++++++ .../core/price-aggregator/wasm/src/lib.rs | 4 +++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/contracts/core/price-aggregator/tests/price_aggregator_proxy.rs b/contracts/core/price-aggregator/tests/price_aggregator_proxy.rs index e96244d668..641a964526 100644 --- a/contracts/core/price-aggregator/tests/price_aggregator_proxy.rs +++ b/contracts/core/price-aggregator/tests/price_aggregator_proxy.rs @@ -72,6 +72,25 @@ where } } +#[rustfmt::skip] +impl PriceAggregatorProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + pub fn upgrade( + self, + ) -> TxTypedUpgrade { + self.wrapped_tx + .payment(NotPayable) + .raw_upgrade() + .original_result() + } +} + #[rustfmt::skip] impl PriceAggregatorProxyMethods where diff --git a/contracts/core/price-aggregator/wasm/src/lib.rs b/contracts/core/price-aggregator/wasm/src/lib.rs index 667c425afd..a8e75f4942 100644 --- a/contracts/core/price-aggregator/wasm/src/lib.rs +++ b/contracts/core/price-aggregator/wasm/src/lib.rs @@ -5,9 +5,10 @@ //////////////////////////////////////////////////// // Init: 1 +// Upgrade: 1 // Endpoints: 21 // Async Callback (empty): 1 -// Total number of exported functions: 23 +// Total number of exported functions: 24 #![no_std] @@ -18,6 +19,7 @@ multiversx_sc_wasm_adapter::endpoints! { multiversx_price_aggregator_sc ( init => init + upgrade => upgrade changeAmounts => change_amounts addOracles => add_oracles removeOracles => remove_oracles From 6906540bfc57edf93fbd39d6a44a1bd7b345c370 Mon Sep 17 00:00:00 2001 From: dragosrebegea Date: Fri, 4 Oct 2024 15:29:49 +0300 Subject: [PATCH 09/13] fixes for discard round --- contracts/core/price-aggregator/src/events.rs | 37 +++++++++++++++++++ contracts/core/price-aggregator/src/lib.rs | 25 +++++++++---- 2 files changed, 54 insertions(+), 8 deletions(-) diff --git a/contracts/core/price-aggregator/src/events.rs b/contracts/core/price-aggregator/src/events.rs index 15c0b64511..13c5f7c2d7 100644 --- a/contracts/core/price-aggregator/src/events.rs +++ b/contracts/core/price-aggregator/src/events.rs @@ -13,6 +13,14 @@ pub struct NewRoundEvent { epoch: u64, } +#[type_abi] +#[derive(TopEncode)] +pub struct DiscardSubmissionEvent { + submission_timestamp: u64, + first_submission_timestamp: u64, + has_caller_already_submitted: bool, +} + #[multiversx_sc::module] pub trait EventsModule { fn emit_new_round_event( @@ -45,6 +53,35 @@ pub trait EventsModule { new_round_event: &NewRoundEvent, ); + fn emit_discard_submission_event( + &self, + token_pair: &TokenPair, + round_id: usize, + submission_timestamp: u64, + first_submission_timestamp: u64, + has_caller_already_submitted: bool, + ) { + self.discard_submission_event( + &token_pair.from.clone(), + &token_pair.to.clone(), + round_id, + &DiscardSubmissionEvent { + submission_timestamp, + first_submission_timestamp, + has_caller_already_submitted + }, + ) + } + + #[event("discard_submission")] + fn discard_submission_event( + &self, + #[indexed] from: &ManagedBuffer, + #[indexed] to: &ManagedBuffer, + #[indexed] round: usize, + discard_submission_event: &DiscardSubmissionEvent, + ); + #[event("discard_round")] fn discard_round_event( &self, diff --git a/contracts/core/price-aggregator/src/lib.rs b/contracts/core/price-aggregator/src/lib.rs index e2936365ba..05698745d7 100644 --- a/contracts/core/price-aggregator/src/lib.rs +++ b/contracts/core/price-aggregator/src/lib.rs @@ -159,6 +159,12 @@ pub trait PriceAggregator: let first_sub_time_mapper = self.first_submission_timestamp(&token_pair); let last_sub_time_mapper = self.last_submission_timestamp(&token_pair); + let mut round_id = 0; + let wrapped_rounds = self.rounds().get(&token_pair); + if wrapped_rounds.is_some() { + round_id = wrapped_rounds.unwrap().len() + 1; + } + let current_timestamp = self.blockchain().get_block_timestamp(); let mut is_first_submission = false; let mut first_submission_timestamp = if submissions.is_empty() { @@ -182,20 +188,17 @@ pub trait PriceAggregator: first_submission_timestamp = current_timestamp; is_first_submission = true; + self.discard_round_event(&token_pair.from.clone(), &token_pair.to.clone(), round_id) } let caller = self.blockchain().get_caller(); - let accepted = !submissions.contains_key(&caller) + let has_caller_already_submitted = submissions.contains_key(&caller); + let accepted = !has_caller_already_submitted && (is_first_submission || submission_timestamp >= first_submission_timestamp); if accepted { submissions.insert(caller.clone(), price.clone()); last_sub_time_mapper.set(current_timestamp); - let mut round_id = 0; - let wrapped_rounds = self.rounds().get(&token_pair); - if wrapped_rounds.is_some() { - round_id = wrapped_rounds.unwrap().len() + 1; - } self.create_new_round(token_pair.clone(), round_id, submissions, decimals); self.add_submission_event( &token_pair.from.clone(), @@ -203,6 +206,14 @@ pub trait PriceAggregator: round_id, &price, ); + } else { + self.emit_discard_submission_event( + &token_pair, + round_id, + submission_timestamp, + first_submission_timestamp, + has_caller_already_submitted, + ); } self.oracle_status() @@ -299,8 +310,6 @@ pub trait PriceAggregator: .get() .push(&price_feed); self.emit_new_round_event(&token_pair, round_id, &price_feed); - } else { - self.discard_round_event(&token_pair.from.clone(), &token_pair.to.clone(), round_id); } } From c17c61381e500a35eb6921cf220dccc78b50373f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Costin=20Caraba=C8=99?= Date: Mon, 7 Oct 2024 22:53:13 +0300 Subject: [PATCH 10/13] price-aggregator: Fix proxy --- .../core/price-aggregator/tests/price_aggregator_proxy.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/contracts/core/price-aggregator/tests/price_aggregator_proxy.rs b/contracts/core/price-aggregator/tests/price_aggregator_proxy.rs index 641a964526..7a7e2aaa74 100644 --- a/contracts/core/price-aggregator/tests/price_aggregator_proxy.rs +++ b/contracts/core/price-aggregator/tests/price_aggregator_proxy.rs @@ -406,3 +406,11 @@ where pub block: u64, pub epoch: u64, } + +#[type_abi] +#[derive(TopEncode)] +pub struct DiscardSubmissionEvent { + pub submission_timestamp: u64, + pub first_submission_timestamp: u64, + pub has_caller_already_submitted: bool, +} From 3426a850853f55c51eaff6fc9247c01c2ae5640c Mon Sep 17 00:00:00 2001 From: Alin Cruceat Date: Tue, 8 Oct 2024 10:06:42 +0300 Subject: [PATCH 11/13] sync bugfix --- contracts/core/price-aggregator/src/events.rs | 4 +-- contracts/core/price-aggregator/src/lib.rs | 32 +++++++------------ 2 files changed, 14 insertions(+), 22 deletions(-) diff --git a/contracts/core/price-aggregator/src/events.rs b/contracts/core/price-aggregator/src/events.rs index 13c5f7c2d7..50f369a223 100644 --- a/contracts/core/price-aggregator/src/events.rs +++ b/contracts/core/price-aggregator/src/events.rs @@ -57,7 +57,7 @@ pub trait EventsModule { &self, token_pair: &TokenPair, round_id: usize, - submission_timestamp: u64, + submission_timestamp: u64, first_submission_timestamp: u64, has_caller_already_submitted: bool, ) { @@ -68,7 +68,7 @@ pub trait EventsModule { &DiscardSubmissionEvent { submission_timestamp, first_submission_timestamp, - has_caller_already_submitted + has_caller_already_submitted, }, ) } diff --git a/contracts/core/price-aggregator/src/lib.rs b/contracts/core/price-aggregator/src/lib.rs index 05698745d7..1b98f35909 100644 --- a/contracts/core/price-aggregator/src/lib.rs +++ b/contracts/core/price-aggregator/src/lib.rs @@ -130,22 +130,17 @@ pub trait PriceAggregator: self.require_not_paused(); self.require_is_oracle(); - let current_timestamp = self.blockchain().get_block_timestamp(); - require!( - submission_timestamp <= current_timestamp, - "Timestamp is from the future" - ); + self.require_valid_submission_timestamp(submission_timestamp); self.check_decimals(&from, &to, decimals); - self.submit_unchecked(from, to, submission_timestamp, price, decimals); + self.submit_unchecked(from, to, price, decimals); } fn submit_unchecked( &self, from: ManagedBuffer, to: ManagedBuffer, - submission_timestamp: u64, price: BigUint, decimals: u8, ) { @@ -168,8 +163,6 @@ pub trait PriceAggregator: let current_timestamp = self.blockchain().get_block_timestamp(); let mut is_first_submission = false; let mut first_submission_timestamp = if submissions.is_empty() { - self.require_valid_first_submission(submission_timestamp, current_timestamp); - first_sub_time_mapper.set(current_timestamp); is_first_submission = true; @@ -180,8 +173,6 @@ pub trait PriceAggregator: // round was not completed in time, so it's discarded if current_timestamp > first_submission_timestamp + MAX_ROUND_DURATION_SECONDS { - self.require_valid_first_submission(submission_timestamp, current_timestamp); - submissions.clear(); first_sub_time_mapper.set(current_timestamp); last_sub_time_mapper.set(current_timestamp); @@ -194,7 +185,7 @@ pub trait PriceAggregator: let caller = self.blockchain().get_caller(); let has_caller_already_submitted = submissions.contains_key(&caller); let accepted = !has_caller_already_submitted - && (is_first_submission || submission_timestamp >= first_submission_timestamp); + && (is_first_submission || current_timestamp >= first_submission_timestamp); if accepted { submissions.insert(caller.clone(), price.clone()); last_sub_time_mapper.set(current_timestamp); @@ -210,7 +201,7 @@ pub trait PriceAggregator: self.emit_discard_submission_event( &token_pair, round_id, - submission_timestamp, + current_timestamp, first_submission_timestamp, has_caller_already_submitted, ); @@ -224,7 +215,12 @@ pub trait PriceAggregator: }); } - fn require_valid_first_submission(&self, submission_timestamp: u64, current_timestamp: u64) { + fn require_valid_submission_timestamp(&self, submission_timestamp: u64) { + let current_timestamp = self.blockchain().get_block_timestamp(); + require!( + submission_timestamp <= current_timestamp, + "Timestamp is from the future" + ); require!( current_timestamp - submission_timestamp <= FIRST_SUBMISSION_TIMESTAMP_MAX_DIFF_SECONDS, "First submission too old" @@ -239,19 +235,15 @@ pub trait PriceAggregator: self.require_not_paused(); self.require_is_oracle(); - let current_timestamp = self.blockchain().get_block_timestamp(); for (from, to, submission_timestamp, price, decimals) in submissions .into_iter() .map(|submission| submission.into_tuple()) { - require!( - submission_timestamp <= current_timestamp, - "Timestamp is from the future" - ); + self.require_valid_submission_timestamp(submission_timestamp); self.check_decimals(&from, &to, decimals); - self.submit_unchecked(from, to, submission_timestamp, price, decimals); + self.submit_unchecked(from, to, price, decimals); } } From 225031949039cea5b1628df488b72a214b03b933 Mon Sep 17 00:00:00 2001 From: Alin Cruceat Date: Wed, 9 Oct 2024 09:47:27 +0300 Subject: [PATCH 12/13] make Dorin proud --- contracts/core/price-aggregator/src/events.rs | 31 +++++++++++-------- contracts/core/price-aggregator/src/lib.rs | 13 +++++--- 2 files changed, 26 insertions(+), 18 deletions(-) diff --git a/contracts/core/price-aggregator/src/events.rs b/contracts/core/price-aggregator/src/events.rs index 50f369a223..cc88c51e8b 100644 --- a/contracts/core/price-aggregator/src/events.rs +++ b/contracts/core/price-aggregator/src/events.rs @@ -2,22 +2,27 @@ multiversx_sc::imports!(); multiversx_sc::derive_imports!(); use crate::price_aggregator_data::{TimestampedPrice, TokenPair}; +pub type RoundId = usize; +pub type Round = usize; +pub type Block = u64; +pub type Epoch = u64; +pub type Timestamp = u64; #[type_abi] #[derive(TopEncode)] pub struct NewRoundEvent { price: BigUint, - timestamp: u64, + timestamp: Timestamp, decimals: u8, - block: u64, - epoch: u64, + block: Block, + epoch: Epoch, } #[type_abi] #[derive(TopEncode)] pub struct DiscardSubmissionEvent { - submission_timestamp: u64, - first_submission_timestamp: u64, + submission_timestamp: Timestamp, + first_submission_timestamp: Timestamp, has_caller_already_submitted: bool, } @@ -26,7 +31,7 @@ pub trait EventsModule { fn emit_new_round_event( &self, token_pair: &TokenPair, - round_id: usize, + round_id: RoundId, price_feed: &TimestampedPrice, ) { let epoch = self.blockchain().get_block_epoch(); @@ -49,16 +54,16 @@ pub trait EventsModule { &self, #[indexed] from: &ManagedBuffer, #[indexed] to: &ManagedBuffer, - #[indexed] round: usize, + #[indexed] round: Round, new_round_event: &NewRoundEvent, ); fn emit_discard_submission_event( &self, token_pair: &TokenPair, - round_id: usize, - submission_timestamp: u64, - first_submission_timestamp: u64, + round_id: RoundId, + submission_timestamp: Timestamp, + first_submission_timestamp: Timestamp, has_caller_already_submitted: bool, ) { self.discard_submission_event( @@ -78,7 +83,7 @@ pub trait EventsModule { &self, #[indexed] from: &ManagedBuffer, #[indexed] to: &ManagedBuffer, - #[indexed] round: usize, + #[indexed] round: Round, discard_submission_event: &DiscardSubmissionEvent, ); @@ -87,7 +92,7 @@ pub trait EventsModule { &self, #[indexed] from: &ManagedBuffer, #[indexed] to: &ManagedBuffer, - #[indexed] round: usize, + #[indexed] round: Round, ); #[event("add_submission")] @@ -95,7 +100,7 @@ pub trait EventsModule { &self, #[indexed] from: &ManagedBuffer, #[indexed] to: &ManagedBuffer, - #[indexed] round: usize, + #[indexed] round: Round, price: &BigUint, ); } diff --git a/contracts/core/price-aggregator/src/lib.rs b/contracts/core/price-aggregator/src/lib.rs index 1b98f35909..0f367552b9 100644 --- a/contracts/core/price-aggregator/src/lib.rs +++ b/contracts/core/price-aggregator/src/lib.rs @@ -6,6 +6,7 @@ mod events; pub mod median; pub mod price_aggregator_data; +use events::{RoundId, Timestamp}; use multiversx_sc_modules::staking; use price_aggregator_data::{OracleStatus, PriceFeed, TimestampedPrice, TokenPair}; @@ -123,7 +124,7 @@ pub trait PriceAggregator: &self, from: ManagedBuffer, to: ManagedBuffer, - submission_timestamp: u64, + submission_timestamp: Timestamp, price: BigUint, decimals: u8, ) { @@ -230,7 +231,9 @@ pub trait PriceAggregator: #[endpoint(submitBatch)] fn submit_batch( &self, - submissions: MultiValueEncoded>, + submissions: MultiValueEncoded< + MultiValue5, + >, ) { self.require_not_paused(); self.require_is_oracle(); @@ -267,7 +270,7 @@ pub trait PriceAggregator: fn create_new_round( &self, token_pair: TokenPair, - round_id: usize, + round_id: RoundId, mut submissions: MapMapper, decimals: u8, ) { @@ -444,13 +447,13 @@ pub trait PriceAggregator: fn first_submission_timestamp( &self, token_pair: &TokenPair, - ) -> SingleValueMapper; + ) -> SingleValueMapper; #[storage_mapper("last_submission_timestamp")] fn last_submission_timestamp( &self, token_pair: &TokenPair, - ) -> SingleValueMapper; + ) -> SingleValueMapper; #[storage_mapper("submissions")] fn submissions( From 29f4029e3e16f747ac04ae3acfe86e70800840bb Mon Sep 17 00:00:00 2001 From: Alin Cruceat Date: Wed, 9 Oct 2024 10:09:16 +0300 Subject: [PATCH 13/13] a few u32 vs usize conversions --- contracts/core/price-aggregator/src/events.rs | 10 +++++----- contracts/core/price-aggregator/src/lib.rs | 6 +++--- .../core/price-aggregator/src/price_aggregator_data.rs | 8 +++++--- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/contracts/core/price-aggregator/src/events.rs b/contracts/core/price-aggregator/src/events.rs index cc88c51e8b..ee80b25594 100644 --- a/contracts/core/price-aggregator/src/events.rs +++ b/contracts/core/price-aggregator/src/events.rs @@ -2,7 +2,7 @@ multiversx_sc::imports!(); multiversx_sc::derive_imports!(); use crate::price_aggregator_data::{TimestampedPrice, TokenPair}; -pub type RoundId = usize; +pub type RoundId = u32; pub type Round = usize; pub type Block = u64; pub type Epoch = u64; @@ -31,14 +31,14 @@ pub trait EventsModule { fn emit_new_round_event( &self, token_pair: &TokenPair, - round_id: RoundId, + round: Round, price_feed: &TimestampedPrice, ) { let epoch = self.blockchain().get_block_epoch(); self.new_round_event( &token_pair.from.clone(), &token_pair.to.clone(), - round_id, + round, &NewRoundEvent { price: price_feed.price.clone(), timestamp: price_feed.timestamp, @@ -61,7 +61,7 @@ pub trait EventsModule { fn emit_discard_submission_event( &self, token_pair: &TokenPair, - round_id: RoundId, + round: Round, submission_timestamp: Timestamp, first_submission_timestamp: Timestamp, has_caller_already_submitted: bool, @@ -69,7 +69,7 @@ pub trait EventsModule { self.discard_submission_event( &token_pair.from.clone(), &token_pair.to.clone(), - round_id, + round, &DiscardSubmissionEvent { submission_timestamp, first_submission_timestamp, diff --git a/contracts/core/price-aggregator/src/lib.rs b/contracts/core/price-aggregator/src/lib.rs index 0f367552b9..b9e5187580 100644 --- a/contracts/core/price-aggregator/src/lib.rs +++ b/contracts/core/price-aggregator/src/lib.rs @@ -6,7 +6,7 @@ mod events; pub mod median; pub mod price_aggregator_data; -use events::{RoundId, Timestamp}; +use events::{Round, Timestamp}; use multiversx_sc_modules::staking; use price_aggregator_data::{OracleStatus, PriceFeed, TimestampedPrice, TokenPair}; @@ -270,7 +270,7 @@ pub trait PriceAggregator: fn create_new_round( &self, token_pair: TokenPair, - round_id: RoundId, + round: Round, mut submissions: MapMapper, decimals: u8, ) { @@ -304,7 +304,7 @@ pub trait PriceAggregator: .or_default() .get() .push(&price_feed); - self.emit_new_round_event(&token_pair, round_id, &price_feed); + self.emit_new_round_event(&token_pair, round, &price_feed); } } diff --git a/contracts/core/price-aggregator/src/price_aggregator_data.rs b/contracts/core/price-aggregator/src/price_aggregator_data.rs index c348b67d22..e5fd64d4eb 100644 --- a/contracts/core/price-aggregator/src/price_aggregator_data.rs +++ b/contracts/core/price-aggregator/src/price_aggregator_data.rs @@ -1,3 +1,5 @@ +use crate::events::{RoundId, Timestamp}; + multiversx_sc::imports!(); multiversx_sc::derive_imports!(); @@ -11,10 +13,10 @@ pub struct TokenPair { #[type_abi] #[derive(NestedEncode, NestedDecode, TopEncode, TopDecode)] pub struct PriceFeed { - pub round_id: u32, + pub round_id: RoundId, pub from: ManagedBuffer, pub to: ManagedBuffer, - pub timestamp: u64, + pub timestamp: Timestamp, pub price: BigUint, pub decimals: u8, } @@ -23,7 +25,7 @@ pub struct PriceFeed { #[derive(TopEncode, TopDecode, Debug, PartialEq, Eq)] pub struct TimestampedPrice { pub price: BigUint, - pub timestamp: u64, + pub timestamp: Timestamp, pub decimals: u8, }