Skip to content

Commit

Permalink
Transfer funds to escrow (#5)
Browse files Browse the repository at this point in the history
* Transfer bid to escrow
  • Loading branch information
jbowa authored May 12, 2024
1 parent 23c3945 commit 66619f5
Show file tree
Hide file tree
Showing 7 changed files with 84 additions and 21 deletions.
6 changes: 4 additions & 2 deletions src/consts.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
// The seed for the market PDA.
pub const MARKET: &[u8] = b"market";
// Escrow seed for PDA.
pub const ESCROW: &[u8] = b"escrow";
// The seed for the bid PDA.
pub const BID: &[u8] = b"bid";
// The seed for the market PDA.
pub const MARKET: &[u8] = b"market";
10 changes: 7 additions & 3 deletions src/instruction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,15 @@ use shank::ShankInstruction;
pub enum PithInstruction {
#[account(0, name = "signer", desc = "Signer", signer)]
#[account(1, name = "market", desc = "Pith market account", writable)]
#[account(2, name = "system_program", desc = "Solana System Program")]
#[account(2, name = "escrow", desc = "Escrow account", writable)]
#[account(3, name = "system_program", desc = "Solana System Program")]
Market = 0,

#[account(0, name = "signer", desc = "Signer", signer)]
#[account(1, name = "market", desc = "Pith market account", writable)]
#[account(2, name = "bid", desc = "Bid account", writable)]
#[account(3, name = "system_program", desc = "Solana System Program")]
#[account(2, name = "escrow", desc = "Escrow account", writable)]
#[account(3, name = "bid", desc = "Bid account", writable)]
#[account(4, name = "system_program", desc = "Solana System Program")]
Bid = 1,
}

Expand All @@ -24,12 +26,14 @@ pub struct MarketArgs {
pub bump: u8,
pub id: u64,
pub title: String,
pub escrow_bump: u8,
}

#[repr(C)]
#[derive(Clone, Debug, BorshDeserialize)]
pub struct BidArgs {
pub bump: u8,
pub id: u64,
/// Bid amount in lamports.
pub amount: u64,
}
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ pub fn process_instruction(
.ok_or(ProgramError::InvalidInstructionData)?;

match PithInstruction::try_from(*tag).or(Err(ProgramError::InvalidInstructionData))? {
PithInstruction::Market => process_market(program_id, accounts, data)?,
PithInstruction::Market => process_init_market(program_id, accounts, data)?,
PithInstruction::Bid => process_bid(program_id, accounts, data)?,
}

Expand Down
30 changes: 25 additions & 5 deletions src/processor/bid.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
use borsh::{BorshDeserialize, BorshSerialize};
use solana_program::{
account_info::AccountInfo, borsh1::try_from_slice_unchecked, entrypoint::ProgramResult, msg,
program_error::ProgramError, pubkey::Pubkey, system_program,
account_info::AccountInfo,
borsh1::try_from_slice_unchecked,
entrypoint::ProgramResult,
program::invoke,
program_error::ProgramError,
pubkey::Pubkey,
system_instruction::{self},
system_program,
};

use crate::{
Expand All @@ -22,12 +28,25 @@ pub fn process_bid<'a, 'info>(
let args = BidArgs::try_from_slice(data)?;

// Load account data
let [signer, market_info, bid_info, system_program] = accounts else {
#[rustfmt::skip]
let [
signer,
market_info,
escrow_info,
bid_info,
system_program
] = accounts else {
return Err(ProgramError::NotEnoughAccountKeys);
};

let mut market_data = try_from_slice_unchecked::<Market>(&market_info.data.borrow())?;

// Transfer bid amount to escrow.
invoke(
&system_instruction::transfer(signer.key, escrow_info.key, args.amount),
&[signer.clone(), escrow_info.clone()],
)?;

load_signer(signer)?;
load_uninitialized_pda(
bid_info,
Expand All @@ -42,7 +61,7 @@ pub fn process_bid<'a, 'info>(
)?;
load_program(system_program, system_program::id())?;

// create bid Program Derived Address.
// create bid account.
create_pda(
bid_info,
&crate::id(),
Expand All @@ -58,12 +77,13 @@ pub fn process_bid<'a, 'info>(
signer,
)?;

let mut bid_data = try_from_slice_unchecked::<Bid>(&bid_info.data.borrow()).unwrap();
let mut bid_data = try_from_slice_unchecked::<Bid>(&bid_info.data.borrow())?;

bid_data.discriminator = Bid::DISCRIMINATOR.to_string();
bid_data.market = *market_info.key;
bid_data.amount = args.amount;
bid_data.authority = *signer.key;
bid_data.id = args.id;
bid_data.serialize(&mut &mut bid_info.data.borrow_mut()[..])?;

market_data.counter += 1;
Expand Down
33 changes: 27 additions & 6 deletions src/processor/market.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,17 @@ use solana_program::{
program_error::ProgramError, pubkey::Pubkey, system_program,
};

use crate::{instruction::MarketArgs, loaders::*, state::Market, utils::*, MARKET};
use crate::{
instruction::MarketArgs,
loaders::*,
state::{Escrow, Market},
utils::*,
ESCROW, MARKET,
};
use borsh::{BorshDeserialize, BorshSerialize};

// process_market creates a new tradable market.
pub fn process_market<'a, 'info>(
// process_init_market creates a new tradable market.
pub fn process_init_market<'a, 'info>(
_program_id: &Pubkey,
accounts: &'a [AccountInfo<'info>],
data: &[u8],
Expand All @@ -16,7 +22,7 @@ pub fn process_market<'a, 'info>(
let args = MarketArgs::try_from_slice(data)?;

// Load account data
let [signer, market_info, system_program] = accounts else {
let [signer, market_info, escrow_info, system_program] = accounts else {
return Err(ProgramError::NotEnoughAccountKeys);
};

Expand All @@ -27,9 +33,15 @@ pub fn process_market<'a, 'info>(
args.bump,
&crate::id(),
)?;
load_uninitialized_pda(
escrow_info,
&[ESCROW, market_info.key.as_ref()],
args.escrow_bump,
&crate::id(),
)?;
load_program(system_program, system_program::id())?;

// Create the market
// Create market account
create_pda(
market_info,
&crate::id(),
Expand All @@ -44,9 +56,18 @@ pub fn process_market<'a, 'info>(
signer,
)?;

// Create escrow account
create_pda(
escrow_info,
&crate::id(),
Escrow::get_account_size(&Market::DISCRIMINATOR.to_string()),
&[ESCROW, market_info.key.as_ref(), &[args.escrow_bump]],
system_program,
signer,
)?;

let mut market_data = try_from_slice_unchecked::<Market>(&market_info.data.borrow()).unwrap();
market_data.discriminator = Market::DISCRIMINATOR.to_string();
market_data.bump = args.bump;
market_data.authority = *signer.key;
market_data.id = args.id;
market_data.title = args.title;
Expand Down
4 changes: 3 additions & 1 deletion src/state/bid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,11 @@ pub struct Bid {
pub amount: u64,
/// The account that placed this bid.
pub authority: Pubkey,
/// The unique bid ID.
pub id: u64,
}

impl Bid {
pub const DISCRIMINATOR: &'static str = "bid";
pub const SIZE: usize = (4 + Bid::DISCRIMINATOR.len()) + 32 + 8 + 32;
pub const SIZE: usize = (4 + Bid::DISCRIMINATOR.len()) + 32 + 8 + 32 + 8;
}
20 changes: 17 additions & 3 deletions src/state/market.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,29 @@ use borsh::{BorshDeserialize, BorshSerialize};
use shank::ShankAccount;
use solana_program::pubkey::Pubkey;

/// Market is the parent account that stores a tradable asset and keeps track of
/// the bids placed on the specific market via a counter.
#[repr(C)]
#[derive(Debug, Clone, BorshSerialize, BorshDeserialize, ShankAccount)]
pub struct Escrow {
pub discriminator: String,
}

impl Escrow {
pub const DISCRIMINATOR: &'static str = "escrow";

pub fn get_account_size(discriminator: &String) -> usize {
return 4 + discriminator.len();
}
}

/// Market is the parent account that stores a tradable asset and keeps track of
/// the bids placed on the specific market via a counter.
#[repr(C)]
#[derive(Debug, Clone, BorshSerialize, BorshDeserialize, ShankAccount)]
pub struct Market {
/// Account discriminator
pub discriminator: String,
/// The market account PDA.
pub bump: u8,
/// The accounts authority.
pub authority: Pubkey,
/// The unique market ID.
Expand All @@ -28,6 +42,6 @@ impl Market {
pub const DISCRIMINATOR: &'static str = "market";

pub fn get_account_size(title: &String, discriminator: &String) -> usize {
return (4 + discriminator.len()) + 1 + 32 + 8 + (4 + title.len()) + 2 + 32;
return (4 + discriminator.len()) + 32 + 8 + (4 + title.len()) + 2 + 32;
}
}

0 comments on commit 66619f5

Please sign in to comment.