Skip to content

Commit

Permalink
feat: Include contract address in message hash
Browse files Browse the repository at this point in the history
  • Loading branch information
LHerskind committed Sep 11, 2023
1 parent 83c9507 commit 9876304
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 15 deletions.
20 changes: 13 additions & 7 deletions yarn-project/end-to-end/src/e2e_token_contract.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ describe('e2e_token_contract', () => {

afterEach(async () => {
await tokenSim.check();
});
}, 30_000);

describe('Access controlled functions', () => {
it('Set admin', async () => {
Expand Down Expand Up @@ -351,6 +351,7 @@ describe('e2e_token_contract', () => {
) => {
return await hashPayload([
caller.address.toField(),
asset.address.toField(),
FunctionSelector.fromSignature('transfer_public((Field),(Field),Field,Field)').toField(),
from.address.toField(),
to.address.toField(),
Expand Down Expand Up @@ -416,7 +417,7 @@ describe('e2e_token_contract', () => {
await txReplay.isMined();
const receiptReplay = await txReplay.getReceipt();
expect(receiptReplay.status).toBe(TxStatus.DROPPED);
}, 30_000);
}, 45_000);

describe('failure cases', () => {
it('transfer more than balance', async () => {
Expand Down Expand Up @@ -477,7 +478,7 @@ describe('e2e_token_contract', () => {

expect(await asset.methods.balance_of_public({ address: accounts[0].address }).view()).toEqual(balance0);
expect(await asset.methods.balance_of_public({ address: accounts[1].address }).view()).toEqual(balance1);
});
}, 30_000);

it('transfer on behalf of other, wrong designated caller', async () => {
const balance0 = await asset.methods.balance_of_public({ address: accounts[0].address }).view();
Expand Down Expand Up @@ -523,6 +524,7 @@ describe('e2e_token_contract', () => {
) => {
return await hashPayload([
caller.address.toField(),
asset.address.toField(),
FunctionSelector.fromSignature('transfer((Field),(Field),Field,Field)').toField(),
from.address.toField(),
to.address.toField(),
Expand All @@ -541,7 +543,7 @@ describe('e2e_token_contract', () => {
const receipt = await tx.wait();
expect(receipt.status).toBe(TxStatus.MINED);
tokenSim.transferPrivate(accounts[0].address, accounts[1].address, amount);
});
}, 30_000);

it('transfer to self', async () => {
const balance0 = await asset.methods.balance_of_private({ address: accounts[0].address }).view();
Expand All @@ -553,7 +555,7 @@ describe('e2e_token_contract', () => {
const receipt = await tx.wait();
expect(receipt.status).toBe(TxStatus.MINED);
tokenSim.transferPrivate(accounts[0].address, accounts[0].address, amount);
});
}, 30_000);

it('transfer on behalf of other', async () => {
const balance0 = await asset.methods.balance_of_private({ address: accounts[0].address }).view();
Expand Down Expand Up @@ -695,6 +697,7 @@ describe('e2e_token_contract', () => {
) => {
return await hashPayload([
caller.address.toField(),
asset.address.toField(),
FunctionSelector.fromSignature('shield((Field),Field,Field,Field)').toField(),
from.address.toField(),
new Fr(amount),
Expand Down Expand Up @@ -733,7 +736,7 @@ describe('e2e_token_contract', () => {
await txClaimDoubleSpend.isMined();
const receiptDoubleSpend = await txClaimDoubleSpend.getReceipt();
expect(receiptDoubleSpend.status).toBe(TxStatus.DROPPED);
});
}, 30_000);

it('on behalf of other', async () => {
const balancePub = await asset.methods.balance_of_public({ address: accounts[0].address }).view();
Expand Down Expand Up @@ -783,7 +786,7 @@ describe('e2e_token_contract', () => {
await txClaimDoubleSpend.isMined();
const receiptDoubleSpend = await txClaimDoubleSpend.getReceipt();
expect(receiptDoubleSpend.status).toBe(TxStatus.DROPPED);
}, 30_000);
}, 60_000);

describe('failure cases', () => {
it('on behalf of self (more than balance)', async () => {
Expand Down Expand Up @@ -887,6 +890,7 @@ describe('e2e_token_contract', () => {
) => {
return await hashPayload([
caller.address.toField(),
asset.address.toField(),
FunctionSelector.fromSignature('unshield((Field),(Field),Field,Field)').toField(),
accounts[0].address.toField(),
accounts[1].address.toField(),
Expand Down Expand Up @@ -1017,6 +1021,7 @@ describe('e2e_token_contract', () => {
const burnMessageHash = async (caller: CompleteAddress, from: CompleteAddress, amount: bigint, nonce: Fr) => {
return await hashPayload([
caller.address.toField(),
asset.address.toField(),
FunctionSelector.fromSignature('burn_public((Field),Field,Field)').toField(),
from.address.toField(),
new Fr(amount),
Expand Down Expand Up @@ -1153,6 +1158,7 @@ describe('e2e_token_contract', () => {
const burnMessageHash = async (caller: CompleteAddress, from: CompleteAddress, amount: bigint, nonce: Fr) => {
return await hashPayload([
caller.address.toField(),
asset.address.toField(),
FunctionSelector.fromSignature('burn((Field),Field,Field)').toField(),
from.address.toField(),
new Fr(amount),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ mod util;
// Minimal token implementation that supports `AuthWit` accounts.
// The auth message follows a similar pattern to the cross-chain message and includes a designated caller.
// The designated caller is ALWAYS used here, and not based on a flag as cross-chain.
// message hash = H([caller, selector, , ...args])
// To be read as `caller` calls function defined by `selector` with `args`
// message hash = H([caller, contract, selector, ...args])
// To be read as `caller` calls function at `contract` defined by `selector` with `args`
// Including a nonce in the message hash ensures that the message can only be used once.

contract Token {
Expand Down Expand Up @@ -165,7 +165,7 @@ contract Token {
if (from.address != context.msg_sender()) {
// The redeem is only spendable once, so we need to ensure that you cannot insert multiple shields from the same message.
let selector = compute_selector("shield((Field),Field,Field,Field)");
let message_field = compute_message_hash([context.msg_sender(), selector, from.address, amount, secret_hash, nonce]);
let message_field = compute_message_hash([context.msg_sender(), context.this_address(), selector, from.address, amount, secret_hash, nonce]);
AccountContract::at(from.address).is_valid(Context::public(&mut context), message_field);
} else {
assert(nonce == 0, "invalid nonce");
Expand Down Expand Up @@ -193,7 +193,7 @@ contract Token {

if (from.address != context.msg_sender()) {
let selector = compute_selector("transfer_public((Field),(Field),Field,Field)");
let message_field = compute_message_hash([context.msg_sender(), selector, from.address, to.address, amount, nonce]);
let message_field = compute_message_hash([context.msg_sender(), context.this_address(), selector, from.address, to.address, amount, nonce]);
AccountContract::at(from.address).is_valid(Context::public(&mut context), message_field);
} else {
assert(nonce == 0, "invalid nonce");
Expand All @@ -217,7 +217,7 @@ contract Token {

if (from.address != context.msg_sender()) {
let selector = compute_selector("burn_public((Field),Field,Field)");
let message_field = compute_message_hash([context.msg_sender(), selector, from.address, amount, nonce]);
let message_field = compute_message_hash([context.msg_sender(), context.this_address(), selector, from.address, amount, nonce]);
AccountContract::at(from.address).is_valid(Context::public(&mut context), message_field);
} else {
assert(nonce == 0, "invalid nonce");
Expand Down Expand Up @@ -257,7 +257,7 @@ contract Token {

if (from.address != context.msg_sender()) {
let selector = compute_selector("unshield((Field),(Field),Field,Field)");
let message_field = compute_message_hash([context.msg_sender(), selector, from.address, to.address, amount, nonce]);
let message_field = compute_message_hash([context.msg_sender(), context.this_address(), selector, from.address, to.address, amount, nonce]);
AccountContract::at(from.address).is_valid(Context::private(&mut context), message_field);
} else {
assert(nonce == 0, "invalid nonce");
Expand All @@ -281,7 +281,7 @@ contract Token {

if (from.address != context.msg_sender()) {
let selector = compute_selector("transfer((Field),(Field),Field,Field)");
let message_field = compute_message_hash([context.msg_sender(), selector, from.address, to.address, amount, nonce]);
let message_field = compute_message_hash([context.msg_sender(), context.this_address(), selector, from.address, to.address, amount, nonce]);
AccountContract::at(from.address).is_valid(Context::private(&mut context), message_field);
} else {
assert(nonce == 0, "invalid nonce");
Expand All @@ -304,7 +304,7 @@ contract Token {

if (from.address != context.msg_sender()) {
let selector = compute_selector("burn((Field),Field,Field)");
let message_field = compute_message_hash([context.msg_sender(), selector, from.address, amount, nonce]);
let message_field = compute_message_hash([context.msg_sender(), context.this_address(), selector, from.address, amount, nonce]);
AccountContract::at(from.address).is_valid(Context::private(&mut context), message_field);
} else {
assert(nonce == 0, "invalid nonce");
Expand Down

0 comments on commit 9876304

Please sign in to comment.