Skip to content
This repository was archived by the owner on Mar 11, 2025. It is now read-only.

Commit 666b0b7

Browse files
authored
Remove initialize signers (#84)
* Remove initialize signers * update js to do initialize atomically
1 parent 271073e commit 666b0b7

File tree

5 files changed

+51
-72
lines changed

5 files changed

+51
-72
lines changed

token/inc/token.h

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,13 @@ typedef enum Token_TokenInstruction_Tag {
3838
/**
3939
* Initializes a new mint and optionally deposits all the newly minted tokens in an account.
4040
*
41+
* The `InitializeWrappedAccount` instruction requires no signers and MUST be included within
42+
* the Transaction that creates the uninitialized account with the system program. Otherwise
43+
* another party can acquire ownership of the uninitialized token account.
44+
*
4145
* Accounts expected by this instruction:
4246
*
43-
* 0. `[writable, signer]` The mint to initialize.
47+
* 0. `[writable]` The mint to initialize.
4448
* 1.
4549
* * If supply is non-zero: `[writable]` The account to hold all the newly minted tokens.
4650
* * If supply is zero: `[]` The owner/multisignature of the mint.
@@ -52,9 +56,13 @@ typedef enum Token_TokenInstruction_Tag {
5256
/**
5357
* Initializes a new account to hold tokens.
5458
*
59+
* The `InitializeWrappedAccount` instruction requires no signers and MUST be included within
60+
* the Transaction that creates the uninitialized account with the system program. Otherwise
61+
* another party can acquire ownership of the uninitialized token account.
62+
*
5563
* Accounts expected by this instruction:
5664
*
57-
* 0. `[writable, signer]` The account to initialize.
65+
* 0. `[writable]` The account to initialize.
5866
* 1. `[]` The mint this account will be associated with.
5967
* 2. `[]` The new account's owner/multisignature.
6068
*/
@@ -66,9 +74,13 @@ typedef enum Token_TokenInstruction_Tag {
6674
* token instruction that require an owner/delegate to be present. The variant field represents the
6775
* number of signers (M) required to validate this multisignature account.
6876
*
77+
* The `InitializeWrappedAccount` instruction requires no signers and MUST be included within
78+
* the Transaction that creates the uninitialized account with the system program. Otherwise
79+
* another party can acquire ownership of the uninitialized token account.
80+
*
6981
* Accounts expected by this instruction:
7082
*
71-
* 0. `[signer, writable]` The multisignature account to initialize.
83+
* 0. `[writable]` The multisignature account to initialize.
7284
* 1. ..1+N. `[]` The signer accounts, must equal to N where 1 <= N <= 11.
7385
*/
7486
InitializeMultisig,

token/js/cli/token-test.js

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -196,9 +196,6 @@ export async function invalidApprove(): Promise<void> {
196196
}
197197

198198
export async function failOnApproveOverspend(): Promise<void> {
199-
const connection = await getConnection();
200-
const balanceNeeded =
201-
(await Token.getMinBalanceRentForExemptAccount(connection)) * 3;
202199
const owner = new Account();
203200
const account1 = await testToken.createAccount(owner.publicKey);
204201
const account2 = await testToken.createAccount(owner.publicKey);
@@ -324,10 +321,6 @@ export async function multisig(): Promise<void> {
324321
const m = 2;
325322
const n = 5;
326323

327-
const connection = await getConnection();
328-
const balanceNeeded = await Token.getMinBalanceRentForExemptAccount(
329-
connection,
330-
);
331324
let signerAccounts = [];
332325
for (var i = 0; i < n; i++) {
333326
signerAccounts.push(new Account());

token/js/client/token.js

Lines changed: 18 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -289,17 +289,10 @@ export class Token {
289289
space: MintLayout.span,
290290
programId,
291291
});
292-
await sendAndConfirmTransaction(
293-
'createAccount',
294-
connection,
295-
transaction,
296-
payer,
297-
mintAccount,
298-
);
299292

300293
// Create the mint
301294
let keys = [
302-
{pubkey: mintAccount.publicKey, isSigner: true, isWritable: false},
295+
{pubkey: mintAccount.publicKey, isSigner: false, isWritable: true},
303296
];
304297
if (supply.toNumber() != 0) {
305298
keys.push({pubkey: initialAccountPublicKey, isSigner: false, isWritable: true});
@@ -324,18 +317,19 @@ export class Token {
324317
);
325318
data = data.slice(0, encodeLength);
326319
}
327-
328-
transaction = new Transaction().add({
320+
transaction.add({
329321
keys,
330322
programId,
331323
data,
332324
});
325+
326+
// Send the two instructions
333327
await sendAndConfirmTransaction(
334-
'InitializeMint',
328+
'createAccount and InitializeMint',
335329
connection,
336330
transaction,
337331
payer,
338-
mintAccount,
332+
mintAccount
339333
);
340334

341335
return [token, initialAccountPublicKey];
@@ -371,21 +365,13 @@ export class Token {
371365
space: AccountLayout.span,
372366
programId: this.programId,
373367
});
374-
await sendAndConfirmTransaction(
375-
'createAccount',
376-
this.connection,
377-
transaction,
378-
this.payer,
379-
mintAccount,
380-
);
381368

382369
// create the new account
383370
const keys = [
384-
{pubkey: mintAccount.publicKey, isSigner: true, isWritable: true},
371+
{pubkey: mintAccount.publicKey, isSigner: false, isWritable: true},
385372
{pubkey: this.publicKey, isSigner: false, isWritable: false},
386373
{pubkey: owner, isSigner: false, isWritable: false},
387374
];
388-
389375
const dataLayout = BufferLayout.struct([BufferLayout.u8('instruction')]);
390376
const data = Buffer.alloc(dataLayout.span);
391377
dataLayout.encode(
@@ -394,17 +380,19 @@ export class Token {
394380
},
395381
data,
396382
);
397-
transaction = new Transaction().add({
383+
transaction.add({
398384
keys,
399385
programId: this.programId,
400386
data,
401387
});
388+
389+
// Send the two instructions
402390
await sendAndConfirmTransaction(
403-
'InitializeAccount',
391+
'createAccount and InitializeAccount',
404392
this.connection,
405393
transaction,
406394
this.payer,
407-
mintAccount,
395+
mintAccount
408396
);
409397

410398
return mintAccount.publicKey;
@@ -436,20 +424,12 @@ export class Token {
436424
space: MultisigLayout.span,
437425
programId: this.programId,
438426
});
439-
await sendAndConfirmTransaction(
440-
'createAccount',
441-
this.connection,
442-
transaction,
443-
this.payer,
444-
multisigAccount,
445-
);
446427

447428
// create the new account
448429
let keys = [
449-
{pubkey: multisigAccount.publicKey, isSigner: true, isWritable: true},
430+
{pubkey: multisigAccount.publicKey, isSigner: false, isWritable: true},
450431
];
451432
signers.forEach(signer => keys.push({pubkey: signer, isSigner: false, isWritable: false}));
452-
453433
const dataLayout = BufferLayout.struct(
454434
[
455435
BufferLayout.u8('instruction'),
@@ -464,17 +444,19 @@ export class Token {
464444
},
465445
data,
466446
);
467-
transaction = new Transaction().add({
447+
transaction.add({
468448
keys,
469449
programId: this.programId,
470450
data,
471451
});
452+
453+
// Send the two instructions
472454
await sendAndConfirmTransaction(
473-
'InitializeMultisig',
455+
'createAccount and InitializeMultisig',
474456
this.connection,
475457
transaction,
476458
this.payer,
477-
multisigAccount,
459+
multisigAccount
478460
);
479461

480462
return multisigAccount.publicKey;

token/src/instruction.rs

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,13 @@ pub struct TokenInfo {
2929
pub enum TokenInstruction {
3030
/// Initializes a new mint and optionally deposits all the newly minted tokens in an account.
3131
///
32+
/// The `InitializeWrappedAccount` instruction requires no signers and MUST be included within
33+
/// the Transaction that creates the uninitialized account with the system program. Otherwise
34+
/// another party can acquire ownership of the uninitialized token account.
35+
///
3236
/// Accounts expected by this instruction:
3337
///
34-
/// 0. `[writable, signer]` The mint to initialize.
38+
/// 0. `[writable]` The mint to initialize.
3539
/// 1.
3640
/// * If supply is non-zero: `[writable]` The account to hold all the newly minted tokens.
3741
/// * If supply is zero: `[]` The owner/multisignature of the mint.
@@ -41,9 +45,13 @@ pub enum TokenInstruction {
4145
InitializeMint(TokenInfo),
4246
/// Initializes a new account to hold tokens.
4347
///
48+
/// The `InitializeWrappedAccount` instruction requires no signers and MUST be included within
49+
/// the Transaction that creates the uninitialized account with the system program. Otherwise
50+
/// another party can acquire ownership of the uninitialized token account.
51+
///
4452
/// Accounts expected by this instruction:
4553
///
46-
/// 0. `[writable, signer]` The account to initialize.
54+
/// 0. `[writable]` The account to initialize.
4755
/// 1. `[]` The mint this account will be associated with.
4856
/// 2. `[]` The new account's owner/multisignature.
4957
InitializeAccount,
@@ -53,9 +61,13 @@ pub enum TokenInstruction {
5361
/// token instruction that require an owner/delegate to be present. The variant field represents the
5462
/// number of signers (M) required to validate this multisignature account.
5563
///
64+
/// The `InitializeWrappedAccount` instruction requires no signers and MUST be included within
65+
/// the Transaction that creates the uninitialized account with the system program. Otherwise
66+
/// another party can acquire ownership of the uninitialized token account.
67+
///
5668
/// Accounts expected by this instruction:
5769
///
58-
/// 0. `[signer, writable]` The multisignature account to initialize.
70+
/// 0. `[writable]` The multisignature account to initialize.
5971
/// 1. ..1+N. `[]` The signer accounts, must equal to N where 1 <= N <= 11.
6072
InitializeMultisig(u8),
6173
/// Transfers tokens from one account to another either directly or via a delegate.
@@ -254,7 +266,7 @@ pub fn initialize_mint(
254266
) -> Result<Instruction, ProgramError> {
255267
let data = TokenInstruction::InitializeMint(token_info).serialize()?;
256268

257-
let mut accounts = vec![AccountMeta::new(*mint_pubkey, true)];
269+
let mut accounts = vec![AccountMeta::new(*mint_pubkey, false)];
258270
if token_info.supply != 0 {
259271
match account_pubkey {
260272
Some(pubkey) => accounts.push(AccountMeta::new(*pubkey, false)),
@@ -289,7 +301,7 @@ pub fn initialize_account(
289301
let data = TokenInstruction::InitializeAccount.serialize()?;
290302

291303
let accounts = vec![
292-
AccountMeta::new(*account_pubkey, true),
304+
AccountMeta::new(*account_pubkey, false),
293305
AccountMeta::new_readonly(*mint_pubkey, false),
294306
AccountMeta::new_readonly(*owner_pubkey, false),
295307
];
@@ -317,7 +329,7 @@ pub fn initialize_multisig(
317329
let data = TokenInstruction::InitializeMultisig(m).serialize()?;
318330

319331
let mut accounts = Vec::with_capacity(1 + signer_pubkeys.len());
320-
accounts.push(AccountMeta::new(*multisig_pubkey, true));
332+
accounts.push(AccountMeta::new(*multisig_pubkey, false));
321333
for signer_pubkey in signer_pubkeys.iter() {
322334
accounts.push(AccountMeta::new_readonly(**signer_pubkey, false));
323335
}

token/src/state.rs

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -97,10 +97,6 @@ impl State {
9797
let account_info_iter = &mut accounts.iter();
9898
let mint_info = next_account_info(account_info_iter)?;
9999

100-
if !mint_info.is_signer {
101-
return Err(ProgramError::MissingRequiredSignature);
102-
}
103-
104100
if State::Unallocated != State::deserialize(&mint_info.data.borrow())? {
105101
return Err(TokenError::AlreadyInUse.into());
106102
}
@@ -140,10 +136,6 @@ impl State {
140136
let mint_info = next_account_info(account_info_iter)?;
141137
let owner_info = next_account_info(account_info_iter)?;
142138

143-
if !new_account_info.is_signer {
144-
return Err(ProgramError::MissingRequiredSignature);
145-
}
146-
147139
let mut new_account_data = new_account_info.data.borrow_mut();
148140
if State::Unallocated != State::deserialize(&new_account_data)? {
149141
return Err(TokenError::AlreadyInUse.into());
@@ -713,18 +705,6 @@ mod tests {
713705
let mint_key = pubkey_rand();
714706
let mut mint_account = Account::new(0, size_of::<State>(), &program_id);
715707

716-
// missing signer
717-
let mut instruction =
718-
initialize_account(&program_id, &account_key, &mint_key, &owner_key).unwrap();
719-
instruction.accounts[0].is_signer = false;
720-
assert_eq!(
721-
Err(ProgramError::MissingRequiredSignature),
722-
do_process_instruction(
723-
instruction,
724-
vec![&mut account_account, &mut mint_account, &mut owner_account],
725-
)
726-
);
727-
728708
// create account
729709
do_process_instruction(
730710
initialize_account(&program_id, &account_key, &mint_key, &owner_key).unwrap(),

0 commit comments

Comments
 (0)