Skip to content

Conversation

@bangyro
Copy link
Collaborator

@bangyro bangyro commented Jan 19, 2026

No description provided.

@bangyro bangyro force-pushed the feat/add-common-protocol-fee branch from 2132c76 to f68848a Compare January 20, 2026 08:03
@bangyro bangyro changed the base branch from main to release_0.2.2 January 20, 2026 08:03
// https://github.com/MeteoraAg/zap-program/blob/main/idls/dlmm.json#L3413-L3422
#[constant]
pub const DLMM_SWAP2_DISC: [u8; 8] = [65, 75, 63, 76, 235, 91, 91, 136];
use protocol_zap::constants::{
Copy link
Collaborator Author

@bangyro bangyro Jan 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

zap program depends on protocol_zap for these constants

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lets rename it to zap-sdk

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Renamed and updated to the IDL found on solscan

Comment on lines +46 to +90
fn ensure_route_plan_fully_converges(route_plan_steps: &[RoutePlanStep]) -> Result<()> {
// Verify each unique input_index sums to exactly 100%
for (i, step) in route_plan_steps.iter().enumerate() {
// Only process first occurrence of each input_index
let seen = route_plan_steps[..i]
.iter()
.any(|s| s.input_index == step.input_index);
if seen {
continue;
}

let percent_sum = route_plan_steps
.iter()
.filter(|s| s.input_index == step.input_index)
.try_fold(0u8, |acc, s| acc.checked_add(s.percent))
.ok_or(ProtocolZapError::MathOverflow)?;

require!(
percent_sum == 100,
ProtocolZapError::InvalidZapOutParameters
);
}

// Count terminal outputs: unique outputs never used as inputs
let terminal_count = route_plan_steps
.iter()
.enumerate()
.filter(|(i, step)| {
let is_first = !route_plan_steps[..*i]
.iter()
.any(|s| s.output_index == step.output_index);
let is_terminal = !route_plan_steps
.iter()
.any(|s| s.input_index == step.output_index);
is_first && is_terminal
})
.count();

require!(
terminal_count == 1,
ProtocolZapError::InvalidZapOutParameters
);

Ok(())
}
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Implementation looks weird because I'm trying to avoid using Map and Set to avoid additional heap allocation

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need zap_out2 since all the additional verification is only done in zap_protocol_fee ix rather than the zap_out ix that comes right after it in the tx.

@bangyro bangyro marked this pull request as ready for review January 20, 2026 10:26
@@ -0,0 +1,11 @@
[package]
name = "protocol-zap"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lets rename it to zap-sdk

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and separate the code:

  • To be used in zap-program
  • To be used in protocol-zap

Copy link
Collaborator Author

@bangyro bangyro Jan 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let me know if this is what you have in mind. So there will be zap-sdk, which zap-program and protocol-zap depends on?

zap-sdk -> common code used by zap-program/protocol-zap
protocol-zap -> common code used by other programs to zap protocol fee


pub const MINTS_DISALLOWED_TO_ZAP_OUT: [Pubkey; 2] = [USDC_ADDRESS, SOL_ADDRESS];

pub const TREASURY: Pubkey = pubkey!("6aYhxiNGmG8AyU25rh2R7iFu4pBrqnQHpNUGhmsEXRcm");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't push treasury wallet in the sdk, it should be re-used by other programs, not only Meteora


pub const TREASURY: Pubkey = pubkey!("6aYhxiNGmG8AyU25rh2R7iFu4pBrqnQHpNUGhmsEXRcm");

pub const TREASURY_USDC_ADDRESS: Pubkey = Pubkey::new_from_array(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto^, we dont fix treasury wallet, so those addresses will be dynamic

.0,
);

pub const TREASURY_SOL_ADDRESS: Pubkey = Pubkey::new_from_array(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto^


[dependencies]
anchor-lang = { workspace = true }
anchor-spl = { workspace = true }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure if we can make it no anchor dependencies, so it is easier to being imported from other projects?


fn ensure_whitelisted_swap_leg(route_plan_steps: &[RoutePlanStep]) -> Result<()> {
for step in route_plan_steps {
match step.swap {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could we make it constants? whitelisted_swap_leg

use anchor_lang::prelude::*;

// Anchor custom user error codes start at 6000. Adding 1000 to avoid conflict with calling program error codes
#[error_code(offset = 7000)]
Copy link
Contributor

@andrewsource147 andrewsource147 Jan 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is breaking change for zap-program
Lets avoid to use Anchor custom error code here, instead return pure ErrorCode
If other program want to import it, they must map the error back their program (Impl From trait)

try_into_impl!(usize, u16);

#[cfg(test)]
mod tests {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lets try to avoid to push test in same file with program code

}

#[cfg(test)]
mod tests {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lets try to avoid to push test in same file with program code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants