Skip to content

Commit

Permalink
allow self remove pubkey auths hax
Browse files Browse the repository at this point in the history
  • Loading branch information
nhanphan committed Mar 6, 2024
1 parent feab133 commit 60dde9c
Show file tree
Hide file tree
Showing 2 changed files with 120 additions and 0 deletions.
91 changes: 91 additions & 0 deletions clients/js/test/removeAuthority.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
plugin,
removePluginAuthority,
updateAuthority,
createCollection,
} from '../src';
import { createUmi } from './_setup';

Expand Down Expand Up @@ -300,3 +301,93 @@ test('it can remove a pubkey authority from a plugin if that pubkey is the signe
],
});
});

test('it can remove a pubkey authority from a asset in collection if that pubkey is the signer authority', async (t) => {
// Given a Umi instance and a new signer.
const umi = await createUmi();
const assetAddress = generateSigner(umi);
const pubkeyAuth = await generateSignerWithSol(umi);
const collectionAddress = generateSigner(umi);

await createCollection(umi, {
collection: collectionAddress,
name: 'Test Collection',
uri: 'https://example.com/collection',
plugins: []
}).sendAndConfirm(umi);

// When we create a new account.
await create(umi, {
dataState: DataState.AccountState,
collection: collectionAddress.publicKey,
asset: assetAddress,
name: 'Test Bread',
uri: 'https://example.com/bread',
plugins: [],
}).sendAndConfirm(umi);

await addPlugin(umi, {
asset: assetAddress.publicKey,
plugin: plugin('Freeze', [{ frozen: false }]),
}).sendAndConfirm(umi);

await addPluginAuthority(umi, {
asset: assetAddress.publicKey,
pluginType: PluginType.Freeze,
newAuthority: {
__kind: 'Pubkey',
address: pubkeyAuth.publicKey,
},
}).sendAndConfirm(umi);

const asset1 = await fetchAssetWithPlugins(umi, assetAddress.publicKey);
// console.log(JSON.stringify(asset1, (_, v) => typeof v === 'bigint' ? v.toString() : v, 2));
t.like(asset1, <AssetWithPlugins>{
publicKey: assetAddress.publicKey,
updateAuthority: updateAuthority('Collection', [collectionAddress.publicKey]),
owner: umi.identity.publicKey,
name: 'Test Bread',
uri: 'https://example.com/bread',
plugins: [
{
authorities: [{ __kind: 'Owner' }, { __kind: 'Pubkey', address: pubkeyAuth.publicKey }],
plugin: {
__kind: 'Freeze',
fields: [{ frozen: false }],
},
},
],
});

const umi2 = await createUmi();

await removePluginAuthority(umi2, {
payer: umi2.identity,
asset: assetAddress.publicKey,
authority: pubkeyAuth,
pluginType: PluginType.Freeze,
authorityToRemove: {
__kind: 'Pubkey',
address: pubkeyAuth.publicKey,
},
}).sendAndConfirm(umi);

const asset2 = await fetchAssetWithPlugins(umi, assetAddress.publicKey);
// console.log(JSON.stringify(asset1, (_, v) => typeof v === 'bigint' ? v.toString() : v, 2));
t.like(asset2, <AssetWithPlugins>{
publicKey: assetAddress.publicKey,
updateAuthority: updateAuthority('Collection', [collectionAddress.publicKey]),
owner: umi.identity.publicKey,
name: 'Test Bread',
uri: 'https://example.com/bread',
plugins: [
{
authorities: [{ __kind: 'Owner' }],
plugin: {
__kind: 'Freeze',
fields: [{ frozen: false }],
},
},
],
});
});
29 changes: 29 additions & 0 deletions programs/mpl-core/src/processor/remove_plugin_authority.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,35 @@ pub(crate) fn remove_plugin_authority<'a>(
};

let (asset, plugin_header, mut plugin_registry) = fetch_core_data::<Asset>(ctx.accounts.asset)?;

// pubkey authorities can remove themselves if they are a signer, skip subsequent checks
// TODO refactor this, duplicate code
let plugin_registry_some = match plugin_registry.as_ref() {
Some(registry) => registry,
None => return Err(MplCoreError::PluginsNotInitialized.into()),
};

let registry_record = &plugin_registry_some
.registry
.iter()
.find(|record| record.plugin_type == args.plugin_type)
.ok_or(MplCoreError::PluginNotFound)?;
if (Authority::Pubkey { address: ctx.accounts.authority.key.clone() } == args.authority_to_remove.clone() &&
registry_record.authorities.contains(&args.authority_to_remove)) {
return process_remove_plugin_authority(
ctx.accounts.asset,
payer,
ctx.accounts.system_program,
&Authority::Pubkey {
address: *ctx.accounts.authority.key,
},
&args.plugin_type,
&args.authority_to_remove,
plugin_header.as_ref(),
plugin_registry.as_mut(),
);
}
// End really bad code

//TODO: Make this better.
let authority_type = if ctx.accounts.authority.key == &asset.owner {
Expand Down

0 comments on commit 60dde9c

Please sign in to comment.