From 7095bd127279fd7cb2f2d929dc06e7dc72d9fec2 Mon Sep 17 00:00:00 2001 From: benesjan Date: Wed, 5 Feb 2025 16:02:09 +0000 Subject: [PATCH 01/14] feat: optimizing contract with config pattern --- .../app_subscription_contract/src/config.nr | 11 +++ .../app_subscription_contract/src/main.nr | 38 +++++----- .../crowdfunding_contract/src/config.nr | 9 +++ .../crowdfunding_contract/src/main.nr | 32 ++++---- .../token_bridge_contract/src/config.nr | 8 ++ .../token_bridge_contract/src/main.nr | 76 ++++++++----------- 6 files changed, 96 insertions(+), 78 deletions(-) create mode 100644 noir-projects/noir-contracts/contracts/app_subscription_contract/src/config.nr create mode 100644 noir-projects/noir-contracts/contracts/crowdfunding_contract/src/config.nr create mode 100644 noir-projects/noir-contracts/contracts/token_bridge_contract/src/config.nr diff --git a/noir-projects/noir-contracts/contracts/app_subscription_contract/src/config.nr b/noir-projects/noir-contracts/contracts/app_subscription_contract/src/config.nr new file mode 100644 index 00000000000..054bba7da19 --- /dev/null +++ b/noir-projects/noir-contracts/contracts/app_subscription_contract/src/config.nr @@ -0,0 +1,11 @@ +use dep::aztec::protocol_types::{address::AztecAddress, traits::{Deserialize, Packable, Serialize}}; +use std::meta::derive; + +#[derive(Eq, Packable)] +pub struct Config { + pub target_address: AztecAddress, + pub subscription_token_address: AztecAddress, + pub subscription_recipient_address: AztecAddress, + pub subscription_price: U128, + pub fee_juice_limit_per_tx: Field, +} diff --git a/noir-projects/noir-contracts/contracts/app_subscription_contract/src/main.nr b/noir-projects/noir-contracts/contracts/app_subscription_contract/src/main.nr index 3639423f2bd..14b72ce50d7 100644 --- a/noir-projects/noir-contracts/contracts/app_subscription_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/app_subscription_contract/src/main.nr @@ -1,3 +1,4 @@ +mod config; mod subscription_note; mod dapp_payload; @@ -5,7 +6,7 @@ use dep::aztec::macros::aztec; #[aztec] pub contract AppSubscription { - use crate::{dapp_payload::DAppPayload, subscription_note::SubscriptionNote}; + use crate::{config::Config, dapp_payload::DAppPayload, subscription_note::SubscriptionNote}; use authwit::auth::assert_current_call_valid_authwit; use aztec::{ @@ -18,15 +19,10 @@ pub contract AppSubscription { use router::utils::privately_check_block_number; use token::Token; - // TODO: This can be optimized by storing the values in Config struct in 1 PublicImmutable (less merkle proofs). #[storage] struct Storage { - target_address: PublicImmutable, - subscription_token_address: PublicImmutable, - subscription_recipient_address: PublicImmutable, - subscription_price: PublicImmutable, + config: PublicImmutable, subscriptions: Map, Context>, - fee_juice_limit_per_tx: PublicImmutable, } global SUBSCRIPTION_DURATION_IN_BLOCKS: Field = 5; @@ -51,8 +47,10 @@ pub contract AppSubscription { context.set_as_fee_payer(); + let config = storage.config.read(); + // TODO(palla/gas) Assert fee_juice_limit_per_tx is less than this tx gas_limit - let _gas_limit = storage.fee_juice_limit_per_tx.read(); + let _gas_limit = config.fee_juice_limit_per_tx; context.end_setup(); @@ -60,7 +58,7 @@ pub contract AppSubscription { // is performing the check. privately_check_block_number(Comparator.LT, note.expiry_block_number, &mut context); - payload.execute_calls(&mut context, storage.target_address.read()); + payload.execute_calls(&mut context, config.target_address); } #[public] @@ -72,11 +70,15 @@ pub contract AppSubscription { subscription_price: U128, fee_juice_limit_per_tx: Field, ) { - storage.target_address.initialize(target_address); - storage.subscription_token_address.initialize(subscription_token_address); - storage.subscription_recipient_address.initialize(subscription_recipient_address); - storage.subscription_price.initialize(subscription_price); - storage.fee_juice_limit_per_tx.initialize(fee_juice_limit_per_tx); + storage.config.initialize( + Config { + target_address, + subscription_recipient_address, + subscription_token_address, + subscription_price, + fee_juice_limit_per_tx, + }, + ); } #[private] @@ -88,11 +90,13 @@ pub contract AppSubscription { ) { assert(tx_count as u64 <= SUBSCRIPTION_TXS as u64); - Token::at(storage.subscription_token_address.read()) + let config = storage.config.read(); + + Token::at(config.subscription_token_address) .transfer_in_private( context.msg_sender(), - storage.subscription_recipient_address.read(), - storage.subscription_price.read(), + config.subscription_recipient_address, + config.subscription_price, nonce, ) .call(&mut context); diff --git a/noir-projects/noir-contracts/contracts/crowdfunding_contract/src/config.nr b/noir-projects/noir-contracts/contracts/crowdfunding_contract/src/config.nr new file mode 100644 index 00000000000..4e96a54d93c --- /dev/null +++ b/noir-projects/noir-contracts/contracts/crowdfunding_contract/src/config.nr @@ -0,0 +1,9 @@ +use dep::aztec::protocol_types::{address::AztecAddress, traits::Packable}; +use std::meta::derive; + +#[derive(Eq, Packable)] +pub struct Config { + pub donation_token: AztecAddress, // Token used for donations (e.g. DAI) + pub operator: AztecAddress, // Crowdfunding campaign operator + pub deadline: u64, // End of the crowdfunding campaign after which no more donations are accepted +} diff --git a/noir-projects/noir-contracts/contracts/crowdfunding_contract/src/main.nr b/noir-projects/noir-contracts/contracts/crowdfunding_contract/src/main.nr index bf564557f61..c1249ce06a7 100644 --- a/noir-projects/noir-contracts/contracts/crowdfunding_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/crowdfunding_contract/src/main.nr @@ -1,9 +1,12 @@ +mod config; + // docs:start:empty-contract use dep::aztec::macros::aztec; #[aztec] pub contract Crowdfunding { // docs:end:empty-contract + use crate::config::Config; // docs:start:all-deps use dep::aztec::{ @@ -31,16 +34,10 @@ pub contract Crowdfunding { amount: U128, } - // TODO: This can be optimized by storing the values in Config struct in 1 PublicImmutable (less merkle proofs). // docs:start:storage #[storage] struct Storage { - // Token used for donations (e.g. DAI) - donation_token: PublicImmutable, - // Crowdfunding campaign operator - operator: PublicImmutable, - // End of the crowdfunding campaign after which no more donations are accepted - deadline: PublicImmutable, + config: PublicImmutable, // Notes emitted to donors when they donate (can be used as proof to obtain rewards, eg in Claim contracts) donation_receipts: PrivateSet, } @@ -56,28 +53,29 @@ pub contract Crowdfunding { fn init(donation_token: AztecAddress, operator: AztecAddress, deadline: u64) { // docs:end:init-header // docs:end:init-header-error - storage.donation_token.initialize(donation_token); - storage.operator.initialize(operator); - storage.deadline.initialize(deadline); + storage.config.initialize(Config { donation_token, operator, deadline }); } // docs:end:init // docs:start:donate #[private] fn donate(amount: U128) { + let config = storage.config.read(); + // 1) Check that the deadline has not passed --> we do that via the router contract to conceal which contract // is performing the check. // docs:start:call-check-deadline - let deadline = storage.deadline.read(); - privately_check_timestamp(Comparator.LT, deadline, &mut context); + privately_check_timestamp(Comparator.LT, config.deadline, &mut context); // docs:end:call-check-deadline + // docs:start:do-transfer // 2) Transfer the donation tokens from donor to this contract let donor = context.msg_sender(); - Token::at(storage.donation_token.read()) + Token::at(config.donation_token) .transfer_in_private(donor, context.this_address(), amount, 0) .call(&mut context); // docs:end:do-transfer + // 3) Create a value note for the donor so that he can later on claim a rewards token in the Claim // contract by proving that the hash of this note exists in the note hash tree. let mut note = UintNote::new(amount, donor); @@ -94,14 +92,14 @@ pub contract Crowdfunding { // Withdraws balance to the operator. Requires that msg_sender() is the operator. #[private] fn withdraw(amount: U128) { + let config = storage.config.read(); + let operator_address = config.operator; + // 1) Check that msg_sender() is the operator - let operator_address = storage.operator.read(); assert(context.msg_sender() == operator_address, "Not an operator"); // 2) Transfer the donation tokens from this contract to the operator - Token::at(storage.donation_token.read()).transfer(operator_address, amount).call( - &mut context, - ); + Token::at(config.donation_token).transfer(operator_address, amount).call(&mut context); // 3) Emit a public event so that anyone can audit how much the operator has withdrawn Crowdfunding::at(context.this_address()) ._publish_donation_receipts(amount, operator_address) diff --git a/noir-projects/noir-contracts/contracts/token_bridge_contract/src/config.nr b/noir-projects/noir-contracts/contracts/token_bridge_contract/src/config.nr new file mode 100644 index 00000000000..6a1684c5cdf --- /dev/null +++ b/noir-projects/noir-contracts/contracts/token_bridge_contract/src/config.nr @@ -0,0 +1,8 @@ +use dep::aztec::protocol_types::{address::{AztecAddress, EthAddress}, traits::Packable}; +use std::meta::derive; + +#[derive(Eq, Packable)] +pub struct Config { + pub token: AztecAddress, + pub portal: EthAddress, +} diff --git a/noir-projects/noir-contracts/contracts/token_bridge_contract/src/main.nr b/noir-projects/noir-contracts/contracts/token_bridge_contract/src/main.nr index b7a4a5919f6..890ef166d7b 100644 --- a/noir-projects/noir-contracts/contracts/token_bridge_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/token_bridge_contract/src/main.nr @@ -1,3 +1,5 @@ +mod config; + // docs:start:token_bridge_imports // Minimal implementation of the token bridge that can move funds between L1 <> L2. @@ -9,6 +11,8 @@ use dep::aztec::macros::aztec; #[aztec] pub contract TokenBridge { + use crate::config::Config; + use dep::aztec::prelude::{AztecAddress, EthAddress, PublicImmutable}; use dep::token_portal_content_hash_lib::{ @@ -18,38 +22,32 @@ pub contract TokenBridge { use dep::token::Token; - use dep::aztec::macros::{ - functions::{initializer, internal, private, public, view}, - storage::storage, - }; + use dep::aztec::macros::{functions::{initializer, private, public, view}, storage::storage}; // docs:end:token_bridge_imports - // TODO: This can be optimized by storing the values in Config struct in 1 PublicImmutable (less merkle proofs). // docs:start:token_bridge_storage_and_constructor // Storage structure, containing all storage, and specifying what slots they use. #[storage] struct Storage { - token: PublicImmutable, - portal_address: PublicImmutable, + config: PublicImmutable, } // Constructs the contract. #[public] #[initializer] - fn constructor(token: AztecAddress, portal_address: EthAddress) { - storage.token.initialize(token); - storage.portal_address.initialize(portal_address); + fn constructor(token: AztecAddress, portal: EthAddress) { + storage.config.initialize(Config { token, portal }); } // docs:end:token_bridge_storage_and_constructor #[private] - fn get_portal_address() -> EthAddress { - storage.portal_address.read() + fn get_portal() -> EthAddress { + storage.config.read().portal } #[public] - fn get_portal_address_public() -> EthAddress { - storage.portal_address.read() + fn get_portal_public() -> EthAddress { + storage.config.read().portal } // docs:start:claim_public @@ -58,16 +56,13 @@ pub contract TokenBridge { fn claim_public(to: AztecAddress, amount: U128, secret: Field, message_leaf_index: Field) { let content_hash = get_mint_to_public_content_hash(to, amount); + let config = storage.config.read(); + // Consume message and emit nullifier - context.consume_l1_to_l2_message( - content_hash, - secret, - storage.portal_address.read(), - message_leaf_index, - ); + context.consume_l1_to_l2_message(content_hash, secret, config.portal, message_leaf_index); // Mint tokens - Token::at(storage.token.read()).mint_to_public(to, amount).call(&mut context); + Token::at(config.token).mint_to_public(to, amount).call(&mut context); } // docs:end:claim_public @@ -81,14 +76,14 @@ pub contract TokenBridge { caller_on_l1: EthAddress, // ethereum address that can call this function on the L1 portal (0x0 if anyone can call) nonce: Field, // nonce used in the approval message by `msg.sender` to let bridge burn their tokens on L2 ) { + let config = storage.config.read(); + // Send an L2 to L1 message let content = get_withdraw_content_hash(recipient, amount, caller_on_l1); - context.message_portal(storage.portal_address.read(), content); + context.message_portal(config.portal, content); // Burn tokens - Token::at(storage.token.read()).burn_public(context.msg_sender(), amount, nonce).call( - &mut context, - ); + Token::at(config.token).burn_public(context.msg_sender(), amount, nonce).call(&mut context); } // docs:end:exit_to_l1_public @@ -103,21 +98,20 @@ pub contract TokenBridge { secret_for_L1_to_L2_message_consumption: Field, // secret used to consume the L1 to L2 message message_leaf_index: Field, ) { + let config = storage.config.read(); + // Consume L1 to L2 message and emit nullifier let content_hash = get_mint_to_private_content_hash(amount); context.consume_l1_to_l2_message( content_hash, secret_for_L1_to_L2_message_consumption, - storage.portal_address.read(), + config.portal, message_leaf_index, ); - // Read the token address from storage - let token_address = storage.token.read(); - // At last we mint the tokens // docs:start:call_mint_on_token - Token::at(token_address).mint_to_private(context.msg_sender(), recipient, amount).call( + Token::at(config.token).mint_to_private(context.msg_sender(), recipient, amount).call( &mut context, ); // docs:end:call_mint_on_token @@ -135,31 +129,25 @@ pub contract TokenBridge { caller_on_l1: EthAddress, // ethereum address that can call this function on the L1 portal (0x0 if anyone can call) nonce: Field, // nonce used in the approval message by `msg.sender` to let bridge burn their tokens on L2 ) { + let config = storage.config.read(); + + // Assert that user provided token address is same as seen in storage. + assert_eq(config.token, token, "Token address is not the same as seen in storage"); + // Send an L2 to L1 message let content = get_withdraw_content_hash(recipient, amount, caller_on_l1); - context.message_portal(storage.portal_address.read(), content); + context.message_portal(config.portal, content); - // docs:start:call_assert_token_is_same - // Assert that user provided token address is same as seen in storage. - TokenBridge::at(context.this_address())._assert_token_is_same(token).enqueue(&mut context); - // docs:end:call_assert_token_is_same // Burn tokens Token::at(token).burn_private(context.msg_sender(), amount, nonce).call(&mut context); } /// docs:end:exit_to_l1_private + // docs:start:get_token #[public] #[view] fn get_token() -> AztecAddress { - storage.token.read() + storage.config.read().token } // docs:end:get_token - - // docs:start:assert_token_is_same - #[public] - #[internal] - fn _assert_token_is_same(token: AztecAddress) { - assert(storage.token.read().eq(token), "Token address is not the same as seen in storage"); - } - // docs:end:assert_token_is_same } From 44d96565819d2b9450fd23a16c6ca10f6793ef96 Mon Sep 17 00:00:00 2001 From: benesjan Date: Wed, 5 Feb 2025 16:21:43 +0000 Subject: [PATCH 02/14] WIP --- .../token_bridge_contract/src/config.nr | 4 +- .../token_bridge_contract/src/main.nr | 16 ++----- .../contracts/uniswap_contract/src/main.nr | 45 ++++++++----------- 3 files changed, 24 insertions(+), 41 deletions(-) diff --git a/noir-projects/noir-contracts/contracts/token_bridge_contract/src/config.nr b/noir-projects/noir-contracts/contracts/token_bridge_contract/src/config.nr index 6a1684c5cdf..20924bade65 100644 --- a/noir-projects/noir-contracts/contracts/token_bridge_contract/src/config.nr +++ b/noir-projects/noir-contracts/contracts/token_bridge_contract/src/config.nr @@ -1,7 +1,7 @@ -use dep::aztec::protocol_types::{address::{AztecAddress, EthAddress}, traits::Packable}; +use dep::aztec::protocol_types::{address::{AztecAddress, EthAddress}, traits::{Deserialize, Packable, Serialize}}; use std::meta::derive; -#[derive(Eq, Packable)] +#[derive(Deserialize, Eq, Packable, Serialize)] pub struct Config { pub token: AztecAddress, pub portal: EthAddress, diff --git a/noir-projects/noir-contracts/contracts/token_bridge_contract/src/main.nr b/noir-projects/noir-contracts/contracts/token_bridge_contract/src/main.nr index 890ef166d7b..07506d73999 100644 --- a/noir-projects/noir-contracts/contracts/token_bridge_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/token_bridge_contract/src/main.nr @@ -41,13 +41,13 @@ pub contract TokenBridge { // docs:end:token_bridge_storage_and_constructor #[private] - fn get_portal() -> EthAddress { - storage.config.read().portal + fn get_config_private() -> Config { + storage.config.read() } #[public] - fn get_portal_public() -> EthAddress { - storage.config.read().portal + fn get_config_public() -> Config { + storage.config.read() } // docs:start:claim_public @@ -142,12 +142,4 @@ pub contract TokenBridge { Token::at(token).burn_private(context.msg_sender(), amount, nonce).call(&mut context); } /// docs:end:exit_to_l1_private - - // docs:start:get_token - #[public] - #[view] - fn get_token() -> AztecAddress { - storage.config.read().token - } - // docs:end:get_token } diff --git a/noir-projects/noir-contracts/contracts/uniswap_contract/src/main.nr b/noir-projects/noir-contracts/contracts/uniswap_contract/src/main.nr index b69252ebc98..d4b0b9ce5dd 100644 --- a/noir-projects/noir-contracts/contracts/uniswap_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/uniswap_contract/src/main.nr @@ -58,7 +58,11 @@ pub contract Uniswap { assert_current_call_valid_authwit_public(&mut context, sender); } - let input_asset = TokenBridge::at(input_asset_bridge).get_token().view(&mut context); + let input_asset_bridge_config = TokenBridge::at(input_asset_bridge).get_config_public().view(&mut context); + + let input_asset = input_asset_bridge_config.token; + let input_asset_bridge_portal_address = input_asset_bridge_config.portal; + // Transfer funds to this contract Token::at(input_asset) @@ -80,10 +84,8 @@ pub contract Uniswap { .call(&mut context); // Create swap message and send to Outbox for Uniswap Portal // this ensures the integrity of what the user originally intends to do on L1. - let input_asset_bridge_portal_address = - TokenBridge::at(input_asset_bridge).get_portal_address_public().view(&mut context); let output_asset_bridge_portal_address = - TokenBridge::at(output_asset_bridge).get_portal_address_public().view(&mut context); + TokenBridge::at(output_asset_bridge).get_config_public().view(&mut context).portal; // ensure portal exists - else funds might be lost assert( !input_asset_bridge_portal_address.is_zero(), @@ -124,11 +126,15 @@ pub contract Uniswap { secret_hash_for_L1_to_l2_message: Field, // for when l1 uniswap portal inserts the message to consume output assets on L2 caller_on_L1: EthAddress, // ethereum address that can call this function on the L1 portal (0x0 if anyone can call) ) { + let input_asset_bridge_config = TokenBridge::at(input_asset_bridge).get_config_private().view(&mut context); + let output_asset_bridge_config = TokenBridge::at(output_asset_bridge).get_config_private().view(&mut context); + // Assert that user provided token address is same as expected by token bridge. // we can't directly use `input_asset_bridge.token` because that is a public method and public can't return data to private - Uniswap::at(context.this_address()) - ._assert_token_is_same(input_asset, input_asset_bridge) - .enqueue_view(&mut context); + assert( + input_asset.eq(input_asset_bridge_config.token), + "input_asset address is not the same as seen in the bridge contract", + ); // Transfer funds to this contract Token::at(input_asset) @@ -151,25 +157,22 @@ pub contract Uniswap { // Create swap message and send to Outbox for Uniswap Portal // this ensures the integrity of what the user originally intends to do on L1. - let input_asset_bridge_portal_address = - TokenBridge::at(input_asset_bridge).get_portal_address().view(&mut context); - let output_asset_bridge_portal_address = - TokenBridge::at(output_asset_bridge).get_portal_address().view(&mut context); + // ensure portal exists - else funds might be lost assert( - !input_asset_bridge_portal_address.is_zero(), + !input_asset_bridge_config.portal.is_zero(), "L1 portal address of input_asset's bridge is 0", ); assert( - !output_asset_bridge_portal_address.is_zero(), + !output_asset_bridge_config.portal.is_zero(), "L1 portal address of output_asset's bridge is 0", ); let content_hash = compute_swap_private_content_hash( - input_asset_bridge_portal_address, + input_asset_bridge_config.portal, input_amount, uniswap_fee_tier, - output_asset_bridge_portal_address, + output_asset_bridge_config.portal, minimum_output_amount, secret_hash_for_L1_to_l2_message, caller_on_L1, @@ -216,16 +219,4 @@ pub contract Uniswap { .call(&mut context) } // docs:end:authwit_uniswap_set - - // docs:start:assert_token_is_same - #[public] - #[internal] - #[view] - fn _assert_token_is_same(token: AztecAddress, token_bridge: AztecAddress) { - assert( - token.eq(TokenBridge::at(token_bridge).get_token().view(&mut context)), - "input_asset address is not the same as seen in the bridge contract", - ); - } - // docs:end:assert_token_is_same } From 5dc1b4d67ce6adacee911bf26884f4e150b649ed Mon Sep 17 00:00:00 2001 From: benesjan Date: Wed, 5 Feb 2025 16:25:30 +0000 Subject: [PATCH 03/14] fmt --- .../contracts/token_bridge_contract/src/config.nr | 5 ++++- .../contracts/uniswap_contract/src/main.nr | 15 +++++++-------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/noir-projects/noir-contracts/contracts/token_bridge_contract/src/config.nr b/noir-projects/noir-contracts/contracts/token_bridge_contract/src/config.nr index 20924bade65..0745cbcc45e 100644 --- a/noir-projects/noir-contracts/contracts/token_bridge_contract/src/config.nr +++ b/noir-projects/noir-contracts/contracts/token_bridge_contract/src/config.nr @@ -1,4 +1,7 @@ -use dep::aztec::protocol_types::{address::{AztecAddress, EthAddress}, traits::{Deserialize, Packable, Serialize}}; +use dep::aztec::protocol_types::{ + address::{AztecAddress, EthAddress}, + traits::{Deserialize, Packable, Serialize}, +}; use std::meta::derive; #[derive(Deserialize, Eq, Packable, Serialize)] diff --git a/noir-projects/noir-contracts/contracts/uniswap_contract/src/main.nr b/noir-projects/noir-contracts/contracts/uniswap_contract/src/main.nr index d4b0b9ce5dd..4be9d6a36d5 100644 --- a/noir-projects/noir-contracts/contracts/uniswap_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/uniswap_contract/src/main.nr @@ -16,10 +16,7 @@ pub contract Uniswap { }; use crate::util::{compute_swap_private_content_hash, compute_swap_public_content_hash}; - use dep::aztec::macros::{ - functions::{initializer, internal, private, public, view}, - storage::storage, - }; + use dep::aztec::macros::{functions::{initializer, internal, private, public}, storage::storage}; use dep::token::Token; use dep::token_bridge::TokenBridge; @@ -58,12 +55,12 @@ pub contract Uniswap { assert_current_call_valid_authwit_public(&mut context, sender); } - let input_asset_bridge_config = TokenBridge::at(input_asset_bridge).get_config_public().view(&mut context); + let input_asset_bridge_config = + TokenBridge::at(input_asset_bridge).get_config_public().view(&mut context); let input_asset = input_asset_bridge_config.token; let input_asset_bridge_portal_address = input_asset_bridge_config.portal; - // Transfer funds to this contract Token::at(input_asset) .transfer_in_public( @@ -126,8 +123,10 @@ pub contract Uniswap { secret_hash_for_L1_to_l2_message: Field, // for when l1 uniswap portal inserts the message to consume output assets on L2 caller_on_L1: EthAddress, // ethereum address that can call this function on the L1 portal (0x0 if anyone can call) ) { - let input_asset_bridge_config = TokenBridge::at(input_asset_bridge).get_config_private().view(&mut context); - let output_asset_bridge_config = TokenBridge::at(output_asset_bridge).get_config_private().view(&mut context); + let input_asset_bridge_config = + TokenBridge::at(input_asset_bridge).get_config_private().view(&mut context); + let output_asset_bridge_config = + TokenBridge::at(output_asset_bridge).get_config_private().view(&mut context); // Assert that user provided token address is same as expected by token bridge. // we can't directly use `input_asset_bridge.token` because that is a public method and public can't return data to private From e54c978cbe6f3b9a5bf151c024b42797f0bf96c9 Mon Sep 17 00:00:00 2001 From: benesjan Date: Wed, 5 Feb 2025 16:31:19 +0000 Subject: [PATCH 04/14] scared Noir fix --- .../noir-contracts/contracts/token_bridge_contract/src/main.nr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/noir-projects/noir-contracts/contracts/token_bridge_contract/src/main.nr b/noir-projects/noir-contracts/contracts/token_bridge_contract/src/main.nr index 07506d73999..20a00d5dd61 100644 --- a/noir-projects/noir-contracts/contracts/token_bridge_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/token_bridge_contract/src/main.nr @@ -141,5 +141,5 @@ pub contract TokenBridge { // Burn tokens Token::at(token).burn_private(context.msg_sender(), amount, nonce).call(&mut context); } - /// docs:end:exit_to_l1_private + // docs:end:exit_to_l1_private } From 4ea660d347a5dad4bda0f8076bca021faad54f9e Mon Sep 17 00:00:00 2001 From: benesjan Date: Wed, 5 Feb 2025 16:53:34 +0000 Subject: [PATCH 05/14] cleanup --- .../contracts/token_bridge_contract/src/main.nr | 4 +++- .../noir-contracts/contracts/uniswap_contract/src/main.nr | 4 ++-- .../end-to-end/src/shared/cross_chain_test_harness.ts | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/noir-projects/noir-contracts/contracts/token_bridge_contract/src/main.nr b/noir-projects/noir-contracts/contracts/token_bridge_contract/src/main.nr index 20a00d5dd61..f95c3570e26 100644 --- a/noir-projects/noir-contracts/contracts/token_bridge_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/token_bridge_contract/src/main.nr @@ -41,11 +41,13 @@ pub contract TokenBridge { // docs:end:token_bridge_storage_and_constructor #[private] - fn get_config_private() -> Config { + #[view] + fn get_config() -> Config { storage.config.read() } #[public] + #[view] fn get_config_public() -> Config { storage.config.read() } diff --git a/noir-projects/noir-contracts/contracts/uniswap_contract/src/main.nr b/noir-projects/noir-contracts/contracts/uniswap_contract/src/main.nr index 4be9d6a36d5..664c34ef286 100644 --- a/noir-projects/noir-contracts/contracts/uniswap_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/uniswap_contract/src/main.nr @@ -124,9 +124,9 @@ pub contract Uniswap { caller_on_L1: EthAddress, // ethereum address that can call this function on the L1 portal (0x0 if anyone can call) ) { let input_asset_bridge_config = - TokenBridge::at(input_asset_bridge).get_config_private().view(&mut context); + TokenBridge::at(input_asset_bridge).get_config().view(&mut context); let output_asset_bridge_config = - TokenBridge::at(output_asset_bridge).get_config_private().view(&mut context); + TokenBridge::at(output_asset_bridge).get_config().view(&mut context); // Assert that user provided token address is same as expected by token bridge. // we can't directly use `input_asset_bridge.token` because that is a public method and public can't return data to private diff --git a/yarn-project/end-to-end/src/shared/cross_chain_test_harness.ts b/yarn-project/end-to-end/src/shared/cross_chain_test_harness.ts index 19a8fb58f16..b87743ac418 100644 --- a/yarn-project/end-to-end/src/shared/cross_chain_test_harness.ts +++ b/yarn-project/end-to-end/src/shared/cross_chain_test_harness.ts @@ -114,7 +114,7 @@ export async function deployAndInitializeTokenAndBridgeContracts( throw new Error(`Token admin is not ${owner}`); } - if (!(await bridge.methods.get_token().simulate()).equals(token.address)) { + if (!(await bridge.methods.get_config().simulate()).token.equals(token.address)) { throw new Error(`Bridge token is not ${token.address}`); } From e812ee2bcff09bc43d2d8c0b2c544541ccd65761 Mon Sep 17 00:00:00 2001 From: benesjan Date: Wed, 5 Feb 2025 16:55:56 +0000 Subject: [PATCH 06/14] migration notes --- docs/docs/migration_notes.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/docs/migration_notes.md b/docs/docs/migration_notes.md index 2a52292eb8d..6db903b05c2 100644 --- a/docs/docs/migration_notes.md +++ b/docs/docs/migration_notes.md @@ -8,7 +8,12 @@ Aztec is in full-speed development. Literally every version breaks compatibility ### TBD +### Changes to `TokenBridge` interface + +`get_token` and `get_portal_address` functions got merged into a single `get_config` function that returns a struct containing both the token and portal addresses. + ### [Aztec.nr] Introduction of `WithHash` + `WithHash` is a struct that allows for efficient reading of value `T` from public storage in private. This is achieved by storing the value with its hash, then obtaining the values via an oracle and verifying them against the hash. This results in in a fewer tree inclusion proofs for values `T` that are packed into more than a single field. From 630b045a1cb9256d55dc21ed7457d525118ef095 Mon Sep 17 00:00:00 2001 From: benesjan Date: Wed, 5 Feb 2025 17:10:16 +0000 Subject: [PATCH 07/14] docs --- .../aztec/src/state_vars/public_immutable.nr | 18 ++++++++++++++++++ .../contracts/amm_contract/src/config.nr | 3 +-- .../app_subscription_contract/src/config.nr | 4 +++- .../crowdfunding_contract/src/config.nr | 2 ++ .../contracts/fpc_contract/src/config.nr | 2 ++ .../token_bridge_contract/src/config.nr | 2 ++ 6 files changed, 28 insertions(+), 3 deletions(-) diff --git a/noir-projects/aztec-nr/aztec/src/state_vars/public_immutable.nr b/noir-projects/aztec-nr/aztec/src/state_vars/public_immutable.nr index 012a0592d2c..918d4bb90a3 100644 --- a/noir-projects/aztec-nr/aztec/src/state_vars/public_immutable.nr +++ b/noir-projects/aztec-nr/aztec/src/state_vars/public_immutable.nr @@ -14,6 +14,24 @@ use dep::protocol_types::{constants::INITIALIZATION_SLOT_SEPARATOR, traits::Pack /// /// This is valuable when T packs to multiple fields, as it maintains "almost constant" verification overhead /// regardless of the original data size. +/// +/// # Optimizing number of reads +/// Given that reading T from public immutable has "almost constant" constraints cost for different sizes of T +/// it is recommended to group multiple values into a single struct when they are being read together. This can +/// typically be some kind of configuration set up during contract initialization. E.g.: +/// +/// ```noir +/// use dep::aztec::protocol_types::{address::AztecAddress, traits::Packable}; +/// use std::meta::derive; +/// +/// #[derive(Eq, Packable)] +/// pub struct Config { +/// pub address_1: AztecAddress, +/// pub value_1: U128, +/// pub value_2: u64, +/// ... +/// } +/// // docs:start:public_immutable_struct pub struct PublicImmutable { context: Context, diff --git a/noir-projects/noir-contracts/contracts/amm_contract/src/config.nr b/noir-projects/noir-contracts/contracts/amm_contract/src/config.nr index fe43bb564c3..3448e4fba33 100644 --- a/noir-projects/noir-contracts/contracts/amm_contract/src/config.nr +++ b/noir-projects/noir-contracts/contracts/amm_contract/src/config.nr @@ -1,9 +1,8 @@ use dep::aztec::protocol_types::{address::AztecAddress, traits::{Deserialize, Packable, Serialize}}; use std::meta::derive; -/// We store the tokens of the pool in a struct such that to load it from SharedImmutable asserts only a single +/// We store the tokens of the pool in a struct such that to load it from PublicImmutable asserts only a single /// merkle proof. -/// (Once we actually do the optimization. WIP in https://github.com/AztecProtocol/aztec-packages/pull/8022). #[derive(Deserialize, Eq, Packable, Serialize)] pub struct Config { pub token0: AztecAddress, diff --git a/noir-projects/noir-contracts/contracts/app_subscription_contract/src/config.nr b/noir-projects/noir-contracts/contracts/app_subscription_contract/src/config.nr index 054bba7da19..ffb280d2f7f 100644 --- a/noir-projects/noir-contracts/contracts/app_subscription_contract/src/config.nr +++ b/noir-projects/noir-contracts/contracts/app_subscription_contract/src/config.nr @@ -1,6 +1,8 @@ -use dep::aztec::protocol_types::{address::AztecAddress, traits::{Deserialize, Packable, Serialize}}; +use dep::aztec::protocol_types::{address::AztecAddress, traits::Packable}; use std::meta::derive; +/// We store the values in a struct such that to load it from PublicImmutable asserts only a single +/// merkle proof. #[derive(Eq, Packable)] pub struct Config { pub target_address: AztecAddress, diff --git a/noir-projects/noir-contracts/contracts/crowdfunding_contract/src/config.nr b/noir-projects/noir-contracts/contracts/crowdfunding_contract/src/config.nr index 4e96a54d93c..1484375e879 100644 --- a/noir-projects/noir-contracts/contracts/crowdfunding_contract/src/config.nr +++ b/noir-projects/noir-contracts/contracts/crowdfunding_contract/src/config.nr @@ -1,6 +1,8 @@ use dep::aztec::protocol_types::{address::AztecAddress, traits::Packable}; use std::meta::derive; +/// We store the values in a struct such that to load it from PublicImmutable asserts only a single +/// merkle proof. #[derive(Eq, Packable)] pub struct Config { pub donation_token: AztecAddress, // Token used for donations (e.g. DAI) diff --git a/noir-projects/noir-contracts/contracts/fpc_contract/src/config.nr b/noir-projects/noir-contracts/contracts/fpc_contract/src/config.nr index fbf1b50eecd..41ff27c9af0 100644 --- a/noir-projects/noir-contracts/contracts/fpc_contract/src/config.nr +++ b/noir-projects/noir-contracts/contracts/fpc_contract/src/config.nr @@ -1,6 +1,8 @@ use dep::aztec::protocol_types::{address::AztecAddress, traits::{Deserialize, Packable, Serialize}}; use std::meta::derive; +/// We store the addresses in a struct such that to load it from PublicImmutable asserts only a single +/// merkle proof. #[derive(Deserialize, Eq, Packable, Serialize)] pub struct Config { pub accepted_asset: AztecAddress, // Asset the FPC accepts (denoted as AA below) diff --git a/noir-projects/noir-contracts/contracts/token_bridge_contract/src/config.nr b/noir-projects/noir-contracts/contracts/token_bridge_contract/src/config.nr index 0745cbcc45e..13b7177e955 100644 --- a/noir-projects/noir-contracts/contracts/token_bridge_contract/src/config.nr +++ b/noir-projects/noir-contracts/contracts/token_bridge_contract/src/config.nr @@ -4,6 +4,8 @@ use dep::aztec::protocol_types::{ }; use std::meta::derive; +/// We store the values in a struct such that to load it from PublicImmutable asserts only a single +/// merkle proof. #[derive(Deserialize, Eq, Packable, Serialize)] pub struct Config { pub token: AztecAddress, From f4ab918ec4d17b6983bf184709c5def0c577d094 Mon Sep 17 00:00:00 2001 From: benesjan Date: Wed, 5 Feb 2025 17:16:57 +0000 Subject: [PATCH 08/14] docs fix --- .../aztec-nr/aztec/src/state_vars/public_immutable.nr | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/noir-projects/aztec-nr/aztec/src/state_vars/public_immutable.nr b/noir-projects/aztec-nr/aztec/src/state_vars/public_immutable.nr index 918d4bb90a3..e014d900fb1 100644 --- a/noir-projects/aztec-nr/aztec/src/state_vars/public_immutable.nr +++ b/noir-projects/aztec-nr/aztec/src/state_vars/public_immutable.nr @@ -15,9 +15,9 @@ use dep::protocol_types::{constants::INITIALIZATION_SLOT_SEPARATOR, traits::Pack /// This is valuable when T packs to multiple fields, as it maintains "almost constant" verification overhead /// regardless of the original data size. /// -/// # Optimizing number of reads -/// Given that reading T from public immutable has "almost constant" constraints cost for different sizes of T -/// it is recommended to group multiple values into a single struct when they are being read together. This can +/// # Optimizing private reads in your contract +/// Given that reading T from public immutable in private has "almost constant" constraints cost for different sizes +/// of T it is recommended to group multiple values into a single struct when they are being read together. This can /// typically be some kind of configuration set up during contract initialization. E.g.: /// /// ```noir From 8d7105bd730ee6c25fd11671761513614ee3a272 Mon Sep 17 00:00:00 2001 From: benesjan Date: Wed, 5 Feb 2025 17:28:40 +0000 Subject: [PATCH 09/14] fixing docs --- .../writing_contracts/common_patterns/index.md | 11 ++++------- .../token_bridge/3_withdrawing_to_l1.md | 4 ++-- .../contract_tutorials/uniswap/l2_contract.md | 8 +------- .../contracts/token_bridge_contract/src/main.nr | 4 ++++ 4 files changed, 11 insertions(+), 16 deletions(-) diff --git a/docs/docs/developers/guides/smart_contracts/writing_contracts/common_patterns/index.md b/docs/docs/developers/guides/smart_contracts/writing_contracts/common_patterns/index.md index 27519369e91..507fb9c3449 100644 --- a/docs/docs/developers/guides/smart_contracts/writing_contracts/common_patterns/index.md +++ b/docs/docs/developers/guides/smart_contracts/writing_contracts/common_patterns/index.md @@ -39,16 +39,14 @@ Note - you could also create a note and send it to the user. The problem is ther ### Reading public storage in private -You can't read public storage in private domain. But nevertheless reading public storage is desirable. There are two ways to achieve the desired effect: +You can read public storage in private domain by leveraging the private getters of `PublicImmutable` (for values that never change) and `SharedMutable` (for values that change infrequently, see [shared state](../../../../reference/smart_contract_reference/storage/shared_state.md) for details) state variables. -1. For public values that change infrequently, you can use [shared state](../../../../reference/smart_contract_reference/storage/shared_state.md). - -1. You pass the data as a parameter to your private method and later assert in public that the data is correct. E.g.: +E.g. when using `PublicImmutable` ```rust #[storage] struct Storage { - token: PublicMutable, + config: PublicImmutable, } contract Bridge { @@ -59,9 +57,8 @@ contract Bridge { amount: Field, ) -> Field { ... - #include_code call_assert_token_is_same /noir-projects/noir-contracts/contracts/token_bridge_contract/src/main.nr raw - } #include_code assert_token_is_same /noir-projects/noir-contracts/contracts/token_bridge_contract/src/main.nr raw + } } ``` diff --git a/docs/docs/developers/tutorials/codealong/contract_tutorials/token_bridge/3_withdrawing_to_l1.md b/docs/docs/developers/tutorials/codealong/contract_tutorials/token_bridge/3_withdrawing_to_l1.md index daf6967280c..cac5c058289 100644 --- a/docs/docs/developers/tutorials/codealong/contract_tutorials/token_bridge/3_withdrawing_to_l1.md +++ b/docs/docs/developers/tutorials/codealong/contract_tutorials/token_bridge/3_withdrawing_to_l1.md @@ -55,11 +55,11 @@ We also use a `_withCaller` parameter to determine the appropriate party that ca We call this pattern _designed caller_ which enables a new paradigm **where we can construct other such portals that talk to the token portal and therefore create more seamless crosschain legos** between L1 and L2. -Before we can compile and use the contract, we need to add two additional functions. +Before we can compile and use the contract, we need to add 1 additional function. We need a function that lets us read the token value. Paste this into `main.nr`: -#include_code get_token /noir-projects/noir-contracts/contracts/token_bridge_contract/src/main.nr rust +#include_code get_config /noir-projects/noir-contracts/contracts/token_bridge_contract/src/main.nr rust ## Compile code diff --git a/docs/docs/developers/tutorials/codealong/contract_tutorials/uniswap/l2_contract.md b/docs/docs/developers/tutorials/codealong/contract_tutorials/uniswap/l2_contract.md index 597755f9a5e..e448ead8861 100644 --- a/docs/docs/developers/tutorials/codealong/contract_tutorials/uniswap/l2_contract.md +++ b/docs/docs/developers/tutorials/codealong/contract_tutorials/uniswap/l2_contract.md @@ -3,7 +3,7 @@ title: L2 Contracts (Aztec) sidebar_position: 1 --- -This page goes over the code in the L2 contract for Uniswap, which works alongside a [token bridge (codealong tutorial)](../token_bridge/index.md). +This page goes over the code in the L2 contract for Uniswap, which works alongside a [token bridge (codealong tutorial)](../token_bridge/index.md). ## Main.nr @@ -57,12 +57,6 @@ Both public and private swap functions call this function: #include_code authwit_uniswap_set noir-projects/noir-contracts/contracts/uniswap_contract/src/main.nr rust -### Assertions - -#include_code assert_token_is_same noir-projects/noir-contracts/contracts/uniswap_contract/src/main.nr rust - -This is a simple function that asserts that the token passed in to the function is the one that the bridge is associated with. - ## Utils ### Compute content hash for public diff --git a/noir-projects/noir-contracts/contracts/token_bridge_contract/src/main.nr b/noir-projects/noir-contracts/contracts/token_bridge_contract/src/main.nr index f95c3570e26..aa54d0de062 100644 --- a/noir-projects/noir-contracts/contracts/token_bridge_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/token_bridge_contract/src/main.nr @@ -40,11 +40,13 @@ pub contract TokenBridge { } // docs:end:token_bridge_storage_and_constructor + // docs:start:get_config #[private] #[view] fn get_config() -> Config { storage.config.read() } + // docs:end:get_config #[public] #[view] @@ -131,10 +133,12 @@ pub contract TokenBridge { caller_on_l1: EthAddress, // ethereum address that can call this function on the L1 portal (0x0 if anyone can call) nonce: Field, // nonce used in the approval message by `msg.sender` to let bridge burn their tokens on L2 ) { + // docs:start:assert_token_is_same let config = storage.config.read(); // Assert that user provided token address is same as seen in storage. assert_eq(config.token, token, "Token address is not the same as seen in storage"); + // docs:end:assert_token_is_same // Send an L2 to L1 message let content = get_withdraw_content_hash(recipient, amount, caller_on_l1); From 4f6cebff591cec74ef4bae93e25e4389590929c1 Mon Sep 17 00:00:00 2001 From: benesjan Date: Wed, 5 Feb 2025 17:31:28 +0000 Subject: [PATCH 10/14] better docs --- .../smart_contracts/writing_contracts/common_patterns/index.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/docs/developers/guides/smart_contracts/writing_contracts/common_patterns/index.md b/docs/docs/developers/guides/smart_contracts/writing_contracts/common_patterns/index.md index 507fb9c3449..c2b723a9d06 100644 --- a/docs/docs/developers/guides/smart_contracts/writing_contracts/common_patterns/index.md +++ b/docs/docs/developers/guides/smart_contracts/writing_contracts/common_patterns/index.md @@ -40,6 +40,7 @@ Note - you could also create a note and send it to the user. The problem is ther ### Reading public storage in private You can read public storage in private domain by leveraging the private getters of `PublicImmutable` (for values that never change) and `SharedMutable` (for values that change infrequently, see [shared state](../../../../reference/smart_contract_reference/storage/shared_state.md) for details) state variables. +Values that change frequently (`PublicMutable`) cannot be read in private as for those we need access to the tip of the chain and only the sequencer has access to that (and sequencer executes only public functions). E.g. when using `PublicImmutable` From 0b010dc3a19905d692976d2bd0fbce6592d0a3df Mon Sep 17 00:00:00 2001 From: benesjan Date: Wed, 5 Feb 2025 17:33:38 +0000 Subject: [PATCH 11/14] papaya --- .../smart_contracts/writing_contracts/common_patterns/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/developers/guides/smart_contracts/writing_contracts/common_patterns/index.md b/docs/docs/developers/guides/smart_contracts/writing_contracts/common_patterns/index.md index c2b723a9d06..fd82ae2210d 100644 --- a/docs/docs/developers/guides/smart_contracts/writing_contracts/common_patterns/index.md +++ b/docs/docs/developers/guides/smart_contracts/writing_contracts/common_patterns/index.md @@ -40,7 +40,7 @@ Note - you could also create a note and send it to the user. The problem is ther ### Reading public storage in private You can read public storage in private domain by leveraging the private getters of `PublicImmutable` (for values that never change) and `SharedMutable` (for values that change infrequently, see [shared state](../../../../reference/smart_contract_reference/storage/shared_state.md) for details) state variables. -Values that change frequently (`PublicMutable`) cannot be read in private as for those we need access to the tip of the chain and only the sequencer has access to that (and sequencer executes only public functions). +Values that change frequently (`PublicMutable`) cannot be read in private as for those we need access to the tip of the chain and only a sequencer has access to that (and sequencer executes only public functions). E.g. when using `PublicImmutable` From fa9c3e7942284f72ed40dd1cedba9ec1d8e5b106 Mon Sep 17 00:00:00 2001 From: benesjan Date: Wed, 5 Feb 2025 18:55:48 +0000 Subject: [PATCH 12/14] inserting stupid slash so that docs compiler shuts up --- .../aztec-nr/aztec/src/state_vars/public_immutable.nr | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/noir-projects/aztec-nr/aztec/src/state_vars/public_immutable.nr b/noir-projects/aztec-nr/aztec/src/state_vars/public_immutable.nr index e014d900fb1..bb27e1379b2 100644 --- a/noir-projects/aztec-nr/aztec/src/state_vars/public_immutable.nr +++ b/noir-projects/aztec-nr/aztec/src/state_vars/public_immutable.nr @@ -25,12 +25,13 @@ use dep::protocol_types::{constants::INITIALIZATION_SLOT_SEPARATOR, traits::Pack /// use std::meta::derive; /// /// #[derive(Eq, Packable)] -/// pub struct Config { +/// pub struct Config \{ /// pub address_1: AztecAddress, /// pub value_1: U128, /// pub value_2: u64, /// ... /// } +/// ``` /// // docs:start:public_immutable_struct pub struct PublicImmutable { From ba442e7933242895edcc1d9d9c11056bf31219a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Bene=C5=A1?= Date: Thu, 6 Feb 2025 12:47:13 +0100 Subject: [PATCH 13/14] Update noir-projects/noir-contracts/contracts/app_subscription_contract/src/config.nr MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Nicolás Venturo --- .../contracts/app_subscription_contract/src/config.nr | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/noir-projects/noir-contracts/contracts/app_subscription_contract/src/config.nr b/noir-projects/noir-contracts/contracts/app_subscription_contract/src/config.nr index ffb280d2f7f..1fd76cbd9e0 100644 --- a/noir-projects/noir-contracts/contracts/app_subscription_contract/src/config.nr +++ b/noir-projects/noir-contracts/contracts/app_subscription_contract/src/config.nr @@ -1,8 +1,8 @@ use dep::aztec::protocol_types::{address::AztecAddress, traits::Packable}; use std::meta::derive; -/// We store the values in a struct such that to load it from PublicImmutable asserts only a single -/// merkle proof. +// We store the values in a struct such that to load it from PublicImmutable asserts only a single +// merkle proof. #[derive(Eq, Packable)] pub struct Config { pub target_address: AztecAddress, From 420d10a39e22fcfc4db0e827cfc3409bcce363ed Mon Sep 17 00:00:00 2001 From: benesjan Date: Thu, 6 Feb 2025 11:49:48 +0000 Subject: [PATCH 14/14] updated comments --- .../contracts/app_subscription_contract/src/config.nr | 4 ++-- .../contracts/crowdfunding_contract/src/config.nr | 4 ++-- .../contracts/token_bridge_contract/src/config.nr | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/noir-projects/noir-contracts/contracts/app_subscription_contract/src/config.nr b/noir-projects/noir-contracts/contracts/app_subscription_contract/src/config.nr index 1fd76cbd9e0..908b4bec409 100644 --- a/noir-projects/noir-contracts/contracts/app_subscription_contract/src/config.nr +++ b/noir-projects/noir-contracts/contracts/app_subscription_contract/src/config.nr @@ -1,8 +1,8 @@ use dep::aztec::protocol_types::{address::AztecAddress, traits::Packable}; use std::meta::derive; -// We store the values in a struct such that to load it from PublicImmutable asserts only a single -// merkle proof. +// PublicImmutable has constant read cost in private regardless of the size of what it stores, so we put all immutable +// values in a single struct #[derive(Eq, Packable)] pub struct Config { pub target_address: AztecAddress, diff --git a/noir-projects/noir-contracts/contracts/crowdfunding_contract/src/config.nr b/noir-projects/noir-contracts/contracts/crowdfunding_contract/src/config.nr index 1484375e879..72451ced5bf 100644 --- a/noir-projects/noir-contracts/contracts/crowdfunding_contract/src/config.nr +++ b/noir-projects/noir-contracts/contracts/crowdfunding_contract/src/config.nr @@ -1,8 +1,8 @@ use dep::aztec::protocol_types::{address::AztecAddress, traits::Packable}; use std::meta::derive; -/// We store the values in a struct such that to load it from PublicImmutable asserts only a single -/// merkle proof. +// PublicImmutable has constant read cost in private regardless of the size of what it stores, so we put all immutable +// values in a single struct #[derive(Eq, Packable)] pub struct Config { pub donation_token: AztecAddress, // Token used for donations (e.g. DAI) diff --git a/noir-projects/noir-contracts/contracts/token_bridge_contract/src/config.nr b/noir-projects/noir-contracts/contracts/token_bridge_contract/src/config.nr index 13b7177e955..d67d08b2887 100644 --- a/noir-projects/noir-contracts/contracts/token_bridge_contract/src/config.nr +++ b/noir-projects/noir-contracts/contracts/token_bridge_contract/src/config.nr @@ -4,8 +4,8 @@ use dep::aztec::protocol_types::{ }; use std::meta::derive; -/// We store the values in a struct such that to load it from PublicImmutable asserts only a single -/// merkle proof. +// PublicImmutable has constant read cost in private regardless of the size of what it stores, so we put all immutable +// values in a single struct #[derive(Deserialize, Eq, Packable, Serialize)] pub struct Config { pub token: AztecAddress,