Skip to content

Commit 2132c76

Browse files
committed
feat: add shared library and use shared library in zap-program
1 parent 4b67bfc commit 2132c76

15 files changed

Lines changed: 813 additions & 57 deletions

File tree

Cargo.lock

Lines changed: 12 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[workspace]
2-
members = ["programs/*", "libs/*"]
2+
members = ["programs/*", "libs/*", "protocol-zap"]
33
resolver = "2"
44

55
[profile.release]
@@ -15,3 +15,4 @@ codegen-units = 1
1515
anchor-lang = "0.31.1"
1616
anchor-spl = "0.31.1"
1717
bytemuck = "1.20.0"
18+
ruint = "1.3.0"

programs/zap/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,5 @@ dlmm = { path = "../../libs/dlmm" }
2626
damm-v2 = { git = "https://github.com/MeteoraAg/damm-v2", features = [
2727
"cpi",
2828
], rev = "d9cef5aaec9cfa1a6d3b0b28d213c87c285127de", package = "cp-amm" }
29-
ruint = "1.3.0"
29+
ruint = { workspace = true }
30+
protocol-zap = { path = "../../protocol-zap" }

programs/zap/src/constants.rs

Lines changed: 5 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,10 @@
11
use anchor_lang::constant;
2-
use anchor_lang::{prelude::Pubkey, pubkey};
2+
use anchor_lang::prelude::Pubkey;
33

4-
#[constant]
5-
pub const DAMM_V2: Pubkey = pubkey!("cpamdpZCGKUy5JxQXB4dcpGPiikHawvSWAd6mEn1sGG");
6-
// https://github.com/MeteoraAg/zap-program/blob/main/idls/damm_v2.json#L3512-L3521
7-
#[constant]
8-
pub const DAMM_V2_SWAP_DISC: [u8; 8] = [248, 198, 158, 145, 225, 117, 135, 200];
9-
10-
#[constant]
11-
pub const JUP_V6: Pubkey = pubkey!("JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4");
12-
// https://github.com/MeteoraAg/zap-program/blob/main/idls/jup_v6.json#L14-L23
13-
#[constant]
14-
pub const JUP_V6_ROUTE_DISC: [u8; 8] = [229, 23, 203, 151, 122, 227, 173, 42];
15-
// https://github.com/MeteoraAg/zap-program/blob/main/idls/jup_v6.json#L257-L266
16-
#[constant]
17-
pub const JUP_V6_SHARED_ACCOUNT_ROUTE_DISC: [u8; 8] = [193, 32, 155, 51, 65, 214, 156, 129];
18-
19-
pub const DLMM: Pubkey = pubkey!("LBUZKhRxPF3XUpBCjp4YzTKgLccjZhTSDM9YuVaPwxo");
20-
// https://github.com/MeteoraAg/zap-program/blob/main/idls/dlmm.json#L3413-L3422
21-
#[constant]
22-
pub const DLMM_SWAP2_DISC: [u8; 8] = [65, 75, 63, 76, 235, 91, 91, 136];
4+
use protocol_zap::constants::{
5+
DAMM_V2, DAMM_V2_SWAP_DISC, DLMM, DLMM_SWAP2_DISC, JUP_V6, JUP_V6_ROUTE_DISC,
6+
JUP_V6_SHARED_ACCOUNT_ROUTE_DISC,
7+
};
238

