Skip to content

Commit 573d61b

Browse files
committed
use asset id as seed of sell state
1 parent 42864c2 commit 573d61b

File tree

6 files changed

+38
-32
lines changed

6 files changed

+38
-32
lines changed

programs/mmm/src/errors.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,4 +78,6 @@ pub enum MMMErrorCode {
7878
InvalidCnftCreators, // 0x1794
7979
#[msg("Invalid cnft metadata")]
8080
InvalidCnftMetadata, // 0x1795
81+
#[msg("Invalid cnft metadata args")]
82+
InvalidCnftMetadataArgs, // 0x1796
8183
}

programs/mmm/src/instructions/cnft/sol_cnft_fulfill_buy.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use crate::{
66
constants::*,
77
errors::MMMErrorCode,
88
index_ra,
9-
state::{BubblegumProgram, Pool, SellState, TreeConfigAnchor},
9+
state::{BubblegumProgram, Pool, SellState},
1010
util::{
1111
assert_valid_fees_bp, check_allowlists_for_cnft, check_remaining_accounts_for_m2,
1212
get_buyside_seller_receives, get_lp_fee_bp, get_sol_fee, get_sol_lp_fee,
@@ -22,6 +22,7 @@ use super::MetadataArgs;
2222
#[derive(AnchorSerialize, AnchorDeserialize)]
2323
pub struct SolCnftFulfillBuyArgs {
2424
// === cNFT transfer args === //
25+
asset_id: Pubkey,
2526
// The Merkle root for the tree. Can be retrieved from off-chain data store.
2627
root: [u8; 32],
2728
// The Keccak256 hash of the NFTs existing creators array (without the verified flag for the creator changed).
@@ -86,7 +87,7 @@ pub struct SolCnftFulfillBuy<'info> {
8687
bump,
8788
)]
8889
/// CHECK: This account is neither written to nor read from.
89-
pub tree_authority: Account<'info, TreeConfigAnchor>,
90+
pub tree_authority: UncheckedAccount<'info>,
9091

9192
// The account that contains the Merkle tree, initialized by create_tree.
9293
/// CHECK: This account is modified in the downstream Bubblegum program
@@ -109,8 +110,7 @@ pub struct SolCnftFulfillBuy<'info> {
109110
seeds = [
110111
SELL_STATE_PREFIX.as_bytes(),
111112
pool.key().as_ref(),
112-
merkle_tree.key().as_ref(),
113-
args.index.to_le_bytes().as_ref(),
113+
args.asset_id.as_ref(),
114114
],
115115
space = SellState::LEN,
116116
bump
@@ -231,6 +231,9 @@ pub fn handler<'info>(
231231
// 3. Transfer CNFT to buyer (pool or owner)
232232
let data_hash = hash_metadata(&args.metadata_args)?;
233233
let asset_mint = get_asset_id(&merkle_tree.key(), args.nonce);
234+
if asset_mint != args.asset_id {
235+
return Err(MMMErrorCode::InvalidCnftMetadataArgs.into());
236+
}
234237
// reinvest fulfill buy is just a placeholder for now if we want to enable double sided
235238
// pool for cnft in the the future.
236239
if pool.reinvest_fulfill_buy {

programs/mmm/src/util.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1226,6 +1226,7 @@ pub fn create_core_metadata_core(royalties: &Royalties) -> MplCoreMetadata {
12261226
}
12271227
}
12281228

1229+
// TODO: use the transfer cpi builder by mpl bubblegum
12291230
#[allow(clippy::too_many_arguments)]
12301231
pub fn transfer_compressed_nft<'info>(
12311232
tree_authority: &AccountInfo<'info>,

sdk/src/cnft.ts

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -52,24 +52,6 @@ export function getByteArray(key: PublicKey): Array<number> {
5252
return Array.from(key.toBuffer());
5353
}
5454

55-
export const getMMMCnftSellStatePDA = (
56-
programId: PublicKey,
57-
pool: PublicKey,
58-
merkleTree: PublicKey,
59-
index: number,
60-
) => {
61-
const [key, bump] = PublicKey.findProgramAddressSync(
62-
[
63-
Buffer.from(PREFIXES.SELL_STATE),
64-
pool.toBuffer(),
65-
merkleTree.toBuffer(),
66-
new BN(index).toBuffer('le', 4),
67-
],
68-
programId,
69-
);
70-
return { key, bump };
71-
};
72-
7355
// get "proof path" from asset proof, these are the accounts that need to be passed to the program as remaining accounts
7456
// may also be empty if tree is small enough, and canopy depth is large enough
7557
export function getProofPath(

sdk/src/idl/mmm.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2675,6 +2675,10 @@ export type Mmm = {
26752675
"type": {
26762676
"kind": "struct",
26772677
"fields": [
2678+
{
2679+
"name": "assetId",
2680+
"type": "publicKey"
2681+
},
26782682
{
26792683
"name": "root",
26802684
"type": {
@@ -3266,6 +3270,11 @@ export type Mmm = {
32663270
"code": 6037,
32673271
"name": "InvalidCnftMetadata",
32683272
"msg": "Invalid cnft metadata"
3273+
},
3274+
{
3275+
"code": 6038,
3276+
"name": "InvalidCnftMetadataArgs",
3277+
"msg": "Invalid cnft metadata args"
32693278
}
32703279
]
32713280
};
@@ -5947,6 +5956,10 @@ export const IDL: Mmm = {
59475956
"type": {
59485957
"kind": "struct",
59495958
"fields": [
5959+
{
5960+
"name": "assetId",
5961+
"type": "publicKey"
5962+
},
59505963
{
59515964
"name": "root",
59525965
"type": {
@@ -6538,6 +6551,11 @@ export const IDL: Mmm = {
65386551
"code": 6037,
65396552
"name": "InvalidCnftMetadata",
65406553
"msg": "Invalid cnft metadata"
6554+
},
6555+
{
6556+
"code": 6038,
6557+
"name": "InvalidCnftMetadataArgs",
6558+
"msg": "Invalid cnft metadata args"
65416559
}
65426560
]
65436561
};

tests/mmm-cnft.spec.ts

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import {
2323
getByteArray,
2424
getM2BuyerSharedEscrow,
2525
getMMMBuysideSolEscrowPDA,
26-
getMMMCnftSellStatePDA,
26+
getMMMSellStatePDA,
2727
getProofPath,
2828
getSolFulfillBuyPrices,
2929
IDL,
@@ -167,11 +167,10 @@ describe('cnft tests', () => {
167167
leafIndex,
168168
});
169169

170-
const { key: sellState } = getMMMCnftSellStatePDA(
170+
const { key: sellState } = getMMMSellStatePDA(
171171
program.programId,
172172
poolData.poolKey,
173-
new PublicKey(nft.tree.merkleTree),
174-
nft.nft.nftIndex,
173+
new PublicKey(assetId),
175174
);
176175

177176
const spotPrice = 1;
@@ -224,6 +223,7 @@ describe('cnft tests', () => {
224223

225224
const fulfillBuyTxnSig = await program.methods
226225
.cnftFulfillBuy({
226+
assetId: new PublicKey(assetId),
227227
root: getByteArray(nft.tree.root),
228228
creatorHash: getByteArray(nft.tree.creatorHash),
229229
nonce: new BN(nft.tree.nonce),
@@ -409,11 +409,10 @@ describe('cnft tests', () => {
409409
leafIndex,
410410
});
411411

412-
const { key: sellState } = getMMMCnftSellStatePDA(
412+
const { key: sellState } = getMMMSellStatePDA(
413413
program.programId,
414414
poolData.poolKey,
415-
new PublicKey(nft.tree.merkleTree),
416-
nft.nft.nftIndex,
415+
new PublicKey(assetId),
417416
);
418417

419418
const spotPrice = 1;
@@ -466,6 +465,7 @@ describe('cnft tests', () => {
466465

467466
const fulfillBuyTxnSig = await program.methods
468467
.cnftFulfillBuy({
468+
assetId: new PublicKey(assetId),
469469
root: getByteArray(nft.tree.root),
470470
creatorHash: getByteArray(nft.tree.creatorHash),
471471
nonce: new BN(nft.tree.nonce),
@@ -625,11 +625,10 @@ describe('cnft tests', () => {
625625
leafIndex,
626626
});
627627

628-
const { key: sellState } = getMMMCnftSellStatePDA(
628+
const { key: sellState } = getMMMSellStatePDA(
629629
program.programId,
630630
poolData.poolKey,
631-
new PublicKey(nft.tree.merkleTree),
632-
nft.nft.nftIndex,
631+
new PublicKey(assetId),
633632
);
634633

635634
const spotPrice = 1;
@@ -682,6 +681,7 @@ describe('cnft tests', () => {
682681

683682
const fulfillBuyTxnSig = await program.methods
684683
.cnftFulfillBuy({
684+
assetId: new PublicKey(assetId),
685685
root: getByteArray(nft.tree.root),
686686
creatorHash: getByteArray(nft.tree.creatorHash),
687687
nonce: new BN(nft.tree.nonce),

0 commit comments

Comments
 (0)