Skip to content

Commit

Permalink
Merge pull request #8 from metaplex-foundation/bug/fix-decreasing-of-…
Browse files Browse the repository at this point in the history
…escrow-account-size

Fixed the inability to descrease in size both the name and URI during escrow_update
  • Loading branch information
tonyboylehub authored Nov 19, 2024
2 parents 90d5eae + f09e25e commit 4aa2705
Show file tree
Hide file tree
Showing 2 changed files with 284 additions and 13 deletions.
273 changes: 273 additions & 0 deletions clients/js/test/updateEscrow.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,273 @@
import test from 'ava';
import { generateSigner, publicKey } from '@metaplex-foundation/umi';
import {
string,
publicKey as publicKeySerializer,
} from '@metaplex-foundation/umi/serializers';
import { createFungible } from '@metaplex-foundation/mpl-token-metadata';
import {
findAssociatedTokenPda,
SPL_ASSOCIATED_TOKEN_PROGRAM_ID,
} from '@metaplex-foundation/mpl-toolbox';
import { createCoreCollection, createUmi } from './_setup';
import {
deserializeEscrowV1,
EscrowV1,
fetchEscrowV1,
initEscrowV1,
MPL_HYBRID_PROGRAM_ID,
Path,
updateEscrowV1,
} from '../src';

test('it can update an escrow', async (t) => {
// Given a Umi instance using the project's plugin.
const umi = await createUmi();
const feeLocation = generateSigner(umi);
const { collection } = await createCoreCollection(umi);
const tokenMint = generateSigner(umi);
await createFungible(umi, {
name: 'Test Token',
uri: 'www.fungible.com',
sellerFeeBasisPoints: {
basisPoints: 0n,
identifier: '%',
decimals: 2,
},
mint: tokenMint,
}).sendAndConfirm(umi);

const escrow = umi.eddsa.findPda(MPL_HYBRID_PROGRAM_ID, [
string({ size: 'variable' }).serialize('escrow'),
publicKeySerializer().serialize(collection.publicKey),
]);

await initEscrowV1(umi, {
escrow,
collection: collection.publicKey,
token: tokenMint.publicKey,
feeLocation: feeLocation.publicKey,
name: 'Test Escrow',
uri: 'www.test.com',
max: 2,
min: 1,
amount: 3,
feeAmount: 4,
path: Path.RerollMetadata,
solFeeAmount: 5,
feeAta: findAssociatedTokenPda(umi, {
mint: tokenMint.publicKey,
owner: publicKey(feeLocation.publicKey),
}),
associatedTokenProgram: SPL_ASSOCIATED_TOKEN_PROGRAM_ID,
}).sendAndConfirm(umi);

await updateEscrowV1(umi, {
escrow,
collection: collection.publicKey,
token: tokenMint.publicKey,
feeLocation: feeLocation.publicKey,
solFeeAmount: 6,
name: 'Update Escrow',
uri: 'www.test.com/updated',
max: 5n,
min: 1n,
amount: 3n,
feeAmount: 4n,
path: Path.RerollMetadata,
}).sendAndConfirm(umi, {
// send: { commitment: 'confirmed' },
// confirm: { commitment: 'confirmed' },
});

t.like(await fetchEscrowV1(umi, escrow), <EscrowV1>{
publicKey: publicKey(escrow),
collection: collection.publicKey,
token: tokenMint.publicKey,
feeLocation: feeLocation.publicKey,
name: 'Update Escrow',
uri: 'www.test.com/updated',
max: 5n,
min: 1n,
amount: 3n,
feeAmount: 4n,
count: 1n,
path: Path.RerollMetadata,
bump: escrow[1],
solFeeAmount: 6n,
});
});

test('it can update an escrow with a longer name and uri', async (t) => {
// Given a Umi instance using the project's plugin.
const umi = await createUmi();
const feeLocation = generateSigner(umi);
const { collection } = await createCoreCollection(umi);
const tokenMint = generateSigner(umi);
await createFungible(umi, {
name: 'Test Token',
uri: 'www.fungible.com',
sellerFeeBasisPoints: {
basisPoints: 0n,
identifier: '%',
decimals: 2,
},
mint: tokenMint,
}).sendAndConfirm(umi);

const escrow = umi.eddsa.findPda(MPL_HYBRID_PROGRAM_ID, [
string({ size: 'variable' }).serialize('escrow'),
publicKeySerializer().serialize(collection.publicKey),
]);

await initEscrowV1(umi, {
escrow,
collection: collection.publicKey,
token: tokenMint.publicKey,
feeLocation: feeLocation.publicKey,
name: 'Test Escrow',
uri: 'www.test.com',
max: 2,
min: 1,
amount: 3,
feeAmount: 4,
path: Path.RerollMetadata,
solFeeAmount: 5,
feeAta: findAssociatedTokenPda(umi, {
mint: tokenMint.publicKey,
owner: publicKey(feeLocation.publicKey),
}),
associatedTokenProgram: SPL_ASSOCIATED_TOKEN_PROGRAM_ID,
}).sendAndConfirm(umi);

const initialEscrowRaw = await umi.rpc.getAccount(escrow[0]);
if (!initialEscrowRaw.exists) {
throw new Error('Escrow account not found');
}

await updateEscrowV1(umi, {
escrow,
collection: collection.publicKey,
token: tokenMint.publicKey,
feeLocation: feeLocation.publicKey,
solFeeAmount: 6,
name: 'Test Escrow Updated',
uri: 'www.test.com/updated',
max: 5n,
min: 1n,
amount: 3n,
feeAmount: 4n,
path: Path.RerollMetadata,
}).sendAndConfirm(umi);

const updatedEscrowRaw = await umi.rpc.getAccount(escrow[0]);
if (!updatedEscrowRaw.exists) {
throw new Error('Escrow account not found');
}

t.true(updatedEscrowRaw.data.length > initialEscrowRaw.data.length);

t.like(await fetchEscrowV1(umi, escrow), <EscrowV1>{
publicKey: publicKey(escrow),
collection: collection.publicKey,
token: tokenMint.publicKey,
feeLocation: feeLocation.publicKey,
name: 'Test Escrow Updated',
uri: 'www.test.com/updated',
max: 5n,
min: 1n,
amount: 3n,
feeAmount: 4n,
count: 1n,
path: Path.RerollMetadata,
bump: escrow[1],
solFeeAmount: 6n,
});
});