249
#[constant]
2510
pub const WHITELISTED_AMM_PROGRAMS: [(Pubkey, [u8; 8]); 4] = [

programs/zap/src/instructions/ix_zap_out.rs

Lines changed: 1 addition & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,12 @@
1-
use std::cmp::min;
2-
31
use anchor_lang::{
42
prelude::*,
53
solana_program::{instruction::Instruction, program::invoke},
64
};
75
use anchor_spl::token_interface::TokenAccount;
6+
use protocol_zap::ZapOutParameters;
87

98
use crate::{constants::WHITELISTED_AMM_PROGRAMS, error::ZapError, safe_math::SafeMath};
109

11-
#[derive(AnchorSerialize, AnchorDeserialize)]
12-
pub struct ZapOutParameters {
13-
pub percentage: u8,
14-
pub offset_amount_in: u16,
15-
pub pre_user_token_balance: u64,
16-
pub max_swap_amount: u64, // avoid the issue someone send token to user token account when user zap out
17-
pub payload_data: Vec<u8>,
18-
}
19-
20-
impl ZapOutParameters {
21-
fn validate(&self) -> Result<()> {
22-
require!(
23-
self.percentage <= 100 && self.percentage > 0,
24-
ZapError::InvalidZapOutParameters
25-
);
26-
27-
Ok(())
28-
}
29-
30-
fn get_swap_amount(&self, balance_change_amount: u64) -> Result<u64> {
31-
let swap_amount = if self.percentage == 100 {
32-
balance_change_amount
33-
} else {
34-
let amount = u128::from(balance_change_amount)
35-
.safe_mul(self.percentage.into())?
36-
.safe_div(100)?;
37-
u64::try_from(amount).map_err(|_| ZapError::TypeCastFailed)?
38-
};
39-
40-
Ok(min(swap_amount, self.max_swap_amount))
41-
}
42-
}
43-
4410
pub fn is_support_amm_program(amm_program: &Pubkey, discriminator: &[u8]) -> bool {
4511
WHITELISTED_AMM_PROGRAMS
4612
.iter()

programs/zap/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ pub mod utils;
1616
use dlmm::types::RemainingAccountsInfo;
1717
pub use utils::*;
1818
declare_id!("zapvX9M3uf5pvy4wRPAbQgdQsM1xmuiFnkfHKPvwMiz");
19+
use protocol_zap::ZapOutParameters;
1920

2021
#[program]
2122
pub mod zap {

protocol-zap/Cargo.toml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
[package]
2+
name = "protocol-zap"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
[dependencies]
7+
anchor-lang = { workspace = true }
8+
anchor-spl = { workspace = true }
9+
const-crypto = "0.3.0"
10+
jupiter = { path = "../libs/jupiter" }
11+
ruint = { workspace = true }

protocol-zap/src/constants.rs

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
use anchor_lang::prelude::*;
2+
use anchor_spl::associated_token::ID as ASSOCIATED_TOKEN_PROGRAM_ID;
3+
use anchor_spl::token::ID as TOKEN_PROGRAM_ID;
4+
use const_crypto::ed25519;
5+
6+
pub const JUP_V6_SHARED_ACCOUNT_ROUTE_AMOUNT_IN_REVERSE_OFFSET: usize = 1 + 2 + 8 + 8; // Due to jupiter parameters have dynamic length type (vec), we have to do parameters_data.length - JUP_V6_SHARED_ACCOUNT_ROUTE_AMOUNT_IN_REVERSE_OFFSET
7+
pub const JUP_V6_SHARED_ACCOUNT_ROUTE_SOURCE_ACCOUNT_INDEX: usize = 3;
8+
pub const JUP_V6_SHARED_ACCOUNT_ROUTE_DESTINATION_ACCOUNT_INDEX: usize = 6;
9+
10+
pub const JUP_V6_ROUTE_AMOUNT_IN_REVERSE_OFFSET: usize = 1 + 2 + 8 + 8;
11+
pub const JUP_V6_ROUTE_SOURCE_ACCOUNT_INDEX: usize = 2;
12+
pub const JUP_V6_ROUTE_DESTINATION_ACCOUNT_INDEX: usize = 4;
13+
14+
pub const DLMM_SWAP2_AMOUNT_IN_OFFSET: u16 = 8;
15+
pub const DLMM_SWAP2_SOURCE_ACCOUNT_INDEX: usize = 4;
16+
pub const DLMM_SWAP2_DESTINATION_ACCOUNT_INDEX: usize = 5;
17+
18+
pub const DAMM_V2_SWAP_AMOUNT_IN_OFFSET: u16 = 8;
19+
pub const DAMM_V2_SWAP_SOURCE_ACCOUNT_INDEX: usize = 2;
20+
pub const DAMM_V2_SWAP_DESTINATION_ACCOUNT_INDEX: usize = 3;
21+
22+
pub const JUP_V6: Pubkey = pubkey!("JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4");
23+
// https://github.com/MeteoraAg/zap-program/blob/4b67bfc64e5a023a1b74386be8b82c3908934a0b/idls/jupiter.json#L161
24+
pub const JUP_V6_ROUTE_DISC: [u8; 8] = [229, 23, 203, 151, 122, 227, 173, 42];
25+
// https://github.com/MeteoraAg/zap-program/blob/4b67bfc64e5a023a1b74386be8b82c3908934a0b/idls/jupiter.json#L270
26+
pub const JUP_V6_SHARED_ACCOUNT_ROUTE_DISC: [u8; 8] = [193, 32, 155, 51, 65, 214, 156, 129];
27+
28+
pub const DLMM: Pubkey = pubkey!("LBUZKhRxPF3XUpBCjp4YzTKgLccjZhTSDM9YuVaPwxo");
29+
// https://github.com/MeteoraAg/zap-program/blob/4b67bfc64e5a023a1b74386be8b82c3908934a0b/idls/dlmm.json#L5242-L5251
30+
pub const DLMM_SWAP2_DISC: [u8; 8] = [65, 75, 63, 76, 235, 91, 91, 136];
31+
32+
pub const DAMM_V2: Pubkey = pubkey!("cpamdpZCGKUy5JxQXB4dcpGPiikHawvSWAd6mEn1sGG");
33+
// https://github.com/MeteoraAg/zap-program/blob/4b67bfc64e5a023a1b74386be8b82c3908934a0b/idls/damm_v2.json#L2154
34+
pub const DAMM_V2_SWAP_DISC: [u8; 8] = [248, 198, 158, 145, 225, 117, 135, 200];
35+
36+
pub const ZAP: Pubkey = pubkey!("zapvX9M3uf5pvy4wRPAbQgdQsM1xmuiFnkfHKPvwMiz");
37+
pub const ZAP_OUT_DISC: [u8; 8] = [155, 108, 185, 112, 104, 210, 161, 64];
38+
39+
pub const USDC_ADDRESS: Pubkey =
40+
Pubkey::from_str_const("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v");
41+
42+
pub const SOL_ADDRESS: Pubkey =
43+
Pubkey::from_str_const("So11111111111111111111111111111111111111112");
44+
45+
pub const MINTS_DISALLOWED_TO_ZAP_OUT: [Pubkey; 2] = [USDC_ADDRESS, SOL_ADDRESS];
46+
47+
pub const TREASURY: Pubkey = pubkey!("6aYhxiNGmG8AyU25rh2R7iFu4pBrqnQHpNUGhmsEXRcm");
48+
49+
pub const TREASURY_USDC_ADDRESS: Pubkey = Pubkey::new_from_array(
50+
ed25519::derive_program_address(
51+
&[
52+
&TREASURY.to_bytes(),
53+
&TOKEN_PROGRAM_ID.to_bytes(),
54+
&USDC_ADDRESS.to_bytes(),
55+
],
56+
&ASSOCIATED_TOKEN_PROGRAM_ID.to_bytes(),
57+
)
58+
.0,
59+
);
60+
61+
pub const TREASURY_SOL_ADDRESS: Pubkey = Pubkey::new_from_array(
62+
ed25519::derive_program_address(
63+
&[
64+
&TREASURY.to_bytes(),
65+
&TOKEN_PROGRAM_ID.to_bytes(),
66+
&SOL_ADDRESS.to_bytes(),
67+
],
68+
&ASSOCIATED_TOKEN_PROGRAM_ID.to_bytes(),
69+
)
70+
.0,
71+
);

protocol-zap/src/damm_v2_zap.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
use crate::{
2+
constants::{
3+
DAMM_V2_SWAP_AMOUNT_IN_OFFSET, DAMM_V2_SWAP_DESTINATION_ACCOUNT_INDEX,
4+
DAMM_V2_SWAP_SOURCE_ACCOUNT_INDEX,
5+
},
6+
RawZapOutAmmInfo, ZapInfoProcessor, ZapOutParameters,
7+
};
8+
use anchor_lang::prelude::*;
9+
10+
pub struct ZapDammV2InfoProcessor;
11+
12+
impl ZapInfoProcessor for ZapDammV2InfoProcessor {
13+
fn validate_payload(&self, _payload: &[u8]) -> Result<()> {
14+
Ok(())
15+
}
16+
17+
fn extract_raw_zap_out_amm_info(
18+
&self,
19+
_zap_params: &ZapOutParameters,
20+
) -> Result<RawZapOutAmmInfo> {
21+
Ok(RawZapOutAmmInfo {
22+
source_index: DAMM_V2_SWAP_SOURCE_ACCOUNT_INDEX,
23+
destination_index: DAMM_V2_SWAP_DESTINATION_ACCOUNT_INDEX,
24+
amount_in_offset: DAMM_V2_SWAP_AMOUNT_IN_OFFSET,
25+
})
26+
}
27+
}

protocol-zap/src/dlmm_zap.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
use crate::{
2+
constants::{
3+
DLMM_SWAP2_AMOUNT_IN_OFFSET, DLMM_SWAP2_DESTINATION_ACCOUNT_INDEX,
4+
DLMM_SWAP2_SOURCE_ACCOUNT_INDEX,
5+
},
6+
RawZapOutAmmInfo, ZapInfoProcessor, ZapOutParameters,
7+
};
8+
use anchor_lang::prelude::*;
9+
10+
pub struct ZapDlmmInfoProcessor;
11+
12+
impl ZapInfoProcessor for ZapDlmmInfoProcessor {
13+
fn validate_payload(&self, _payload: &[u8]) -> Result<()> {
14+
Ok(())
15+
}
16+
17+
fn extract_raw_zap_out_amm_info(
18+
&self,
19+
_zap_params: &ZapOutParameters,
20+
) -> Result<RawZapOutAmmInfo> {
21+
Ok(RawZapOutAmmInfo {
22+
source_index: DLMM_SWAP2_SOURCE_ACCOUNT_INDEX,
23+
destination_index: DLMM_SWAP2_DESTINATION_ACCOUNT_INDEX,
24+
amount_in_offset: DLMM_SWAP2_AMOUNT_IN_OFFSET,
25+
})
26+
}
27+
}

0 commit comments

Comments
 (0)