Skip to content

Commit

Permalink
safe math (#340)
Browse files Browse the repository at this point in the history
  • Loading branch information
mutobui authored Oct 2, 2023
1 parent 1495f51 commit df9e5d7
Show file tree
Hide file tree
Showing 13 changed files with 228 additions and 97 deletions.
169 changes: 116 additions & 53 deletions Cargo.lock

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion game/pallet-game/src/features/common.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/// Item module provides utility functions for pallet-game
use crate::*;
use frame_support::pallet_prelude::*;
use sp_runtime::traits::Saturating;

impl<T: Config<I>, I: 'static> Pallet<T, I> {
/// Transfer an `amount` of `item` in `collection` from `from` to `to`.
Expand Down Expand Up @@ -113,7 +114,7 @@ impl<T: Config<I>, I: 'static> Pallet<T, I> {
pub fn total_weight(table: &LootTable<T::CollectionId, T::ItemId>) -> u32 {
let mut counter = 0;
for package in table {
counter += package.weight;
counter = counter.saturating_add(package.weight);
}
counter
}
Expand Down
4 changes: 2 additions & 2 deletions game/pallet-game/src/features/loot_table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ impl<T: Config<I>, I: 'static> Pallet<T, I> {

while i < table.len() && positon > table[i].weight {
positon -= table[i].weight;
i += 1;
i.saturating_inc();
}

if i < table.len() {
Expand Down Expand Up @@ -66,7 +66,7 @@ impl<T: Config<I>, I: 'static> Pallet<T, I> {

while i < table.len() && positon > table[i].weight {
positon -= table[i].weight;
i += 1;
i.saturating_inc();
}

if i < table.len() {
Expand Down
2 changes: 1 addition & 1 deletion game/pallet-game/src/features/minting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ impl<T: Config<I>, I: 'static>

let reserve = pool_details.mint_settings.price.saturating_mul(amount.into());
<T as Config<I>>::Currency::reserve(&who, reserve)?;
let execute_block = block_number + T::MintInterval::get();
let execute_block = block_number.saturating_add(T::MintInterval::get());

let mint_request = MintRequest {
miner: who.clone(),
Expand Down
5 changes: 3 additions & 2 deletions game/pallet-game/src/features/upgrade_item.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::*;
use frame_support::{pallet_prelude::*, traits::ExistenceRequirement};
use gafi_support::game::{Amount, UpgradeItem, Level};
use gafi_support::game::{Amount, Level, UpgradeItem};
use sp_runtime::Saturating;

impl<T: Config<I>, I: 'static>
Expand Down Expand Up @@ -72,7 +72,8 @@ impl<T: Config<I>, I: 'static>
) -> DispatchResult {
ensure!(amount > 0, Error::<T, I>::InvalidAmount);

let next_level = LevelOf::<T, I>::get(collection, item) + 1;
let mut next_level = LevelOf::<T, I>::get(collection, item);
next_level.saturating_inc();

// get origin item
let origin_item = match OriginItemOf::<T, I>::get((collection, item)) {
Expand Down
5 changes: 3 additions & 2 deletions game/pallet-game/src/trades/auction.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::*;
use frame_support::{pallet_prelude::*, traits::BalanceStatus};
use gafi_support::game::{Auction, Bundle};
use sp_runtime::Saturating;

impl<T: Config<I>, I: 'static>
Auction<T::AccountId, T::CollectionId, T::ItemId, T::TradeId, BalanceOf<T, I>, T::BlockNumber>
Expand Down Expand Up @@ -70,7 +71,7 @@ impl<T: Config<I>, I: 'static>
Error::<T, I>::AuctionNotStarted
);
ensure!(
block_number < config.start_block + config.duration,
block_number < config.start_block.saturating_add(config.duration),
Error::<T, I>::AuctionEnded
);

Expand Down Expand Up @@ -101,7 +102,7 @@ impl<T: Config<I>, I: 'static>
let block_number = <frame_system::Pallet<T>>::block_number();

ensure!(
block_number >= (config.start_block + config.duration),
block_number >= (config.start_block.saturating_add(config.duration)),
Error::<T, I>::AuctionInProgress
);
let maybe_bid = HighestBidOf::<T, I>::get(trade);
Expand Down
25 changes: 16 additions & 9 deletions game/pallet-game/src/trades/retail.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ use gafi_support::game::{Amount, Package, Retail, TradeType};
use sp_runtime::Saturating;

impl<T: Config<I>, I: 'static>
Retail<T::AccountId, T::CollectionId, T::ItemId, T::TradeId, BalanceOf<T, I>, BlockNumber<T>> for Pallet<T, I>
Retail<T::AccountId, T::CollectionId, T::ItemId, T::TradeId, BalanceOf<T, I>, BlockNumber<T>>
for Pallet<T, I>
{
fn do_set_price(
trade: &T::TradeId,
Expand Down Expand Up @@ -118,8 +119,11 @@ impl<T: Config<I>, I: 'static>
ItemBalanceStatus::Free,
)?;

let new_package =
Package::new(package.collection, package.item, package.amount - amount);
let new_package = Package::new(
package.collection,
package.item,
package.amount.saturating_sub(amount),
);

<BundleOf<T, I>>::try_mutate(trade, |package_vec| -> DispatchResult {
*package_vec = BundleFor::<T, I>::try_from([new_package].to_vec())
Expand Down Expand Up @@ -206,7 +210,7 @@ impl<T: Config<I>, I: 'static>
let new_package = Package::new(
package.collection,
package.item,
package.amount + supply.amount,
package.amount.saturating_add(supply.amount),
);

<BundleOf<T, I>>::try_mutate(trade, |package_vec| -> DispatchResult {
Expand Down Expand Up @@ -238,7 +242,7 @@ impl<T: Config<I>, I: 'static>
// ensure reserve deposit
<T as Config<I>>::Currency::reserve(&who, T::BundleDeposit::get())?;

let deposit = unit_price * package.amount.into();
let deposit = unit_price.saturating_mul(package.amount.into());
<T as Config<I>>::Currency::reserve(&who, deposit)?;

<BundleOf<T, I>>::try_mutate(trade, |package_vec| -> DispatchResult {
Expand Down Expand Up @@ -280,7 +284,7 @@ impl<T: Config<I>, I: 'static>
) -> DispatchResult {
if let Some(config) = TradeConfigOf::<T, I>::get(trade) {
ensure!(config.trade == TradeType::SetBuy, Error::<T, I>::NotSetBuy);

let block_number = <frame_system::Pallet<T>>::block_number();
if let Some(start_block) = config.start_block {
ensure!(block_number >= start_block, Error::<T, I>::TradeNotStarted);
Expand Down Expand Up @@ -315,12 +319,15 @@ impl<T: Config<I>, I: 'static>
<T as pallet::Config<I>>::Currency::repatriate_reserved(
&config.owner,
&who,
price * amount.into(),
price.saturating_mul(amount.into()),
BalanceStatus::Free,
)?;

let new_package =
Package::new(package.collection, package.item, package.amount - amount);
let new_package = Package::new(
package.collection,
package.item,
package.amount.saturating_sub(amount),
);

<BundleOf<T, I>>::try_mutate(trade, |package_vec| -> DispatchResult {
*package_vec = BundleFor::<T, I>::try_from([new_package].to_vec())
Expand Down
4 changes: 2 additions & 2 deletions game/randomness/src/features/randomness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,12 @@ impl<T: Config> GameRandomness for Pallet<T> {
}
let mut random_number = Self::generate_random_number(seed);
for _ in 1..T::RandomAttemps::get() {
if random_number < u32::MAX.saturating_sub(u32::MAX % total) {
if random_number < u32::MAX.saturating_sub(u32::MAX.wrapping_rem(total)) {
break
}
random_number = Self::generate_random_number(seed);
}
return Some((random_number % total).saturating_add(1))
return Some((random_number.wrapping_rem(total)).saturating_add(1))
}
None
}
Expand Down
7 changes: 5 additions & 2 deletions game/randomness/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use sp_core::{offchain::KeyTypeId, Get};
use sp_runtime::{
traits::TrailingZeroInput,
transaction_validity::{InvalidTransaction, TransactionValidity, ValidTransaction},
Saturating,
};

mod features;
Expand Down Expand Up @@ -54,7 +55,9 @@ pub mod crypto {
}

/// Payload used to hold seed data required to submit a transaction.
#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, scale_info::TypeInfo, MaxEncodedLen)]
#[derive(
Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, scale_info::TypeInfo, MaxEncodedLen,
)]
pub struct SeedPayload<BlockNumber, Seed> {
block_number: BlockNumber,
seed: Seed,
Expand Down Expand Up @@ -167,7 +170,7 @@ pub mod pallet {
ensure_none(origin)?;

RandomSeed::<T>::put(SeedPayload { block_number, seed });
<NextUnsignedAt<T>>::put(block_number + T::UnsignedInterval::get());
<NextUnsignedAt<T>>::put(block_number.saturating_add(T::UnsignedInterval::get()));
Self::deposit_event(Event::<T>::NewSeed { block_number, seed });
Ok(())
}
Expand Down
2 changes: 2 additions & 0 deletions pallets/pallet-faucet/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ sp-std = {workspace = true}

# Local
gafi-support = {version = "4.0.0-dev", default-features = false, path = "../../support"}
gu-convertor = { default-features = false, version = "4.0.0-dev", path = "../../utils/convertor" }

[dev-dependencies]
pallet-balances = {workspace = true}
Expand All @@ -38,6 +39,7 @@ std = [
"codec/std",
"scale-info/std",
"frame-support/std",
"gu-convertor/std",
"frame-system/std",
"sp-runtime/std",
"pallet-balances/std",
Expand Down
43 changes: 28 additions & 15 deletions pallets/pallet-faucet/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
#![cfg_attr(not(feature = "std"), no_std)]

pub use crate::weights::WeightInfo;
use frame_support::traits::{Currency, ExistenceRequirement};
use gafi_support::pallet::cache::Cache;
use gu_convertor::{balance_try_to_u128, u128_to_balance};
pub use pallet::*;
pub use crate::weights::WeightInfo;
use sp_std::vec;
use gafi_support::pallet::cache::Cache;

#[cfg(test)]
mod mock;
Expand Down Expand Up @@ -41,7 +42,7 @@ pub mod pallet {
type WeightInfo: WeightInfo;

/// Add Cache
type Cache: Cache<Self::AccountId,AccountOf<Self> ,u128> ;
type Cache: Cache<Self::AccountId, AccountOf<Self>, u128>;

/// Faucet Amount
type FaucetAmount: Get<BalanceOf<Self>>;
Expand All @@ -64,7 +65,9 @@ pub mod pallet {
#[cfg(feature = "std")]
impl<T: Config> Default for GenesisConfig<T> {
fn default() -> Self {
Self { genesis_accounts: vec![]}
Self {
genesis_accounts: vec![],
}
}
}

Expand Down Expand Up @@ -110,10 +113,17 @@ pub mod pallet {
let sender = ensure_signed(origin)?;
let genesis_accounts = GenesisAccounts::<T>::get();
let faucet_amount = T::FaucetAmount::get();
let faucet_u128 = balance_try_to_u128::<<T as pallet::Config>::Currency, T::AccountId>(
faucet_amount,
)?;

let amount = faucet_u128.saturating_div(10u128);
let faucet = u128_to_balance::<<T as pallet::Config>::Currency, T::AccountId>(amount);

ensure!(Self::get_cache(&sender) == None, <Error<T>>::PleaseWait);

ensure!(
T::Currency::free_balance(&sender) < (faucet_amount / 10u128.try_into().ok().unwrap()),
T::Currency::free_balance(&sender) < faucet,
<Error<T>>::DontBeGreedy
);

Expand Down Expand Up @@ -144,13 +154,13 @@ pub mod pallet {
/// Weight: `O(1)`
#[pallet::call_index(1)]
#[pallet::weight(<T as pallet::Config>::WeightInfo::donate(50u32))]
pub fn donate(
origin: OriginFor<T>,
amount: BalanceOf<T>,
) -> DispatchResult {
pub fn donate(origin: OriginFor<T>, amount: BalanceOf<T>) -> DispatchResult {
let from = ensure_signed(origin)?;

ensure!(T::Currency::free_balance(&from) > amount, <Error<T>>::NotEnoughBalance);
ensure!(
T::Currency::free_balance(&from) > amount,
<Error<T>>::NotEnoughBalance
);
let genesis_accounts = GenesisAccounts::<T>::get();
ensure!(genesis_accounts[0] != from, <Error<T>>::SelfTransfer);

Expand All @@ -161,24 +171,27 @@ pub mod pallet {
ExistenceRequirement::KeepAlive,
)?;

Self::deposit_event(Event::Transferred(from, genesis_accounts[0].clone(), amount));
Self::deposit_event(Event::Transferred(
from,
genesis_accounts[0].clone(),
amount,
));

Ok(())
}
}

impl<T: Config> Pallet<T> {
fn insert_cache(sender: T::AccountId, faucet_amount: BalanceOf<T>)-> Option<()> {
match faucet_amount.try_into(){
fn insert_cache(sender: T::AccountId, faucet_amount: BalanceOf<T>) -> Option<()> {
match faucet_amount.try_into() {
Ok(value) => Some(T::Cache::insert(&sender, sender.clone(), value)),
Err(_) => None,
}

}

fn get_cache(sender: &T::AccountId) -> Option<u128> {
if let Some(faucet_cache) = T::Cache::get(sender, sender.clone()) {
return Some(faucet_cache);
return Some(faucet_cache)
}
None
}
Expand Down
52 changes: 46 additions & 6 deletions support/src/common/currency.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,29 +60,69 @@ impl TokenInfo for GafiCurrency {
/// assert_eq!(balance, 10_000_000_000_000_000_000);
/// ```
pub fn unit(token: NativeToken) -> u128 {
10u128.saturating_pow(GafiCurrency::token_info(token).decimals.into())
10u128.saturating_pow(GafiCurrency::token_info(token).decimals.into())
}

/// 1 centi = 0.01 unit
pub fn centi(token: NativeToken) -> u128 {
unit(token) / 100
unit(token).saturating_div(100)
}

/// 1 milli = 0.001 unit
pub fn milli(token: NativeToken) -> u128 {
unit(token) / 1000
unit(token).saturating_div(1000)
}

/// 1 millicent = 0.00001 unit
pub fn millicent(token: NativeToken) -> u128 {
centi(token) / 1000
centi(token).saturating_div(1000)
}

/// 1 microcent = 0.000001 unit
pub fn microcent(token: NativeToken) -> u128 {
milli(token) / 1000
milli(token).saturating_div(1000)
}

pub fn deposit(items: u32, bytes: u32, token: NativeToken) -> Balance {
items as Balance * 20 * unit(token.clone()) + (bytes as Balance) * 100 * millicent(token)
let mut balance = items as Balance;
balance = balance
.saturating_mul(20)
.saturating_mul(unit(token.clone()))
.saturating_add((bytes as Balance).saturating_mul(100).saturating_mul(millicent(token)));
balance
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_unit() {
assert_eq!(unit(NativeToken::GAKI), 1_000_000_000_000_000_000);
}

#[test]
fn test_centi() {
assert_eq!(centi(NativeToken::GAKI), 10_000_000_000_000_000);
}

#[test]
fn test_milli() {
assert_eq!(milli(NativeToken::GAKI), 1_000_000_000_000_000);
}

#[test]
fn test_millicent() {
assert_eq!(millicent(NativeToken::GAKI), 10_000_000_000_000);
}

#[test]
fn test_microcent() {
assert_eq!(microcent(NativeToken::GAKI), 1_000_000_000_000);
}

#[test]
fn test_deposit() {
assert_eq!(deposit(5, 100, NativeToken::GAKI), 100_100_000_000_000_000_000);
}
}
Loading

0 comments on commit df9e5d7

Please sign in to comment.