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

Added Minor Deviation allowance for withdrawal #936

Merged
merged 4 commits into from
Mar 25, 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
26 changes: 18 additions & 8 deletions pallets/ocex/src/settlement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,17 @@
//! Helper functions for updating the balance

use crate::{storage::OffchainState, Config, Pallet};
use core::ops::Sub;
use log::{error, info};
use orderbook_primitives::constants::POLKADEX_MAINNET_SS58;
use orderbook_primitives::ocex::TradingPairConfig;
use orderbook_primitives::types::Order;
use orderbook_primitives::{constants::FEE_POT_PALLET_ID, types::Trade};
use parity_scale_codec::{alloc::string::ToString, Decode, Encode};
use polkadex_primitives::{fees::FeeConfig, AccountId, AssetId};
use rust_decimal::RoundingStrategy::ToZero;
use rust_decimal::{prelude::ToPrimitive, Decimal};
use sp_core::crypto::ByteArray;
use sp_core::crypto::{ByteArray, Ss58AddressFormat, Ss58Codec};
use sp_runtime::traits::AccountIdConversion;
use sp_std::collections::btree_map::BTreeMap;

Expand Down Expand Up @@ -88,7 +91,7 @@ pub fn add_balance(
/// Updates provided trie db with reducing balance of account asset if it exists in the db.
///
/// If account asset balance does not exists in the db `AccountBalanceNotFound` error will be
/// returned.
/// returned. Balance returned is the acutal balance that was deduced accounting for rounding errors/deviation.
///
/// # Parameters
///
Expand All @@ -100,26 +103,33 @@ pub fn sub_balance(
state: &mut OffchainState,
account: &AccountId,
asset: AssetId,
balance: Decimal,
) -> Result<(), &'static str> {
mut balance: Decimal,
) -> Result<Decimal, &'static str> {
log::info!(target:"ocex", "subtracting {:?} asset {:?} from account {:?}", balance.to_f64().unwrap(), asset.to_string(), account);
let mut balances: BTreeMap<AssetId, Decimal> = match state.get(&account.to_raw_vec())? {
None => return Err("Account not found in trie"),
Some(encoded) => BTreeMap::decode(&mut &encoded[..])
.map_err(|_| "Unable to decode balances for account")?,
};

let account_balance = balances.get_mut(&asset).ok_or("NotEnoughBalance")?;
let account_balance = balances.get_mut(&asset).ok_or("NotEnoughBalance: zero balance")?;

if *account_balance < balance {
log::error!(target:"ocex","Asset found but balance low for asset: {:?}, of account: {:?}",asset, account);
return Err("NotEnoughBalance");
// If the deviation is smaller that system limit, then we can allow what's stored in the offchain balance
let deviation = balance.sub(&*account_balance);
if !deviation.round_dp_with_strategy(8, ToZero).is_zero() {
log::error!(target:"ocex","Asset found but balance low for asset: {:?}, of account: {:?}",asset, account);
return Err("NotEnoughBalance");
} else {
log::warn!(target:"ocex","Asset found but minor balance deviation of {:?} for asset: {:?}, of account: {:?}",deviation,asset.to_string(), account.to_ss58check_with_version(Ss58AddressFormat::from(POLKADEX_MAINNET_SS58)));
balance = *account_balance;
}
}
*account_balance = Order::rounding_off(account_balance.saturating_sub(balance));

state.insert(account.to_raw_vec(), balances.encode());

Ok(())
Ok(balance)
}

