diff --git a/l1-contracts/test/portals/TokenPortal.sol b/l1-contracts/test/portals/TokenPortal.sol index 674b007ce95d..495ccc8334aa 100644 --- a/l1-contracts/test/portals/TokenPortal.sol +++ b/l1-contracts/test/portals/TokenPortal.sol @@ -22,11 +22,7 @@ contract TokenPortal { ); event DepositToAztecPrivate( - bytes32 secretHashForRedeemingMintedNotes, - uint256 amount, - bytes32 secretHashForL2MessageConsumption, - bytes32 key, - uint256 index + uint256 amount, bytes32 secretHashForL2MessageConsumption, bytes32 key, uint256 index ); IRegistry public registry; @@ -76,26 +72,21 @@ contract TokenPortal { // docs:start:deposit_private /** * @notice Deposit funds into the portal and adds an L2 message which can only be consumed privately on Aztec - * @param _secretHashForRedeemingMintedNotes - The hash of the secret to redeem minted notes privately on Aztec. The hash should be 254 bits (so it can fit in a Field element) * @param _amount - The amount to deposit * @param _secretHashForL2MessageConsumption - The hash of the secret consumable L1 to L2 message. The hash should be 254 bits (so it can fit in a Field element) * @return The key of the entry in the Inbox and its leaf index */ - function depositToAztecPrivate( - bytes32 _secretHashForRedeemingMintedNotes, - uint256 _amount, - bytes32 _secretHashForL2MessageConsumption - ) external returns (bytes32, uint256) { + function depositToAztecPrivate(uint256 _amount, bytes32 _secretHashForL2MessageConsumption) + external + returns (bytes32, uint256) + { // Preamble IInbox inbox = IRollup(registry.getRollup()).INBOX(); DataStructures.L2Actor memory actor = DataStructures.L2Actor(l2Bridge, 1); // Hash the message content to be reconstructed in the receiving contract - bytes32 contentHash = Hash.sha256ToField( - abi.encodeWithSignature( - "mint_private(bytes32,uint256)", _secretHashForRedeemingMintedNotes, _amount - ) - ); + bytes32 contentHash = + Hash.sha256ToField(abi.encodeWithSignature("mint_private(uint256)", _amount)); // Hold the tokens in the portal underlying.safeTransferFrom(msg.sender, address(this), _amount); @@ -105,9 +96,7 @@ contract TokenPortal { inbox.sendL2Message(actor, contentHash, _secretHashForL2MessageConsumption); // Emit event - emit DepositToAztecPrivate( - _secretHashForRedeemingMintedNotes, _amount, _secretHashForL2MessageConsumption, key, index - ); + emit DepositToAztecPrivate(_amount, _secretHashForL2MessageConsumption, key, index); return (key, index); } diff --git a/l1-contracts/test/portals/TokenPortal.t.sol b/l1-contracts/test/portals/TokenPortal.t.sol index 51df3054a537..a82d9ff249d4 100644 --- a/l1-contracts/test/portals/TokenPortal.t.sol +++ b/l1-contracts/test/portals/TokenPortal.t.sol @@ -49,9 +49,6 @@ contract TokenPortalTest is Test { // this hash is just a random 32 byte string bytes32 internal secretHashForL2MessageConsumption = 0x147e4fec49805c924e28150fc4b36824679bc17ecb1d7d9f6a9effb7fde6b6a0; - // this hash is just a random 32 byte string - bytes32 internal secretHashForRedeemingMintedNotes = - 0x157e4fec49805c924e28150fc4b36824679bc17ecb1d7d9f6a9effb7fde6b6a0; // params for withdraw: address internal recipient = address(0xdead); @@ -94,11 +91,7 @@ contract TokenPortalTest is Test { return DataStructures.L1ToL2Msg({ sender: DataStructures.L1Actor(address(tokenPortal), block.chainid), recipient: DataStructures.L2Actor(l2TokenAddress, 1), - content: Hash.sha256ToField( - abi.encodeWithSignature( - "mint_private(bytes32,uint256)", secretHashForRedeemingMintedNotes, amount - ) - ), + content: Hash.sha256ToField(abi.encodeWithSignature("mint_private(uint256)", amount)), secretHash: secretHashForL2MessageConsumption, index: _index }); @@ -137,9 +130,8 @@ contract TokenPortalTest is Test { // event we will get // Perform op - (bytes32 leaf, uint256 index) = tokenPortal.depositToAztecPrivate( - secretHashForRedeemingMintedNotes, amount, secretHashForL2MessageConsumption - ); + (bytes32 leaf, uint256 index) = + tokenPortal.depositToAztecPrivate(amount, secretHashForL2MessageConsumption); assertEq(leaf, expectedLeaf, "returned leaf and calculated leaf should match"); assertEq(index, expectedIndex, "returned index and calculated index should match"); diff --git a/l1-contracts/test/portals/UniswapPortal.sol b/l1-contracts/test/portals/UniswapPortal.sol index fc6bebd74a48..a4eb66d8b806 100644 --- a/l1-contracts/test/portals/UniswapPortal.sol +++ b/l1-contracts/test/portals/UniswapPortal.sol @@ -158,7 +158,6 @@ contract UniswapPortal { * @param _uniswapFeeTier - The fee tier for the swap on UniswapV3 * @param _outputTokenPortal - The ethereum address of the output token portal * @param _amountOutMinimum - The minimum amount of output assets to receive from the swap (slippage protection) - * @param _secretHashForRedeemingMintedNotes - The hash of the secret to redeem minted notes privately on Aztec. The hash should be 254 bits (so it can fit in a Field element) * @param _secretHashForL1ToL2Message - The hash of the secret consumable message. The hash should be 254 bits (so it can fit in a Field element) * @param _withCaller - When true, using `msg.sender` as the caller, otherwise address(0) * @return A hash of the L1 to L2 message inserted in the Inbox @@ -169,7 +168,6 @@ contract UniswapPortal { uint24 _uniswapFeeTier, address _outputTokenPortal, uint256 _amountOutMinimum, - bytes32 _secretHashForRedeemingMintedNotes, bytes32 _secretHashForL1ToL2Message, bool _withCaller, // Avoiding stack too deep @@ -195,13 +193,12 @@ contract UniswapPortal { // prevent stack too deep errors vars.contentHash = Hash.sha256ToField( abi.encodeWithSignature( - "swap_private(address,uint256,uint24,address,uint256,bytes32,bytes32,address)", + "swap_private(address,uint256,uint24,address,uint256,bytes32,address)", _inputTokenPortal, _inAmount, _uniswapFeeTier, _outputTokenPortal, _amountOutMinimum, - _secretHashForRedeemingMintedNotes, _secretHashForL1ToL2Message, _withCaller ? msg.sender : address(0) ) @@ -247,9 +244,8 @@ contract UniswapPortal { vars.outputAsset.approve(address(_outputTokenPortal), amountOut); // Deposit the output asset to the L2 via its portal - return TokenPortal(_outputTokenPortal).depositToAztecPrivate( - _secretHashForRedeemingMintedNotes, amountOut, _secretHashForL1ToL2Message - ); + return + TokenPortal(_outputTokenPortal).depositToAztecPrivate(amountOut, _secretHashForL1ToL2Message); } } // docs:end:solidity_uniswap_swap_private diff --git a/l1-contracts/test/portals/UniswapPortal.t.sol b/l1-contracts/test/portals/UniswapPortal.t.sol index 11783bead7d1..958f1d5d676e 100644 --- a/l1-contracts/test/portals/UniswapPortal.t.sol +++ b/l1-contracts/test/portals/UniswapPortal.t.sol @@ -44,7 +44,6 @@ contract UniswapPortalTest is Test { uint24 internal uniswapFeePool = 3000; // 0.3% fee uint256 internal amountOutMinimum = 0; bytes32 internal aztecRecipient = bytes32(uint256(0x3)); - bytes32 internal secretHashForRedeemingMintedNotes = bytes32(uint256(0x4)); uint256 internal l2BlockNumber = 69; @@ -140,26 +139,21 @@ contract UniswapPortalTest is Test { /** * L2 to L1 message to be added to the outbox - - * @param _secretHashForRedeemingMintedNotes - The hash of the secret to redeem minted notes privately on Aztec * @param _caller - designated caller on L1 that will call the swap function - typically address(this) * Set to address(0) if anyone can call. */ - function _createUniswapSwapMessagePrivate( - bytes32 _secretHashForRedeemingMintedNotes, - address _caller - ) internal view returns (bytes32) { + function _createUniswapSwapMessagePrivate(address _caller) internal view returns (bytes32) { DataStructures.L2ToL1Msg memory message = DataStructures.L2ToL1Msg({ sender: DataStructures.L2Actor(l2UniswapAddress, 1), recipient: DataStructures.L1Actor(address(uniswapPortal), block.chainid), content: Hash.sha256ToField( abi.encodeWithSignature( - "swap_private(address,uint256,uint24,address,uint256,bytes32,bytes32,address)", + "swap_private(address,uint256,uint24,address,uint256,bytes32,address)", address(daiTokenPortal), amount, uniswapFeePool, address(wethTokenPortal), amountOutMinimum, - _secretHashForRedeemingMintedNotes, secretHash, _caller ) @@ -572,8 +566,7 @@ contract UniswapPortalTest is Test { }) ]; - bytes32 messageHashPortalChecksAgainst = - _createUniswapSwapMessagePrivate(secretHashForRedeemingMintedNotes, address(this)); + bytes32 messageHashPortalChecksAgainst = _createUniswapSwapMessagePrivate(address(this)); bytes32 actualRoot; bytes32 consumedRoot; @@ -607,7 +600,6 @@ contract UniswapPortalTest is Test { uniswapFeePool, address(wethTokenPortal), amountOutMinimum, - secretHashForRedeemingMintedNotes, secretHash, true, outboxMessageMetadata diff --git a/noir-projects/noir-contracts/contracts/test_contract/src/main.nr b/noir-projects/noir-contracts/contracts/test_contract/src/main.nr index 8b745370265c..f6711c7f18c9 100644 --- a/noir-projects/noir-contracts/contracts/test_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/test_contract/src/main.nr @@ -386,7 +386,6 @@ contract Test { #[private] fn consume_mint_private_message( - secret_hash_for_redeeming_minted_notes: Field, amount: Field, secret_for_L1_to_L2_message_consumption: Field, portal_address: EthAddress, @@ -394,7 +393,7 @@ contract Test { ) { // Consume L1 to L2 message and emit nullifier let content_hash = - get_mint_private_content_hash(secret_hash_for_redeeming_minted_notes, amount); + get_mint_private_content_hash(amount); context.consume_l1_to_l2_message( content_hash, secret_for_L1_to_L2_message_consumption, 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 4ef9953c9388..fd77d309d79c 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 @@ -9,7 +9,7 @@ use dep::aztec::macros::aztec; #[aztec] contract TokenBridge { - use dep::aztec::prelude::{AztecAddress, EthAddress, PublicMutable, SharedImmutable}; + use dep::aztec::prelude::{AztecAddress, EthAddress, SharedImmutable}; use dep::token_portal_content_hash_lib::{ get_mint_private_content_hash, get_mint_public_content_hash, get_withdraw_content_hash, @@ -27,7 +27,7 @@ contract TokenBridge { // Storage structure, containing all storage, and specifying what slots they use. #[storage] struct Storage { - token: PublicMutable, + token: SharedImmutable, portal_address: SharedImmutable, } @@ -35,7 +35,7 @@ contract TokenBridge { #[public] #[initializer] fn constructor(token: AztecAddress, portal_address: EthAddress) { - storage.token.write(token); + storage.token.initialize(token); storage.portal_address.initialize(portal_address); } // docs:end:token_bridge_storage_and_constructor @@ -65,7 +65,7 @@ contract TokenBridge { ); // Mint tokens - Token::at(storage.token.read()).mint_public(to, amount).call(&mut context); + Token::at(storage.token.read_public()).mint_public(to, amount).call(&mut context); } // docs:end:claim_public @@ -84,25 +84,26 @@ contract TokenBridge { context.message_portal(storage.portal_address.read_public(), content); // Burn tokens - Token::at(storage.token.read()).burn_public(context.msg_sender(), amount, nonce).call( - &mut context, - ); + Token::at(storage.token.read_public()) + .burn_public(context.msg_sender(), amount, nonce) + .call(&mut context); } // docs:end:exit_to_l1_public + // docs:start:claim_private - // Consumes a L1->L2 message and calls the token contract to mint the appropriate amount in private assets - // User needs to call token.redeem_shield() to get the private assets - // TODO(#8416): Consider creating a truly private claim flow. + /// Claims the bridged tokens and makes them accessible in private. Note that recipient's address is not revealed + /// but the amount is. Hence it's most likely possible to determine to which L1 deposit this claim corresponds to + /// (unless there are multiple pending deposits of the same amount). + /// TODO(#8416): Consider creating a truly private claim flow. #[private] fn claim_private( - secret_hash_for_redeeming_minted_notes: Field, // secret hash used to redeem minted notes at a later time. This enables anyone to call this function and mint tokens to a user on their behalf + recipient: AztecAddress, // recipient of the bridged tokens amount: Field, secret_for_L1_to_L2_message_consumption: Field, // secret used to consume the L1 to L2 message message_leaf_index: Field, ) { // Consume L1 to L2 message and emit nullifier - let content_hash = - get_mint_private_content_hash(secret_hash_for_redeeming_minted_notes, amount); + let content_hash = get_mint_private_content_hash(amount); context.consume_l1_to_l2_message( content_hash, secret_for_L1_to_L2_message_consumption, @@ -110,16 +111,37 @@ contract TokenBridge { message_leaf_index, ); - // Mint tokens on L2 - // `mint_private` on token is public. So we call an internal public function - // which then calls the public method on the token contract. - // Since the secret_hash is passed, no secret is leaked. + // Read the token address from storage + let token_address = storage.token.read_private(); + + // Prepare the partial note for the minted tokens + let note_hiding_point_slot = + Token::at(token_address).prepare_transfer_to_private(recipient).call(&mut context); + + // We enqueue a public call in which we finalize the claim + // We pass the token address as an argument in order to not have to read it from public storage again. TokenBridge::at(context.this_address()) - ._call_mint_on_token(amount, secret_hash_for_redeeming_minted_notes) + ._finalize_private_claim(token_address, amount, note_hiding_point_slot) .enqueue(&mut context); } // docs:end:claim_private + #[public] + #[internal] + fn _finalize_private_claim( + token_address: AztecAddress, + amount: Field, + note_hiding_point_slot: Field, + ) { + let token = Token::at(token_address); + + // Mint the amount to this contract + token.mint_public(context.this_address(), amount).call(&mut context); + + // Transfer the publicly minted tokens to the partial note + token.finalize_transfer_to_private(amount, note_hiding_point_slot).call(&mut context); + } + // docs:start:exit_to_l1_private // Burns the appropriate amount of tokens and creates a L2 to L1 withdraw message privately // Requires `msg.sender` (caller of the method) to give approval to the bridge to burn tokens on their behalf using witness signatures @@ -147,26 +169,18 @@ contract TokenBridge { #[public] #[view] fn get_token() -> AztecAddress { - storage.token.read() + storage.token.read_public() } // docs:end:get_token - // docs:start:call_mint_on_token - // This is a public call as we need to read from public storage. - // Also, note that user hashes their secret in private and only sends the hash in public - // meaning only user can `redeem_shield` at a later time with their secret. - #[public] - #[internal] - fn _call_mint_on_token(amount: Field, secret_hash: Field) { - Token::at(storage.token.read()).mint_private_old(amount, secret_hash).call(&mut context); - } - // docs:end:call_mint_on_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"); + assert( + storage.token.read_public().eq(token), + "Token address is not the same as seen in storage", + ); } // docs:end:assert_token_is_same } diff --git a/noir-projects/noir-contracts/contracts/token_portal_content_hash_lib/src/lib.nr b/noir-projects/noir-contracts/contracts/token_portal_content_hash_lib/src/lib.nr index f7789aefcd58..c31f6c4e0a93 100644 --- a/noir-projects/noir-contracts/contracts/token_portal_content_hash_lib/src/lib.nr +++ b/noir-projects/noir-contracts/contracts/token_portal_content_hash_lib/src/lib.nr @@ -29,23 +29,20 @@ pub fn get_mint_public_content_hash(owner: AztecAddress, amount: Field) -> Field // Computes a content hash of a deposit/mint_private message. // Refer TokenPortal.sol for reference on L1. pub fn get_mint_private_content_hash( - secret_hash_for_redeeming_minted_notes: Field, amount: Field ) -> Field { - let mut hash_bytes = [0; 68]; - let secret_hash_bytes:[u8; 32] = secret_hash_for_redeeming_minted_notes.to_be_bytes(); + let mut hash_bytes = [0; 36]; let amount_bytes:[u8; 32] = amount.to_be_bytes(); for i in 0..32 { - hash_bytes[i + 4] = secret_hash_bytes[i]; - hash_bytes[i + 36] = amount_bytes[i]; + hash_bytes[i + 4] = amount_bytes[i]; } - // Function selector: 0xefa012c1 keccak256('mint_private(bytes32,uint256)') - hash_bytes[0] = 0xef; - hash_bytes[1] = 0xa0; - hash_bytes[2] = 0x12; - hash_bytes[3] = 0xc1; + // Function selector: 0xb81559e2 keccak256('mint_private(uint256)') + hash_bytes[0] = 0xb8; + hash_bytes[1] = 0x15; + hash_bytes[2] = 0x59; + hash_bytes[3] = 0xe2; let content_hash = sha256_to_field(hash_bytes); content_hash 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 a9219a45144f..f95c986983d8 100644 --- a/noir-projects/noir-contracts/contracts/uniswap_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/uniswap_contract/src/main.nr @@ -121,7 +121,6 @@ contract Uniswap { uniswap_fee_tier: Field, // which uniswap tier to use (eg 3000 for 0.3% fee) minimum_output_amount: Field, // minimum output amount to receive (slippage protection for the swap) // params for the depositing output_asset back to Aztec - secret_hash_for_redeeming_minted_notes: Field, // secret hash used to redeem minted notes at a later time. This enables anyone to call this function and mint tokens to a user on their behalf 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) ) { @@ -172,7 +171,6 @@ contract Uniswap { uniswap_fee_tier, output_asset_bridge_portal_address, minimum_output_amount, - secret_hash_for_redeeming_minted_notes, secret_hash_for_L1_to_l2_message, caller_on_L1, ); diff --git a/noir-projects/noir-contracts/contracts/uniswap_contract/src/util.nr b/noir-projects/noir-contracts/contracts/uniswap_contract/src/util.nr index 8d93994d6249..a0e2ca12774b 100644 --- a/noir-projects/noir-contracts/contracts/uniswap_contract/src/util.nr +++ b/noir-projects/noir-contracts/contracts/uniswap_contract/src/util.nr @@ -58,11 +58,10 @@ pub fn compute_swap_private_content_hash( uniswap_fee_tier: Field, output_asset_bridge_portal_address: EthAddress, minimum_output_amount: Field, - secret_hash_for_redeeming_minted_notes: Field, secret_hash_for_L1_to_l2_message: Field, caller_on_L1: EthAddress, ) -> Field { - let mut hash_bytes = [0; 260]; // 8 fields of 32 bytes each + 4 bytes fn selector + let mut hash_bytes = [0; 228]; // 7 fields of 32 bytes each + 4 bytes fn selector let input_token_portal_bytes: [u8; 32] = input_asset_bridge_portal_address.to_field().to_be_bytes(); let in_amount_bytes: [u8; 32] = input_amount.to_be_bytes(); @@ -70,17 +69,15 @@ pub fn compute_swap_private_content_hash( let output_token_portal_bytes: [u8; 32] = output_asset_bridge_portal_address.to_field().to_be_bytes(); let amount_out_min_bytes: [u8; 32] = minimum_output_amount.to_be_bytes(); - let secret_hash_for_redeeming_minted_notes_bytes: [u8; 32] = - secret_hash_for_redeeming_minted_notes.to_be_bytes(); let secret_hash_for_L1_to_l2_message_bytes: [u8; 32] = secret_hash_for_L1_to_l2_message.to_be_bytes(); let caller_on_L1_bytes: [u8; 32] = caller_on_L1.to_field().to_be_bytes(); - // function selector: 0x16f416eb keccak256("swap_private(address,uint256,uint24,address,uint256,bytes32,bytes32,address)") - hash_bytes[0] = 0x16; - hash_bytes[1] = 0xf4; - hash_bytes[2] = 0x16; - hash_bytes[3] = 0xeb; + // function selector: 0x84e55078 keccak256("swap_private(address,uint256,uint24,address,uint256,bytes32,address)") + hash_bytes[0] = 0x84; + hash_bytes[1] = 0xe5; + hash_bytes[2] = 0x50; + hash_bytes[3] = 0x78; for i in 0..32 { hash_bytes[i + 4] = input_token_portal_bytes[i]; @@ -88,9 +85,8 @@ pub fn compute_swap_private_content_hash( hash_bytes[i + 68] = uniswap_fee_tier_bytes[i]; hash_bytes[i + 100] = output_token_portal_bytes[i]; hash_bytes[i + 132] = amount_out_min_bytes[i]; - hash_bytes[i + 164] = secret_hash_for_redeeming_minted_notes_bytes[i]; - hash_bytes[i + 196] = secret_hash_for_L1_to_l2_message_bytes[i]; - hash_bytes[i + 228] = caller_on_L1_bytes[i]; + hash_bytes[i + 164] = secret_hash_for_L1_to_l2_message_bytes[i]; + hash_bytes[i + 196] = caller_on_L1_bytes[i]; } let content_hash = sha256_to_field(hash_bytes); content_hash diff --git a/yarn-project/aztec.js/src/index.ts b/yarn-project/aztec.js/src/index.ts index 525954709361..4fa48b1e7763 100644 --- a/yarn-project/aztec.js/src/index.ts +++ b/yarn-project/aztec.js/src/index.ts @@ -62,7 +62,7 @@ export { type FunctionSelectorLike, type L2AmountClaim, type L2Claim, - type L2RedeemableAmountClaim, + type L2AmountClaimWithRecipient as L2RedeemableAmountClaim, type WrappedFieldLike, } from './utils/index.js'; diff --git a/yarn-project/aztec.js/src/utils/portal_manager.ts b/yarn-project/aztec.js/src/utils/portal_manager.ts index 3953f32f54e8..344b4d398ace 100644 --- a/yarn-project/aztec.js/src/utils/portal_manager.ts +++ b/yarn-project/aztec.js/src/utils/portal_manager.ts @@ -38,10 +38,9 @@ export type L2Claim = { /** L1 to L2 message info that corresponds to an amount to claim. */ export type L2AmountClaim = L2Claim & { /** Amount to claim */ claimAmount: Fr }; -/** L1 to L2 message info that corresponds to an amount to claim with associated notes to be redeemed. */ -export type L2RedeemableAmountClaim = L2AmountClaim & { - /** Secret for redeeming the minted notes */ redeemSecret: Fr; - /** Hash of the redeem secret*/ redeemSecretHash: Fr; +/** L1 to L2 message info that corresponds to an amount to claim with associated recipient. */ +export type L2AmountClaimWithRecipient = L2AmountClaim & { + /** Address that will receive the newly minted notes. */ recipient: AztecAddress; }; /** Stringifies an eth address for logging. */ @@ -279,7 +278,7 @@ export class L1ToL2TokenPortalManager { * @param amount - Amount of tokens to send. * @param mint - Whether to mint the tokens before sending (only during testing). */ - public async bridgeTokensPrivate(to: AztecAddress, amount: bigint, mint = false): Promise { + public async bridgeTokensPrivate(to: AztecAddress, amount: bigint, mint = false): Promise { const [claimSecret, claimSecretHash] = await this.bridgeSetup(amount, mint); const redeemSecret = Fr.random(); @@ -301,7 +300,6 @@ export class L1ToL2TokenPortalManager { this.portal.abi, 'DepositToAztecPrivate', log => - log.args.secretHashForRedeemingMintedNotes === redeemSecretHash.toString() && log.args.amount === amount && log.args.secretHashForL2MessageConsumption === claimSecretHash.toString(), this.logger, @@ -313,8 +311,7 @@ export class L1ToL2TokenPortalManager { claimAmount: new Fr(amount), claimSecret, claimSecretHash, - redeemSecret, - redeemSecretHash, + recipient: to, messageHash: log.args.key, messageLeafIndex: log.args.index, }; 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 a32510fdb8a2..a7804ef10b19 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 @@ -256,16 +256,14 @@ export class CrossChainTestHarness { } async consumeMessageOnAztecAndMintPrivately( - claim: Pick, + claim: Pick, ) { this.logger.info('Consuming messages on L2 privately'); - const { claimAmount, claimSecret: secretForL2MessageConsumption, messageLeafIndex, redeemSecretHash } = claim; - const consumptionReceipt = await this.l2Bridge.methods - .claim_private(redeemSecretHash, claimAmount, secretForL2MessageConsumption, messageLeafIndex) + const { recipient, claimAmount, claimSecret: secretForL2MessageConsumption, messageLeafIndex } = claim; + await this.l2Bridge.methods + .claim_private(recipient, claimAmount, secretForL2MessageConsumption, messageLeafIndex) .send() .wait(); - - await this.addPendingShieldNoteToPXE(claimAmount.toBigInt(), redeemSecretHash, consumptionReceipt.txHash); } async consumeMessageOnAztecAndMintPublicly( @@ -364,11 +362,6 @@ export class CrossChainTestHarness { await this.ownerWallet.addNote(extendedNote); } - async redeemShieldPrivatelyOnL2(shieldAmount: bigint, secret: Fr) { - this.logger.info('Spending note in private call'); - await this.l2Token.methods.redeem_shield(this.ownerAddress, shieldAmount, secret).send().wait(); - } - async transferToPublicOnL2(amount: bigint, nonce = Fr.ZERO) { this.logger.info('Transferring tokens to public'); await this.l2Token.methods.transfer_to_public(this.ownerAddress, this.ownerAddress, amount, nonce).send().wait(); diff --git a/yarn-project/end-to-end/src/shared/uniswap_l1_l2.ts b/yarn-project/end-to-end/src/shared/uniswap_l1_l2.ts index d33bcb1ccab7..d50515324287 100644 --- a/yarn-project/end-to-end/src/shared/uniswap_l1_l2.ts +++ b/yarn-project/end-to-end/src/shared/uniswap_l1_l2.ts @@ -223,7 +223,6 @@ export const uniswapL1L2TestSuite = ( // 4. Swap on L1 - sends L2 to L1 message to withdraw WETH to L1 and another message to swap assets. logger.info('Withdrawing weth to L1 and sending message to swap to dai'); const [secretForDepositingSwappedDai, secretHashForDepositingSwappedDai] = generateClaimSecret(); - const [secretForRedeemingDai, secretHashForRedeemingDai] = generateClaimSecret(); const l2UniswapInteractionReceipt = await uniswapL2Contract.methods .swap_private( @@ -234,14 +233,13 @@ export const uniswapL1L2TestSuite = ( nonceForWETHTransferToPublicApproval, uniswapFeeTier, minimumOutputAmount, - secretHashForRedeemingDai, secretHashForDepositingSwappedDai, ownerEthAddress, ) .send() .wait(); - const swapPrivateFunction = 'swap_private(address,uint256,uint24,address,uint256,bytes32,bytes32,address)'; + const swapPrivateFunction = 'swap_private(address,uint256,uint24,address,uint256,bytes32,address)'; const swapPrivateContent = sha256ToField([ Buffer.from(toFunctionSelector(swapPrivateFunction).substring(2), 'hex'), wethCrossChainHarness.tokenPortalAddress.toBuffer32(), @@ -249,7 +247,6 @@ export const uniswapL1L2TestSuite = ( new Fr(uniswapFeeTier), daiCrossChainHarness.tokenPortalAddress.toBuffer32(), new Fr(minimumOutputAmount), - secretHashForRedeemingDai, secretHashForDepositingSwappedDai, ownerEthAddress.toBuffer32(), ]); @@ -322,7 +319,6 @@ export const uniswapL1L2TestSuite = ( Number(uniswapFeeTier), daiCrossChainHarness.tokenPortalAddress.toString(), minimumOutputAmount, - secretHashForRedeemingDai.toString(), secretHashForDepositingSwappedDai.toString(), true, [withdrawMessageMetadata, swapPrivateMessageMetadata], @@ -352,12 +348,10 @@ export const uniswapL1L2TestSuite = ( // 6. claim dai on L2 logger.info('Consuming messages to mint dai on L2'); await daiCrossChainHarness.consumeMessageOnAztecAndMintPrivately({ - redeemSecretHash: secretHashForRedeemingDai, claimAmount: new Fr(daiAmountToBridge), claimSecret: secretForDepositingSwappedDai, messageLeafIndex: tokenOutMsgIndex, }); - await daiCrossChainHarness.redeemShieldPrivatelyOnL2(daiAmountToBridge, secretForRedeemingDai); await daiCrossChainHarness.expectPrivateBalanceOnL2(ownerAddress, daiL2BalanceBeforeSwap + daiAmountToBridge); const wethL2BalanceAfterSwap = await wethCrossChainHarness.getL2PrivateBalanceOf(ownerAddress); @@ -678,7 +672,6 @@ export const uniswapL1L2TestSuite = ( uniswapFeeTier, minimumOutputAmount, Fr.random(), - Fr.random(), ownerEthAddress, ) .prove(), @@ -824,7 +817,6 @@ export const uniswapL1L2TestSuite = ( // Swap logger.info('Withdrawing weth to L1 and sending message to swap to dai'); - const [, secretHashForRedeemingDai] = generateClaimSecret(); const [, secretHashForDepositingSwappedDai] = generateClaimSecret(); const withdrawReceipt = await uniswapL2Contract.methods @@ -836,7 +828,6 @@ export const uniswapL1L2TestSuite = ( nonceForWETHTransferToPublicApproval, uniswapFeeTier, minimumOutputAmount, - secretHashForRedeemingDai, secretHashForDepositingSwappedDai, ownerEthAddress, ) @@ -845,7 +836,7 @@ export const uniswapL1L2TestSuite = ( const swapPrivateContent = sha256ToField([ Buffer.from( - toFunctionSelector('swap_private(address,uint256,uint24,address,uint256,bytes32,bytes32,address)').substring( + toFunctionSelector('swap_private(address,uint256,uint24,address,uint256,bytes32,address)').substring( 2, ), 'hex', @@ -855,7 +846,6 @@ export const uniswapL1L2TestSuite = ( new Fr(uniswapFeeTier), daiCrossChainHarness.tokenPortalAddress.toBuffer32(), new Fr(minimumOutputAmount), - secretHashForRedeemingDai, secretHashForDepositingSwappedDai, ownerEthAddress.toBuffer32(), ]); @@ -1049,7 +1039,6 @@ export const uniswapL1L2TestSuite = ( await rollup.write.setAssumeProvenThroughBlockNumber([await rollup.read.getPendingBlockNumber()]); // Call swap_private on L1 - const secretHashForRedeemingDai = Fr.random(); // creating my own secret hash logger.info('Execute withdraw and swap on the uniswapPortal!'); const swapArgs = [ @@ -1058,7 +1047,6 @@ export const uniswapL1L2TestSuite = ( Number(uniswapFeeTier), daiCrossChainHarness.tokenPortalAddress.toString(), minimumOutputAmount, - secretHashForRedeemingDai.toString(), secretHashForDepositingSwappedDai.toString(), true, [withdrawMessageMetadata, swapPublicMessageMetadata], diff --git a/yarn-project/protocol-contracts/src/protocol_contract_data.ts b/yarn-project/protocol-contracts/src/protocol_contract_data.ts index 7eb1cdc3397b..b5a9f3c96232 100644 --- a/yarn-project/protocol-contracts/src/protocol_contract_data.ts +++ b/yarn-project/protocol-contracts/src/protocol_contract_data.ts @@ -50,14 +50,14 @@ export const ProtocolContractAddress: Record }; export const ProtocolContractLeaf = { - AuthRegistry: Fr.fromString('0x0931f3bf89563f3898ae9650851083cd560ad800c2e3c561c3853eec4dd7ea8b'), - ContractInstanceDeployer: Fr.fromString('0x266ea4c9917455daa905c1dd1a10753714c6d0369b6f2fe23feeca6de556d164'), - ContractClassRegisterer: Fr.fromString('0x1ccb7a219f72a851089e956d527997b01068d5a28c9ae96b35ebeb45f068af23'), - MultiCallEntrypoint: Fr.fromString('0x1d060217817cf472a579638db722903fd1bbc4c3bdb0ecefa5694c0d4eed851a'), - FeeJuice: Fr.fromString('0x1dab5b687d0c04d2f17a1c8623dea23e7416700891ba1c6e0e86ef678f4727cb'), - Router: Fr.fromString('0x00827d5a8aedb9627d9e5de04735600a4dbb817d4a2f51281aab991699f5de99'), + AuthRegistry: Fr.fromString('0x1a129d5eeeb6eed1139d24c108050f941a6cc4cbe91a844dc10c40f4c1513b14'), + ContractInstanceDeployer: Fr.fromString('0x01314b6c482a9d8f5418cd0d43c17a1c5899ae7c2e1d2f82817baaf3f3b45bd9'), + ContractClassRegisterer: Fr.fromString('0x04b3be8e2240fc0f0a2fd5d8072afabc406e79bebefc6236d20600072246a326'), + MultiCallEntrypoint: Fr.fromString('0x20a2e7e882045d27b3aa9e36188b8e45483b3c11652d4a46406699e5eb4efa9b'), + FeeJuice: Fr.fromString('0x0edb9dfdcacb06d81507ad6b95d0789a5dbd217424b000f056034ea8fadd07c2'), + Router: Fr.fromString('0x195eb06e13bd2a704f50a8480aa66a30e0913e73daa453fc2bea2ab880855dae'), }; export const protocolContractTreeRoot = Fr.fromString( - '0x0f174f6837842b1004a9a41dd736800c12c5dc19f206aed35551b07f8ca6edfb', + '0x28c4676f6233fc2adf42179f2a5fec7d8cae9efa6344ade2fd0db8ed9ac386da', );