Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SFT donation treasury #86

Merged
merged 3 commits into from
Apr 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,4 @@ pub const ERR_ONLY_WITHDRAWAL_ADDRESS_CAN_WITHDRAW: &str =
pub const ERR_WITHDRAWAL_ADDRESS_NOT_SET: &str = "Withdrawal address not set";
pub const ERR_WRONG_AMOUNT_OF_FUNDS: &str = "Wrong amount of funds";
pub const ERR_WRONG_BOND_PERIOD: &str = "Wrong bond period";
pub const ERR_PERCENTAGE_TOO_HIGH: &str = "Percentage too high";
13 changes: 12 additions & 1 deletion src/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,17 @@ pub trait EventsModule {
#[event("setTreasuryAddress")]
fn treasury_address_event(&self, #[indexed] treasury_address: &ManagedAddress);

// Emitted whenever donation treasury address is set
#[event("setDonationTreasuryAddress")]
fn donation_treasury_address_event(
&self,
#[indexed] donation_treasury_address: &ManagedAddress,
);

// Emitted whenever max donation percentage is set
#[event("setMaxDonationPercentage")]
fn max_donation_percentage_event(&self, #[indexed] max_donation_percentage: &u64);

// Emitted whenever whitelist enabling changes value
#[event("whitelistEnableToggle")]
fn whitelist_enable_toggle_event(&self, #[indexed] enable_value: &bool);
Expand Down Expand Up @@ -129,7 +140,7 @@ pub trait EventsModule {
#[indexed] token: &EgldOrEsdtTokenIdentifier,
#[indexed] price: &BigUint,
#[indexed] bond_amount: &BigUint,
#[indexed] extra_assets: &ManagedVec<ManagedBuffer>
#[indexed] extra_assets: &ManagedVec<ManagedBuffer>,
);

#[event("setWithdrawalAddress")]
Expand Down
61 changes: 55 additions & 6 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ use crate::{
callbacks::CallbackProxy,
errors::{
ERR_ALREADY_IN_WHITELIST, ERR_CONTRACT_ALREADY_INITIALIZED, ERR_DATA_STREAM_IS_EMPTY,
ERR_ISSUE_COST, ERR_NOT_IN_WHITELIST, ERR_WHITELIST_IS_EMPTY, ERR_WRONG_AMOUNT_OF_FUNDS,
ERR_WRONG_BOND_PERIOD,
ERR_ISSUE_COST, ERR_NOT_IN_WHITELIST, ERR_PERCENTAGE_TOO_HIGH, ERR_WHITELIST_IS_EMPTY,
ERR_WRONG_AMOUNT_OF_FUNDS, ERR_WRONG_BOND_PERIOD,
},
storage::DataNftAttributes,
};
Expand Down Expand Up @@ -148,6 +148,7 @@ pub trait DataNftMint:
title: ManagedBuffer,
description: ManagedBuffer,
lock_period_sec: u64,
donation_percentage: u64,
extra_assets: MultiValueEncoded<ManagedBuffer>,
) -> DataNftAttributes<Self::Api> {
self.require_ready_for_minting_and_burning();
Expand All @@ -161,6 +162,23 @@ pub trait DataNftMint:
self.require_title_description_are_valid(&title, &description);
self.require_sft_is_valid(&royalties, &supply);

sc_print!("donation percentage: {} ", donation_percentage.clone());

let donation_supply = if donation_percentage > 0 {
require!(
donation_percentage <= self.max_donation_percentage().get(),
ERR_PERCENTAGE_TOO_HIGH
);

let donation_supply =
&supply * &BigUint::from(donation_percentage) / BigUint::from(10_000u64);
donation_supply
} else {
BigUint::zero()
};

sc_print!("donation supply:{}", donation_supply);

let caller = self.blockchain().get_caller();
let current_time = self.blockchain().get_block_timestamp();
self.require_minting_is_allowed(&caller, current_time);
Expand Down Expand Up @@ -206,14 +224,14 @@ pub trait DataNftMint:
};

let token_identifier = self.token_id().get_token_id();
let extra_assets_vec = extra_assets.into_vec_of_buffers();
let extra_assets_vec = extra_assets.into_vec_of_buffers();
self.mint_event(
&caller,
&one_token,
&payment.token_identifier,
&price,
&payment.amount,
&extra_assets_vec
&extra_assets_vec,
);

let nonce = self.send().esdt_nft_create(
Expand All @@ -234,8 +252,24 @@ pub trait DataNftMint:
payment,
);

self.send()
.direct_esdt(&caller, &token_identifier, nonce, &supply);
if donation_supply > BigUint::zero() {
let donation_treasury_address = self.donation_treasury_address().get();
self.send().direct_esdt(
&donation_treasury_address,
&token_identifier,
nonce,
&donation_supply,
);
self.send().direct_esdt(
&caller,
&token_identifier,
nonce,
&(&supply - &donation_supply),
);
} else {
self.send()
.direct_esdt(&caller, &token_identifier, nonce, &supply);
}

attributes
}
Expand Down Expand Up @@ -268,6 +302,21 @@ pub trait DataNftMint:
self.treasury_address().set(&address);
}

#[endpoint(setDonationTreasuryAddress)]
fn set_donation_treasury_address(&self, address: ManagedAddress) {
self.require_is_privileged(&self.blockchain().get_caller());
self.donation_treasury_address_event(&address);
self.donation_treasury_address().set(&address);
}

#[endpoint(setMaxDonationPercentage)]
fn set_max_donation_percentage(&self, percentage: u64) {
self.require_is_privileged(&self.blockchain().get_caller());
require!(percentage <= 10_000, ERR_PERCENTAGE_TOO_HIGH);
self.max_donation_percentage_event(&percentage);
self.max_donation_percentage().set(percentage);
}

// Endpoint that will be used by privileged address to change the contract pause value.
#[endpoint(setIsPaused)]
fn set_is_paused(&self, is_paused: bool) {
Expand Down
4 changes: 4 additions & 0 deletions src/requirements.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ pub trait RequirementsModule: crate::storage::StorageModule {
if self.treasury_address().is_empty() {
is_mint_ready = false;
}

if self.bond_contract_address().is_empty() {
is_mint_ready = false;
}
Expand All @@ -35,6 +36,9 @@ pub trait RequirementsModule: crate::storage::StorageModule {
if self.bond_contract_address().is_empty() {
is_mint_ready = false;
}
if self.donation_treasury_address().is_empty() {
is_mint_ready = false;
}
require!(is_mint_ready, ERR_MINTING_AND_BURNING_NOT_ALLOWED);
}

Expand Down
8 changes: 8 additions & 0 deletions src/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,14 @@ pub trait StorageModule {
#[storage_mapper("treasury_address")]
fn treasury_address(&self) -> SingleValueMapper<ManagedAddress>;

#[view(getDonationTreasuryAddress)]
#[storage_mapper("donation_treasury_address")]
fn donation_treasury_address(&self) -> SingleValueMapper<ManagedAddress>;

#[view(getMaxDonationPercentage)]
#[storage_mapper("max_donation_percentage")]
fn max_donation_percentage(&self) -> SingleValueMapper<u64>;

#[view(getWithdrawalAddress)]
#[storage_mapper("withdrawal_address")]
fn withdrawal_address(&self) -> SingleValueMapper<ManagedAddress>;
Expand Down
3 changes: 3 additions & 0 deletions src/views.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ pub struct UserDataOut<M: ManagedTypeApi> {
pub total_minted: BigUint<M>,
pub frozen: bool,
pub frozen_nonces: ManagedVec<M, u64>,
pub max_donation_percentage: u64,
}

//Module that handles read-only endpoints (views) for the smart contract
Expand Down Expand Up @@ -47,6 +48,7 @@ pub trait ViewsModule: crate::storage::StorageModule {
.frozen_sfts_per_address(&address)
.iter()
.collect::<ManagedVec<u64>>();
let max_donation_percentage = self.max_donation_percentage().get();

let user_data = UserDataOut {
anti_spam_tax_value,
Expand All @@ -62,6 +64,7 @@ pub trait ViewsModule: crate::storage::StorageModule {
total_minted,
frozen,
frozen_nonces,
max_donation_percentage,
};
user_data
}
Expand Down
1 change: 1 addition & 0 deletions tests/endpoints/burn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ fn burn_token_test() {
ITHEUM_TOKEN_IDENTIFIER,
0u64,
100u64 + 100u64,
0u64,
None,
);

Expand Down
Loading
Loading