Skip to content

Commit

Permalink
Merge pull request #7 from Itheum/develop
Browse files Browse the repository at this point in the history
Improvements
  • Loading branch information
bucurdavid authored Mar 15, 2024
2 parents 35e1e66 + 02cc0b4 commit bb99e6e
Show file tree
Hide file tree
Showing 12 changed files with 159 additions and 99 deletions.
61 changes: 58 additions & 3 deletions src/admin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ use crate::{
compensation_cache::{self, CompensationCache},
},
errors::{
ERR_ALREADY_ACTIVE, ERR_ALREADY_INACTIVE, ERR_ALREADY_IN_STORAGE,
ERR_COMPENSATION_NOT_FOUND, ERR_INVALID_PENALTY_VALUE, ERR_INVALID_TIMESTAMP,
ERR_INVALID_TOKEN_IDENTIFIER, ERR_NOT_PRIVILEGED,
ERR_INVALID_TOKEN_IDENTIFIER, ERR_NOT_IN_STORAGE, ERR_NOT_PRIVILEGED,
},
events, only_privileged,
storage::{self, PenaltyType},
Expand All @@ -19,6 +20,22 @@ multiversx_sc::derive_imports!();
pub trait AdminModule:
crate::config::ConfigModule + storage::StorageModule + events::EventsModule
{
#[endpoint(initiateBond)]
fn initiate_bond_for_address(
&self,
address: ManagedAddress,
token_identifier: TokenIdentifier,
nonce: u64,
) {
only_privileged!(self, ERR_NOT_PRIVILEGED);

let bond_id = self
.bonds_ids()
.get_id_or_insert((token_identifier.clone(), nonce));

self.address_bonds(&address).insert(bond_id);
}

#[endpoint(setBlacklist)]
fn add_to_black_list(
&self,
Expand All @@ -35,6 +52,12 @@ pub trait AdminModule:
self.add_to_blacklist_event(&compensation_id, &addresses);

for address in addresses.into_iter() {
if self
.compensation_blacklist(compensation_id)
.contains(&address)
{
sc_panic!(ERR_ALREADY_IN_STORAGE);
}
self.compensation_blacklist(compensation_id).insert(address);
}
}
Expand All @@ -55,6 +78,12 @@ pub trait AdminModule:
self.remove_from_blacklist_event(&compensation_id, &addresses);

for address in addresses.into_iter() {
if !self
.compensation_blacklist(compensation_id)
.contains(&address)
{
sc_panic!(ERR_NOT_IN_STORAGE);
}
self.compensation_blacklist(compensation_id)
.swap_remove(&address);
}
Expand Down Expand Up @@ -90,6 +119,10 @@ pub trait AdminModule:
) {
only_privileged!(self, ERR_NOT_PRIVILEGED);

if penalty != PenaltyType::Custom {
require!(custom_penalty.is_none(), ERR_INVALID_PENALTY_VALUE);
}

let bond_id = self
.bonds_ids()
.get_id_non_zero((token_identifier.clone(), nonce));
Expand Down Expand Up @@ -154,13 +187,21 @@ pub trait AdminModule:
#[endpoint(setContractStateActive)]
fn set_contract_state_active(&self) {
only_privileged!(self, ERR_NOT_PRIVILEGED);
require!(
self.contract_state().get() == State::Inactive,
ERR_ALREADY_ACTIVE
);
self.contract_state().set(State::Active);
self.contract_state_event(State::Active);
}

#[endpoint(setContractStateInactive)]
fn set_contract_state_inactive(&self) {
only_privileged!(self, ERR_NOT_PRIVILEGED);
require!(
self.contract_state().get() == State::Active,
ERR_ALREADY_INACTIVE
);
self.contract_state().set(State::Inactive);
self.contract_state_event(State::Inactive);
}
Expand All @@ -170,6 +211,9 @@ pub trait AdminModule:
only_privileged!(self, ERR_NOT_PRIVILEGED);
self.set_accepted_callers_event(&callers);
for caller in callers.into_iter() {
if self.accepted_callers().contains(&caller) {
sc_panic!(ERR_ALREADY_IN_STORAGE)
}
self.accepted_callers().insert(caller);
}
}
Expand All @@ -179,6 +223,9 @@ pub trait AdminModule:
only_privileged!(self, ERR_NOT_PRIVILEGED);
self.remove_accepted_callers_event(&callers);
for caller in callers.into_iter() {
if !self.accepted_callers().contains(&caller) {
sc_panic!(ERR_NOT_IN_STORAGE)
}
self.accepted_callers().swap_remove(&caller);
}
}
Expand All @@ -194,11 +241,16 @@ pub trait AdminModule:
self.bond_payment_token().set(token_identifier);
}

