From dd29702eaa666ce030386117681059cc2b099c1a Mon Sep 17 00:00:00 2001 From: bucurdavid Date: Mon, 4 Nov 2024 09:55:13 +0200 Subject: [PATCH] feat: support range bond child for vault bond --- programs/core-sol-bond-stake-sc/src/errors.rs | 4 + .../instructions/admin/create_bond_config.rs | 2 +- .../src/instructions/bond.rs | 5 +- .../src/instructions/bond_range.rs | 99 +++++++++++++++++++ .../src/instructions/mod.rs | 2 + programs/core-sol-bond-stake-sc/src/lib.rs | 22 +++++ .../core-sol-bond-stake-sc/src/states/bond.rs | 6 +- programs/core-sol-bond-stake-sc/src/utils.rs | 2 + 8 files changed, 139 insertions(+), 3 deletions(-) create mode 100644 programs/core-sol-bond-stake-sc/src/instructions/bond_range.rs diff --git a/programs/core-sol-bond-stake-sc/src/errors.rs b/programs/core-sol-bond-stake-sc/src/errors.rs index 3133268..f70443b 100644 --- a/programs/core-sol-bond-stake-sc/src/errors.rs +++ b/programs/core-sol-bond-stake-sc/src/errors.rs @@ -40,4 +40,8 @@ pub enum Errors { NotCreator, #[msg("Asset Id mismatch")] AssetIdMismatch, + #[msg("ParentBondIsNotVault")] + ParentBondIsNotVault, + #[msg("ParentBondIsNotActive")] + ParentBondIsNotActive, } diff --git a/programs/core-sol-bond-stake-sc/src/instructions/admin/create_bond_config.rs b/programs/core-sol-bond-stake-sc/src/instructions/admin/create_bond_config.rs index 11fc483..ba0e373 100644 --- a/programs/core-sol-bond-stake-sc/src/instructions/admin/create_bond_config.rs +++ b/programs/core-sol-bond-stake-sc/src/instructions/admin/create_bond_config.rs @@ -44,7 +44,7 @@ pub fn create_bond_config( bond_config.lock_period = lock_period; bond_config.bond_amount = bond_amount; bond_config.withdraw_penalty = withdraw_penalty; - // bond_config.padding = [0; 32]; + bond_config.padding = [0; 32]; Ok(()) } diff --git a/programs/core-sol-bond-stake-sc/src/instructions/bond.rs b/programs/core-sol-bond-stake-sc/src/instructions/bond.rs index 9f8c07c..4e9eca7 100644 --- a/programs/core-sol-bond-stake-sc/src/instructions/bond.rs +++ b/programs/core-sol-bond-stake-sc/src/instructions/bond.rs @@ -216,7 +216,10 @@ pub fn bond<'a, 'b, 'c: 'info, 'info>( bond_amount: amount, asset_id: asset_id.key(), owner: ctx.accounts.authority.key(), - padding: [0; 64], + parent_bond: Pubkey::default(), + start_nonce: 0u64, + end_nonce: 0u64, + padding: [0; 16], }); Ok(()) diff --git a/programs/core-sol-bond-stake-sc/src/instructions/bond_range.rs b/programs/core-sol-bond-stake-sc/src/instructions/bond_range.rs new file mode 100644 index 0000000..05ce2c6 --- /dev/null +++ b/programs/core-sol-bond-stake-sc/src/instructions/bond_range.rs @@ -0,0 +1,99 @@ +use anchor_lang::prelude::*; + +use crate::{ + AddressBondsRewards, Bond, BondConfig, Errors, State, ADDRESS_BONDS_REWARDS_SEED, + BOND_CONFIG_SEED, BOND_SEED, +}; + +#[derive(Accounts)] +#[instruction(bond_config_index:u8, bond_id:u8, parent_bond_id:u8, start_nonce: u64, end_nonce: u64)] + +pub struct BondRange<'info> { + #[account( + mut, + seeds=[ADDRESS_BONDS_REWARDS_SEED.as_bytes(), authority.key().as_ref()], + bump=address_bonds_rewards.bump, + )] + pub address_bonds_rewards: Box>, + + // a way to limit the usage of the range again + // To be added + #[account( + seeds=[BOND_SEED.as_bytes(),authority.key().as_ref(),&parent_bond_id.to_le_bytes()], + bump, + )] + pub parent_bond: Box>, + + #[account( + init, + payer = authority, + constraint=address_bonds_rewards.current_index + 1 == bond_id @ Errors::WrongBondId, + seeds = [ + BOND_SEED.as_bytes(), + authority.key().as_ref(), + &bond_id.to_le_bytes() + ], + bump, + space = Bond::INIT_SPACE + )] + pub bond: Box>, + + #[account( + seeds=[BOND_CONFIG_SEED.as_bytes(),&bond_config_index.to_be_bytes()], + bump=bond_config.bump, + )] + pub bond_config: Box>, + + /// CHECK: unsafe + #[account( + constraint= merkle_tree.key() == bond_config.merkle_tree.key() @ Errors::MerkleTreeMismatch, + )] + pub merkle_tree: UncheckedAccount<'info>, + + #[account( + mut, + constraint=address_bonds_rewards.address == authority.key() @ Errors::OwnerMismatch, + )] + pub authority: Signer<'info>, + + pub system_program: Program<'info, System>, +} + +pub fn bond_range<'info>( + ctx: Context, + _bond_config_index: u8, + bond_id: u8, + _parent_bond_id: u8, + start_nonce: u64, + end_nonce: u64, +) -> Result<()> { + require!( + ctx.accounts.parent_bond.is_vault, + Errors::ParentBondIsNotVault + ); + require!( + ctx.accounts.parent_bond.state == State::Active.to_code(), + Errors::ParentBondIsNotActive + ); + + let address_bonds_rewards = &mut ctx.accounts.address_bonds_rewards; + + address_bonds_rewards.current_index = bond_id; + + ctx.accounts.bond.set_inner(Bond { + bump: ctx.bumps.bond, + state: State::Child.to_code(), + is_vault: false, + unbond_timestamp: 0u64, + bond_timestamp: 0u64, + bond_amount: 0u64, + asset_id: Pubkey::default(), + owner: ctx.accounts.authority.key(), + parent_bond: ctx.accounts.parent_bond.key(), + start_nonce, + end_nonce, + padding: [0; 16], + }); + + Ok(()) +} diff --git a/programs/core-sol-bond-stake-sc/src/instructions/mod.rs b/programs/core-sol-bond-stake-sc/src/instructions/mod.rs index 6824bdd..8600c1b 100644 --- a/programs/core-sol-bond-stake-sc/src/instructions/mod.rs +++ b/programs/core-sol-bond-stake-sc/src/instructions/mod.rs @@ -15,3 +15,5 @@ pub mod claim_rewards; pub use claim_rewards::*; pub mod initialize_address; pub use initialize_address::*; +pub mod bond_range; +pub use bond_range::*; diff --git a/programs/core-sol-bond-stake-sc/src/lib.rs b/programs/core-sol-bond-stake-sc/src/lib.rs index 98e2d34..ada2d34 100644 --- a/programs/core-sol-bond-stake-sc/src/lib.rs +++ b/programs/core-sol-bond-stake-sc/src/lib.rs @@ -169,6 +169,28 @@ pub mod core_sol_bond_stake_sc { ) } + pub fn bond_range<'info>( + ctx: Context, + bond_config_index: u8, + bond_id: u8, + parent_bond_id: u8, + start_nonce: u64, + end_nonce: u64, + ) -> Result<()> { + require!( + ctx.accounts.bond_config.bond_state == State::Active.to_code(), + Errors::ProgramIsPaused + ); + instructions::bond_range( + ctx, + bond_config_index, + bond_id, + parent_bond_id, + start_nonce, + end_nonce, + ) + } + pub fn renew(ctx: Context, _bond_config_index: u8, _bond_id: u8) -> Result<()> { require!( ctx.accounts.bond_config.bond_state == State::Active.to_code(), diff --git a/programs/core-sol-bond-stake-sc/src/states/bond.rs b/programs/core-sol-bond-stake-sc/src/states/bond.rs index 04637c9..357a74f 100644 --- a/programs/core-sol-bond-stake-sc/src/states/bond.rs +++ b/programs/core-sol-bond-stake-sc/src/states/bond.rs @@ -10,7 +10,11 @@ pub struct Bond { pub bond_amount: u64, pub asset_id: Pubkey, pub owner: Pubkey, - pub padding: [u8; 64], + // Range bond for cNFTs + pub parent_bond: Pubkey, + pub start_nonce: u64, + pub end_nonce: u64, + pub padding: [u8; 16], } impl Space for Bond { const INIT_SPACE: usize = 8 + 1 + 1 + 1 + 8 + 8 + 8 + 32 + 32 + 64; diff --git a/programs/core-sol-bond-stake-sc/src/utils.rs b/programs/core-sol-bond-stake-sc/src/utils.rs index 0be9243..baf5b8e 100644 --- a/programs/core-sol-bond-stake-sc/src/utils.rs +++ b/programs/core-sol-bond-stake-sc/src/utils.rs @@ -5,12 +5,14 @@ use solana_program::clock; pub enum State { Inactive = 0, Active = 1, + Child = 2, } impl State { pub fn to_code(&self) -> u8 { match self { State::Inactive => 0, State::Active => 1, + State::Child => 2, } } }