generated from eigerco/beerus
-
Notifications
You must be signed in to change notification settings - Fork 104
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
db4e021
commit 2021966
Showing
4 changed files
with
265 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,3 +14,4 @@ mod sha256_test; | |
mod sha512_test; | ||
mod test_keccak256; | ||
mod zellers_congruence_test; | ||
mod wad_ray_math_test; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,160 @@ | ||
use core::debug::PrintTrait; | ||
use alexandria_math::{pow}; | ||
use alexandria_math::wad_ray_math::{ | ||
ray_div, ray_mul, wad_div, wad_mul, ray_to_wad, wad_to_ray, ray, wad, half_ray, half_wad | ||
}; | ||
|
||
// conversion | ||
#[test] | ||
#[available_gas(2000000)] | ||
fn test_wad_to_ray_conversion() { | ||
let a = 5 * pow(10, 17); // 0.5e18 | ||
let expected = 5 * pow(10, 26); // 0.5e27 | ||
assert(wad_to_ray(a) == expected, 'Wrong wad_to_ray conversion'); | ||
} | ||
|
||
#[test] | ||
#[available_gas(2000000)] | ||
fn test_ray_to_wad_conversion() { | ||
let a = 5 * pow(10, 26); // 0.5e27 | ||
let expected = 5 * pow(10, 17); // 0.5e18 | ||
assert(ray_to_wad(a) == expected, 'Wrong ray_to_wad conversion'); | ||
} | ||
|
||
// wad | ||
#[test] | ||
#[available_gas(2000000)] | ||
#[should_panic()] | ||
fn test_revertWhen_wad_mul_overflow() { | ||
wad_mul(pow(2, 128), pow(2, 128)); | ||
} | ||
|
||
#[test] | ||
#[available_gas(2000000)] | ||
fn test_wad_mul_trivial() { | ||
assert(wad_mul(pow(2, 128) - 1, wad()) == pow(2, 128) - 1, 'Wrong result: 2**128 -1 * 1e18'); | ||
assert(wad_mul(0, 0) == 0, 'Wrong result: 0 * 0'); | ||
assert(wad_mul(0, wad()) == 0, 'Wrong result: 0 * 1e18'); | ||
assert(wad_mul(wad(), 0) == 0, 'Wrong result: 1e18 * 0'); | ||
assert(wad_mul(wad(), wad()) == wad(), 'Wrong result: 1e18 * 1e18 '); | ||
} | ||
|
||
#[test] | ||
#[available_gas(2000000)] | ||
fn test_wad_mul_fractions() { | ||
let val: u256 = 2 * pow(10, 17); // 0.2e18 | ||
assert(wad_mul(wad(), val) == val, 'Wrong result: 1e18 * 0.2e18'); | ||
assert(wad_mul(wad() * 2, val) == val * 2, 'Wrong result: 2e18 * 0.2e18'); | ||
} | ||
|
||
#[test] | ||
#[available_gas(2000000)] | ||
#[should_panic()] | ||
fn test_revertWhen_wad_div_zero() { | ||
wad_div(wad(), 0); | ||
} | ||
|
||
#[test] | ||
#[available_gas(3000000)] | ||
fn test_wad_div_trivial() { | ||
assert(wad_div(pow(2, 128) - 1, wad()) == pow(2, 128) - 1, 'Wrong result: 2**128 -1 / 1e18'); | ||
assert(wad_div(0, pow(2, 128) - 1) == 0, 'Wrong result: 0 / 2**128 -1'); | ||
assert(wad_div(wad(), wad()) == wad(), 'Wrong result: 1e18 / 1e18'); | ||
} | ||
|
||
#[test] | ||
#[available_gas(2000000)] | ||
fn test_wad_div_fractions() { | ||
assert(wad_div(wad() * 2, wad() * 2) == wad(), 'Wrong result: 2e18 / 2e18'); | ||
assert(wad_div(wad(), wad() * 2) == half_wad(), 'Wrong result: 1e18 / 2e18'); | ||
} | ||
|
||
#[test] | ||
#[available_gas(2000000)] | ||
fn test_wad_mul_rounding() { | ||
let a = 950000000000005647; | ||
let b = 1000000000; | ||
let expected = 950000000; | ||
assert(wad_mul(a, b) == expected, 'Wrong rounding down: a * b'); | ||
assert(wad_mul(b, a) == expected, 'Wrong rounding down: b * a'); | ||
} | ||
|
||
#[test] | ||
#[available_gas(2000000)] | ||
fn test_wad_mul_rounding_up() { | ||
let a = pow(10, 18) - 1; | ||
let b = 2; | ||
let expected = 2; | ||
assert(wad_mul(a, b) == expected, 'Wrong rounding: a * b'); | ||
assert(wad_mul(b, a) == expected, 'Wrong rounding: b * a'); | ||
} | ||
|
||
|
||
// wad | ||
#[test] | ||
#[available_gas(2000000)] | ||
#[should_panic()] | ||
fn test_revertWhen_ray_mul_overflow() { | ||
ray_mul(pow(2, 128), pow(2, 128)); | ||
} | ||
|
||
#[test] | ||
#[available_gas(2000000)] | ||
fn test_ray_mul_trivial() { | ||
assert(ray_mul(pow(2, 128) - 1, ray()) == pow(2, 128) - 1, 'Wrong result: 2**128 -1 * 1e27'); | ||
assert(ray_mul(0, 0) == 0, 'Wrong result: 0 * 0'); | ||
assert(ray_mul(0, ray()) == 0, 'Wrong result: 0 * 1e27'); | ||
assert(ray_mul(ray(), 0) == 0, 'Wrong result: 1e27 * 0'); | ||
assert(ray_mul(ray(), ray()) == ray(), 'Wrong result: 1e27 * 1e27 '); | ||
} | ||
|
||
#[test] | ||
#[available_gas(2000000)] | ||
fn test_ray_mul_fractions() { | ||
let val: u256 = 2 * pow(10, 26); // 0.2e27 | ||
assert(ray_mul(ray(), val) == val, 'Wrong result: 1e27 * 0.2e27'); | ||
assert(ray_mul(ray() * 2, val) == val * 2, 'Wrong result: 2e27 * 0.2e27'); | ||
} | ||
|
||
#[test] | ||
#[available_gas(2000000)] | ||
#[should_panic()] | ||
fn test_revertWhen_ray_div_zero() { | ||
ray_div(ray(), 0); | ||
} | ||
|
||
#[test] | ||
#[available_gas(3000000)] | ||
fn test_ray_div_trivial() { | ||
assert(ray_div(pow(2, 128) - 1, ray()) == pow(2, 128) - 1, 'Wrong result: 2**128 -1 / 1e27'); | ||
assert(ray_div(0, pow(2, 128) - 1) == 0, 'Wrong result: 0 / 2**128 -1'); | ||
assert(ray_div(ray(), ray()) == ray(), 'Wrong result: 1e27 / 1e27'); | ||
} | ||
|
||
#[test] | ||
#[available_gas(2000000)] | ||
fn test_ray_div_fractions() { | ||
assert(ray_div(ray() * 2, ray() * 2) == ray(), 'Wrong result: 2e27 / 2e27'); | ||
assert(ray_div(ray(), ray() * 2) == half_ray(), 'Wrong result: 1e27 / 2e27'); | ||
} | ||
|
||
#[test] | ||
#[available_gas(2000000)] | ||
fn test_ray_mul_rounding() { | ||
let a = pow(10, 18); | ||
let b = 95 * pow(10, 26) + 5647; | ||
let expected = 95 * pow(10, 17); | ||
assert(ray_mul(a, b) == expected, 'Wrong rounding down: a * b'); | ||
assert(ray_mul(b, a) == expected, 'Wrong rounding down: b * a'); | ||
} | ||
|
||
|
||
#[test] | ||
#[available_gas(2000000)] | ||
fn test_ray_mul_rounding_up() { | ||
let a = pow(10, 27) - 1; | ||
let b = 2; | ||
let expected = 2; | ||
assert(ray_mul(a, b) == expected, 'Wrong rounding up: a * b'); | ||
assert(ray_mul(b, a) == expected, 'Wrong rounding up: b * a'); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
/// Provides functions to perform calculations with Wad and Ray units | ||
/// @dev Provides mul and div function for wads (decimal numbers with 18 digits of precision) and rays (decimal numbers | ||
/// with 27 digits of precision) | ||
/// Operations are rounded. If a value is >=.5, will be rounded up, otherwise rounded down. | ||
/// https://github.com/aave/aave-v3-core/blob/master/contracts/protocol/libraries/math/WadRayMath.sol | ||
|
||
const WAD: u256 = 1_000_000_000_000_000_000; // 1e18 | ||
const HALF_WAD: u256 = 500_000_000_000_000_000; // 0.5e18 | ||
const RAY: u256 = 1_000_000_000_000_000_000_000_000_000; // 1e27 | ||
const HALF_RAY: u256 = 500_000_000_000_000_000_000_000_000; // 0.5e27 | ||
const WAD_RAY_RATIO: u256 = 1_000_000_000; // 1e9 | ||
|
||
|
||
/// Return the wad value | ||
/// # Returns | ||
/// * `u256` - The value | ||
fn wad() -> u256 { | ||
return WAD; | ||
} | ||
|
||
/// Return the ray value | ||
/// # Returns | ||
/// * `u256` - The value | ||
fn ray() -> u256 { | ||
return RAY; | ||
} | ||
|
||
/// Return the half wad value | ||
/// # Returns | ||
/// * `u256` - The value | ||
fn half_wad() -> u256 { | ||
return HALF_WAD; | ||
} | ||
|
||
/// Return the half ray value | ||
/// # Returns | ||
/// * `u256` - The value | ||
fn half_ray() -> u256 { | ||
return HALF_RAY; | ||
} | ||
|
||
|
||
/// Multiplies two wad, rounding half up to the nearest wad | ||
/// # Arguments | ||
/// * a Wad | ||
/// * b Wad | ||
/// # Returns | ||
/// * a*b, in wad | ||
fn wad_mul(a: u256, b: u256) -> u256 { | ||
return (a * b + HALF_WAD) / WAD; | ||
} | ||
|
||
/// Divides two wad, rounding half up to the nearest wad | ||
/// # Arguments | ||
/// * a Wad | ||
/// * b Wad | ||
/// # Returns | ||
/// * a/b, in wad | ||
fn wad_div(a: u256, b: u256) -> u256 { | ||
let half_b = b / 2; | ||
return (a * WAD + half_b) / b; | ||
} | ||
|
||
/// Multiplies two ray, rounding half up to the nearest ray | ||
/// # Arguments | ||
/// * a Ray | ||
/// * b Ray | ||
/// # Returns | ||
/// * a raymul b | ||
fn ray_mul(a: u256, b: u256) -> u256 { | ||
return (a * b + HALF_RAY) / RAY; | ||
} | ||
|
||
/// Divides two ray, rounding half up to the nearest ray | ||
/// # Arguments | ||
/// * a Ray | ||
/// * b Ray | ||
/// # Returns | ||
/// * a raydiv b | ||
fn ray_div(a: u256, b: u256) -> u256 { | ||
let half_b = b / 2; | ||
return (a * RAY + half_b) / b; | ||
} | ||
|
||
/// Casts ray down to wad | ||
/// # Arguments | ||
/// * a Ray | ||
/// # Returns | ||
/// * a converted to wad, rounded half up to the nearest wad | ||
fn ray_to_wad(a: u256) -> u256 { | ||
let half_ratio = WAD_RAY_RATIO / 2; | ||
return (half_ratio + a) / WAD_RAY_RATIO; | ||
} | ||
|
||
/// Converts wad up to ray | ||
/// # Arguments | ||
/// * a Wad | ||
/// # Returns | ||
/// * a converted to ray | ||
fn wad_to_ray(a: u256) -> u256 { | ||
return a * WAD_RAY_RATIO; | ||
} | ||
|