impl<T: Config> Pallet<T> {
Expand Down
15 changes: 8 additions & 7 deletions pallets/ocex/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -316,16 +316,16 @@ fn test_sub_balance_existing_account_with_balance() {

//sub balance
let amount2 = 2000000;
let result = sub_balance(&mut state, &account_id, asset_id, amount2.into());
assert_eq!(result, Ok(()));
let result = sub_balance(&mut state, &account_id, asset_id, amount2.into()).unwrap();
assert_eq!(result, amount2.into());
let encoded = state.get(&account_id.to_raw_vec()).unwrap().unwrap();
let account_info: BTreeMap<AssetId, Decimal> = BTreeMap::decode(&mut &encoded[..]).unwrap();
assert_eq!(account_info.get(&asset_id).unwrap(), &(amount - amount2).into());

//sub balance till 0
let amount3 = amount - amount2;
let result = sub_balance(&mut state, &account_id, asset_id, amount3.into());
assert_eq!(result, Ok(()));
let result = sub_balance(&mut state, &account_id, asset_id, amount3.into()).unwrap();
assert_eq!(result, amount3.into());
let encoded = state.get(&account_id.to_raw_vec()).unwrap().unwrap();
let account_info: BTreeMap<AssetId, Decimal> = BTreeMap::decode(&mut &encoded[..]).unwrap();
assert_eq!(amount - amount2 - amount3, 0);
Expand Down Expand Up @@ -416,8 +416,9 @@ fn test_balance_update_depost_first_then_trade() {

//sub balance till 0
let amount3 = Decimal::from_f64_retain(2.0).unwrap();
let result = sub_balance(&mut state, &account_id, AssetId::Polkadex, amount3.into());
assert_eq!(result, Ok(()));
let result =
sub_balance(&mut state, &account_id, AssetId::Polkadex, amount3.into()).unwrap();
assert_eq!(result, amount3);
});
}

Expand Down Expand Up @@ -469,7 +470,7 @@ fn test_trade_between_two_accounts_without_balance() {
let result = OCEX::process_trade(&mut state, &trade, config, maker_fees, taker_fees);
match result {
Ok(_) => assert!(false),
Err(e) => assert_eq!(e, "NotEnoughBalance"),
Err(e) => assert_eq!(e, "NotEnoughBalance: zero balance"),
}
});
}
Expand Down
6 changes: 3 additions & 3 deletions pallets/ocex/src/validator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -681,15 +681,15 @@ impl<T: Config> Pallet<T> {
if !request.verify() {
return Err("SignatureVerificationFailed");
}
sub_balance(
let actual_deducted = sub_balance(
state,
&Decode::decode(&mut &request.main.encode()[..])
.map_err(|_| "account id decode error")?,
request.asset(),
amount,
)?;
let withdrawal = request.convert(stid).map_err(|_| "Withdrawal conversion error")?;

let mut withdrawal = request.convert(stid).map_err(|_| "Withdrawal conversion error")?;
withdrawal.amount = actual_deducted; // The acutal deducted balance
Ok(withdrawal)
}

Expand Down
2 changes: 1 addition & 1 deletion runtimes/mainnet/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
// and set impl_version to 0. If only runtime
// implementation changes and behavior does not, then leave spec_version as
// is and increment impl_version.
spec_version: 338,
spec_version: 341,
impl_version: 0,
apis: RUNTIME_API_VERSIONS,
transaction_version: 2,
Expand Down
1 change: 1 addition & 0 deletions runtimes/parachain/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -837,6 +837,7 @@ impl_runtime_apis! {
}
}

#[allow(dead_code)]
struct CheckInherents;

impl cumulus_pallet_parachain_system::CheckInherents<Block> for CheckInherents {
Expand Down
2 changes: 1 addition & 1 deletion scripts/get_balance_rpc.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ curl -H "Content-Type: application/json" -d '{
"jsonrpc":"2.0",
"id":1,
"method":"ob_getBalance",
"params":["esr4dJBv5123tkiA3beRZ3TrHbppJ6PdPxo2xHN4rmZJGDQJo",{"asset":"3496813586714279103986568049643838918"}]
"params":["espg8YLUhUDVXcrfNMyHqzjBBrrq3HBKj3FBQNq6Hte3p28Eh",{"asset":"95930534000017180603917534864279132680"}]
}' http://localhost:9944
Loading