From 46935ca785fdd066935ca411d26d2417d3c0d038 Mon Sep 17 00:00:00 2001 From: LHerskind Date: Wed, 28 Feb 2024 10:56:51 +0000 Subject: [PATCH 1/2] chore: purge SafeU120 --- .../contracts/resources/common_patterns/main.md | 8 -------- docs/docs/developers/tutorials/writing_token_contract.md | 7 +++---- .../contracts/gas_token_contract/src/main.nr | 4 ++-- .../contracts/lending_contract/src/interest_math.nr | 4 ++-- .../token_blacklist_contract/src/types/balances_map.nr | 1 - .../contracts/token_contract/src/types/balances_map.nr | 6 +----- 6 files changed, 8 insertions(+), 22 deletions(-) diff --git a/docs/docs/developers/contracts/resources/common_patterns/main.md b/docs/docs/developers/contracts/resources/common_patterns/main.md index e00f9770397..45b4c8f623e 100644 --- a/docs/docs/developers/contracts/resources/common_patterns/main.md +++ b/docs/docs/developers/contracts/resources/common_patterns/main.md @@ -10,14 +10,6 @@ Similarly we have discovered some anti-patterns too (like privacy leakage) that ## Common Patterns -### Safe Math and SafeU120 - -Field operations may overflow/underflow. Hence we have built a SafeMath library that you can use [based on instructions here](../dependencies.md#safe-math) - -### SafeU120 for comparison operations on Field elements - -Comparison on Field is also not possible today. For such cases, we recommend using u120, which is wrapped under the SafeU120 class found in the SafeMath library. - ### Approving another user/contract to execute an action on your behalf We call this the "authentication witness" pattern or authwit for short. diff --git a/docs/docs/developers/tutorials/writing_token_contract.md b/docs/docs/developers/tutorials/writing_token_contract.md index a232e40fa8b..7ca4f4c7b42 100644 --- a/docs/docs/developers/tutorials/writing_token_contract.md +++ b/docs/docs/developers/tutorials/writing_token_contract.md @@ -206,7 +206,6 @@ Just below the contract definition, add the following imports: We are importing the Option type, items from the `value_note` library to help manage private value storage, note utilities, context (for managing private and public execution contexts), `state_vars` for helping manage state, `types` for data manipulation and `oracle` for help passing data from the private to public execution context. We also import the `auth` [library](https://github.com/AztecProtocol/aztec-packages/blob/#include_aztec_version/noir-projects/aztec-nr/aztec/src/auth.nr) to handle token authorizations from [Account Contracts](../../learn/concepts/accounts/main). Check out the Account Contract with AuthWitness [here](https://github.com/AztecProtocol/aztec-packages/blob/#include_aztec_version/noir-projects/noir-contracts/contracts/schnorr_single_key_account_contract/src/main.nr). -[SafeU120](https://github.com/AztecProtocol/aztec-packages/blob/#include_aztec_version/noir-projects/aztec-nr/safe-math/src/safe_u120.nr) is a library to do safe math operations on unsigned integers that protects against overflows and underflows. For more detail on execution contexts, see [Contract Communication](../../learn/concepts/communication/main). @@ -277,7 +276,7 @@ This function allows the `admin` to add or a remove a `minter` from the public ` This function allows an account approved in the public `minters` mapping to create new public tokens owned by the provided `to` address. -First, storage is initialized. Then the function checks that the `msg_sender` is approved to mint in the `minters` mapping. If it is, a new `SafeU120` value is created of the `amount` provided. The function reads the recipients public balance and then adds the amount to mint, saving the output as `new_balance`, then reads to total supply and adds the amount to mint, saving the output as `supply`. `new_balance` and `supply` are then written to storage. +First, storage is initialized. Then the function checks that the `msg_sender` is approved to mint in the `minters` mapping. If it is, a new `U128` value is created of the `amount` provided. The function reads the recipients public balance and then adds the amount to mint, saving the output as `new_balance`, then reads to total supply and adds the amount to mint, saving the output as `supply`. `new_balance` and `supply` are then written to storage. The function returns 1 to indicate successful execution. @@ -311,7 +310,7 @@ It returns `1` to indicate successful execution. This public function enables public transfers between Aztec accounts. The sender's public balance will be debited the specified `amount` and the recipient's public balances will be credited with that amount. -After storage is initialized, the [authorization flow specified above](#authorizing-token-spends) is checked. Then the sender and recipient's balances are updated and saved to storage using the `SafeU120` library. +After storage is initialized, the [authorization flow specified above](#authorizing-token-spends) is checked. Then the sender and recipient's balances are updated and saved to storage. #include_code transfer_public /noir-projects/noir-contracts/contracts/token_contract/src/main.nr rust @@ -319,7 +318,7 @@ After storage is initialized, the [authorization flow specified above](#authoriz This public function enables public burning (destroying) of tokens from the sender's public balance. -After storage is initialized, the [authorization flow specified above](#authorizing-token-spends) is checked. Then the sender's public balance and the `total_supply` are updated and saved to storage using the `SafeU120` library. +After storage is initialized, the [authorization flow specified above](#authorizing-token-spends) is checked. Then the sender's public balance and the `total_supply` are updated and saved to storage. #include_code burn_public /noir-projects/noir-contracts/contracts/token_contract/src/main.nr rust diff --git a/noir-projects/noir-contracts/contracts/gas_token_contract/src/main.nr b/noir-projects/noir-contracts/contracts/gas_token_contract/src/main.nr index 92b53618c7b..736e5777b12 100644 --- a/noir-projects/noir-contracts/contracts/gas_token_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/gas_token_contract/src/main.nr @@ -26,8 +26,8 @@ contract GasToken { #[aztec(public)] fn check_balance(fee_limit: Field) { - let fee_limit_u120 = U128::from_integer(fee_limit); - assert(storage.balances.at(context.msg_sender()).read() >= fee_limit_u120, "Balance too low"); + let fee_limit = U128::from_integer(fee_limit); + assert(storage.balances.at(context.msg_sender()).read() >= fee_limit, "Balance too low"); } #[aztec(public)] diff --git a/noir-projects/noir-contracts/contracts/lending_contract/src/interest_math.nr b/noir-projects/noir-contracts/contracts/lending_contract/src/interest_math.nr index a678da6baf0..e92c91f908d 100644 --- a/noir-projects/noir-contracts/contracts/lending_contract/src/interest_math.nr +++ b/noir-projects/noir-contracts/contracts/lending_contract/src/interest_math.nr @@ -1,5 +1,5 @@ // Binomial approximation of exponential -// using lower than desired precisions for everything due to u120 limit +// using lower than desired precisions for everything due to u128 limit // (1+x)^n = 1+n*x+[n/2*(n-1)]*x^2+[n/6*(n-1)*(n-2)*x^3]... // we are loosing around almost 8 digits of precision from yearly -> daily interest // dividing with 31536000 (seconds per year). @@ -24,7 +24,7 @@ pub fn compute_multiplier(rate_per_second: U128, dt: u64) -> U128 { let second_term = temp.mul(base_power_two).div(U128::from_integer(2)); let third_term = temp.mul(exp_minus_two).mul(base_power_three).div(U128::from_integer(6)); - // throwing away precision to keep us under u120 :sob: + // throwing away precision to keep us under u128 :sob: let offset = dt.mul(rate).add(second_term).add(third_term).div(diff); res = base.add(offset); diff --git a/noir-projects/noir-contracts/contracts/token_blacklist_contract/src/types/balances_map.nr b/noir-projects/noir-contracts/contracts/token_blacklist_contract/src/types/balances_map.nr index a8ca9bf21e2..c979e0f2769 100644 --- a/noir-projects/noir-contracts/contracts/token_blacklist_contract/src/types/balances_map.nr +++ b/noir-projects/noir-contracts/contracts/token_blacklist_contract/src/types/balances_map.nr @@ -34,7 +34,6 @@ impl BalancesMap { owner: AztecAddress, offset: u32 ) -> U128 where T: NoteInterface + OwnedNote { - // Same as SafeU120::new(0), but fewer constraints because no check. let mut balance = U128::from_integer(0); // docs:start:view_notes let options = NoteViewerOptions::new().set_offset(offset); diff --git a/noir-projects/noir-contracts/contracts/token_contract/src/types/balances_map.nr b/noir-projects/noir-contracts/contracts/token_contract/src/types/balances_map.nr index 40e526d18d2..8e84d308df1 100644 --- a/noir-projects/noir-contracts/contracts/token_contract/src/types/balances_map.nr +++ b/noir-projects/noir-contracts/contracts/token_contract/src/types/balances_map.nr @@ -26,10 +26,7 @@ impl BalancesMap { } } - unconstrained pub fn balance_of( - self: Self, - owner: AztecAddress - ) -> U128 where T: NoteInterface + OwnedNote { + unconstrained pub fn balance_of(self: Self, owner: AztecAddress) -> U128 where T: NoteInterface + OwnedNote { self.balance_of_with_offset(owner, 0) } @@ -38,7 +35,6 @@ impl BalancesMap { owner: AztecAddress, offset: u32 ) -> U128 where T: NoteInterface + OwnedNote { - // Same as SafeU120::new(0), but fewer constraints because no check. let mut balance = U128::from_integer(0); // docs:start:view_notes let options = NoteViewerOptions::new().set_offset(offset); From 7bc407c32f5017bc7c817cee6600e121bec300f4 Mon Sep 17 00:00:00 2001 From: LHerskind Date: Fri, 1 Mar 2024 11:20:42 +0000 Subject: [PATCH 2/2] chore: rebasing conflicts --- docs/docs/developers/contracts/references/storage/main.md | 4 ++-- .../developers/contracts/references/storage/private_state.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/docs/developers/contracts/references/storage/main.md b/docs/docs/developers/contracts/references/storage/main.md index edae1e9eac9..75275c33987 100644 --- a/docs/docs/developers/contracts/references/storage/main.md +++ b/docs/docs/developers/contracts/references/storage/main.md @@ -11,13 +11,13 @@ You control this storage in Aztec using the `Storage` struct. This struct serves These state variables come in two forms: public and private. Public variables are visible to anyone, and private variables remain hidden within the contract. -Aztec.nr has a few abstractions to help define the type of data your contract holds. These include PrivateMutable, PublicMutable, PrivateSet, and SharedImmutable. +Aztec.nr has a few abstractions to help define the type of data your contract holds. These include PrivateMutable, PrivateImmutable, PublicMutable, PrivateSet, and SharedImmutable. On this and the following pages in this section, you’ll learn: - How to manage a smart contract's storage structure - The distinctions and applications of public and private state variables -- How to use Singleton, ImmutableSingleton, Set, and Map +- How to use PrivateMutable, PrivateImmutable, PrivateSet, PublicMutable, SharedImmutable and Map - An overview of 'notes' and the UTXO model - Practical implications of Storage in real smart contracts In an Aztec.nr contract, storage is to be defined as a single struct, that contains both public and private state variables. diff --git a/docs/docs/developers/contracts/references/storage/private_state.md b/docs/docs/developers/contracts/references/storage/private_state.md index 12219128489..402e891ffa8 100644 --- a/docs/docs/developers/contracts/references/storage/private_state.md +++ b/docs/docs/developers/contracts/references/storage/private_state.md @@ -91,7 +91,7 @@ When this function is called, a nullifier of the storage slot is created, preven :::danger Privacy-Leak Beware that because this nullifier is created only from the storage slot without randomness it leaks privacy. This means that it is possible for an external observer to determine when the note is nullified. -For example, if the storage slot depends on the an address then it is possible to link the nullifier to the address. If the singleton is part of a `map` with an `AztecAddress` as the key then the nullifier will be linked to the address. +For example, if the storage slot depends on the an address then it is possible to link the nullifier to the address. If the PrivateMutable is part of a `map` with an `AztecAddress` as the key then the nullifier will be linked to the address. ::: Unlike public states, which have a default initial value of `0` (or many zeros, in the case of a struct, array or map), a private state (of type `PrivateMutable`, `PrivateImmutable` or `PrivateSet`) does not have a default initial value. The `initialize` method (or `insert`, in the case of a `PrivateSet`) must be called. @@ -149,7 +149,7 @@ When this function is invoked, it creates a nullifier for the storage slot, ensu :::danger Privacy-Leak Beware that because this nullifier is created only from the storage slot without randomness it leaks privacy. This means that it is possible for an external observer to determine when the note is nullified. -For example, if the storage slot depends on the an address then it is possible to link the nullifier to the address. If the singleton is part of a `map` with an `AztecAddress` as the key then the nullifier will be linked to the address. +For example, if the storage slot depends on the an address then it is possible to link the nullifier to the address. If the PrivateImmutable is part of a `map` with an `AztecAddress` as the key then the nullifier will be linked to the address. ::: Set the value of an PrivateImmutable by calling the `initialize` method: