Skip to content

Commit

Permalink
refactor: portal managers in cli
Browse files Browse the repository at this point in the history
new private claim flow
  • Loading branch information
sklppy88 committed Aug 20, 2024
1 parent aad1faf commit cf95217
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,15 @@ contract TokenBridge {
// Storage structure, containing all storage, and specifying what slots they use.
#[aztec(storage)]
struct Storage {
token: PublicMutable<AztecAddress>,
token: SharedImmutable<AztecAddress>,
portal_address: SharedImmutable<EthAddress>,
}

// Constructs the contract.
#[aztec(public)]
#[aztec(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
Expand Down Expand Up @@ -55,7 +55,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

Expand All @@ -74,7 +74,7 @@ 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
Expand Down Expand Up @@ -102,6 +102,22 @@ contract TokenBridge {
}
// docs:end:claim_private

#[aztec(private)]
fn claim_private_for_caller(
amount: Field,
secret_for_L1_to_L2_message_consumption: Field // secret used to consume the L1 to L2 message
) {
// Consume L1 to L2 message and emit nullifier
let content_hash = get_mint_private_content_hash(0, amount);
context.consume_l1_to_l2_message(
content_hash,
secret_for_L1_to_L2_message_consumption,
storage.portal_address.read_private()
);

Token::at(storage.token.read_private()).mint_private_for(context.msg_sender(), amount).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
Expand Down Expand Up @@ -131,7 +147,7 @@ contract TokenBridge {
#[aztec(public)]
#[aztec(view)]
fn get_token() -> AztecAddress {
storage.token.read()
storage.token.read_public()
}
// docs:end:get_token

Expand All @@ -142,15 +158,15 @@ contract TokenBridge {
#[aztec(public)]
#[aztec(internal)]
fn _call_mint_on_token(amount: Field, secret_hash: Field) {
Token::at(storage.token.read()).mint_private(amount, secret_hash).call(&mut context);
Token::at(storage.token.read_public()).mint_private(amount, secret_hash).call(&mut context);
}
// docs:end:call_mint_on_token

// docs:start:assert_token_is_same
#[aztec(public)]
#[aztec(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
}
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,13 @@ contract Token {
}
// docs:end:mint_private

#[aztec(private)]
fn mint_private_for(to: AztecAddress, amount: Field) {
let minter = context.msg_sender();
storage.balances.add(to, U128::from_integer(amount)).emit(encode_and_encrypt_note(&mut context, minter, to));
Token::at(context.this_address()).assert_minter_and_mint(minter, amount).enqueue(&mut context);
}

// TODO: Nuke this - test functions do not belong to token contract!
#[aztec(private)]
fn privately_mint_private_note(amount: Field) {
Expand Down
3 changes: 2 additions & 1 deletion yarn-project/cli/src/cmds/l1/bridge_erc20.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export async function bridgeERC20(
tokenAddress: EthAddress,
portalAddress: EthAddress,
privateTransfer: boolean,
newPrivateTransfer: boolean,
mint: boolean,
json: boolean,
log: LogFn,
Expand All @@ -29,7 +30,7 @@ export async function bridgeERC20(
let claimSecret: Fr;
let messageHash: `0x${string}`;
if (privateTransfer) {
({ claimSecret, messageHash } = await manager.bridgeTokensPrivate(recipient, amount, mint));
({ claimSecret, messageHash } = await manager.bridgeTokensPrivate(recipient, amount, mint, newPrivateTransfer));
} else {
({ claimSecret, messageHash } = await manager.bridgeTokensPublic(recipient, amount, mint));
}
Expand Down
3 changes: 3 additions & 0 deletions yarn-project/cli/src/cmds/l1/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,8 @@ export function injectCommands(program: Command, log: LogFn, debugLogger: DebugL
)
.option('--mint', 'Mint the tokens on L1', false)
.option('--private', 'If the bridge should use the private flow', false)
// TODO (ek): remove this after testing
.option('--new-private', 'If the bridge should use the new private flow', false)
.addOption(l1ChainIdOption)
.requiredOption('-t, --token <string>', 'The address of the token to bridge', parseEthereumAddress)
.requiredOption('-p, --portal <string>', 'The address of the portal contract', parseEthereumAddress)
Expand All @@ -126,6 +128,7 @@ export function injectCommands(program: Command, log: LogFn, debugLogger: DebugL
options.token,
options.portal,
options.private,
options.newPrivate,
options.mint,
options.json,
log,
Expand Down
22 changes: 16 additions & 6 deletions yarn-project/cli/src/utils/portal_manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,18 +147,24 @@ export class L1PortalManager {
}

public bridgeTokensPublic(to: AztecAddress, amount: bigint, mint = false): Promise<L2Claim> {
return this.bridgeTokens(to, amount, mint, /* privateTransfer */ false);
return this.bridgeTokens(to, amount, mint, /* privateTransfer */ false, false);
}

public bridgeTokensPrivate(to: AztecAddress, amount: bigint, mint = false): Promise<L2Claim> {
return this.bridgeTokens(to, amount, mint, /* privateTransfer */ true);
public bridgeTokensPrivate(
to: AztecAddress,
amount: bigint,
mint = false,
newPrivateTransfer = false,
): Promise<L2Claim> {
return this.bridgeTokens(to, amount, mint, /* privateTransfer */ true, newPrivateTransfer);
}

private async bridgeTokens(
to: AztecAddress,
amount: bigint,
mint: boolean,
privateTransfer: boolean,
newPrivateTransfer: boolean,
): Promise<L2Claim> {
const [claimSecret, claimSecretHash] = generateClaimSecret();

Expand All @@ -175,19 +181,23 @@ export class L1PortalManager {
const secretHash = computeSecretHash(secret);
this.logger.info('Sending L1 tokens to L2 to be claimed privately');
({ result: messageHash } = await this.contract.simulate.depositToAztecPrivate([
secretHash.toString(),
newPrivateTransfer ? Fr.ZERO.toString() : secretHash.toString(),
amount,
claimSecretHash.toString(),
]));

await this.publicClient.waitForTransactionReceipt({
hash: await this.contract.write.depositToAztecPrivate([
secretHash.toString(),
newPrivateTransfer ? Fr.ZERO.toString() : secretHash.toString(),
amount,
claimSecretHash.toString(),
]),
});
this.logger.info(`Redeem shield secret: ${secret.toString()}, secret hash: ${secretHash.toString()}`);
this.logger.info(
newPrivateTransfer
? `Redeem shield secret: ${secret.toString()}, secret hash: ${secretHash.toString()}`
: 'Redeem bridged tokens with claim_private_for.',
);
} else {
this.logger.info('Sending L1 tokens to L2 to be claimed publicly');
({ result: messageHash } = await this.contract.simulate.depositToAztecPublic([
Expand Down

0 comments on commit cf95217

Please sign in to comment.