Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: purge SafeU120 #4819

Merged
merged 2 commits into from
Mar 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions docs/docs/developers/contracts/references/storage/main.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
7 changes: 3 additions & 4 deletions docs/docs/developers/tutorials/writing_token_contract.md
Original file line number Diff line number Diff line change
Expand Up @@ -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).

Expand Down Expand Up @@ -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.

Expand Down Expand Up @@ -311,15 +310,15 @@ 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

#### `burn_public`

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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down
Original file line number Diff line number Diff line change
@@ -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).
Expand All @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ impl<T> BalancesMap<T> {
owner: AztecAddress,
offset: u32
) -> U128 where T: NoteInterface<T_SERIALIZED_LEN> + 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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,7 @@ impl<T> BalancesMap<T> {
}
}

unconstrained pub fn balance_of<T_SERIALIZED_LEN>(
self: Self,
owner: AztecAddress
) -> U128 where T: NoteInterface<T_SERIALIZED_LEN> + OwnedNote {
unconstrained pub fn balance_of<T_SERIALIZED_LEN>(self: Self, owner: AztecAddress) -> U128 where T: NoteInterface<T_SERIALIZED_LEN> + OwnedNote {
self.balance_of_with_offset(owner, 0)
}

Expand All @@ -38,7 +35,6 @@ impl<T> BalancesMap<T> {
owner: AztecAddress,
offset: u32
) -> U128 where T: NoteInterface<T_SERIALIZED_LEN> + 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);
Expand Down
Loading