Skip to content

Commit

Permalink
token-2022: Add Pausable extension (solana-labs#7562)
Browse files Browse the repository at this point in the history
* token-2022: Add Pausable extension

#### Problem

Users want a more Ethereum-style token experience by being able to
"pause" their token, similar to the "Pausable" interface. When a mint is
paused, tokens cannot be minted, burned, or transferred.

#### Summary of changes

Add the extension and some tests. It covers the following interactions:

* mint / mint-checked
* burn / burn-checked
* transfer / transfer-checked / transfer-with-fee
* confidential transfer / confidential transfer with fee
* confidential mint / confidential burn

Unfortunately, the confidential mint / burn extension doesn't have
testing, so I couldn't get a full end-to-end test for it.

Also note that it's still possible to:

* move withheld tokens
* initialize token accounts
* close token accounts
* set authority
* freeze / thaw
* approve / revoke
* almost every other bit of extension management

* Fix comments and semicolon

* Add tests for deposit and withdraw
  • Loading branch information
joncinque authored Dec 9, 2024
1 parent f634a9b commit 612a301
Show file tree
Hide file tree
Showing 14 changed files with 1,128 additions and 4 deletions.
53 changes: 51 additions & 2 deletions token/client/src/token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ use {
ConfidentialTransferFeeConfig,
},
cpi_guard, default_account_state, group_member_pointer, group_pointer,
interest_bearing_mint, memo_transfer, metadata_pointer, scaled_ui_amount, transfer_fee,
transfer_hook, BaseStateWithExtensions, Extension, ExtensionType,
interest_bearing_mint, memo_transfer, metadata_pointer, pausable, scaled_ui_amount,
transfer_fee, transfer_hook, BaseStateWithExtensions, Extension, ExtensionType,
StateWithExtensionsOwned,
},
instruction, offchain,
Expand Down Expand Up @@ -193,6 +193,9 @@ pub enum ExtensionInitializationParams {
authority: Option<Pubkey>,
multiplier: f64,
},
PausableConfig {
authority: Pubkey,
},
}
impl ExtensionInitializationParams {
/// Get the extension type associated with the init params
Expand All @@ -213,6 +216,7 @@ impl ExtensionInitializationParams {
Self::GroupPointer { .. } => ExtensionType::GroupPointer,
Self::GroupMemberPointer { .. } => ExtensionType::GroupMemberPointer,
Self::ScaledUiAmountConfig { .. } => ExtensionType::ScaledUiAmount,
Self::PausableConfig { .. } => ExtensionType::Pausable,
}
}
/// Generate an appropriate initialization instruction for the given mint
Expand Down Expand Up @@ -331,6 +335,9 @@ impl ExtensionInitializationParams {
authority,
multiplier,
),
Self::PausableConfig { authority } => {
pausable::instruction::initialize(token_program_id, mint, &authority)
}
}
}
}
Expand Down Expand Up @@ -1753,6 +1760,48 @@ where
.await
}

/// Pause transferring, minting, and burning on the mint
pub async fn pause<S: Signers>(
&self,
authority: &Pubkey,
signing_keypairs: &S,
) -> TokenResult<T::Output> {
let signing_pubkeys = signing_keypairs.pubkeys();
let multisig_signers = self.get_multisig_signers(authority, &signing_pubkeys);

self.process_ixs(
&[pausable::instruction::pause(
&self.program_id,
self.get_address(),
authority,
&multisig_signers,
)?],
signing_keypairs,
)
.await
}

/// Resume transferring, minting, and burning on the mint
pub async fn resume<S: Signers>(
&self,
authority: &Pubkey,
signing_keypairs: &S,
) -> TokenResult<T::Output> {
let signing_pubkeys = signing_keypairs.pubkeys();
let multisig_signers = self.get_multisig_signers(authority, &signing_pubkeys);

self.process_ixs(
&[pausable::instruction::resume(
&self.program_id,
self.get_address(),
authority,
&multisig_signers,
)?],
signing_keypairs,
)
.await
}

/// Prevent unsafe usage of token account through CPI
pub async fn enable_cpi_guard<S: Signers>(
&self,
Expand Down
Loading

0 comments on commit 612a301

Please sign in to comment.