Skip to content

Commit

Permalink
Merge pull request #6 from rarible/fix-private-phase-no-merkle-issue
Browse files Browse the repository at this point in the history
[FIX] prevent adding private phase without merkle root
  • Loading branch information
ifelsedeveloper authored Oct 23, 2024
2 parents 2e5d964 + d0c651a commit 28fd1ff
Show file tree
Hide file tree
Showing 7 changed files with 60 additions and 14 deletions.
11 changes: 5 additions & 6 deletions Anchor.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,16 @@ resolution = true
skip-lint = false

[programs.localnet]
libreplex_editions = "GHVmd43GebD2SSedqG1AAh76izf5CPAhz6KotkZyRzUD"
libreplex_editions_controls = "CCWfNBFcrjbKSjKes9DqgiQYsnmCFgCVKx21mmV2xWgN"
libreplex_editions = "A927QYSgP2fJWWDJn1gZknSfsMXyyKnJvMf2kJoY5yeQ"
libreplex_editions_controls = "5GSxbLSQms8VoBmNPEsPPyr8TtSApX19cP8jAg4isJ3K"

[registry]
url = "https://api.apr.dev"

[provider]
cluster = "Localnet"
### @dev testing wallet
# wallet = "~/.config/solana/id.json"
### wallet = "~/.config/solana/id.json"
wallet = "usb://ledger"

[scripts]
Expand All @@ -27,8 +27,8 @@ upgradeable = false

[test.validator]
bind_address = "0.0.0.0"
### @dev: Utilize the testnet cluster for running the testsuite
# url = "https://api.testnet.solana.com"
### @dev: Utilize the testnet cluster for running test-suite with anchor test
### url = "https://api.testnet.solana.com"
url = "https://api.mainnet-beta.solana.com"
ledger = ".anchor/test-ledger"
rpc_port = 8899
Expand All @@ -47,4 +47,3 @@ address = "metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s"

[[test.validator.clone]]
address = "5hx15GaPPqsYA61v6QpcGPpo125v7rfvEfZQ4dJErG5V"

3 changes: 2 additions & 1 deletion programs/libreplex_editions/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ use anchor_lang::prelude::*;

pub mod instructions;
pub use instructions::*;
declare_id!("GHVmd43GebD2SSedqG1AAh76izf5CPAhz6KotkZyRzUD");

declare_id!("A927QYSgP2fJWWDJn1gZknSfsMXyyKnJvMf2kJoY5yeQ");

pub mod errors;
pub mod state;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@ pub fn add_phase(ctx: Context<AddPhaseCtx>, input: InitialisePhaseInput) -> Resu
if !input.price_token.eq(&wrapped_sol::ID) {
panic!("Only native price currently supported")
}

if input.is_private && input.merkle_root.is_none() {
panic!("Merkle root must be provided for private phases");
}

let editions_controls = &mut ctx.accounts.editions_controls;

editions_controls.phases.push(Phase{
Expand Down
2 changes: 1 addition & 1 deletion programs/libreplex_editions_controls/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ pub use logic::*;

pub mod instructions;
pub use instructions::*;
declare_id!("CCWfNBFcrjbKSjKes9DqgiQYsnmCFgCVKx21mmV2xWgN");
declare_id!("5GSxbLSQms8VoBmNPEsPPyr8TtSApX19cP8jAg4isJ3K");

pub mod errors;
pub mod state;
Expand Down
2 changes: 1 addition & 1 deletion target/types/libreplex_editions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* IDL can be found at `target/idl/libreplex_editions.json`.
*/
export type LibreplexEditions = {
"address": "5hx15GaPPqsYA61v6QpcGPpo125v7rfvEfZQ4dJErG5V",
"address": "A927QYSgP2fJWWDJn1gZknSfsMXyyKnJvMf2kJoY5yeQ",
"metadata": {
"name": "libreplexEditions",
"version": "0.2.1",
Expand Down
10 changes: 5 additions & 5 deletions target/types/libreplex_editions_controls.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* IDL can be found at `target/idl/libreplex_editions_controls.json`.
*/
export type LibreplexEditionsControls = {
"address": "CCWfNBFcrjbKSjKes9DqgiQYsnmCFgCVKx21mmV2xWgN",
"address": "5GSxbLSQms8VoBmNPEsPPyr8TtSApX19cP8jAg4isJ3K",
"metadata": {
"name": "libreplexEditionsControls",
"version": "0.2.1",
Expand Down Expand Up @@ -51,7 +51,7 @@ export type LibreplexEditionsControls = {
},
{
"name": "libreplexEditionsProgram",
"address": "GHVmd43GebD2SSedqG1AAh76izf5CPAhz6KotkZyRzUD"
"address": "A927QYSgP2fJWWDJn1gZknSfsMXyyKnJvMf2kJoY5yeQ"
}
],
"args": [
Expand Down Expand Up @@ -152,7 +152,7 @@ export type LibreplexEditionsControls = {
},
{
"name": "libreplexEditionsProgram",
"address": "GHVmd43GebD2SSedqG1AAh76izf5CPAhz6KotkZyRzUD"
"address": "A927QYSgP2fJWWDJn1gZknSfsMXyyKnJvMf2kJoY5yeQ"
}
],
"args": [
Expand Down Expand Up @@ -365,7 +365,7 @@ export type LibreplexEditionsControls = {
},
{
"name": "libreplexEditionsProgram",
"address": "GHVmd43GebD2SSedqG1AAh76izf5CPAhz6KotkZyRzUD"
"address": "A927QYSgP2fJWWDJn1gZknSfsMXyyKnJvMf2kJoY5yeQ"
}
],
"args": [
Expand Down Expand Up @@ -595,7 +595,7 @@ export type LibreplexEditionsControls = {
},
{
"name": "libreplexEditionsProgram",
"address": "GHVmd43GebD2SSedqG1AAh76izf5CPAhz6KotkZyRzUD"
"address": "A927QYSgP2fJWWDJn1gZknSfsMXyyKnJvMf2kJoY5yeQ"
}
],
"args": [
Expand Down
41 changes: 41 additions & 0 deletions test/tests/editions_controls.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -510,6 +510,47 @@ describe('Editions Controls Test Suite', () => {
// verify state
expect(editionsControlsDecoded.data.phases.length).to.equal(6);
});

it('Should fail to add a private phase without providing the merkle root', async () => {
const invalidPhaseConfig = {
maxMintsPerWallet: new anchor.BN(100),
maxMintsTotal: new anchor.BN(1000),
priceAmount: new anchor.BN(500000), // 0.05 SOL
startTime: new anchor.BN(new Date().getTime() / 1000),
endTime: new anchor.BN(new Date().getTime() / 1000 + 60 * 60 * 24), // 1 day from now
priceToken: new PublicKey('So11111111111111111111111111111111111111112'),
isPrivate: true,
merkleRoot: null, // Invalid: null merkle root for private phase
};

const phaseIx = await editionsControlsProgram.methods
.addPhase(invalidPhaseConfig)
.accountsStrict({
editionsControls: editionsControlsPda,
creator: payer.publicKey,
payer: payer.publicKey,
systemProgram: SystemProgram.programId,
tokenProgram: TOKEN_2022_PROGRAM_ID,
libreplexEditionsProgram: editionsProgram.programId,
})
.signers([])
.instruction();

const transaction = new Transaction().add(phaseIx);

try {
await provider.sendAndConfirm(transaction, [payer]);
// If we reach this point, the test should fail
expect.fail('Transaction should have failed');
} catch (error) {
const errorString = JSON.stringify(error);
expect(errorString).to.include('Merkle root must be provided for private phases');
}

// Verify state hasn't changed
const editionsControlsDecoded = await getEditionsControls(provider.connection, editionsControlsPda, editionsControlsProgram);
expect(editionsControlsDecoded.data.phases.length).to.equal(6); // Should still be 6 phases
})
});

describe('Minting', () => {
Expand Down

0 comments on commit 28fd1ff

Please sign in to comment.