From c5d048d22a1e50178d9bed5dbfa39dfe844566de Mon Sep 17 00:00:00 2001 From: Dorin Marian Iancu Date: Mon, 25 Sep 2023 11:31:43 +0300 Subject: [PATCH 1/2] fixes --- src/xbulk.rs | 149 +++++++++++++++++++++++++-------------------------- 1 file changed, 74 insertions(+), 75 deletions(-) diff --git a/src/xbulk.rs b/src/xbulk.rs index eb31623..7674698 100644 --- a/src/xbulk.rs +++ b/src/xbulk.rs @@ -2,13 +2,26 @@ use core::ops::Deref; multiversx_sc::imports!(); +multiversx_sc::derive_imports!(); + +#[derive(ManagedVecItem)] +pub struct DestAmountPair { + pub dest: ManagedAddress, + pub amount: BigUint, +} #[multiversx_sc::derive::contract] pub trait XBulk: multiversx_sc_modules::dns::DnsModule { #[init] fn init(&self, new_owner: OptionalValue) { - if let Some(o) = new_owner.into_option() { - self.owners().insert(o); + match new_owner { + OptionalValue::Some(o) => { + let _ = self.owners().insert(o); + } + OptionalValue::None => { + let sc_owner = self.blockchain().get_owner_address(); + let _ = self.owners().insert(sc_owner); + } } } @@ -19,69 +32,58 @@ pub trait XBulk: multiversx_sc_modules::dns::DnsModule { #[only_owner] #[endpoint(addOwner)] fn add_owner(&self, new_owner: ManagedAddress) { - require!( - !self.owners().contains(&new_owner), - "The address is already an owner" - ); - self.owners().insert(new_owner); - } - - fn require_owner(&self) { - let owners = self.owners(); - if !owners.is_empty() { - require!( - owners.contains(&self.blockchain().get_caller()), - "You are not allowed to call this method on this contract" - ); - } + let _ = self.owners().insert(new_owner); } #[payable("*")] - #[endpoint] - fn bulksend( - &self, - #[payment_token] payment_token: EgldOrEsdtTokenIdentifier, - #[payment_amount] payment_amount: BigUint, - #[payment_nonce] nonce: u64, - destinations: MultiValueEncoded>, - ) { + #[endpoint(bulkSend)] + fn bulk_send(&self, destinations: MultiValueEncoded>) { self.require_owner(); - let mut amount_to_spend = BigUint::from(0u64); + let payment = self.call_value().egld_or_single_esdt(); - for destination in destinations.clone() { - let (_address_to_send, amount_to_send) = destination.into_tuple(); + let mut amount_to_spend = BigUint::zero(); + let mut dest_amount_pairs = ManagedVec::>::new(); + for destination in destinations { + let (address_to_send, amount_to_send) = destination.into_tuple(); amount_to_spend += &amount_to_send; + + dest_amount_pairs.push(DestAmountPair { + dest: address_to_send, + amount: amount_to_send, + }); } require!( - payment_amount == amount_to_spend, + payment.amount == amount_to_spend, "The sent amount must be equal to the sum of each transaction you want to send" ); - for destination in destinations { - let (address_to_send, amount_to_send) = destination.into_tuple(); - self.send() - .direct(&address_to_send, &payment_token, nonce, &amount_to_send); + for pair in &dest_amount_pairs { + self.send().direct( + &pair.dest, + &payment.token_identifier, + payment.token_nonce, + &pair.amount, + ); } } #[payable("*")] - #[endpoint(bulksendSameAmount)] - fn bulksend_same_amount( - &self, - #[payment_token] payment_token: EgldOrEsdtTokenIdentifier, - #[payment_amount] payment_amount: BigUint, - #[payment_nonce] nonce: u64, - destinations: MultiValueEncoded, - ) { + #[endpoint(bulkSendSameAmount)] + fn bulk_send_same_amount(&self, destinations: MultiValueEncoded) { self.require_owner(); - let amount_to_send = payment_amount / BigUint::from(destinations.len() as u64); + let payment = self.call_value().egld_or_single_esdt(); + let amount_to_send = payment.amount / (destinations.len() as u64); for destination in destinations { - self.send() - .direct(&destination, &payment_token, nonce, &amount_to_send); + self.send().direct( + &destination, + &payment.token_identifier, + payment.token_nonce, + &amount_to_send, + ); } } @@ -90,35 +92,33 @@ pub trait XBulk: multiversx_sc_modules::dns::DnsModule { fn draw( &self, participants: MultiValueEncoded, - #[payment_multi] payments: ManagedRef<'static, ManagedVec>>, ) -> MultiValueEncoded { self.require_owner(); + let payments = self.call_value().all_esdt_transfers(); + let mut part_vecs = participants.to_vec(); let mut rand_source = RandomnessSource::new(); let mut winners: ManagedVec = ManagedVec::new(); for payment in payments.deref() { - let token_payment = EgldOrEsdtTokenPayment::from(payment); - - //draw a winner + // draw a winner let winner_index = rand_source.next_usize_in_range(0, part_vecs.len()); let winner_item = part_vecs.get(winner_index); - let winner = winner_item.deref().clone(); - //add the winner to the winners array - winners.push(winner.clone()); - - //send the token to the winner - self.send().direct( + // send the token to the winner + self.send().direct_esdt( &winner, - &token_payment.token_identifier, - token_payment.token_nonce, - &token_payment.amount, + &payment.token_identifier, + payment.token_nonce, + &payment.amount, ); + // add the winner to the winners array + winners.push(winner); + //remove the winner from the participants part_vecs.remove(winner_index); } @@ -128,32 +128,31 @@ pub trait XBulk: multiversx_sc_modules::dns::DnsModule { #[payable("*")] #[endpoint(nftDistribution)] - fn nft_distribution( - &self, - destinations: MultiValueEncoded, - #[payment_multi] payments: ManagedRef<'static, ManagedVec>>, - ) { + fn nft_distribution(&self, destinations: MultiValueEncoded) { self.require_owner(); + let payments = self.call_value().all_esdt_transfers(); require!( payments.len() == destinations.len(), "The number of NFTs must be equal to the number of destinations" ); - let destinations_vec = destinations.to_vec(); - - for i in 0..payments.len() { - let payment = payments.get(i); - let destination = destinations_vec.get(i); - - let token_payment = EgldOrEsdtTokenPayment::from(payment); - - self.send().direct( - &destination, - &token_payment.token_identifier, - token_payment.token_nonce, - &token_payment.amount, + for (dest, payment) in destinations.into_iter().zip(payments.iter()) { + // send the token to the winner + self.send().direct_esdt( + &dest, + &payment.token_identifier, + payment.token_nonce, + &payment.amount, ); } } + + fn require_owner(&self) { + let caller = self.blockchain().get_caller(); + require!( + self.owners().contains(&caller), + "You are not allowed to call this method on this contract" + ); + } } From 2ce5692c6eafb72e3a8f211c8c641337b18fa3a2 Mon Sep 17 00:00:00 2001 From: Dorin Marian Iancu Date: Mon, 25 Sep 2023 11:35:26 +0300 Subject: [PATCH 2/2] get caller instead of owner --- src/xbulk.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/xbulk.rs b/src/xbulk.rs index 7674698..e20700c 100644 --- a/src/xbulk.rs +++ b/src/xbulk.rs @@ -19,7 +19,7 @@ pub trait XBulk: multiversx_sc_modules::dns::DnsModule { let _ = self.owners().insert(o); } OptionalValue::None => { - let sc_owner = self.blockchain().get_owner_address(); + let sc_owner = self.blockchain().get_caller(); let _ = self.owners().insert(sc_owner); } }