test('it can update an escrow with a shortner name and uri', async (t) => {
// Given a Umi instance using the project's plugin.
const umi = await createUmi();
const feeLocation = generateSigner(umi);
const { collection } = await createCoreCollection(umi);
const tokenMint = generateSigner(umi);
await createFungible(umi, {
name: 'Test Token',
uri: 'www.fungible.com',
sellerFeeBasisPoints: {
basisPoints: 0n,
identifier: '%',
decimals: 2,
},
mint: tokenMint,
}).sendAndConfirm(umi);

const escrow = umi.eddsa.findPda(MPL_HYBRID_PROGRAM_ID, [
string({ size: 'variable' }).serialize('escrow'),
publicKeySerializer().serialize(collection.publicKey),
]);

await initEscrowV1(umi, {
escrow,
collection: collection.publicKey,
token: tokenMint.publicKey,
feeLocation: feeLocation.publicKey,
name: 'Test Escrow',
uri: 'www.test.com',
max: 2,
min: 1,
amount: 3,
feeAmount: 4,
path: Path.RerollMetadata,
solFeeAmount: 5,
feeAta: findAssociatedTokenPda(umi, {
mint: tokenMint.publicKey,
owner: publicKey(feeLocation.publicKey),
}),
associatedTokenProgram: SPL_ASSOCIATED_TOKEN_PROGRAM_ID,
}).sendAndConfirm(umi);

const initialEscrowRaw = await umi.rpc.getAccount(escrow[0]);
if (!initialEscrowRaw.exists) {
throw new Error('Escrow account not found');
}

await updateEscrowV1(umi, {
escrow,
collection: collection.publicKey,
token: tokenMint.publicKey,
feeLocation: feeLocation.publicKey,
solFeeAmount: 6,
name: 'Updated',
uri: 'www.test.io',
max: 5n,
min: 1n,
amount: 3n,
feeAmount: 4n,
path: Path.RerollMetadata,
}).sendAndConfirm(umi);

const updatedEscrowRaw = await umi.rpc.getAccount(escrow[0]);
if (!updatedEscrowRaw.exists) {
throw new Error('Escrow account not found');
}

t.true(updatedEscrowRaw.data.length < initialEscrowRaw.data.length);

t.like(deserializeEscrowV1(updatedEscrowRaw), <EscrowV1>{
publicKey: publicKey(escrow),
collection: collection.publicKey,
token: tokenMint.publicKey,
feeLocation: feeLocation.publicKey,
name: 'Updated',
uri: 'www.test.io',
max: 5n,
min: 1n,
amount: 3n,
feeAmount: 4n,
count: 1n,
path: Path.RerollMetadata,
bump: escrow[1],
solFeeAmount: 6n,
});
});
24 changes: 11 additions & 13 deletions programs/mpl-hybrid/src/instructions/update_escrow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,18 +79,18 @@ pub fn handler_update_escrow_v1(
escrow.authority = authority.key();
escrow.token = token.key();
escrow.fee_location = fee_location.key();

if let Some(name) = ix.name {
size_diff += name
.len()
.checked_sub(escrow.name.len())
.ok_or(MplHybridError::NumericalOverflow)? as isize;
size_diff += (name.len() as isize)
.checked_sub(escrow.name.len() as isize)
.ok_or(MplHybridError::NumericalOverflow)?;
escrow.name = name;
}

if let Some(uri) = ix.uri {
size_diff += uri
.len()
.checked_sub(escrow.uri.len())
.ok_or(MplHybridError::NumericalOverflow)? as isize;
size_diff += (uri.len() as isize)
.checked_sub(escrow.uri.len() as isize)
.ok_or(MplHybridError::NumericalOverflow)?;
escrow.uri = uri;
}
if let Some(max) = ix.max {
Expand All @@ -112,16 +112,14 @@ pub fn handler_update_escrow_v1(
escrow.path = path;
}

let new_size = escrow
.to_account_info()
.data_len()
.checked_add(size_diff as usize)
let new_size = (escrow.to_account_info().data_len() as isize)
.checked_add(size_diff)
.ok_or(MplHybridError::NumericalOverflow)?;
resize_or_reallocate_account_raw(
&escrow.to_account_info(),
authority,
&ctx.accounts.system_program,
new_size,
new_size as usize,
)?;

Ok(())
Expand Down

0 comments on commit 4aa2705

Please sign in to comment.