Skip to content

Commit

Permalink
import bundled positions
Browse files Browse the repository at this point in the history
  • Loading branch information
yugure-orca committed Feb 20, 2023
1 parent c3a02ee commit d0ac15e
Show file tree
Hide file tree
Showing 44 changed files with 6,399 additions and 25 deletions.
2 changes: 2 additions & 0 deletions programs/whirlpool/src/constants/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
pub mod test_constants;
pub mod nft;

pub use test_constants::*;
pub use nft::*;
18 changes: 18 additions & 0 deletions programs/whirlpool/src/constants/nft.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
use anchor_lang::prelude::*;

pub mod whirlpool_nft_update_auth {
use super::*;
declare_id!("3axbTs2z5GBy6usVbNVoqEgZMng3vZvMnAoX29BFfwhr");
}

// METADATA_NAME : max 32 bytes
// METADATA_SYMBOL : max 10 bytes
// METADATA_URI : max 200 bytes
pub const WP_METADATA_NAME: &str = "Orca Whirlpool Position";
pub const WP_METADATA_SYMBOL: &str = "OWP";
pub const WP_METADATA_URI: &str = "https://arweave.net/E19ZNY2sqMqddm1Wx7mrXPUZ0ZZ5ISizhebb0UsVEws";

pub const WPB_METADATA_NAME_PREFIX: &str = "Orca Position Bundle";
pub const WPB_METADATA_SYMBOL: &str = "OPB";
pub const WPB_METADATA_URI: &str = "https://arweave.net/A_Wo8dx2_3lSUwMIi7bdT_sqxi8soghRNAWXXiqXpgE";

9 changes: 9 additions & 0 deletions programs/whirlpool/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,15 @@ pub enum ErrorCode {
InvalidIntermediaryMint, //0x1799
#[msg("Duplicate two hop pool")]
DuplicateTwoHopPool, //0x179a

#[msg("Bundle index is out of bounds")]
InvalidBundleIndex, //0x179b
#[msg("Position has already been opened")]
BundledPositionAlreadyOpened, //0x179c
#[msg("Position has already been closed")]
BundledPositionAlreadyClosed, //0x179d
#[msg("Unable to delete PositionBundle with open positions")]
PositionBundleNotDeletable, //0x179e
}

impl From<TryFromIntError> for ErrorCode {
Expand Down
58 changes: 58 additions & 0 deletions programs/whirlpool/src/instructions/close_bundled_position.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
use anchor_lang::prelude::*;
use anchor_spl::token::{TokenAccount};

use crate::errors::ErrorCode;
use crate::{state::*, util::verify_position_bundle_authority};

#[derive(Accounts)]
#[instruction(bundle_index: u16)]
pub struct CloseBundledPosition<'info> {
#[account(mut,
close = receiver,
seeds = [
b"position".as_ref(),
position_bundle.position_bundle_mint.key().as_ref(),
bundle_index.to_string().as_bytes()
],
bump,
)]
pub bundled_position: Account<'info, Position>,

#[account(mut)]
pub position_bundle: Box<Account<'info, PositionBundle>>,

#[account(
constraint = position_bundle_token_account.mint == bundled_position.position_mint,
constraint = position_bundle_token_account.mint == position_bundle.position_bundle_mint,
constraint = position_bundle_token_account.amount == 1
)]
pub position_bundle_token_account: Box<Account<'info, TokenAccount>>,

pub position_bundle_authority: Signer<'info>,

#[account(mut)]
pub receiver: UncheckedAccount<'info>,
}

pub fn handler(
ctx: Context<CloseBundledPosition>,
bundle_index: u16,
) -> ProgramResult {
let position_bundle = &mut ctx.accounts.position_bundle;

// Allow delegation
verify_position_bundle_authority(
&ctx.accounts.position_bundle_token_account,
&ctx.accounts.position_bundle_authority,
)?;

if !Position::is_position_empty(&ctx.accounts.bundled_position) {
return Err(ErrorCode::ClosePositionNotEmpty.into());
}

position_bundle.close_bundled_position(bundle_index)?;

// Anchor will close the Position account

Ok(())
}
6 changes: 5 additions & 1 deletion programs/whirlpool/src/instructions/close_position.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,11 @@ pub struct ClosePosition<'info> {
#[account(mut)]
pub receiver: UncheckedAccount<'info>,

#[account(mut, close = receiver)]
#[account(mut,
close = receiver,
seeds = [b"position".as_ref(), position_mint.key().as_ref()],
bump,
)]
pub position: Account<'info, Position>,

#[account(mut, address = position.position_mint)]
Expand Down
46 changes: 46 additions & 0 deletions programs/whirlpool/src/instructions/delete_position_bundle.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
use anchor_lang::prelude::*;
use anchor_spl::token::{self, Mint, Token, TokenAccount};

use crate::errors::ErrorCode;
use crate::state::*;
use crate::util::burn_and_close_position_bundle_token;

#[derive(Accounts)]
pub struct DeletePositionBundle<'info> {
#[account(mut, close = receiver)]
pub position_bundle: Account<'info, PositionBundle>,

#[account(mut, address = position_bundle.position_bundle_mint)]
pub position_bundle_mint: Account<'info, Mint>,

#[account(mut,
constraint = position_bundle_token_account.mint == position_bundle.position_bundle_mint,
constraint = position_bundle_token_account.owner == position_bundle_owner.key(),
constraint = position_bundle_token_account.amount == 1,
)]
pub position_bundle_token_account: Box<Account<'info, TokenAccount>>,

pub position_bundle_owner: Signer<'info>,

#[account(mut)]
pub receiver: UncheckedAccount<'info>,

#[account(address = token::ID)]
pub token_program: Program<'info, Token>,
}

pub fn handler(ctx: Context<DeletePositionBundle>) -> ProgramResult {
let position_bundle = &ctx.accounts.position_bundle;

if !position_bundle.is_deletable() {
return Err(ErrorCode::PositionBundleNotDeletable.into());
}

burn_and_close_position_bundle_token(
&ctx.accounts.position_bundle_owner,
&ctx.accounts.receiver,
&ctx.accounts.position_bundle_mint,
&ctx.accounts.position_bundle_token_account,
&ctx.accounts.token_program,
)
}
60 changes: 60 additions & 0 deletions programs/whirlpool/src/instructions/initialize_position_bundle.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
use anchor_lang::prelude::*;
use anchor_spl::associated_token::AssociatedToken;
use anchor_spl::token::{self, Mint, Token, TokenAccount};

use crate::{state::*, util::mint_position_bundle_token_and_remove_authority};

#[derive(Accounts)]
pub struct InitializePositionBundle<'info> {
#[account(init,
payer = funder,
space = PositionBundle::LEN,
seeds = [b"position_bundle".as_ref(), position_bundle_mint.key().as_ref()],
bump,
)]
pub position_bundle: Box<Account<'info, PositionBundle>>,

#[account(init,
payer = funder,
space = Mint::LEN,
mint::authority = funder, // will be removed in the transaction
mint::decimals = 0,
)]
pub position_bundle_mint: Account<'info, Mint>,

#[account(init,
payer = funder,
associated_token::mint = position_bundle_mint,
associated_token::authority = position_bundle_owner,
)]
pub position_bundle_token_account: Box<Account<'info, TokenAccount>>,

pub position_bundle_owner: UncheckedAccount<'info>,

#[account(mut)]
pub funder: Signer<'info>,

#[account(address = token::ID)]
pub token_program: Program<'info, Token>,
pub system_program: Program<'info, System>,
pub rent: Sysvar<'info, Rent>,
pub associated_token_program: Program<'info, AssociatedToken>,
}

pub fn handler(
ctx: Context<InitializePositionBundle>,
) -> ProgramResult {
let position_bundle_mint = &ctx.accounts.position_bundle_mint;
let position_bundle = &mut ctx.accounts.position_bundle;

position_bundle.initialize(
position_bundle_mint.key()
)?;

mint_position_bundle_token_and_remove_authority(
&ctx.accounts.funder,
position_bundle_mint,
&ctx.accounts.position_bundle_token_account,
&ctx.accounts.token_program,
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
use anchor_lang::prelude::*;
use anchor_spl::associated_token::AssociatedToken;
use anchor_spl::token::{self, Mint, Token, TokenAccount};

use crate::{state::*, util::mint_position_bundle_token_with_metadata_and_remove_authority};
use crate::constants::nft::whirlpool_nft_update_auth::ID as WPB_NFT_UPDATE_AUTH;

#[derive(Accounts)]
pub struct InitializePositionBundleWithMetadata<'info> {
#[account(init,
payer = funder,
space = PositionBundle::LEN,
seeds = [b"position_bundle".as_ref(), position_bundle_mint.key().as_ref()],
bump,
)]
pub position_bundle: Box<Account<'info, PositionBundle>>,

#[account(init,
payer = funder,
space = Mint::LEN,
mint::authority = funder, // will be removed in the transaction
mint::decimals = 0,
)]
pub position_bundle_mint: Account<'info, Mint>,

/// CHECK: checked via the Metadata CPI call
/// https://github.com/metaplex-foundation/metaplex-program-library/blob/773a574c4b34e5b9f248a81306ec24db064e255f/token-metadata/program/src/utils/metadata.rs#L100
#[account(mut)]
pub position_bundle_metadata: UncheckedAccount<'info>,

#[account(init,
payer = funder,
associated_token::mint = position_bundle_mint,
associated_token::authority = position_bundle_owner,
)]
pub position_bundle_token_account: Box<Account<'info, TokenAccount>>,

pub position_bundle_owner: UncheckedAccount<'info>,

#[account(mut)]
pub funder: Signer<'info>,

/// CHECK: checked via account constraints
#[account(address = WPB_NFT_UPDATE_AUTH)]
pub metadata_update_auth: UncheckedAccount<'info>,

#[account(address = token::ID)]
pub token_program: Program<'info, Token>,
pub system_program: Program<'info, System>,
pub rent: Sysvar<'info, Rent>,
pub associated_token_program: Program<'info, AssociatedToken>,

/// CHECK: checked via account constraints
#[account(address = mpl_token_metadata::ID)]
pub metadata_program: UncheckedAccount<'info>,
}

pub fn handler(
ctx: Context<InitializePositionBundleWithMetadata>,
) -> ProgramResult {
let position_bundle_mint = &ctx.accounts.position_bundle_mint;
let position_bundle = &mut ctx.accounts.position_bundle;

position_bundle.initialize(
position_bundle_mint.key()
)?;

mint_position_bundle_token_with_metadata_and_remove_authority(
&ctx.accounts.funder,
position_bundle_mint,
&ctx.accounts.position_bundle_token_account,
&ctx.accounts.position_bundle_metadata,
&ctx.accounts.metadata_update_auth,
&ctx.accounts.metadata_program,
&ctx.accounts.token_program,
&ctx.accounts.system_program,
&ctx.accounts.rent
)
}
10 changes: 10 additions & 0 deletions programs/whirlpool/src/instructions/mod.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
pub mod close_position;
pub mod close_bundled_position;
pub mod collect_fees;
pub mod collect_protocol_fees;
pub mod collect_reward;
pub mod decrease_liquidity;
pub mod delete_position_bundle;
pub mod increase_liquidity;
pub mod initialize_config;
pub mod initialize_fee_tier;
pub mod initialize_pool;
pub mod initialize_position_bundle;
pub mod initialize_position_bundle_with_metadata;
pub mod initialize_reward;
pub mod initialize_tick_array;
pub mod open_position;
pub mod open_position_with_metadata;
pub mod open_bundled_position;
pub mod set_collect_protocol_fees_authority;
pub mod set_default_fee_rate;
pub mod set_default_protocol_fee_rate;
Expand All @@ -26,18 +31,23 @@ pub mod two_hop_swap;
pub mod update_fees_and_rewards;

pub use close_position::*;
pub use close_bundled_position::*;
pub use collect_fees::*;
pub use collect_protocol_fees::*;
pub use collect_reward::*;
pub use decrease_liquidity::*;
pub use delete_position_bundle::*;
pub use increase_liquidity::*;
pub use initialize_config::*;
pub use initialize_fee_tier::*;
pub use initialize_pool::*;
pub use initialize_position_bundle::*;
pub use initialize_position_bundle_with_metadata::*;
pub use initialize_reward::*;
pub use initialize_tick_array::*;
pub use open_position::*;
pub use open_position_with_metadata::*;
pub use open_bundled_position::*;
pub use set_collect_protocol_fees_authority::*;
pub use set_default_fee_rate::*;
pub use set_default_protocol_fee_rate::*;
Expand Down
Loading

0 comments on commit d0ac15e

Please sign in to comment.