Skip to content

Commit

Permalink
Add collection check.
Browse files Browse the repository at this point in the history
  • Loading branch information
blockiosaurus committed Mar 12, 2024
1 parent 0c8b9f2 commit 5527d78
Show file tree
Hide file tree
Showing 7 changed files with 38 additions and 1 deletion.
13 changes: 13 additions & 0 deletions clients/js/src/generated/errors/mplCore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,19 @@ export class NotAvailableError extends ProgramError {
codeToErrorMap.set(0x17, NotAvailableError);
nameToErrorMap.set('NotAvailable', NotAvailableError);

/** MissingCollection: Missing collection */
export class MissingCollectionError extends ProgramError {
override readonly name: string = 'MissingCollection';

readonly code: number = 0x18; // 24

constructor(program: Program, cause?: Error) {
super('Missing collection', program, cause);
}
}
codeToErrorMap.set(0x18, MissingCollectionError);
nameToErrorMap.set('MissingCollection', MissingCollectionError);

/**
* Attempts to resolve a custom program error from the provided error code.
* @category Errors
Expand Down
4 changes: 3 additions & 1 deletion clients/js/test/plugins/asset/permanentFreeze.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,7 @@ test('it cannot move asset in a permanently frozen collection', async (t) => {
const result = transfer(umi, {
asset: asset.publicKey,
newOwner: newOwner.publicKey,
collection: collection.publicKey,
}).sendAndConfirm(umi);

await t.throwsAsync(result, {
Expand All @@ -236,7 +237,7 @@ test('it cannot move asset in a permanently frozen collection', async (t) => {
...DEFAULT_ASSET,
asset: asset.publicKey,
owner: umi.identity.publicKey,
updateAuthority: updateAuthority('Collection', [umi.identity.publicKey]),
updateAuthority: updateAuthority('Collection', [collection.publicKey]),
});
});

Expand Down Expand Up @@ -276,6 +277,7 @@ test('it can move asset with permanent freeze override in a frozen collection',
asset: asset.publicKey,
newOwner: newOwner.publicKey,
authority: umi.identity,
collection: collection.publicKey,
}).sendAndConfirm(umi);

await assertAsset(t, umi, {
Expand Down
3 changes: 3 additions & 0 deletions clients/rust/src/generated/errors/mpl_core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,9 @@ pub enum MplCoreError {
/// 23 (0x17) - Feature not available
#[error("Feature not available")]
NotAvailable,
/// 24 (0x18) - Missing collection
#[error("Missing collection")]
MissingCollection,
}

impl solana_program::program_error::PrintProgramError for MplCoreError {
Expand Down
5 changes: 5 additions & 0 deletions idls/mpl_core.json
Original file line number Diff line number Diff line change
Expand Up @@ -2369,6 +2369,11 @@
"code": 23,
"name": "NotAvailable",
"msg": "Feature not available"
},
{
"code": 24,
"name": "MissingCollection",
"msg": "Missing collection"
}
],
"metadata": {
Expand Down
4 changes: 4 additions & 0 deletions programs/mpl-core/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,10 @@ pub enum MplCoreError {
/// 23 - Feature not available
#[error("Feature not available")]
NotAvailable,

/// 24 - Missing collection
#[error("Missing collection")]
MissingCollection,
}

impl PrintProgramError for MplCoreError {
Expand Down
1 change: 1 addition & 0 deletions programs/mpl-core/src/plugins/lifecycle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ impl PluginType {
PluginType::Royalties => CheckResult::CanReject,
PluginType::Freeze => CheckResult::CanReject,
PluginType::Transfer => CheckResult::CanApprove,
PluginType::PermanentFreeze => CheckResult::CanReject,
_ => CheckResult::None,
}
}
Expand Down
9 changes: 9 additions & 0 deletions programs/mpl-core/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,15 @@ pub fn validate_asset_permissions<'a>(
) -> Result<(Asset, Option<PluginHeader>, Option<PluginRegistry>), ProgramError> {
let (deserialized_asset, plugin_header, plugin_registry) = fetch_core_data::<Asset>(asset)?;

// If the asset is part of a collection, the collection must be passed in and it must be correct.
if let UpdateAuthority::Collection(collection_address) = deserialized_asset.update_authority {
if collection.is_none() {
return Err(MplCoreError::MissingCollection.into());
} else if collection.unwrap().key != &collection_address {
return Err(MplCoreError::InvalidCollection.into());
}
}

let mut checks: BTreeMap<PluginType, (Key, CheckResult, RegistryRecord)> = BTreeMap::new();

// The asset approval overrides the collection approval.
Expand Down

0 comments on commit 5527d78

Please sign in to comment.