Skip to content

Commit

Permalink
refactor!: using native u128 type (#12213)
Browse files Browse the repository at this point in the history
  • Loading branch information
benesjan authored Feb 26, 2025
1 parent a20da9b commit 52ae8cc
Show file tree
Hide file tree
Showing 81 changed files with 546 additions and 801 deletions.
18 changes: 17 additions & 1 deletion docs/docs/migration_notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,22 @@ Aztec is in full-speed development. Literally every version breaks compatibility

## TBD

### `U128` type replaced with native `u128`

The `U128` type has been replaced with the native `u128` type. This means that you can no longer use the `U128` type in your code. Instead, you should use the `u128` type.
Doing the changes is as straightforward as:

```diff
#[public]
#[view]
- fn balance_of_public(owner: AztecAddress) -> U128 {
+ fn balance_of_public(owner: AztecAddress) -> u128 {
storage.public_balances.at(owner).read()
}
```

`UintNote` has also been updated to use the native `u128` type.

### [aztec-nr] Removed `compute_note_hash_and_optionally_a_nullifer`

This function is no longer mandatory for contracts, and the `#[aztec]` macro no longer injects it.
Expand Down Expand Up @@ -63,7 +79,7 @@ await contract.methods
txHash.hash,
toBoundedVec(txEffects!.data.noteHashes, MAX_NOTE_HASHES_PER_TX),
txEffects!.data.nullifiers[0],
wallet.getAddress(),
wallet.getAddress()
)
.simulate();
```
Expand Down
5 changes: 2 additions & 3 deletions noir-projects/aztec-nr/aztec/src/macros/notes/mod.nr
Original file line number Diff line number Diff line change
Expand Up @@ -412,7 +412,7 @@ comptime fn generate_fixed_generators() -> (Quoted, Quoted) {
/// std::hash::from_field_unsafe(npk_m_hash as Field),
/// std::hash::from_field_unsafe(randomness as Field)
/// ]
/// args_list: [amount: U128, npk_m_hash: Field, randomness: Field]
/// args_list: [amount: u128, npk_m_hash: Field, randomness: Field]
/// aux_vars: []
comptime fn generate_multi_scalar_mul(
indexed_fields: [(Quoted, Type, u32)],
Expand Down Expand Up @@ -695,7 +695,7 @@ comptime fn get_setup_log_plaintext_body(
/// }
///
/// impl TokenNoteFinalizationPayload {
/// fn new(mut self, context: &mut aztec::prelude::PublicContext, slot: Field, amount: U128) -> TokenNoteFinalizationPayload {
/// fn new(mut self, context: &mut aztec::prelude::PublicContext, slot: Field, amount: u128) -> TokenNoteFinalizationPayload {
/// self.context = context;
/// self.hiding_point_slot = slot;
/// self.setup_log_slot = slot + aztec::protocol_types::point::POINT_LENGTH as Field;
Expand Down Expand Up @@ -978,7 +978,6 @@ comptime fn register_note(

/// Separates note struct members into fixed and nullable ones. It also stores the index of where each struct member
/// starts in the serialized note. Note that each struct member can occupy multiple fields (as in Field type).
/// An example of a struct member occupying multiple fields is `amount` in `TokenNote` that uses `U128` type.
comptime fn index_note_fields(
s: StructDefinition,
nullable_fields: [Quoted],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ use dep::protocol_types::{constants::INITIALIZATION_SLOT_SEPARATOR, traits::Pack
/// #[derive(Eq, Packable)]
/// pub struct Config \{
/// pub address_1: AztecAddress,
/// pub value_1: U128,
/// pub value_1: u128,
/// pub value_2: u64,
/// ...
/// }
Expand Down
6 changes: 3 additions & 3 deletions noir-projects/aztec-nr/uint-note/src/uint_note.nr
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@ use dep::aztec::{
#[derive(Eq, Serialize)]
pub struct UintNote {
// The amount of tokens in the note
value: U128,
value: u128,
owner: AztecAddress,
// Randomness of the note to protect against note hash preimage attacks
randomness: Field,
}
// docs:end:UintNote
impl UintNote {
pub fn new(value: U128, owner: AztecAddress) -> Self {
pub fn new(value: u128, owner: AztecAddress) -> Self {
// Safety: We use the randomness to preserve the privacy of the note recipient by preventing brute-forcing,
// so a malicious sender could use non-random values to make the note less private. But they already know
// the full note pre-image anyway, and so the recipient already trusts them to not disclose this
Expand All @@ -26,7 +26,7 @@ impl UintNote {
Self { value, owner, randomness }
}

pub fn get_value(self) -> U128 {
pub fn get_value(self) -> u128 {
self.value
}
}
14 changes: 9 additions & 5 deletions noir-projects/aztec-nr/value-note/src/filter.nr
Original file line number Diff line number Diff line change
@@ -1,19 +1,23 @@
use crate::value_note::ValueNote;
use dep::aztec::note::retrieved_note::RetrievedNote;
use dep::aztec::protocol_types::constants::MAX_NOTE_HASH_READ_REQUESTS_PER_CALL;
use aztec::{
note::retrieved_note::RetrievedNote,
protocol_types::{
constants::MAX_NOTE_HASH_READ_REQUESTS_PER_CALL, utils::field::full_field_less_than,
},
};

pub fn filter_notes_min_sum(
notes: [Option<RetrievedNote<ValueNote>>; MAX_NOTE_HASH_READ_REQUESTS_PER_CALL],
min_sum: Field,
) -> [Option<RetrievedNote<ValueNote>>; MAX_NOTE_HASH_READ_REQUESTS_PER_CALL] {
let mut selected = [Option::none(); MAX_NOTE_HASH_READ_REQUESTS_PER_CALL];

let mut sum = U128::from_integer(0);
let mut sum = 0;
for i in 0..notes.len() {
if notes[i].is_some() & (sum < U128::from_integer(min_sum)) {
if notes[i].is_some() & full_field_less_than(sum, min_sum) {
let retrieved_note = notes[i].unwrap_unchecked();
selected[i] = Option::some(retrieved_note);
sum += U128::from_integer(retrieved_note.note.value);
sum += retrieved_note.note.value;
}
}

Expand Down
52 changes: 26 additions & 26 deletions noir-projects/noir-contracts/contracts/amm_contract/src/lib.nr
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
/// Given an input amount of an asset and pair balances, returns the maximum output amount of the other asset.
pub fn get_amount_out(amount_in: U128, balance_in: U128, balance_out: U128) -> U128 {
assert(amount_in > U128::zero(), "INSUFFICIENT_INPUT_AMOUNT");
assert((balance_in > U128::zero()) & (balance_out > U128::zero()), "INSUFFICIENT_LIQUIDITY");
pub fn get_amount_out(amount_in: u128, balance_in: u128, balance_out: u128) -> u128 {
assert(amount_in > 0 as u128, "INSUFFICIENT_INPUT_AMOUNT");
assert((balance_in > 0 as u128) & (balance_out > 0 as u128), "INSUFFICIENT_LIQUIDITY");

// The expression below is:
// (amount_in * 997 * balance_out) / (balance_in * 10000 + amount_in * 997)
// which is equivalent to:
// balance_out * ((amount_in * 0.997) / (balance_in + amount_in * 0.997))
// resulting in an implicit 0.3% fee on the amount in, as the fee tokens are not taken into consideration.

let amount_in_with_fee = amount_in * U128::from_integer(997);
let amount_in_with_fee = amount_in * 997 as u128;
let numerator = amount_in_with_fee * balance_out;
let denominator = balance_in * U128::from_integer(1000) + amount_in_with_fee;
let denominator = balance_in * 1000 as u128 + amount_in_with_fee;
numerator / denominator
}

/// Given an output amount of an asset and pair balances, returns a required input amount of the other asset.
pub fn get_amount_in(amount_out: U128, balance_in: U128, balance_out: U128) -> U128 {
assert(amount_out > U128::zero(), "INSUFFICIENT_OUTPUT_AMOUNT");
assert((balance_in > U128::zero()) & (balance_out > U128::zero()), "INSUFFICIENT_LIQUIDITY");
pub fn get_amount_in(amount_out: u128, balance_in: u128, balance_out: u128) -> u128 {
assert(amount_out > 0 as u128, "INSUFFICIENT_OUTPUT_AMOUNT");
assert((balance_in > 0 as u128) & (balance_out > 0 as u128), "INSUFFICIENT_LIQUIDITY");

// The expression below is:
// (balance_in * amount_out * 1000) / (balance_out - amount_out * 997) + 1
Expand All @@ -27,26 +27,26 @@ pub fn get_amount_in(amount_out: U128, balance_in: U128, balance_out: U128) -> U
// resulting in an implicit 0.3% fee on the amount in, as the fee tokens are not taken into consideration. The +1
// at the end ensures the rounding error favors the pool.

let numerator = balance_in * amount_out * U128::from_integer(1000);
let denominator = (balance_out - amount_out) * U128::from_integer(997);
(numerator / denominator) + U128::from_integer(1)
let numerator = balance_in * amount_out * 1000 as u128;
let denominator = (balance_out - amount_out) * 997 as u128;
(numerator / denominator) + 1 as u128
}

/// Given the desired amounts and balances of token0 and token1 returns the optimal amount of token0 and token1 to be added to the pool.
pub fn get_amounts_to_add(
amount0_max: U128,
amount1_max: U128,
amount0_min: U128,
amount1_min: U128,
balance0: U128,
balance1: U128,
) -> (U128, U128) {
amount0_max: u128,
amount1_max: u128,
amount0_min: u128,
amount1_min: u128,
balance0: u128,
balance1: u128,
) -> (u128, u128) {
// When adding tokens, both balances must grow by the same ratio, which means that their spot price is unchanged.
// Since any swaps would affect these ratios, liquidity providers supply a range of minimum and maximum balances
// they are willing to supply for each token (which translates to minimum and maximum relative prices of the
// tokens, preventing loss of value outside of this range due to e.g. front-running).

if (balance0 == U128::zero()) | (balance1 == U128::zero()) {
if (balance0 == 0 as u128) | (balance1 == 0 as u128) {
// The token balances should only be zero when initializing the pool. In this scenario there is no prior ratio
// to follow so we simply transfer the full maximum balance - it is up to the caller to make sure that the ratio
// they've chosen results in a a reasonable spot price.
Expand Down Expand Up @@ -75,20 +75,20 @@ pub fn get_amounts_to_add(

/// Returns the amount of tokens to return to a liquidity provider when they remove liquidity from the pool.
pub fn get_amounts_on_remove(
to_burn: U128,
total_supply: U128,
balance0: U128,
balance1: U128,
) -> (U128, U128) {
to_burn: u128,
total_supply: u128,
balance0: u128,
balance1: u128,
) -> (u128, u128) {
// Since the liquidity token tracks ownership of the pool, the liquidity provider gets a proportional share of each
// token.
(to_burn * balance0 / total_supply, to_burn * balance1 / total_supply)
}

/// Given some amount of an asset and pair balances, returns an equivalent amount of the other asset. Tokens should be
/// added and removed from the Pool respecting this ratio.
fn get_equivalent_amount(amount0: U128, balance0: U128, balance1: U128) -> U128 {
assert((balance0 > U128::zero()) & (balance1 > U128::zero()), "INSUFFICIENT_LIQUIDITY");
fn get_equivalent_amount(amount0: u128, balance0: u128, balance1: u128) -> u128 {
assert((balance0 > 0 as u128) & (balance1 > 0 as u128), "INSUFFICIENT_LIQUIDITY");

// This is essentially the Rule of Three, since we're computing proportional ratios. Note we divide at the end to
// avoid introducing too much error due to truncation.
Expand Down
Loading

0 comments on commit 52ae8cc

Please sign in to comment.