Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
323 changes: 46 additions & 277 deletions noir-projects/aztec-nr/aztec/src/context/call_interfaces.nr

Large diffs are not rendered by default.

346 changes: 344 additions & 2 deletions noir-projects/aztec-nr/aztec/src/contract_self.nr

Large diffs are not rendered by default.

87 changes: 43 additions & 44 deletions noir-projects/noir-contracts/contracts/app/amm_contract/src/main.nr
Original file line number Diff line number Diff line change
Expand Up @@ -104,29 +104,27 @@ pub contract AMM {
// We don't yet know how many tokens the sender will actually supply - that can only be computed during public
// execution since the amounts supplied must have the same ratio as the live balances. We therefore transfer the
// maximum amounts here, and prepare partial notes that return the change to the sender (if any).
let refund_token0_partial_note = token0
let refund_token0_partial_note = self.call(token0
.transfer_to_public_and_prepare_private_balance_increase(
sender,
self.address,
amount0_max,
authwit_nonce,
)
.call(self.context);
));

let refund_token1_partial_note = token1
let refund_token1_partial_note = self.call(token1
.transfer_to_public_and_prepare_private_balance_increase(
sender,
self.address,
amount1_max,
authwit_nonce,
)
.call(self.context);
));

// The number of liquidity tokens to mint for the caller depends on both the live balances and the amount
// supplied, both of which can only be known during public execution. We therefore prepare a partial note that
// will get completed via minting.
let liquidity_partial_note =
liquidity_token.prepare_private_balance_increase(sender).call(self.context);
self.call(liquidity_token.prepare_private_balance_increase(sender));

