Skip to content
Open
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
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions js/compressed-token/src/v3/layout/layout-transfer2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export const EXTENSION_DISCRIMINANT_COMPRESSIBLE = 32;
export const COMPRESSION_MODE_COMPRESS = 0;
export const COMPRESSION_MODE_DECOMPRESS = 1;
export const COMPRESSION_MODE_COMPRESS_AND_CLOSE = 2;
export const COMPRESSION_MODE_DECOMPRESS_IDEMPOTENT = 3;

/**
* Compression struct for Transfer2 instruction
Expand Down
8 changes: 8 additions & 0 deletions program-libs/token-interface/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,12 @@ pub enum TokenError {

#[error("ATA derivation failed or mismatched for is_ata compressed token")]
InvalidAtaDerivation,

#[error("DecompressIdempotent requires exactly 1 input and 1 compression")]
IdempotentDecompressRequiresSingleInput,

#[error("DecompressIdempotent is only supported for ATA accounts (is_ata must be true)")]
IdempotentDecompressRequiresAta,
}

impl From<TokenError> for u32 {
Expand Down Expand Up @@ -277,6 +283,8 @@ impl From<TokenError> for u32 {
TokenError::DecompressAmountMismatch => 18064,
TokenError::CompressionIndexOutOfBounds => 18065,
TokenError::InvalidAtaDerivation => 18066,
TokenError::IdempotentDecompressRequiresSingleInput => 18067,
TokenError::IdempotentDecompressRequiresAta => 18068,
TokenError::HasherError(e) => u32::from(e),
TokenError::ZeroCopyError(e) => u32::from(e),
TokenError::CompressedAccountError(e) => u32::from(e),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ pub enum CompressionMode {
/// Signer must be rent authority, token account must be compressible
/// Not implemented for spl token accounts.
CompressAndClose,
/// Permissionless ATA decompress with single-input constraint.
/// Requires CompressedOnly extension with is_ata=true.
/// On-chain behavior is identical to Decompress.
DecompressIdempotent,
}

impl ZCompressionMode {
Expand All @@ -24,7 +28,10 @@ impl ZCompressionMode {
}

pub fn is_decompress(&self) -> bool {
matches!(self, ZCompressionMode::Decompress)
matches!(
self,
ZCompressionMode::Decompress | ZCompressionMode::DecompressIdempotent
)
}

pub fn is_compress_and_close(&self) -> bool {
Expand All @@ -35,6 +42,7 @@ impl ZCompressionMode {
pub const COMPRESS: u8 = 0u8;
pub const DECOMPRESS: u8 = 1u8;
pub const COMPRESS_AND_CLOSE: u8 = 2u8;
pub const DECOMPRESS_IDEMPOTENT: u8 = 3u8;

impl<'a> ZeroCopyAtMut<'a> for CompressionMode {
type ZeroCopyAtMut = Ref<&'a mut [u8], u8>;
Expand Down Expand Up @@ -204,6 +212,20 @@ impl Compression {
decimals: 0,
}
}

pub fn decompress_idempotent(amount: u64, mint: u8, recipient: u8) -> Self {
Compression {
amount,
mode: CompressionMode::DecompressIdempotent,
mint,
source_or_recipient: recipient,
authority: 0,
pool_account_index: 0,
pool_index: 0,
bump: 0,
decimals: 0,
}
}
}

impl ZCompressionMut<'_> {
Expand All @@ -212,6 +234,7 @@ impl ZCompressionMut<'_> {
COMPRESS => Ok(CompressionMode::Compress),
DECOMPRESS => Ok(CompressionMode::Decompress),
COMPRESS_AND_CLOSE => Ok(CompressionMode::CompressAndClose),
DECOMPRESS_IDEMPOTENT => Ok(CompressionMode::DecompressIdempotent),
_ => Err(TokenError::InvalidCompressionMode),
}
}
Expand All @@ -226,7 +249,7 @@ impl ZCompression<'_> {
.checked_add((*self.amount).into())
.ok_or(TokenError::ArithmeticOverflow)
}
ZCompressionMode::Decompress => {
ZCompressionMode::Decompress | ZCompressionMode::DecompressIdempotent => {
// Decompress: subtract from balance (tokens are being removed from spl token pool)
current_balance
.checked_sub((*self.amount).into())
Expand Down
Loading
Loading