Skip to content

Commit

Permalink
Add capability to freeze token Accounts (solana-labs#297)
Browse files Browse the repository at this point in the history
* Add freeze elements to state structs

* Add can_freeze paramter to InitializeMint instruction, and plumb

* Add fixed_supply parameter to InitializeMint

* Convert to SetAuthority instruction

* Add frozen restrictions

* Add FreezeAccount instruction

* Make FreezeAccount into toggle

* Add parameter to make freezing explicit

* Pass mint owner, freeze_authority as parameters

* Rename ToggleFreeze

* Make AuthorityType more explicit

* Rename mint owner => mint_authority

* Add Account::is_frozen method

* C header updates

* s/is_initialized/state for Account

* Minting nit

* Add helpers to clean up AuthorityType packing

* Split FreezeAccount into 2 instructions

* Pass new_authority as parameter not account

* More C header updates

* Use new COption helpers

* Use boolean for toggle fn
  • Loading branch information
CriesofCarrots authored Aug 25, 2020
1 parent c2da3db commit c00adbe
Show file tree
Hide file tree
Showing 5 changed files with 1,294 additions and 220 deletions.
209 changes: 157 additions & 52 deletions token/program2/inc/token2.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,85 @@
*/
#define Token_MIN_SIGNERS 1

/**
* Account state.
*/
enum Token_AccountState
#ifdef __cplusplus
: uint8_t
#endif // __cplusplus
{
/**
* Account is not yet initialized
*/
Token_AccountState_Uninitialized,
/**
* Account is initialized; the account owner and/or delegate may perform permitted operations
* on this account
*/
Token_AccountState_Initialized,
/**
* Account has been frozen by the mint freeze authority. Neither the account owner nor
* the delegate are able to perform operations on this account.
*/
Token_AccountState_Frozen,
};
#ifndef __cplusplus
typedef uint8_t Token_AccountState;
#endif // __cplusplus

/**
* Specifies the authority type for SetAuthority instructions
*/
enum Token_AuthorityType
#ifdef __cplusplus
: uint8_t
#endif // __cplusplus
{
/**
* Authority to mint new tokens
*/
Token_AuthorityType_MintTokens,
/**
* Authority to freeze any account associated with the Mint
*/
Token_AuthorityType_FreezeAccount,
/**
* Holder of a given token account
*/
Token_AuthorityType_AccountHolder,
};
#ifndef __cplusplus
typedef uint8_t Token_AuthorityType;
#endif // __cplusplus

typedef uint8_t Token_Pubkey[32];

/**
* A C representation of Rust's `std::option::Option`
*/
typedef enum Token_COption_Pubkey_Tag {
/**
* No value
*/
Token_COption_Pubkey_None_Pubkey,
/**
* Some value `T`
*/
Token_COption_Pubkey_Some_Pubkey,
} Token_COption_Pubkey_Tag;

typedef struct Token_COption_Pubkey_Token_Some_Body_Pubkey {
Token_Pubkey _0;
} Token_COption_Pubkey_Token_Some_Body_Pubkey;

typedef struct Token_COption_Pubkey {
Token_COption_Pubkey_Tag tag;
union {
Token_COption_Pubkey_Token_Some_Body_Pubkey some;
};
} Token_COption_Pubkey;

/**
* Instructions supported by the token program.
*/
Expand All @@ -35,11 +114,7 @@ typedef enum Token_TokenInstruction_Tag {
* Accounts expected by this instruction:
*
* 0. `[writable]` The mint to initialize.
* 1.
* * If supply is non-zero: `[writable]` The account to hold all the newly minted tokens.
* * If supply is zero: `[]` The owner/multisignature of the mint.
* 2. `[]` (optional) The owner/multisignature of the mint if supply is non-zero, if
* present then further minting is supported.
* 1. If supply is non-zero: `[writable]` The account to hold all the newly minted tokens.
*
*/
Token_TokenInstruction_InitializeMint,
Expand Down Expand Up @@ -127,36 +202,34 @@ typedef enum Token_TokenInstruction_Tag {
*/
Token_TokenInstruction_Revoke,
/**
* Sets a new owner of a mint or account.
* Sets a new authority of a mint or account.
*
* Accounts expected by this instruction:
*
* * Single owner
* 0. `[writable]` The mint or account to change the owner of.
* 1. `[]` The new owner/delegate/multisignature.
* 2. `[signer]` The owner of the mint or account.
* * Single authority
* 0. `[writable]` The mint or account to change the authority of.
* 1. `[signer]` The current authority of the mint or account.
*
* * Multisignature owner
* 0. `[writable]` The mint or account to change the owner of.
* 1. `[]` The new owner/delegate/multisignature.
* 2. `[]` The mint's or account's multisignature owner.
* * Multisignature authority
* 0. `[writable]` The mint or account to change the authority of.
* 1. `[]` The mint's or account's multisignature authority.
* 3. ..3+M '[signer]' M signer accounts
*/
Token_TokenInstruction_SetOwner,
Token_TokenInstruction_SetAuthority,
/**
* Mints new tokens to an account. The native mint does not support minting.
*
* Accounts expected by this instruction:
*
* * Single owner
* * Single authority
* 0. `[writable]` The mint.
* 1. `[writable]` The account to mint tokens to.
* 2. `[signer]` The mint's owner.
* 2. `[signer]` The mint's minting authority.
*
* * Multisignature owner
* * Multisignature authority
* 0. `[writable]` The mint.
* 1. `[writable]` The account to mint tokens to.
* 2. `[]` The mint's multisignature owner.
* 2. `[]` The mint's multisignature mint-tokens authority.
* 3. ..3+M '[signer]' M signer accounts.
*/
Token_TokenInstruction_MintTo,
Expand Down Expand Up @@ -194,6 +267,40 @@ typedef enum Token_TokenInstruction_Tag {
* 3. ..3+M '[signer]' M signer accounts.
*/
Token_TokenInstruction_CloseAccount,
/**
* Freeze an Initialized account using the Mint's freeze_authority (if set).
*
* Accounts expected by this instruction:
*
* * Single owner
* 0. `[writable]` The account to freeze.
* 1. '[]' The token mint.
* 2. `[signer]` The mint freeze authority.
*
* * Multisignature owner
* 0. `[writable]` The account to freeze.
* 1. '[]' The token mint.
* 2. `[]` The mint's multisignature freeze authority.
* 3. ..3+M '[signer]' M signer accounts.
*/
Token_TokenInstruction_FreezeAccount,
/**
* Thaw a Frozen account using the Mint's freeze_authority (if set).
*
* Accounts expected by this instruction:
*
* * Single owner
* 0. `[writable]` The account to freeze.
* 1. '[]' The token mint.
* 2. `[signer]` The mint freeze authority.
*
* * Multisignature owner
* 0. `[writable]` The account to freeze.
* 1. '[]' The token mint.
* 2. `[]` The mint's multisignature freeze authority.
* 3. ..3+M '[signer]' M signer accounts.
*/
Token_TokenInstruction_ThawAccount,
} Token_TokenInstruction_Tag;

typedef struct Token_TokenInstruction_Token_InitializeMint_Body {
Expand All @@ -205,6 +312,15 @@ typedef struct Token_TokenInstruction_Token_InitializeMint_Body {
* Number of base 10 digits to the right of the decimal place.
*/
uint8_t decimals;
/**
* The authority/multisignature to mint tokens, if supply is non-zero. If present,
* further minting is supported.
*/
Token_COption_Pubkey mint_authority;
/**
* The freeze authority/multisignature of the mint.
*/
Token_COption_Pubkey freeze_authority;
} Token_TokenInstruction_Token_InitializeMint_Body;

typedef struct Token_TokenInstruction_Token_InitializeMultisig_Body {
Expand All @@ -228,6 +344,17 @@ typedef struct Token_TokenInstruction_Token_Approve_Body {
uint64_t amount;
} Token_TokenInstruction_Token_Approve_Body;

typedef struct Token_TokenInstruction_Token_SetAuthority_Body {
/**
* The type of authority to update.
*/
Token_AuthorityType authority_type;
/**
* The new authority
*/
Token_COption_Pubkey new_authority;
} Token_TokenInstruction_Token_SetAuthority_Body;

typedef struct Token_TokenInstruction_Token_MintTo_Body {
/**
* The amount of new tokens to mint.
Expand All @@ -249,48 +376,22 @@ typedef struct Token_TokenInstruction {
Token_TokenInstruction_Token_InitializeMultisig_Body initialize_multisig;
Token_TokenInstruction_Token_Transfer_Body transfer;
Token_TokenInstruction_Token_Approve_Body approve;
Token_TokenInstruction_Token_SetAuthority_Body set_authority;
Token_TokenInstruction_Token_MintTo_Body mint_to;
Token_TokenInstruction_Token_Burn_Body burn;
};
} Token_TokenInstruction;

typedef uint8_t Token_Pubkey[32];

/**
* A C representation of Rust's `std::option::Option`
*/
typedef enum Token_COption_Pubkey_Tag {
/**
* No value
*/
Token_COption_Pubkey_None_Pubkey,
/**
* Some value `T`
*/
Token_COption_Pubkey_Some_Pubkey,
} Token_COption_Pubkey_Tag;

typedef struct Token_COption_Pubkey_Token_Some_Body_Pubkey {
Token_Pubkey _0;
} Token_COption_Pubkey_Token_Some_Body_Pubkey;

typedef struct Token_COption_Pubkey {
Token_COption_Pubkey_Tag tag;
union {
Token_COption_Pubkey_Token_Some_Body_Pubkey some;
};
} Token_COption_Pubkey;

/**
* Mint data.
*/
typedef struct Token_Mint {
/**
* Optional owner, used to mint new tokens. The owner may only
* be provided during mint creation. If no owner is present then the mint
* has a fixed supply and no further tokens may be minted.
* Optional authority used to mint new tokens. The mint authority may only be provided during
* mint creation. If no mint authority is present then the mint has a fixed supply and no
* further tokens may be minted.
*/
Token_COption_Pubkey owner;
Token_COption_Pubkey mint_authority;
/**
* Number of base 10 digits to the right of the decimal place.
*/
Expand All @@ -299,6 +400,10 @@ typedef struct Token_Mint {
* Is `true` if this structure has been initialized
*/
bool is_initialized;
/**
* Optional authority to freeze token accounts.
*/
Token_COption_Pubkey freeze_authority;
} Token_Mint;

/**
Expand All @@ -323,9 +428,9 @@ typedef struct Token_Account {
*/
Token_COption_Pubkey delegate;
/**
* Is `true` if this structure has been initialized
* The account's state
*/
bool is_initialized;
Token_AccountState state;
/**
* Is this a native token
*/
Expand Down
12 changes: 12 additions & 0 deletions token/program2/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,21 @@ pub enum TokenError {
/// Invalid instruction
#[error("Invalid instruction")]
InvalidInstruction,
/// State is invalid for requested operation.
#[error("State is invalid for requested operation")]
InvalidState,
/// Operation overflowed
#[error("Operation overflowed")]
Overflow,
/// Account does not support specified authority type.
#[error("Account does not support specified authority type")]
AuthorityTypeNotSupported,
/// This token mint cannot freeze accounts.
#[error("This token mint cannot freeze accounts")]
MintCannotFreeze,
/// Account is frozen; all account operations will fail
#[error("Account is frozen")]
AccountFrozen,
}
impl From<TokenError> for ProgramError {
fn from(e: TokenError) -> Self {
Expand Down
Loading

0 comments on commit c00adbe

Please sign in to comment.