Health token adjustment: Deal with odd I80F48 behavior
The identity a * b = -((-a) * b) does not hold for I80F48, probably it's rounding to -inf. This meant that withdrawing the full native token balance could fail because the magnitude of -position * price was bigger than position * price.
This commit is contained in:
parent
3b93a38395
commit
511db72f8e
|
@ -652,7 +652,12 @@ impl HealthCache {
|
||||||
pub fn adjust_token_balance(&mut self, token_index: TokenIndex, change: I80F48) -> Result<()> {
|
pub fn adjust_token_balance(&mut self, token_index: TokenIndex, change: I80F48) -> Result<()> {
|
||||||
let entry_index = self.token_entry_index(token_index)?;
|
let entry_index = self.token_entry_index(token_index)?;
|
||||||
let mut entry = &mut self.token_infos[entry_index];
|
let mut entry = &mut self.token_infos[entry_index];
|
||||||
entry.balance = cm!(entry.balance + change * entry.oracle_price);
|
|
||||||
|
// Work around the fact that -((-x) * y) == x * y does not hold for I80F48:
|
||||||
|
// We need to make sure that if balance is before * price, then change = -before
|
||||||
|
// brings it to exactly zero.
|
||||||
|
let removed_contribution = (-change) * entry.oracle_price;
|
||||||
|
entry.balance = cm!(entry.balance - removed_contribution);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,3 +38,17 @@ pub fn format_zero_terminated_utf8_bytes(
|
||||||
.trim_matches(char::from(0)),
|
.trim_matches(char::from(0)),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use fixed::types::I80F48;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
pub fn test_i80f48_mul_rounding() {
|
||||||
|
// It's not desired, but I80F48 seems to round to -inf
|
||||||
|
let price = I80F48::from_num(0.04);
|
||||||
|
let x = I80F48::from_bits(96590783907000000);
|
||||||
|
assert_eq!((x * price).to_string(), "13.726375969298193");
|
||||||
|
assert_eq!(((-x) * price).to_string(), "-13.726375969298196");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue