Skip to content

Commit

Permalink
Create tokenized_assets.rs
Browse files Browse the repository at this point in the history
  • Loading branch information
KOSASIH authored Aug 8, 2024
1 parent 01f562c commit c540598
Showing 1 changed file with 195 additions and 0 deletions.
195 changes: 195 additions & 0 deletions pi-nexus-smart-contracts/solana/contracts/tokenized_assets.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
use solana_program::{
account_info::{next_account_info, AccountInfo},
entrypoint,
entrypoint::ProgramResult,
msg,
program_error::ProgramError,
pubkey::Pubkey,
};

// Define the TokenizedAssetsInstruction enum
enum TokenizedAssetsInstruction {
InitializeTokenizedAsset,
MintTokens,
BurnTokens,
TransferTokens,
ApproveTokens,
}

// Implement the TokenizedAssetsInstruction enum
impl TokenizedAssetsInstruction {
fn unpack(instruction_data: &[u8]) -> Result<TokenizedAssetsInstruction, ProgramError> {
if instruction_data.len() != 1 {
msg!("Error: Invalid instruction data");
return Err(ProgramError::InvalidInstructionData);
}

match instruction_data[0] {
0 => Ok(TokenizedAssetsInstruction::InitializeTokenizedAsset),
1 => Ok(TokenizedAssetsInstruction::MintTokens),
2 => Ok(TokenizedAssetsInstruction::BurnTokens),
3 => Ok(TokenizedAssetsInstruction::TransferTokens),
4 => Ok(TokenizedAssetsInstruction::ApproveTokens),
_ => {
msg!("Error: Unknown instruction");
Err(ProgramError::InvalidInstruction)
}
}
}
}

// Define the TokenizedAsset struct
struct TokenizedAsset {
mint: Pubkey,
owner: Pubkey,
amount: u64,
}

// Implement the TokenizedAsset struct
impl TokenizedAsset {
fn unpack(account_data: &[u8]) -> Result<TokenizedAsset, ProgramError> {
if account_data.len() != 32 + 32 + 8 {
msg!("Error: Invalid account data");
return Err(ProgramError::InvalidAccountData);
}

let mint = Pubkey::new_from_array(&account_data[0..32]);
let owner = Pubkey::new_from_array(&account_data[32..64]);
let amount = u64::from_le_bytes(account_data[64..72].try_into().unwrap());

Ok(TokenizedAsset { mint, owner, amount })
}
}

// Define the program entrypoint
entrypoint!(process_instruction);

fn process_instruction(
program_id: &Pubkey,
accounts: &[AccountInfo],
instruction_data: &[u8],
) -> ProgramResult {
let instruction = TokenizedAssetsInstruction::unpack(instruction_data)?;

match instruction {
TokenizedAssetsInstruction::InitializeTokenizedAsset => {
initialize_tokenized_asset(program_id, accounts)
}
TokenizedAssetsInstruction::MintTokens => mint_tokens(program_id, accounts),
TokenizedAssetsInstruction::BurnTokens => burn_tokens(program_id, accounts),
TokenizedAssetsInstruction::TransferTokens => transfer_tokens(program_id, accounts),
TokenizedAssetsInstruction::ApproveTokens => approve_tokens(program_id, accounts),
}
}

// Initialize a tokenized asset
fn initialize_tokenized_asset(program_id: &Pubkey, accounts: &[AccountInfo]) -> ProgramResult {
// Get the account infos
let tokenized_asset_account_info = next_account_info(accounts)?;
let mint_account_info = next_account_info(accounts)?;
let owner_account_info = next_account_info(accounts)?;

// Unpack the accounts
let tokenized_asset = TokenizedAsset::unpack(&tokenized_asset_account_info.data.borrow())?;

// Check that the owner is correct
if owner_account_info.key != &tokenized_asset.owner {
msg!("Error: Owner mismatch");
return Err(ProgramError::Custom(1));
}

// Initialize the tokenized asset
tokenized_asset.mint = *mint_account_info.key;
tokenized_asset.amount = 0;

Ok(())
}

// Mint tokens
fn mint_tokens(program_id: &Pubkey, accounts: &[AccountInfo]) -> ProgramResult {
// Get the account infos
let tokenized_asset_account_info = next_account_info(accounts)?;
let mint_account_info = next_account_info(accounts)?;
let owner_account_info = next_account_info(accounts)?;

// Unpack the accounts
let tokenized_asset = TokenizedAsset::unpack(&tokenized_asset_account_info.data.borrow())?;

// Check that the owner is correct
if owner_account_info.key != &tokenized_asset.owner {
msg!("Error: Owner mismatch");
return Err(ProgramError::Custom(2));
}

// Mint tokens
tokenized_asset.amount += 1;

Ok(())
}

// Burn tokens
fn burn_tokens(program_id: &Pubkey, accounts: &[AccountInfo]) -> ProgramResult {
// Get the account infos
let tokenized_asset_account_info = next_account_info(accounts)?;
let mint_account_info = next_account_info(accounts)?;
let owner_account_info = next_account_info(accounts)?;

// Unpack the accounts
let tokenized_asset = TokenizedAsset::unpack(&tokenized_asset_account_info.data.borrow())?;

// Check that the owner is correct
if owner_account_info.key != &tokenized_asset.owner {
msg!("Error: Owner mismatch");
return Err(ProgramError::Custom(3));
}

// Burn tokens
tokenized_asset.amount -= 1;

Ok(())
}

// Transfer tokens
fn transfer_tokens(program_id: &Pubkey, accounts: &[AccountInfo]) -> ProgramResult {
// Get the account infos
let tokenized_asset_account_info = next_account_info(accounts)?;
let recipient_account_info = next_account_info(accounts)?;
let owner_account_info = next_account_info(accounts)?;

// Unpack the accounts
let tokenized_asset = TokenizedAsset::unpack(&tokenized_asset_account_info.data.borrow())?;

// Check that the owner is correct
if owner_account_info.key != &tokenized_asset.owner {
msg!("Error: Owner mismatch");
return Err(ProgramError::Custom(4));
}

// Transfer tokens
tokenized_asset.owner = *recipient_account_info.key;
tokenized_asset.amount -= 1;

Ok(())
}

// Approve tokens
fn approve_tokens(program_id: &Pubkey, accounts: &[AccountInfo]) -> ProgramResult {
// Get the account infos
let tokenized_asset_account_info = next_account_info(accounts)?;
let spender_account_info = next_account_info(accounts)?;
let owner_account_info = next_account_info(accounts)?;

// Unpack the accounts
let tokenized_asset = TokenizedAsset::unpack(&tokenized_asset_account_info.data.borrow())?;

// Check that the owner is correct
if owner_account_info.key != &tokenized_asset.owner {
msg!("Error: Owner mismatch");
return Err(ProgramError::Custom(5));
}

// Approve tokens
// TODO: implement approval logic

Ok(())
}

0 comments on commit c540598

Please sign in to comment.