#[endpoint(setPeriodsBonds)]
fn set_lock_periods_with_bonds(&self, args: MultiValueEncoded<MultiValue2<u64, BigUint>>) {
#[endpoint(addPeriodsBonds)]
fn add_lock_periods_with_bonds(&self, args: MultiValueEncoded<MultiValue2<u64, BigUint>>) {
only_privileged!(self, ERR_NOT_PRIVILEGED);
for input in args.into_iter() {
let (lock_period, bond) = input.into_tuple();

if self.lock_periods().contains(&lock_period) {
sc_panic!(ERR_ALREADY_IN_STORAGE);
}

self.set_period_and_bond_event(&lock_period, &bond);
self.lock_periods().insert(lock_period);
self.lock_period_bond_amount(lock_period).set(bond);
Expand All @@ -209,6 +261,9 @@ pub trait AdminModule:
fn remove_lock_periods_with_bonds(&self, lock_periods: MultiValueEncoded<u64>) {
only_privileged!(self, ERR_NOT_PRIVILEGED);
for period in lock_periods.into_iter() {
if !self.lock_periods().contains(&period) {
sc_panic!(ERR_NOT_IN_STORAGE);
}
self.remove_period_and_bond_event(&period, &self.lock_period_bond_amount(period).get());
self.lock_periods().remove(&period);
self.lock_period_bond_amount(period).clear();
Expand Down
53 changes: 44 additions & 9 deletions src/config.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::{events, storage};
use crate::{errors::ERR_ALREADY_IN_STORAGE, events, storage};

multiversx_sc::imports!();
multiversx_sc::derive_imports!();
Expand Down Expand Up @@ -29,17 +29,16 @@ pub trait ConfigModule: storage::StorageModule + events::EventsModule {
#[endpoint(setAdministrator)]
fn set_administrator(&self, administrator: ManagedAddress) {
self.set_administrator_event(&administrator);

if !self.administrator().is_empty() {
require!(
administrator != self.administrator().get(),
ERR_ALREADY_IN_STORAGE
);
}
self.administrator().set(administrator);
}

#[view(getContractState)]
#[storage_mapper("contract_state")]
fn contract_state(&self) -> SingleValueMapper<State>;

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

#[inline]
fn is_contract_owner(&self, address: &ManagedAddress) -> bool {
&(self.blockchain().get_owner_address()) == address
Expand Down Expand Up @@ -81,4 +80,40 @@ pub trait ConfigModule: storage::StorageModule + events::EventsModule {
fn is_state_active(&self, state: State) -> bool {
state == State::Active
}

#[view(getContractState)]
#[storage_mapper("contract_state")]
fn contract_state(&self) -> SingleValueMapper<State>;

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

#[view(getAcceptedCallers)]
#[storage_mapper("accepted_callers")]
fn accepted_callers(&self) -> UnorderedSetMapper<ManagedAddress>;

#[view(getBondPaymentToken)]
#[storage_mapper("bond_payment_token")]
fn bond_payment_token(&self) -> SingleValueMapper<TokenIdentifier>;

#[view(getLockPeriods)]
#[storage_mapper("lock_periods")]
fn lock_periods(&self) -> SetMapper<u64>;

#[view(getLockPeriodBondAmount)]
#[storage_mapper("lock_period_bond_amount")]
fn lock_period_bond_amount(&self, lock_period: u64) -> SingleValueMapper<BigUint>;

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

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

#[view(getWithdrawPenalty)]
#[storage_mapper("withdraw_penalty")]
fn withdraw_penalty(&self) -> SingleValueMapper<u64>;
}
4 changes: 4 additions & 0 deletions src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,7 @@ pub const ERR_INVALID_TIMELINE_TO_REFUND: &str = "Invalid timeline to refund";
pub const ERR_REFUND_NOT_FOUND: &str = "Refund not found";
pub const ERR_INVALID_TIMESTAMP: &str = "Invalid timestamp";
pub const ERR_PENALTIES_EXCEED_WITHDRAWAL_AMOUNT: &str = "Penalties exceed withdrawal amount";
pub const ERR_ALREADY_IN_STORAGE: &str = "Already in storage";
pub const ERR_NOT_IN_STORAGE: &str = "Not in storage";
pub const ERR_ALREADY_ACTIVE: &str = "Already active";
pub const ERR_ALREADY_INACTIVE: &str = "Already inactive";
2 changes: 0 additions & 2 deletions src/events.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
// [TO DO] implement events for endpoints

use multiversx_sc::types::MultiValueEncoded;

use crate::{
Expand Down
47 changes: 14 additions & 33 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ pub trait LifeBondingContract:
original_caller: ManagedAddress,
token_identifier: TokenIdentifier,
nonce: u64,
lock_period: u64, //seconds
lock_period_seconds: u64,
) {
require_contract_ready!(self, ERR_CONTRACT_NOT_READY);
let caller = self.blockchain().get_caller();
Expand All @@ -85,36 +85,27 @@ pub trait LifeBondingContract:
ERR_INVALID_TOKEN_IDENTIFIER
);

// check token_identifier is accepted (not really needed as this endpoint will be called by the minting contract)

require!(
self.lock_periods().contains(&lock_period),
self.lock_periods().contains(&lock_period_seconds),
ERR_INVALID_LOCK_PERIOD
);
require!(
!self.lock_period_bond_amount(lock_period).is_empty(),
!self.lock_period_bond_amount(lock_period_seconds).is_empty(),
ERR_INVALID_LOCK_PERIOD
); // check not really needed
);

let bond_amount = self.lock_period_bond_amount(lock_period).get();
let bond_amount = self.lock_period_bond_amount(lock_period_seconds).get();

require!(payment.amount == bond_amount, ERR_INVALID_AMOUNT);

let current_timestamp = self.blockchain().get_block_timestamp();
let unbound_timestamp = current_timestamp + lock_period;

// let check_bond_id = self.bonds_ids().get_id((token_identifier.clone(), nonce));

// require!(
// !self.bonds_ids().contains_id(check_bond_id),
// ERR_BOND_ALREADY_CREATED
// );
let unbound_timestamp = current_timestamp + lock_period_seconds;

self.bond_address(bond_id).set(original_caller.clone());
self.bond_token_identifier(bond_id)
.set(token_identifier.clone());
self.bond_nonce(bond_id).set(nonce);
self.bond_lock_period(bond_id).set(lock_period);
self.bond_lock_period(bond_id).set(lock_period_seconds);
self.bond_timestamp(bond_id).set(current_timestamp);
self.unbound_timestamp(bond_id).set(unbound_timestamp);
self.bond_amount(bond_id).set(payment.amount.clone());
Expand Down Expand Up @@ -185,10 +176,8 @@ pub trait LifeBondingContract:
0u64,
&bond_cache.remaining_amount,
);
// clear compensations as the entire bond is withdrawn
// compensation_cache.clear();
// self.compensations_ids().remove_by_id(compensation_id);
self.compensations().swap_remove(&compensation_id); // remove from showing if it's withdrawn

self.compensations().swap_remove(&compensation_id);
}

self.withdraw_event(
Expand All @@ -198,11 +187,7 @@ pub trait LifeBondingContract:
&penalty_amount,
);

// Do not clear bond totally as creator can come and bond/renew again
// bond_cache.clear();
// self.bonds_ids().remove_by_id(bond_id);
// self.address_bonds(&caller).swap_remove(&bond_id);
self.bonds().swap_remove(&bond_id); // remove from showing if it's withdrawn
self.bonds().swap_remove(&bond_id);
}

#[endpoint(renew)]
Expand Down Expand Up @@ -281,7 +266,7 @@ pub trait LifeBondingContract:
let current_timestamp = self.blockchain().get_block_timestamp();

require!(
current_timestamp > compensation_cache.end_date + COMPENSATION_SAFE_PERIOD, // 86_400 seconds safe period for black list to be uploaded
current_timestamp > compensation_cache.end_date + COMPENSATION_SAFE_PERIOD,
ERR_INVALID_TIMELINE_TO_REFUND
);

Expand All @@ -297,7 +282,7 @@ pub trait LifeBondingContract:
let address_refund = self.address_refund(&caller, compensation_id).get();

self.send()
.direct_non_zero_esdt_payment(&caller, &address_refund.proof_of_refund); // sending back the nfts
.direct_non_zero_esdt_payment(&caller, &address_refund.proof_of_refund);

compensation_cache.proof_amount -= &address_refund.proof_of_refund.amount;
self.compensation_blacklist(compensation_id)
Expand Down Expand Up @@ -351,14 +336,10 @@ pub trait LifeBondingContract:
self.address_refund(&caller, compensation_id).clear();
}

if compensation_cache.accumulated_amount == BigUint::zero() // remove compensation if there is no more accumulated amount
if compensation_cache.accumulated_amount == BigUint::zero()
&& compensation_cache.proof_amount == BigUint::zero()
{
self.compensations().swap_remove(&compensation_id); // remove from showing if it's empty

// Do not clear compensation totally as creator can come and bond/renew again
// compensation_cache.clear();
// self.compensations_ids().remove_by_id(compensation_id);
self.compensations().swap_remove(&compensation_id);
}
}
}
Loading

0 comments on commit bb99e6e

Please sign in to comment.