diff --git a/pallets/ocex/src/settlement.rs b/pallets/ocex/src/settlement.rs index efe6753dc..d3e30d142 100644 --- a/pallets/ocex/src/settlement.rs +++ b/pallets/ocex/src/settlement.rs @@ -27,7 +27,6 @@ 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, Ss58AddressFormat, Ss58Codec}; use sp_runtime::traits::AccountIdConversion; @@ -104,6 +103,7 @@ pub fn sub_balance( account: &AccountId, asset: AssetId, mut balance: Decimal, + is_withdrawal: bool, ) -> Result { log::info!(target:"ocex", "subtracting {:?} asset {:?} from account {:?}", balance.to_f64().unwrap(), asset.to_string(), account); let mut balances: BTreeMap = match state.get(&account.to_raw_vec())? { @@ -115,14 +115,14 @@ pub fn sub_balance( let account_balance = balances.get_mut(&asset).ok_or("NotEnoughBalance: zero balance")?; if *account_balance < balance { - // 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() { + if is_withdrawal { + // 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); + log::warn!(target:"ocex","[withdrawal] balance deviation of {:?} for asset: {:?}, of account: {:?}: Withdrawing available balance",deviation,asset.to_string(), account.to_ss58check_with_version(Ss58AddressFormat::from(POLKADEX_MAINNET_SS58))); + balance = *account_balance; + } else { 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)); @@ -170,7 +170,7 @@ impl Pallet { add_balance(state, &pot_account, maker_asset.asset, maker_fees)?; let (maker_asset, maker_debit) = trade.debit(true); - sub_balance(state, &maker_asset.main, maker_asset.asset, maker_debit)?; + sub_balance(state, &maker_asset.main, maker_asset.asset, maker_debit, false)?; maker_fees }; let taker_fees = { @@ -182,7 +182,7 @@ impl Pallet { add_balance(state, &pot_account, taker_asset.asset, taker_fees)?; let (taker_asset, taker_debit) = trade.debit(false); - sub_balance(state, &taker_asset.main, taker_asset.asset, taker_debit)?; + sub_balance(state, &taker_asset.main, taker_asset.asset, taker_debit, false)?; taker_fees }; diff --git a/pallets/ocex/src/tests.rs b/pallets/ocex/src/tests.rs index afb9c7bf9..8793464fa 100644 --- a/pallets/ocex/src/tests.rs +++ b/pallets/ocex/src/tests.rs @@ -252,8 +252,14 @@ fn test_two_assets() { let asset456 = AssetId::Asset(456); let amount456 = Decimal::from_str("10.0").unwrap(); // works - sub_balance(&mut state, &account_id, asset1, Decimal::from_str("0.01").unwrap().into()) - .unwrap(); + sub_balance( + &mut state, + &account_id, + asset1, + Decimal::from_str("0.01").unwrap().into(), + false, + ) + .unwrap(); add_balance(&mut state, &coinalpha, asset123, amount123.into()).unwrap(); add_balance(&mut state, &coinalpha, asset456, amount456.into()).unwrap(); let root = state.commit().unwrap(); @@ -262,10 +268,22 @@ fn test_two_assets() { let mut root = crate::storage::load_trie_root(); let mut trie_state = crate::storage::State; let mut state = OffchainState::load(&mut trie_state, &mut root); - sub_balance(&mut state, &account_id, asset1, Decimal::from_str("0.01").unwrap().into()) - .unwrap(); - sub_balance(&mut state, &account_id, asset1, Decimal::from_str("0.01").unwrap().into()) - .unwrap(); + sub_balance( + &mut state, + &account_id, + asset1, + Decimal::from_str("0.01").unwrap().into(), + false, + ) + .unwrap(); + sub_balance( + &mut state, + &account_id, + asset1, + Decimal::from_str("0.01").unwrap().into(), + false, + ) + .unwrap(); }); } @@ -282,7 +300,7 @@ fn test_sub_balance_new_account() { let mut root = crate::storage::load_trie_root(); let mut trie_state = crate::storage::State; let mut state = OffchainState::load(&mut trie_state, &mut root); - let result = sub_balance(&mut state, &account_id, asset_id, amount.into()); + let result = sub_balance(&mut state, &account_id, asset_id, amount.into(), false); match result { Ok(_) => assert!(false), Err(e) => assert_eq!(e, "Account not found in trie"), @@ -316,7 +334,7 @@ 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()).unwrap(); + let result = sub_balance(&mut state, &account_id, asset_id, amount2.into(), false).unwrap(); assert_eq!(result, amount2.into()); let encoded = state.get(&account_id.to_raw_vec()).unwrap().unwrap(); let account_info: BTreeMap = BTreeMap::decode(&mut &encoded[..]).unwrap(); @@ -324,7 +342,7 @@ fn test_sub_balance_existing_account_with_balance() { //sub balance till 0 let amount3 = amount - amount2; - let result = sub_balance(&mut state, &account_id, asset_id, amount3.into()).unwrap(); + let result = sub_balance(&mut state, &account_id, asset_id, amount3.into(), false).unwrap(); assert_eq!(result, amount3.into()); let encoded = state.get(&account_id.to_raw_vec()).unwrap().unwrap(); let account_info: BTreeMap = BTreeMap::decode(&mut &encoded[..]).unwrap(); @@ -417,7 +435,7 @@ 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()).unwrap(); + sub_balance(&mut state, &account_id, AssetId::Polkadex, amount3.into(), false).unwrap(); assert_eq!(result, amount3); }); } @@ -443,7 +461,7 @@ fn test_sub_more_than_available_balance_from_existing_account_with_balance() { //sub balance let amount2 = 4000000; - let result = sub_balance(&mut state, &account_id, asset_id, amount2.into()); + let result = sub_balance(&mut state, &account_id, asset_id, amount2.into(), false); match result { Ok(_) => assert!(false), Err(e) => assert_eq!(e, "NotEnoughBalance"), diff --git a/pallets/ocex/src/validator.rs b/pallets/ocex/src/validator.rs index f7d8b07a3..96eb86352 100644 --- a/pallets/ocex/src/validator.rs +++ b/pallets/ocex/src/validator.rs @@ -473,6 +473,7 @@ impl Pallet { .map_err(|_| "account id decode error")?, market.quote_asset, withdrawing_quote, + false, )?; // Sub Base @@ -482,6 +483,7 @@ impl Pallet { .map_err(|_| "account id decode error")?, market.base_asset, withdrawing_base, + false, )?; // Egress message is verified @@ -561,6 +563,7 @@ impl Pallet { .map_err(|_| "account id decode error")?, market.base_asset, base_balance, + false, )?; sub_balance( @@ -569,6 +572,7 @@ impl Pallet { .map_err(|_| "account id decode error")?, market.quote_asset, quote_balance, + false, )?; verified_egress_messages.push(EgressMessages::PoolForceClosed( @@ -617,6 +621,7 @@ impl Pallet { .map_err(|_| "account id decode error")?, asset, balance, + true, )?; } verified_egress_messages.push(egress_msg.clone()); @@ -687,9 +692,10 @@ impl Pallet { .map_err(|_| "account id decode error")?, request.asset(), amount, + true, )?; let mut withdrawal = request.convert(stid).map_err(|_| "Withdrawal conversion error")?; - withdrawal.amount = actual_deducted; // The acutal deducted balance + withdrawal.amount = actual_deducted; // The actual deducted balance Ok(withdrawal) } diff --git a/runtimes/mainnet/src/lib.rs b/runtimes/mainnet/src/lib.rs index 04669a6a6..b434e3072 100644 --- a/runtimes/mainnet/src/lib.rs +++ b/runtimes/mainnet/src/lib.rs @@ -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: 343, + spec_version: 346, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 2,