Skip to content

Commit

Permalink
Merge branch 'main' into group-short-positions
Browse files Browse the repository at this point in the history
  • Loading branch information
jackburrus committed Jan 13, 2025
2 parents e654667 + c605fa0 commit 15b2d00
Show file tree
Hide file tree
Showing 28 changed files with 1,452 additions and 633 deletions.
5 changes: 5 additions & 0 deletions .changeset/modern-candles-camp.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@delvtech/fixed-point-wasm": patch
---

Fixed the `trailingZeros` option of the `format` method to actually be `false` by default as its doc comment states.
5 changes: 5 additions & 0 deletions .changeset/tasty-penguins-rule.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@delvtech/fixed-point-wasm": patch
---

Added `toHex()` method.
5 changes: 5 additions & 0 deletions .changeset/tricky-goats-mix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@delvtech/fixed-point-wasm": patch
---

Added support for negative exponents to `parseFixed`, e.g., `parseFixed(1e-18)`.
1 change: 1 addition & 0 deletions apps/hyperdrive-trading/src/base/formatRate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export function formatRate({
let formatted = fixed(rate).format({
percent: true,
decimals: 2,
trailingZeros: true,
});

if (formatted === "-0.00%") {
Expand Down
7 changes: 6 additions & 1 deletion apps/hyperdrive-trading/src/testing/setupTests.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
import * as fixedPoint from "@delvtech/fixed-point-wasm";
import { beforeEach } from "vitest";

beforeEach(() => {});
beforeEach(() => {
// This is safe to call multiple times. Internally it will return early if
// the WASM module has already been initialized.
fixedPoint.initSync(fixedPoint.wasmBuffer);
});
Original file line number Diff line number Diff line change
Expand Up @@ -512,7 +512,7 @@ export function OpenShortForm({
subValue={
<Tooltip
position="top"
tooltip="Short positions provide the fixed rate to Long positions. Opening a Short is a one-time cost."
tooltip="Short positions provide the fixed rate yield to Long positions. Opening a Short is a one-time cost."
className="gap-1 before:text-left"
>
What am I paying for?{" "}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ export function OpenLongsContainer(): ReactElement {
<ExternalLink
href="https://docs.hyperdrive.box/hyperdrive-overview/position-types/longs-fixed-rates"
newTab
className="daisy-link"
>
documentation
</ExternalLink>{" "}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ export function LpAndWithdrawalSharesContainer(): ReactElement {
<ExternalLink
newTab
href="https://docs.hyperdrive.box/hyperdrive-overview/position-types/liquidity-provider"
className="daisy-link"
>
documentation
</ExternalLink>{" "}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ export function OpenShortsContainer(): ReactElement | null {
<ExternalLink
newTab
href="https://docs.hyperdrive.box/hyperdrive-overview/position-types/shorts-variable-rates"
className="daisy-link"
>
documentation
</ExternalLink>{" "}
Expand Down
7 changes: 4 additions & 3 deletions crates/delv-core/src/conversions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,6 @@ where
macro_rules! try_bigint {
($value:expr) => {{
let location = std::panic::Location::caller();
// FIXME: Is this going to result in "self" being printed?
let string = stringify!($value);
BigInt::from_str(string)
.map_err(|_| $crate::type_error_at!(location, "Invalid BigInt: {}", string))
Expand All @@ -194,14 +193,16 @@ pub trait ToBigInt {
impl ToBigInt for String {
#[track_caller]
fn to_bigint(&self) -> Result<BigInt, Error> {
try_bigint!(self)
let location = std::panic::Location::caller();
BigInt::from_str(self).map_err(|_| type_error_at!(location, "Invalid BigInt: {}", self))
}
}

impl ToBigInt for &str {
#[track_caller]
fn to_bigint(&self) -> Result<BigInt, Error> {
try_bigint!(self)
let location = std::panic::Location::caller();
BigInt::from_str(self).map_err(|_| type_error_at!(location, "Invalid BigInt: {}", self))
}
}

Expand Down
4 changes: 1 addition & 3 deletions crates/fixed-point-wasm/src/formatting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,9 +99,7 @@ impl WasmFixedPoint {
)?;
}

if options.trailing_zeros == Some(true)
|| (decimals.is_some() && options.trailing_zeros != Some(false))
{
if options.trailing_zeros == Some(true) {
Reflect::set(
&options_obj,
&"minimumFractionDigits".into(),
Expand Down
20 changes: 18 additions & 2 deletions crates/fixed-point-wasm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use core::fmt;

use delv_core::{
conversions::{ToBigInt, ToI256},
error,
error::{Error, ToResult},
};
use ethers::types::I256;
Expand Down Expand Up @@ -384,15 +385,30 @@ impl WasmFixedPoint {
str[..str.len() - decimals_delta as usize].to_string()
}

/// Get the scaled hexadecimal string representation of this fixed-point
/// number with the `0x` prefix.
///
/// @example
/// ```ts
/// const num = fixed(1_123456789012345678n);
/// console.log(num.toHex());
/// // 0xf9751ff4d94f34e
/// ```
#[wasm_bindgen(js_name = toHex)]
pub fn to_hex(&self) -> Result<String, Error> {
let hex = self.bigint()?.to_string(16).map_err(|e| error!("{e:?}"))?;
Ok(JsString::from("0x").concat(&hex).into())
}

/// Get the float representation of this fixed-point number.
///
/// __Caution__: This method may lose precision.
///
/// @example
///
/// ```ts
/// const fixed = fixed(1_123456789012345678n);
/// console.log(fixed.toNumber());
/// const num = fixed(1_123456789012345678n);
/// console.log(num.toNumber());
/// // 1.1234567890123457
/// ```
#[wasm_bindgen(skip_jsdoc, js_name = toNumber)]
Expand Down
9 changes: 4 additions & 5 deletions crates/fixed-point-wasm/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,28 +71,27 @@ pub fn fixed(value: Numberish, decimals: Option<u8>) -> Result<WasmFixedPoint, E
pub fn parse_fixed(value: Numberish, decimals: Option<u8>) -> Result<WasmFixedPoint, Error> {
// If the value is already a fixed-point number, it's already scaled.
if value.is_fixed_point() == Some(true) {
return fixed(value, decimals);
return WasmFixedPoint::new(value, decimals);
}

let decimals = decimals.unwrap_or(INNER_DECIMALS);
let mut s = value.to_string().as_string().unwrap_or_default();

if s.contains("e") {
s = value.as_string().unwrap_or_default();
let mut parts = s.split("e");
let mantissa_str = parts.next().unwrap_or_default();
let exponent_str = parts.next().unwrap_or_default();
let exponent = u8::from_str_radix(exponent_str, 10).to_result()?;
let exponent = i8::from_str_radix(exponent_str, 10).to_result()?;
let mut mantissa_parts = mantissa_str.split(".");
let int_str = mantissa_parts.next().unwrap_or_default();
let fraction_str = mantissa_parts.next().unwrap_or_default();
let mut inner = I256::from_dec_str(&format!("{int_str}{fraction_str}"))
.to_result()?
.fixed();
let fraction_digits = fraction_str.len() as u8;
let fraction_digits = fraction_str.len() as i8;

if fraction_digits > exponent {
inner /= (10u32.pow((fraction_digits - exponent) as u32)).into();
inner /= (10u128.pow((fraction_digits - exponent) as u32)).into();
return Ok(WasmFixedPoint { inner, decimals });
}

Expand Down
18 changes: 16 additions & 2 deletions packages/fixed-point-wasm/fixed_point_wasm.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -378,15 +378,28 @@ export class FixedPoint {
*/
toString(): string;
/**
* Get the scaled hexadecimal string representation of this fixed-point
* number with the `0x` prefix.
*
* @example
* ```ts
* const num = fixed(1_123456789012345678n);
* console.log(num.toHex());
* // 0xf9751ff4d94f34e
* ```
* @returns {string}
*/
toHex(): string;
/**
* Get the float representation of this fixed-point number.
*
* __Caution__: This method may lose precision.
*
* @example
*
* ```ts
* const fixed = fixed(1_123456789012345678n);
* console.log(fixed.toNumber());
* const num = fixed(1_123456789012345678n);
* console.log(num.toNumber());
* // 1.1234567890123457
* ```
*/
Expand Down Expand Up @@ -461,6 +474,7 @@ export interface InitOutput {
readonly fixedpoint_max: (a: number, b: number, c: number, d: number) => void;
readonly fixedpoint_clamp: (a: number, b: number, c: number, d: number, e: number) => void;
readonly fixedpoint_toString: (a: number, b: number) => void;
readonly fixedpoint_toHex: (a: number, b: number) => void;
readonly fixedpoint_toNumber: (a: number) => number;
readonly fixedpoint_is_fixed_point: (a: number) => number;
readonly fixedpoint_toFixed: (a: number, b: number) => number;
Expand Down
46 changes: 43 additions & 3 deletions packages/fixed-point-wasm/fixed_point_wasm.js

Large diffs are not rendered by default.

Loading

0 comments on commit 15b2d00

Please sign in to comment.