Skip to content

Commit

Permalink
🔧 fix: try fns
Browse files Browse the repository at this point in the history
  • Loading branch information
josemvcerqueira committed Dec 23, 2024
1 parent 6c7f3b6 commit 4b8daa7
Show file tree
Hide file tree
Showing 6 changed files with 101 additions and 42 deletions.
20 changes: 16 additions & 4 deletions sources/fixed18.move
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ use interest_math::uint_macro as macro;

const FIXED_18_BASE: u256 = 1_000_000_000_000_000_000;

const MAX_U256: u256 = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;

// === Structs ===

public struct Fixed18 has copy, drop, store { value: u256 }
Expand Down Expand Up @@ -102,23 +104,33 @@ public fun u256_to_fixed18_up(x: u256, decimals: u8): Fixed18 {

// === Try Functions ===

public fun try_add(x: Fixed18, y: Fixed18): (bool, Fixed18) {
let (pred, value) = macro::try_add!(x.value, y.value, MAX_U256);
(pred, Fixed18 { value })
}

public fun try_sub(x: Fixed18, y: Fixed18): (bool, Fixed18) {
let (pred, value) = macro::try_sub!(x.value, y.value);
(pred, Fixed18 { value })
}

public fun try_mul_down(x: Fixed18, y: Fixed18): (bool, Fixed18) {
let (pred, value) = macro::try_mul_div_down!(x.value, y.value, FIXED_18_BASE);
let (pred, value) = macro::try_mul_div_down!(x.value, y.value, FIXED_18_BASE, MAX_U256);
(pred, Fixed18 { value })
}

public fun try_mul_up(x: Fixed18, y: Fixed18): (bool, Fixed18) {
let (pred, value) = macro::try_mul_div_up!(x.value, y.value, FIXED_18_BASE);
let (pred, value) = macro::try_mul_div_up!(x.value, y.value, FIXED_18_BASE, MAX_U256);
(pred, Fixed18 { value })
}

public fun try_div_down(x: Fixed18, y: Fixed18): (bool, Fixed18) {
let (pred, value) = macro::try_mul_div_down!(x.value, FIXED_18_BASE, y.value);
let (pred, value) = macro::try_mul_div_down!(x.value, FIXED_18_BASE, y.value, MAX_U256);
(pred, Fixed18 { value })
}

public fun try_div_up(x: Fixed18, y: Fixed18): (bool, Fixed18) {
let (pred, value) = macro::try_mul_div_up!(x.value, FIXED_18_BASE, y.value);
let (pred, value) = macro::try_mul_div_up!(x.value, FIXED_18_BASE, y.value, MAX_U256);
(pred, Fixed18 { value })
}

Expand Down
10 changes: 4 additions & 6 deletions sources/uint/u128.move
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ public fun try_sub(x: u128, y: u128): (bool, u128) {
}

public fun try_mul(x: u128, y: u128): (bool, u128) {
let (pred, c) = macro::try_mul!(x, y);
if (!pred || c > MAX_U128) (false, 0) else (true, (c as u128))
let (pred, r) = macro::try_mul!(x, y, MAX_U128);
(pred, r as u128)
}

public fun try_div_down(x: u128, y: u128): (bool, u128) {
Expand All @@ -30,13 +30,11 @@ public fun try_div_up(x: u128, y: u128): (bool, u128) {
}

public fun try_mul_div_down(x: u128, y: u128, z: u128): (bool, u128) {
let (pred, r) = macro::try_mul_div_down!(x, y, z);
if (!pred || r > MAX_U128) (false, 0) else (true, (r as u128))
macro::try_mul_div_down!(x, y, z, MAX_U128)
}

public fun try_mul_div_up(x: u128, y: u128, z: u128): (bool, u128) {
let (pred, r) = macro::try_mul_div_up!(x, y, z);
if (!pred || r > MAX_U128) (false, 0) else (true, (r as u128))
macro::try_mul_div_up!(x, y, z, MAX_U128)
}

public fun try_mod(x: u128, y: u128): (bool, u128) {
Expand Down
8 changes: 4 additions & 4 deletions sources/uint/u256.move
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ module interest_math::u256;

use interest_math::uint_macro as macro;

// === Constants ===
// === Constants ===

const MAX_U256: u256 = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff;

Expand All @@ -22,7 +22,7 @@ public fun try_sub(x: u256, y: u256): (bool, u256) {
}

public fun try_mul(x: u256, y: u256): (bool, u256) {
macro::try_mul!(x, y)
macro::try_mul!(x, y, MAX_U256)
}

public fun try_div_down(x: u256, y: u256): (bool, u256) {
Expand All @@ -34,11 +34,11 @@ public fun try_div_up(x: u256, y: u256): (bool, u256) {
}

public fun try_mul_div_down(x: u256, y: u256, z: u256): (bool, u256) {
macro::try_mul_div_down!(x, y, z)
macro::try_mul_div_down!(x, y, z, MAX_U256)
}

public fun try_mul_div_up(x: u256, y: u256, z: u256): (bool, u256) {
macro::try_mul_div_up!(x, y, z)
macro::try_mul_div_up!(x, y, z, MAX_U256)
}

public fun try_mod(x: u256, y: u256): (bool, u256) {
Expand Down
22 changes: 10 additions & 12 deletions sources/uint/u64.move
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module interest_math::u64;

use interest_math::{uint_macro as macro, i256::{Self, I256}};
use interest_math::{i256::{Self, I256}, uint_macro as macro};

// === Constants ===

Expand All @@ -12,15 +12,15 @@ const WRAPPING_MAX: u256 = MAX_U64 + 1;
// === WrappingFunctions ===

public fun wrapping_add(x: u64, y: u64): u64 {
(wrap(i256::from_u64(x).add( i256::from_u64(y)), WRAPPING_MAX) as u64)
(wrap(i256::from_u64(x).add(i256::from_u64(y)), WRAPPING_MAX) as u64)
}

public fun wrapping_sub(x: u64, y: u64): u64 {
(wrap(i256::from_u64(x).sub( i256::from_u64(y)), WRAPPING_MAX) as u64)
(wrap(i256::from_u64(x).sub(i256::from_u64(y)), WRAPPING_MAX) as u64)
}

public fun wrapping_mul(x: u64, y: u64): u64 {
(wrap(i256::from_u64(x).mul( i256::from_u64(y)), WRAPPING_MAX) as u64)
(wrap(i256::from_u64(x).mul(i256::from_u64(y)), WRAPPING_MAX) as u64)
}

// === Try Functions ===
Expand All @@ -34,8 +34,8 @@ public fun try_sub(x: u64, y: u64): (bool, u64) {
}

public fun try_mul(x: u64, y: u64): (bool, u64) {
let (pred, r) = macro::try_mul!(x, y);
if (!pred || r > MAX_U64) (false, 0) else (true, (r as u64))
let (pred, r) = macro::try_mul!(x, y, MAX_U64);
(pred, r as u64)
}

public fun try_div_down(x: u64, y: u64): (bool, u64) {
Expand All @@ -47,13 +47,11 @@ public fun try_div_up(x: u64, y: u64): (bool, u64) {
}

public fun try_mul_div_down(x: u64, y: u64, z: u64): (bool, u64) {
let (pred, r) = macro::try_mul_div_down!(x, y, z);
if (!pred || r > MAX_U64) (false, 0) else (true, (r as u64))
macro::try_mul_div_down!(x, y, z, MAX_U64)
}

public fun try_mul_div_up(x: u64, y: u64, z: u64): (bool, u64) {
let (pred, r) = macro::try_mul_div_up!(x, y, z);
if (!pred || r > MAX_U64) (false, 0) else (true, (r as u64))
macro::try_mul_div_up!(x, y, z, MAX_U64)
}

public fun try_mod(x: u64, y: u64): (bool, u64) {
Expand Down Expand Up @@ -168,10 +166,10 @@ public fun max_value(): u64 {
(MAX_U64 as u64)
}

// === Private Functions ===
// === Private Functions ===

fun wrap(self: I256, max: u256): u256 {
let max = i256::from_u256(max);

i256::to_u256(if (self.is_negative()) self.add( max) else self.sub( max.mul( self.div( max))))
i256::to_u256(if (self.is_negative()) self.add(max) else self.sub(max.mul(self.div(max))))
}
59 changes: 43 additions & 16 deletions sources/uint/uint.move
Original file line number Diff line number Diff line change
@@ -1,22 +1,31 @@
module interest_math::uint_macro;

public(package) macro fun try_add<$T>($x: _, $y: _, $max: u256): (bool, $T) {
let r = ($x as u256) + ($y as u256);
if (r > $max) (false, 0) else (true, (r as $T))
let x = $x as u256;
let y = $y as u256;
let max = $max as u256;

if (x == max && y != 0) return (false, 0 as $T);

let rem = max - x;
if (y > rem) return (false, 0 as $T);

(true, (x + y) as $T)
}

public(package) macro fun try_sub($x: _, $y: _): (bool, _) {
if ($y > $x) (false, 0) else (true, $x - $y)
}

public(package) macro fun try_mul($x: _, $y: _): (bool, u256) {
public(package) macro fun try_mul($x: _, $y: _, $max: u256): (bool, u256) {
let x = $x as u256;
let y = $y as u256;
let max = $max as u256;

if (y == 0) return (true, 0);
if (
x > 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff / y
) (false, 0) else (true, x * y)
if (x > max / y) return (false, 0);

(true, (x * y))
}

public(package) macro fun try_div_down($x: _, $y: _): (bool, _) {
Expand All @@ -27,28 +36,46 @@ public(package) macro fun try_div_up($x: _, $y: _): (bool, _) {
if ($y == 0) (false, 0) else (true, div_up!($x, $y))
}

public(package) macro fun try_mul_div_down($x: _, $y: _, $z: _): (bool, u256) {
public(package) macro fun try_mul_div_down<$T>($x: _, $y: _, $z: _, $max: u256): (bool, $T) {
let x = $x as u256;
let y = $y as u256;
let z = $z as u256;
let max = $max as u256;

if (z == 0) return (false, 0 as $T);
let (pred, _) = try_mul!(
x,
y,
0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff,
);
if (!pred) return (false, 0 as $T);

let r = mul_div_down!<u256>(x, y, z);

if (z == 0) return (false, 0);
let (pred, _) = try_mul!(x, y);
if (!pred) return (false, 0);
if (r > max) return (false, 0 as $T);

(true, mul_div_down!<u256>(x, y, z))
(true, r as $T)
}

public(package) macro fun try_mul_div_up($x: _, $y: _, $z: _): (bool, u256) {
public(package) macro fun try_mul_div_up<$T>($x: _, $y: _, $z: _, $max: u256): (bool, $T) {
let x = $x as u256;
let y = $y as u256;
let z = $z as u256;
let max = $max as u256;

if (z == 0) return (false, 0 as $T);
let (pred, _) = try_mul!(
x,
y,
0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff,
);
if (!pred) return (false, 0 as $T);

let r = mul_div_up!<u256>(x, y, z);

if (z == 0) return (false, 0);
let (pred, _) = try_mul!(x, y);
if (!pred) return (false, 0);
if (r > max) return (false, 0 as $T);

(true, mul_div_up!<u256>(x, y, z))
(true, r as $T)
}

public(package) macro fun try_mod($x: _, $y: _): (bool, _) {
Expand Down
24 changes: 24 additions & 0 deletions tests/fixed18.move
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ use interest_math::fixed18::{
base,
add,
sub,
try_add,
try_sub
};
use sui::test_utils::assert_eq;

Expand Down Expand Up @@ -75,6 +77,28 @@ fun test_convert_functions() {
);
}

#[test]
fun test_try_add() {
let (pred, r) = try_add(3u256.from(), 5u256.from());
assert_eq(pred, true);
assert_eq(r.raw_value(), 8 * FIXED_18_BASE);

let (pred, r) = try_add(MAX_U256.from_raw(), MAX_U256.from_raw());
assert_eq(pred, false);
assert_eq(r.raw_value(), 0);
}

#[test]
fun test_try_sub() {
let (pred, r) = try_sub(5u256.from(), 3u256.from());
assert_eq(pred, true);
assert_eq(r.raw_value(), 2 * FIXED_18_BASE);

let (pred, r) = try_sub(3u256.from(), 5u256.from());
assert_eq(pred, false);
assert_eq(r.raw_value(), 0);
}

#[test]
fun test_try_mul_down() {
let (pred, r) = try_mul_down(3u256.from(), 5u256.from());
Expand Down

0 comments on commit 4b8daa7

Please sign in to comment.