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

refactor: token refunds cleanup #9943

Merged
merged 3 commits into from
Nov 13, 2024
Merged
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
64 changes: 8 additions & 56 deletions noir-projects/noir-contracts/contracts/token_contract/src/main.nr
Original file line number Diff line number Diff line change
Expand Up @@ -666,62 +666,14 @@ contract Token {
user,
));

// 4. Now we get the partial payloads
// TODO(#7775): Manually fetching the randomness here is not great. If we decide to include randomness in all
// notes we could just inject it in macros.
let fee_payer_randomness = unsafe { random() };
let user_randomness = unsafe { random() };

let fee_payer_setup_payload = UintNote::setup_payload().new(
fee_payer,
fee_payer_randomness,
storage.balances.at(fee_payer).set.storage_slot,
);

let user_setup_payload = UintNote::setup_payload().new(
user,
user_randomness,
storage.balances.at(user).set.storage_slot,
);

// 5. We get transient storage slots
// Using the x-coordinate as a hiding point slot is safe against someone else interfering with it because
// we have a guarantee that the public functions of the transaction are executed right after the private ones
// and for this reason the protocol guarantees that nobody can front-run us in consuming the hiding point.
// This guarantee would break if `finalize_transfer_to_private` was not called in the same transaction. This
// however is not the flow we are currently concerned with. To support the multi-transaction flow we could
// introduce a `from` function argument, hash the x-coordinate with it and then repeat the hashing in
// `finalize_transfer_to_private`.
//
// We can also be sure that the `hiding_point_slot` will not overwrite any other value in the storage because
// in our state variables we derive slots using a different hash function from multi scalar multiplication
// (MSM).
let fee_payer_point_slot = fee_payer_setup_payload.hiding_point.x;
let user_point_slot = user_setup_payload.hiding_point.x;

// 6. We compute setup logs
let fee_payer_setup_log =
fee_payer_setup_payload.encrypt_log(&mut context, user_ovpk, fee_payer, fee_payer);
let user_setup_log =
user_setup_payload.encrypt_log(&mut context, user_ovpk, user, fee_payer);

// 7. We store the hiding points an logs in transients storage
Token::at(context.this_address())
._store_payload_in_transient_storage_unsafe(
fee_payer_point_slot,
fee_payer_setup_payload.hiding_point,
fee_payer_setup_log,
)
.enqueue(&mut context);
Token::at(context.this_address())
._store_payload_in_transient_storage_unsafe(
user_point_slot,
user_setup_payload.hiding_point,
user_setup_log,
)
.enqueue(&mut context);

// 8. Set the public teardown function to `complete_refund(...)`. Public teardown is the only time when a public
// 4. We prepare the partial notes
// TODO(#9887): In each `_prepare_transfer_to_private` call we fetch the user's ovpk_m 2 more times. This is
// very inefficient.
let fee_payer_point_slot =
_prepare_transfer_to_private(user, fee_payer, &mut context, storage);
let user_point_slot = _prepare_transfer_to_private(user, user, &mut context, storage);

// 5. Set the public teardown function to `complete_refund(...)`. Public teardown is the only time when a public
// function has access to the final transaction fee, which is needed to compute the actual refund amount.
context.set_public_teardown_function(
context.this_address(),
Expand Down
Loading