// We then complete the flow in public. Note that the type of operation and amounts will all be publicly known,
// but the identity of the caller is not revealed despite us being able to send tokens to them by completing the
Expand Down Expand Up @@ -162,10 +160,10 @@ pub contract AMM {
// We read the current AMM balance of both tokens. Note that by the time this function is called the token
// transfers have already been completed (since those calls were enqueued before this call), and so we need to
// subtract the transfer amount to get the pre-deposit balance.
let balance0_plus_amount0_max = token0.balance_of_public(self.address).view(self.context);
let balance0_plus_amount0_max = self.view(token0.balance_of_public(self.address));
let balance0 = balance0_plus_amount0_max - amount0_max;

let balance1_plus_amount1_max = token1.balance_of_public(self.address).view(self.context);
let balance1_plus_amount1_max = self.view(token1.balance_of_public(self.address));
let balance1 = balance1_plus_amount1_max - amount1_max;

// With the current balances known, we can calculate the token amounts to the pool, respecting the user's
Expand All @@ -186,19 +184,21 @@ pub contract AMM {
// We can simply skip the refund if the amount to return is 0 in order to save gas: the partial note will
// simply stay in public storage and not be completed, but this is not an issue.
if (refund_amount_token0 > 0 as u128) {
token0
.finalize_transfer_to_private(refund_amount_token0, refund_token0_partial_note)
.call(self.context);
self.call(token0.finalize_transfer_to_private(
refund_amount_token0,
refund_token0_partial_note,
));
}
if (refund_amount_token1 > 0 as u128) {
token1
.finalize_transfer_to_private(refund_amount_token1, refund_token1_partial_note)
.call(self.context);
self.call(token1.finalize_transfer_to_private(
refund_amount_token1,
refund_token1_partial_note,
));
}

// With the deposit amounts known, we can compute the number of liquidity tokens to mint and finalize the
// depositor's partial note.
let total_supply = liquidity_token.total_supply().view(self.context);
let total_supply = self.view(liquidity_token.total_supply());
let liquidity_amount = if total_supply != 0 as u128 {
// The liquidity token supply increases by the same ratio as the balances. In case one of the token balances
// increased with a ratio different from the other one, we simply take the smallest value.
Expand Down Expand Up @@ -254,16 +254,12 @@ pub contract AMM {
// a function to privately burn, so we instead transfer the tokens into the AMM's public balance, and then have
// the AMM publicly burn its own tokens.
// TODO(#10287): consider adding a private burn
liquidity_token.transfer_to_public(sender, self.address, liquidity, authwit_nonce).call(
self.context,
);
self.call(liquidity_token.transfer_to_public(sender, self.address, liquidity, authwit_nonce));

// We don't yet know how many tokens the sender will get - that can only be computed during public execution
// since the it depends on the live balances. We therefore simply prepare partial notes to the sender.
let token0_partial_note =
token0.prepare_private_balance_increase(sender).call(self.context);
let token1_partial_note =
token1.prepare_private_balance_increase(sender).call(self.context);
let token0_partial_note = self.call(token0.prepare_private_balance_increase(sender));
let token1_partial_note = self.call(token1.prepare_private_balance_increase(sender));

// We then complete the flow in public. Note that the type of operation and amounts will all be publicly known,
// but the identity of the caller is not revealed despite us being able to send tokens to them by completing the
Expand Down Expand Up @@ -294,9 +290,9 @@ pub contract AMM {

// We need the current balance of both tokens as well as the liquidity token total supply in order to compute
// the amounts to send the user.
let balance0 = token0.balance_of_public(self.address).view(self.context);
let balance1 = token1.balance_of_public(self.address).view(self.context);
let total_supply = liquidity_token.total_supply().view(self.context);
let balance0 = self.view(token0.balance_of_public(self.address));
let balance1 = self.view(token1.balance_of_public(self.address));
let total_supply = self.view(liquidity_token.total_supply());

// We calculate the amounts of token0 and token1 the user is entitled to based on the amount of liquidity they
// are removing, and check that they are above the minimum amounts they requested.
Expand All @@ -306,9 +302,9 @@ pub contract AMM {

// We can now burn the liquidity tokens that had been privately transferred into the AMM, as well as complete
// both partial notes.
liquidity_token.burn_public(self.address, liquidity, 0).call(self.context);
token0.finalize_transfer_to_private(amount0, token0_partial_note).call(self.context);
token1.finalize_transfer_to_private(amount1, token1_partial_note).call(self.context);
self.call(liquidity_token.burn_public(self.address, liquidity, 0));
self.call(token0.finalize_transfer_to_private(amount0, token0_partial_note));
self.call(token1.finalize_transfer_to_private(amount1, token1_partial_note));
}

/// Privately swaps `amount_in` `token_in` tokens for at least `amount_out_mint` `token_out` tokens with the pool.
Expand All @@ -335,11 +331,14 @@ pub contract AMM {

// We transfer the full amount in, since it is an exact amount, and prepare a partial note for the amount out,
// which will only be known during public execution as it depends on the live balances.
Token::at(token_in).transfer_to_public(sender, self.address, amount_in, authwit_nonce).call(
self.context,
);
self.call(Token::at(token_in).transfer_to_public(
sender,
self.address,
amount_in,
authwit_nonce,
));
let token_out_partial_note =
Token::at(token_out).prepare_private_balance_increase(sender).call(self.context);
self.call(Token::at(token_out).prepare_private_balance_increase(sender));

self.enqueue_self._swap_exact_tokens_for_tokens(
token_in,
Expand All @@ -363,10 +362,10 @@ pub contract AMM {
// transfer has already been completed as that function call was enqueued before this one. We therefore need to
// subtract the amount in to get the pre-swap balances.
let balance_in_plus_amount_in =
Token::at(token_in).balance_of_public(self.address).view(self.context);
self.view(Token::at(token_in).balance_of_public(self.address));
let balance_in = balance_in_plus_amount_in - amount_in;

let balance_out = Token::at(token_out).balance_of_public(self.address).view(self.context);
let balance_out = self.view(Token::at(token_out).balance_of_public(self.address));

// We can now compute the number of tokens to transfer and complete the partial note.
let amount_out = get_amount_out(amount_in, balance_in, balance_out);
Expand Down Expand Up @@ -405,17 +404,16 @@ pub contract AMM {
// Technically the token out note does not need to be partial, since we do know the amount out, but we do want
// to wait until the swap has been completed before committing the note to the tree to avoid it being spent too
// early.
let change_token_in_partial_note = Token::at(token_in)
let change_token_in_partial_note = self.call(Token::at(token_in)
.transfer_to_public_and_prepare_private_balance_increase(
sender,
self.address,
amount_in_max,
authwit_nonce,
)
.call(self.context);
));

let token_out_partial_note =
Token::at(token_out).prepare_private_balance_increase(sender).call(self.context);
self.call(Token::at(token_out).prepare_private_balance_increase(sender));

self.enqueue_self._swap_tokens_for_exact_tokens(
token_in,
Expand All @@ -441,20 +439,21 @@ pub contract AMM {
// transfer has already been completed as that function call was enqueued before this one. We therefore need to
// subtract the amount in to get the pre-swap balances.
let balance_in_plus_amount_in_max =
Token::at(token_in).balance_of_public(self.address).view(self.context);
self.view(Token::at(token_in).balance_of_public(self.address));
let balance_in = balance_in_plus_amount_in_max - amount_in_max;

let balance_out = Token::at(token_out).balance_of_public(self.address).view(self.context);
let balance_out = self.view(Token::at(token_out).balance_of_public(self.address));

// We can now compute the number of tokens we need to receive and complete the partial note with the change.
let amount_in = get_amount_in(amount_out, balance_in, balance_out);
assert(amount_in <= amount_in_max, "INSUFFICIENT_OUTPUT_AMOUNT");

let change = amount_in_max - amount_in;
if (change > 0 as u128) {
Token::at(token_in)
.finalize_transfer_to_private(change, change_token_in_partial_note)
.call(self.context);
self.call(Token::at(token_in).finalize_transfer_to_private(
change,
change_token_in_partial_note,
));
}

// Note again that we already knew the amount out, but for consistency we want to only commit this note once
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,14 +135,12 @@ pub contract AppSubscription {

let config = self.storage.config.read();

Token::at(config.subscription_token_address)
.transfer_in_private(
self.msg_sender().unwrap(),
config.subscription_recipient_address,
config.subscription_price,
authwit_nonce,
)
.call(self.context);
self.call(Token::at(config.subscription_token_address).transfer_in_private(
self.msg_sender().unwrap(),
config.subscription_recipient_address,
config.subscription_price,
authwit_nonce,
));

// Assert that the `current_block_number > expiry_block_number - SUBSCRIPTION_DURATION_IN_BLOCKS`.
// --> We do that via the router contract to conceal which contract is performing the check.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,9 @@ pub contract Claim {
self.context.push_nullifier(nullifier);

// 4) Finally we mint the reward token to the sender of the transaction
Token::at(self.storage.reward_token.read())
.mint_to_public(recipient, proof_retrieved_note.note.get_value())
.enqueue(self.context);
self.enqueue(Token::at(self.storage.reward_token.read()).mint_to_public(
recipient,
proof_retrieved_note.note.get_value(),
));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ pub contract Crowdfunding {
assert(self.msg_sender().unwrap() == operator_address, "Not an operator");

// 2) Transfer the donation tokens from this contract to the operator
Token::at(config.donation_token).transfer(operator_address, amount).call(self.context);
self.call(Token::at(config.donation_token).transfer(operator_address, amount));
// 3) Emit a public event so that anyone can audit how much the operator has withdrawn
self.enqueue_self._publish_donation_receipts(amount, operator_address);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,6 @@ pub contract Escrow {

let note = self.storage.owner.get_note();
assert(note.get_address() == sender);
Token::at(token).transfer(recipient, amount).call(self.context);
self.call(Token::at(token).transfer(recipient, amount));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -110,9 +110,12 @@ pub contract Lending {
) {
let on_behalf_of =
compute_identifier(secret, on_behalf_of, self.msg_sender().unwrap().to_field());
let _res = Token::at(collateral_asset)
.transfer_to_public(from, self.address, amount, authwit_nonce)
.call(self.context);
let _res = self.call(Token::at(collateral_asset).transfer_to_public(
from,
self.address,
amount,
authwit_nonce,
));
// docs:start:enqueue_public
self.enqueue_self._deposit(AztecAddress::from_field(on_behalf_of), amount, collateral_asset);
// docs:end:enqueue_public
Expand All @@ -125,9 +128,12 @@ pub contract Lending {
on_behalf_of: Field,
collateral_asset: AztecAddress,
) {
let _ = Token::at(collateral_asset)
.transfer_in_public(self.msg_sender().unwrap(), self.address, amount, authwit_nonce)
.call(self.context);
let _ = self.call(Token::at(collateral_asset).transfer_in_public(
self.msg_sender().unwrap(),
self.address,
amount,
authwit_nonce,
));
let _ = self.call_self._deposit(
AztecAddress::from_field(on_behalf_of),
amount,
Expand Down Expand Up @@ -163,7 +169,7 @@ pub contract Lending {
#[only_self]
fn _withdraw(owner: AztecAddress, recipient: AztecAddress, amount: u128) {
let asset = self.call_self.update_accumulator();
let price = PriceFeed::at(asset.oracle).get_price(0).view(self.context).price;
let price = self.view(PriceFeed::at(asset.oracle).get_price(0)).price;

let coll_loc = self.storage.collateral.at(owner);
let collateral = coll_loc.read();
Expand All @@ -188,9 +194,12 @@ pub contract Lending {

// @todo @LHerskind Support both shielding and transfers (for now just transfer)
let collateral_asset = self.storage.collateral_asset.read();
let _ = Token::at(collateral_asset)
.transfer_in_public(self.address, recipient, amount, 0)
.call(self.context);
let _ = self.call(Token::at(collateral_asset).transfer_in_public(
self.address,
recipient,
amount,
0,
));
}

#[external("private")]
Expand All @@ -208,7 +217,7 @@ pub contract Lending {
#[only_self]
fn _borrow(owner: AztecAddress, to: AztecAddress, amount: u128) {
let asset = self.call_self.update_accumulator();
let price = PriceFeed::at(asset.oracle).get_price(0).view(self.context).price;
let price = self.view(PriceFeed::at(asset.oracle).get_price(0)).price;

// Fetch collateral and static_debt, compute health of current position
let collateral = self.storage.collateral.at(owner).read();
Expand All @@ -224,7 +233,7 @@ pub contract Lending {

// @todo @LHerskind Need to support both private and public minting.
let stable_coin = self.storage.stable_coin.read();
let _ = Token::at(stable_coin).mint_to_public(to, amount).call(self.context);
let _ = self.call(Token::at(stable_coin).mint_to_public(to, amount));
}

#[external("private")]
Expand All @@ -239,7 +248,7 @@ pub contract Lending {
let on_behalf_of =
compute_identifier(secret, on_behalf_of, self.msg_sender().unwrap().to_field());
// docs:start:private_call
let _ = Token::at(stable_coin).burn_private(from, amount, authwit_nonce).call(self.context);
let _ = self.call(Token::at(stable_coin).burn_private(from, amount, authwit_nonce));
// docs:end:private_call
self.enqueue_self._repay(AztecAddress::from_field(on_behalf_of), amount, stable_coin);
}
Expand All @@ -251,9 +260,11 @@ pub contract Lending {
owner: AztecAddress,
stable_coin: AztecAddress,
) {
let _ = Token::at(stable_coin)
.burn_public(self.msg_sender().unwrap(), amount, authwit_nonce)
.call(self.context);
let _ = self.call(Token::at(stable_coin).burn_public(
self.msg_sender().unwrap(),
amount,
authwit_nonce,
));
let _ = self.call_self._repay(owner, amount, stable_coin);
}

Expand Down
Loading
Loading