Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: transfer and transferfrom to save constrains for simpler cases #7013

Merged
merged 2 commits into from
Jun 12, 2024
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
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ contract AppSubscription {
) {
assert(tx_count as u64 <= SUBSCRIPTION_TXS as u64);

Token::at(storage.subscription_token_address.read_private()).transfer(
Token::at(storage.subscription_token_address.read_private()).transfer_from(
context.msg_sender(),
storage.subscription_recipient_address.read_private(),
storage.subscription_price.read_private(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ contract Crowdfunding {
// 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_private()).transfer(donor, context.this_address(), amount as Field, 0).call(&mut context);
Token::at(storage.donation_token.read_private()).transfer_from(donor, context.this_address(), amount as Field, 0).call(&mut context);
// docs:end:do-transfer

let header = context.get_header();
Expand All @@ -100,7 +100,7 @@ contract Crowdfunding {
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_private()).transfer(context.this_address(), operator_address, amount as Field, 0).call(&mut context);
Token::at(storage.donation_token.read_private()).transfer(operator_address, amount as Field).call(&mut context);

// 3) Emit an unencrypted event so that anyone can audit how much the operator has withdrawn
let event = WithdrawalProcessed { amount, who: operator_address };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,11 @@ contract Escrow {
// Withdraws balance. Requires that msg.sender is the owner.
#[aztec(private)]
fn withdraw(token: AztecAddress, amount: Field, recipient: AztecAddress) {
let this = context.this_address();
let sender = context.msg_sender();

let note = storage.owner.get_note();
assert(note.address == sender);

Token::at(token).transfer(this, recipient, amount, 0).call(&mut context);
Token::at(token).transfer(recipient, amount).call(&mut context);
}
}
20 changes: 18 additions & 2 deletions noir-projects/noir-contracts/contracts/token_contract/src/main.nr
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,24 @@ contract Token {

// docs:start:transfer
#[aztec(private)]
fn transfer(from: AztecAddress, to: AztecAddress, amount: Field, nonce: Field) {
fn transfer(to: AztecAddress, amount: Field) {
let from = context.msg_sender();

// By fetching the keys here, we can avoid doing an extra read from the storage, since from_ovpk would
// be needed twice.
let header = context.get_header();
let from_ovpk = header.get_ovpk_m(&mut context, from);
let from_ivpk = header.get_ivpk_m(&mut context, from);
let to_ivpk = header.get_ivpk_m(&mut context, to);

let amount = U128::from_integer(amount);
storage.balances.sub(from, amount).emit(encode_and_encrypt_with_keys(&mut context, from_ovpk, from_ivpk));
storage.balances.add(to, amount).emit(encode_and_encrypt_with_keys(&mut context, from_ovpk, to_ivpk));
}
// docs:end:transfer

#[aztec(private)]
fn transfer_from(from: AztecAddress, to: AztecAddress, amount: Field, nonce: Field) {
// docs:start:assert_current_call_valid_authwit
if (!from.eq(context.msg_sender())) {
assert_current_call_valid_authwit(&mut context, from);
Expand All @@ -334,7 +351,6 @@ contract Token {
// docs:end:increase_private_balance
storage.balances.add(to, amount).emit(encode_and_encrypt_with_keys(&mut context, from_ovpk, to_ivpk));
}
// docs:end:transfer

// docs:start:burn
#[aztec(private)]
Expand Down
2 changes: 1 addition & 1 deletion yarn-project/aztec/src/examples/token.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ async function main() {

// We will now transfer tokens from Alice to Bob
logger.info(`Transferring ${TRANSFER_AMOUNT} tokens from Alice to Bob...`);
await tokenAlice.methods.transfer(alice, bob, TRANSFER_AMOUNT, 0).send().wait();
await tokenAlice.methods.transfer(bob, TRANSFER_AMOUNT).send().wait();

// Check the new balances
const aliceBalance = await tokenAlice.methods.balance_of_private(alice).simulate();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ describe('benchmarks/proving', () => {

const fnCalls = [
(await getTokenContract(0)).methods.transfer_public(schnorrWalletAddress.address, recipient.address, 1000, 0),
(await getTokenContract(1)).methods.transfer(schnorrWalletAddress.address, recipient.address, 1000, 0),
(await getTokenContract(1)).methods.transfer(recipient.address, 1000),
// (await getTestContractOnPXE(2)).methods.emit_unencrypted(43),
// (await getTestContractOnPXE(3)).methods.create_l2_to_l1_message_public(45, 46, EthAddress.random()),
];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ describe('benchmarks/tx_size_fees', () => {
const paymentMethod = createPaymentMethod();
const gasSettings = GasSettings.default();
const tx = await token.methods
.transfer(aliceWallet.getAddress(), bobAddress, 1n, 0)
.transfer(bobAddress, 1n)
.send({ fee: paymentMethod ? { gasSettings, paymentMethod } : undefined })
.wait();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ describe('Aztec persistence', () => {

const initialOwnerBalance = await contract.methods.balance_of_private(ownerWallet.getAddress()).simulate();

await contract.methods.transfer(ownerWallet.getAddress(), otherWallet.getAddress(), 500n, Fr.ZERO).send().wait();
await contract.methods.transfer(otherWallet.getAddress(), 500n).send().wait();

const [ownerBalance, targetBalance] = await Promise.all([
contract.methods.balance_of_private(ownerWallet.getAddress()).simulate(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ describe('e2e_sandbox_example', () => {
// We will now transfer tokens from ALice to Bob
const transferQuantity = 543n;
logger.info(`Transferring ${transferQuantity} tokens from Alice to Bob...`);
await tokenContractAlice.methods.transfer(alice, bob, transferQuantity, 0).send().wait();
await tokenContractAlice.methods.transfer(bob, transferQuantity).send().wait();

// Check the new balances
aliceBalance = await tokenContractAlice.methods.balance_of_private(alice).simulate();
Expand Down
25 changes: 5 additions & 20 deletions yarn-project/end-to-end/src/e2e_2_pxes.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -139,10 +139,7 @@ describe('e2e_2_pxes', () => {

// Transfer funds from A to B via PXE A
const contractWithWalletA = await TokenContract.at(token.address, walletA);
await contractWithWalletA.methods
.transfer(walletA.getAddress(), walletB.getAddress(), transferAmount1, 0)
.send()
.wait();
await contractWithWalletA.methods.transfer(walletB.getAddress(), transferAmount1).send().wait();

// Check balances and logs are as expected
await expectTokenBalance(walletA, token.address, walletA.getAddress(), initialBalance - transferAmount1);
Expand All @@ -151,10 +148,7 @@ describe('e2e_2_pxes', () => {

// Transfer funds from B to A via PXE B
const contractWithWalletB = await TokenContract.at(token.address, walletB);
await contractWithWalletB.methods
.transfer(walletB.getAddress(), walletA.getAddress(), transferAmount2, 0)
.send()
.wait({ interval: 0.1 });
await contractWithWalletB.methods.transfer(walletA.getAddress(), transferAmount2).send().wait({ interval: 0.1 });

// Check balances and logs are as expected
await expectTokenBalance(
Expand Down Expand Up @@ -281,10 +275,7 @@ describe('e2e_2_pxes', () => {

// Transfer funds from A to B via PXE A
const contractWithWalletA = await TokenContract.at(tokenAddress, walletA);
await contractWithWalletA.methods
.transfer(walletA.getAddress(), walletB.getAddress(), transferAmount1, 0)
.send()
.wait();
await contractWithWalletA.methods.transfer(walletB.getAddress(), transferAmount1).send().wait();

// now add the contract and check balances
await pxeB.registerContract(token);
Expand Down Expand Up @@ -316,17 +307,11 @@ describe('e2e_2_pxes', () => {

// Transfer funds from A to Shared Wallet via PXE A
const contractWithWalletA = await TokenContract.at(token.address, walletA);
await contractWithWalletA.methods
.transfer(walletA.getAddress(), sharedAccountAddress.address, transferAmount1, 0)
.send()
.wait();
await contractWithWalletA.methods.transfer(sharedAccountAddress.address, transferAmount1).send().wait();

// Now send funds from Shared Wallet to B via PXE A
const contractWithSharedWalletA = await TokenContract.at(token.address, sharedWalletOnA);
await contractWithSharedWalletA.methods
.transfer(sharedAccountAddress.address, walletB.getAddress(), transferAmount2, 0)
.send()
.wait();
await contractWithSharedWalletA.methods.transfer(walletB.getAddress(), transferAmount2).send().wait();

// check balances from PXE-A's perspective
await expectTokenBalance(walletA, token.address, walletA.getAddress(), initialBalance - transferAmount1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ describe('e2e_crowdfunding_and_claim', () => {
{
const action = donationToken
.withWallet(donorWallets[0])
.methods.transfer(donorWallets[0].getAddress(), crowdfundingContract.address, donationAmount, 0);
.methods.transfer_from(donorWallets[0].getAddress(), crowdfundingContract.address, donationAmount, 0);
const witness = await donorWallets[0].createAuthWit({ caller: crowdfundingContract.address, action });
await donorWallets[0].addAuthWitness(witness);
}
Expand Down Expand Up @@ -275,7 +275,7 @@ describe('e2e_crowdfunding_and_claim', () => {
{
const action = donationToken
.withWallet(donorWallets[1])
.methods.transfer(donorWallets[1].getAddress(), crowdfundingContract.address, donationAmount, 0);
.methods.transfer_from(donorWallets[1].getAddress(), crowdfundingContract.address, donationAmount, 0);
const witness = await donorWallets[1].createAuthWit({ caller: crowdfundingContract.address, action });
await donorWallets[1].addAuthWitness(witness);
}
Expand Down Expand Up @@ -368,7 +368,7 @@ describe('e2e_crowdfunding_and_claim', () => {
{
const action = donationToken
.withWallet(donorWallets[1])
.methods.transfer(donorWallets[1].getAddress(), crowdfundingContract.address, donationAmount, 0);
.methods.transfer_from(donorWallets[1].getAddress(), crowdfundingContract.address, donationAmount, 0);
const witness = await donorWallets[1].createAuthWit({ caller: crowdfundingContract.address, action });
await donorWallets[1].addAuthWitness(witness);
}
Expand Down
2 changes: 1 addition & 1 deletion yarn-project/end-to-end/src/e2e_escrow_contract.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ describe('e2e_escrow_contract', () => {
await expectBalance(owner, 50n);

const actions = [
token.methods.transfer(owner, recipient, 10, 0).request(),
token.methods.transfer(recipient, 10).request(),
escrowContract.methods.withdraw(token.address, 20, recipient).request(),
];

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ describe('e2e_fees dapp_subscription', () => {

async function subscribe(paymentMethod: FeePaymentMethod, blockDelta: number = 5, txCount: number = 4) {
const nonce = Fr.random();
const action = bananaCoin.methods.transfer(aliceAddress, bobAddress, t.SUBSCRIPTION_AMOUNT, nonce);
const action = bananaCoin.methods.transfer_from(aliceAddress, bobAddress, t.SUBSCRIPTION_AMOUNT, nonce);
await aliceWallet.createAuthWit({ caller: subscriptionContract.address, action });

return subscriptionContract
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ describe('e2e_fees native_payments', () => {
it('sends tx with native fee payment method with no public calls', async () => {
const initialBalance = await gasTokenContract.methods.balance_of_public(aliceAddress).simulate();
const { transactionFee } = await bananaCoin.methods
.transfer(aliceAddress, bobAddress, 1n, 0n)
.transfer(bobAddress, 1n)
.send({ fee: { gasSettings, paymentMethod } })
.wait();
expect(transactionFee).toBeGreaterThan(0n);
Expand Down
4 changes: 2 additions & 2 deletions yarn-project/end-to-end/src/e2e_fees/private_payments.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ describe('e2e_fees private_payment', () => {
* this is expected to squash notes and nullifiers
*/
const transferAmount = 5n;
const interaction = bananaCoin.methods.transfer(aliceAddress, bobAddress, transferAmount, 0n);
const interaction = bananaCoin.methods.transfer(bobAddress, transferAmount);
const localTx = await interaction.prove({
fee: {
gasSettings,
Expand Down Expand Up @@ -313,7 +313,7 @@ describe('e2e_fees private_payment', () => {
* create transparent note with RefundAmount
*/
const tx = await new BatchCall(aliceWallet, [
bananaCoin.methods.transfer(aliceAddress, bobAddress, privateTransfer, 0n).request(),
bananaCoin.methods.transfer(bobAddress, privateTransfer).request(),
bananaCoin.methods.shield(aliceAddress, shieldedBananas, shieldSecretHash, 0n).request(),
])
.send({
Expand Down
6 changes: 3 additions & 3 deletions yarn-project/end-to-end/src/e2e_key_rotation.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ describe('e2e_key_rotation', () => {
const transfer1Amount = 654n;
{
({ txHash: txHashTransfer1 } = await contractWithWalletA.methods
.transfer(walletA.getAddress(), walletB.getAddress(), transfer1Amount, 0)
.transfer(walletB.getAddress(), transfer1Amount)
.send()
.wait());

Expand Down Expand Up @@ -190,7 +190,7 @@ describe('e2e_key_rotation', () => {
const transfer2Amount = 321n;
{
({ txHash: txHashTransfer2 } = await contractWithWalletA.methods
.transfer(walletA.getAddress(), walletB.getAddress(), transfer2Amount, 0)
.transfer(walletB.getAddress(), transfer2Amount)
.send()
.wait());

Expand Down Expand Up @@ -225,7 +225,7 @@ describe('e2e_key_rotation', () => {
// --> this way we verify that it's possible to obtain both keys via oracles
{
await contractWithWalletB.methods
.transfer(walletB.getAddress(), walletA.getAddress(), transfer1Amount + transfer2Amount, 0)
.transfer(walletA.getAddress(), transfer1Amount + transfer2Amount)
.send()
.wait();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ describe('e2e_multiple_accounts_1_enc_key', () => {

const contractWithWallet = await TokenContract.at(tokenAddress, wallets[senderIndex]);

await contractWithWallet.methods.transfer(sender, receiver, transferAmount, 0).send().wait();
await contractWithWallet.methods.transfer(receiver, transferAmount).send().wait();

for (let i = 0; i < expectedBalances.length; i++) {
await expectBalance(i, expectedBalances[i]);
Expand Down
9 changes: 2 additions & 7 deletions yarn-project/end-to-end/src/e2e_prover/full.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,7 @@ describe('full_prover', () => {
const privateBalance = await provenAssets[0].methods.balance_of_private(accounts[0].address).simulate();
const privateSendAmount = privateBalance / 2n;
expect(privateSendAmount).toBeGreaterThan(0n);
const privateInteraction = provenAssets[0].methods.transfer(
accounts[0].address,
accounts[1].address,
privateSendAmount,
0,
);
const privateInteraction = provenAssets[0].methods.transfer(accounts[1].address, privateSendAmount);

const publicBalance = await provenAssets[1].methods.balance_of_public(accounts[0].address).simulate();
const publicSendAmount = publicBalance / 2n;
Expand Down Expand Up @@ -94,7 +89,7 @@ describe('full_prover', () => {
);

it('rejects txs with invalid proofs', async () => {
const privateInteraction = t.fakeProofsAsset.methods.transfer(accounts[0].address, accounts[1].address, 1, 0);
const privateInteraction = t.fakeProofsAsset.methods.transfer(accounts[1].address, 1);
const publicInteraction = t.fakeProofsAsset.methods.transfer_public(accounts[0].address, accounts[1].address, 1, 0);

const sentPrivateTx = privateInteraction.send();
Expand Down
7 changes: 1 addition & 6 deletions yarn-project/end-to-end/src/e2e_prover/with_padding.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,7 @@ describe('full_prover_with_padding_tx', () => {
const privateBalance = await provenAssets[0].methods.balance_of_private(accounts[0].address).simulate();
const privateSendAmount = privateBalance / 2n;
expect(privateSendAmount).toBeGreaterThan(0n);
const privateInteraction = provenAssets[0].methods.transfer(
accounts[0].address,
accounts[1].address,
privateSendAmount,
0,
);
const privateInteraction = provenAssets[0].methods.transfer(accounts[1].address, privateSendAmount);

const privateTx = await privateInteraction.prove();

Expand Down
Loading
Loading