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

Fix Withdraw precision issue #942

Merged
merged 5 commits into from
Apr 13, 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
18 changes: 9 additions & 9 deletions pallets/ocex/src/settlement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -104,6 +103,7 @@ pub fn sub_balance(
account: &AccountId,
asset: AssetId,
mut balance: Decimal,
is_withdrawal: bool,
) -> 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())? {
Expand All @@ -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));
Expand Down Expand Up @@ -170,7 +170,7 @@ impl<T: Config> Pallet<T> {
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 = {
Expand All @@ -182,7 +182,7 @@ impl<T: Config> Pallet<T> {
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
};

Expand Down
40 changes: 29 additions & 11 deletions pallets/ocex/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -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();
});
}

Expand All @@ -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"),
Expand Down Expand Up @@ -316,15 +334,15 @@ 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<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()).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<AssetId, Decimal> = BTreeMap::decode(&mut &encoded[..]).unwrap();
Expand Down Expand Up @@ -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);
});
}
Expand All @@ -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"),
Expand Down
8 changes: 7 additions & 1 deletion pallets/ocex/src/validator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -473,6 +473,7 @@ impl<T: Config> Pallet<T> {
.map_err(|_| "account id decode error")?,
market.quote_asset,
withdrawing_quote,
false,
)?;

// Sub Base
Expand All @@ -482,6 +483,7 @@ impl<T: Config> Pallet<T> {
.map_err(|_| "account id decode error")?,
market.base_asset,
withdrawing_base,
false,
)?;

// Egress message is verified
Expand Down Expand Up @@ -561,6 +563,7 @@ impl<T: Config> Pallet<T> {
.map_err(|_| "account id decode error")?,
market.base_asset,
base_balance,
false,
)?;

sub_balance(
Expand All @@ -569,6 +572,7 @@ impl<T: Config> Pallet<T> {
.map_err(|_| "account id decode error")?,
market.quote_asset,
quote_balance,
false,
)?;

verified_egress_messages.push(EgressMessages::PoolForceClosed(
Expand Down Expand Up @@ -617,6 +621,7 @@ impl<T: Config> Pallet<T> {
.map_err(|_| "account id decode error")?,
asset,
balance,
true,
)?;
}
verified_egress_messages.push(egress_msg.clone());
Expand Down Expand Up @@ -687,9 +692,10 @@ impl<T: Config> Pallet<T> {
.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)
}

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: 343,
spec_version: 346,
impl_version: 0,
apis: RUNTIME_API_VERSIONS,
transaction_version: 2,
Expand Down
Loading