Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
90513c6
Add min_validations to Controller
GuidoDipietro Mar 19, 2026
4004443
Use controller's min_validations on settler's create_intent
GuidoDipietro Mar 19, 2026
04a39b9
Add tests for min_validations on Settler
GuidoDipietro Mar 19, 2026
ad78d1e
Fix incorrect assertion in tests
GuidoDipietro Mar 19, 2026
fba3c30
Scaffold execute_proposal body
GuidoDipietro Mar 25, 2026
142117e
Implement execute_proposal (transfer intent)
GuidoDipietro Mar 26, 2026
35a6545
Abstract execute_transfer out to function
GuidoDipietro Mar 31, 2026
fabea4e
Documents execute_transfer remaining_accounts transfer branch
GuidoDipietro Mar 31, 2026
0e018a1
execute_proposal WIP
GuidoDipietro Mar 31, 2026
53b2737
Improvements in execute_proposal
GuidoDipietro Mar 31, 2026
1b7824c
WIP tests
GuidoDipietro Mar 31, 2026
a0ed7e2
Fix double borrow issue in Rust
GuidoDipietro Apr 7, 2026
9ab7b69
Fix execute_proposal tests scaffold
GuidoDipietro Apr 7, 2026
4d9ea5c
Implement execute_proposal happy path!
GuidoDipietro Apr 7, 2026
7b1a75d
Implement some unhappy paths
GuidoDipietro Apr 7, 2026
e7c406d
Implement more unhappy paths
GuidoDipietro Apr 7, 2026
d1230de
Finish execute_proposal tests (first iteration)
GuidoDipietro Apr 7, 2026
4468a9d
Fix clippy
GuidoDipietro Apr 8, 2026
8fa0272
Cargo fmt
GuidoDipietro Apr 8, 2026
5b0be6d
Add pay_solver_fees logic
GuidoDipietro Apr 8, 2026
41c785c
Scaffold tests for pay_solver_fees
GuidoDipietro Apr 8, 2026
8fa39bf
Implement happy path with pay_solver_fees
GuidoDipietro Apr 8, 2026
b3902ab
Add custom errors for pay_solver_fees
GuidoDipietro Apr 8, 2026
50b09a9
Implement missing tests
GuidoDipietro Apr 17, 2026
7d840b2
Run clippy and yarn lint, remove .skip
GuidoDipietro Apr 20, 2026
8b20045
Merge branch 'solana/settler' into solana/execute-proposal
GuidoDipietro Apr 23, 2026
723d852
Code review comments
GuidoDipietro Apr 27, 2026
24540b8
Simplify before in function
GuidoDipietro Apr 27, 2026
941e1ee
Remove nasty arrow functions from helper functions
GuidoDipietro Apr 28, 2026
9e86fa6
Remove duplicated nested context
GuidoDipietro Apr 28, 2026
d5d2088
Nit
GuidoDipietro Apr 28, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,503 changes: 1,383 additions & 120 deletions packages/svm/Cargo.lock

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ pub struct ResizeSettings<'info> {
}

fn check_settings_data(data: &[u8], expected_admin: Pubkey) -> Result<()> {
if !data.starts_with(&ControllerSettings::DISCRIMINATOR) {
if !data.starts_with(ControllerSettings::DISCRIMINATOR) {
return Err(ProgramError::InvalidAccountData.into());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ pub struct EntityRegistry {
}

impl EntityRegistry {
pub fn size(entity_address: &Vec<u8>) -> usize {
pub fn size(entity_address: &[u8]) -> usize {
EntityType::INIT_SPACE + VEC_LEN_SIZE + entity_address.len() + 1
}
}
3 changes: 2 additions & 1 deletion packages/svm/programs/settler/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,14 @@ cpi = ["no-entrypoint"]
no-entrypoint = []
no-idl = []
no-log-ix-name = []
idl-build = ["anchor-lang/idl-build"]
idl-build = ["anchor-lang/idl-build", "anchor-spl/idl-build"]
anchor-debug = []
custom-heap = []
custom-panic = []

[dependencies]
anchor-lang = { version = "0.32.1", features = [ "init-if-needed" ] }
anchor-spl = { version = "0.32.1" }
alloy-sol-types = "1.5.4"
alloy-primitives = "1.5.4"

Expand Down
2 changes: 2 additions & 0 deletions packages/svm/programs/settler/src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@ pub const DEPLOYER_KEY: &str = env!(
"DEPLOYER_KEY",
"Please set the DEPLOYER_KEY env variable before compiling."
);

pub const CHAIN_ID: u32 = 507424;
43 changes: 41 additions & 2 deletions packages/svm/programs/settler/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@ pub enum SettlerError {
#[msg("Validator is not allowlisted")]
ValidatorNotAllowlisted,

#[msg("Signer must be intent creator")]
#[msg("Incorrect intent creator")]
IncorrectIntentCreator,

#[msg("Signer must be proposal creator")]
#[msg("Incorrect proposal creator")]
IncorrectProposalCreator,

#[msg("Intent is already final")]
Expand Down Expand Up @@ -59,6 +59,9 @@ pub enum SettlerError {
#[msg("Proposal deadline can't be after the Intent's deadline")]
ProposalDeadlineExceedsIntentDeadline,

#[msg("Incorrect proposal data")]
IncorrectProposalData,

#[msg("Intent has insufficient validations")]
InsufficientIntentValidations,

Expand Down Expand Up @@ -86,6 +89,42 @@ pub enum SettlerError {
#[msg("Fee amount exceeds max fee")]
FeeAmountExceedsMaxFee,

#[msg("Unsupported intent op")]
UnsupportedIntentOp,

#[msg("Incorrect intent chain id")]
IncorrectChainId,

#[msg("Invalid transfer recipient: malformed pubkey")]
InvalidTransferRecipient,

#[msg("Incorrect transfer recipient account")]
IncorrectTransferRecipient,

#[msg("Invalid transfer token: malformed pubkey")]
InvalidTransferToken,

#[msg("Incorrect transfer token mint account")]
IncorrectTransferToken,

#[msg("Incorrect fee token mint account")]
IncorrectFeeToken,

#[msg("Account not owned by TokenKeg or Token2022 programs")]
AccountNotOwnedByTokenProgram,

#[msg("Incorrect recipient token account: mint or authority do not match expected")]
IncorrectRecipientTokenAccount,

#[msg("Incorrect user token account: mint or authority do not match expected")]
IncorrectUserTokenAccount,

#[msg("Incorrect solver token account: mint or authority do not match expected")]
IncorrectSolverTokenAccount,

#[msg("Incorrect token program account provided")]
IncorrectTokenProgram,

#[msg("Math Error")]
MathError,
}
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ pub fn create_intent(
) -> Result<()> {
let now = Clock::get()?.unix_timestamp as u64;
require!(deadline > now, SettlerError::DeadlineIsInThePast);
require!(max_fees.len() > 0, SettlerError::NoMaxFees);
require!(!max_fees.is_empty(), SettlerError::NoMaxFees);

// TODO: check hash

Expand Down
50 changes: 43 additions & 7 deletions packages/svm/programs/settler/src/instructions/execute_proposal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use crate::{
errors::SettlerError,
state::{FulfilledIntent, Intent, Proposal},
types::IntentEvent,
utils::{handle_intent_execution, pay_solver_fees},
};

#[derive(Accounts)]
Expand Down Expand Up @@ -40,6 +41,7 @@ pub struct ExecuteProposal<'info> {
#[account(
mut,
constraint = intent.creator == intent_creator.key() @ SettlerError::IncorrectIntentCreator,
constraint = intent.is_final @ SettlerError::IntentIsNotFinal,
close = intent_creator
)]
pub intent: Box<Account<'info, Intent>>,
Expand All @@ -53,24 +55,58 @@ pub struct ExecuteProposal<'info> {
)]
pub fulfilled_intent: Box<Account<'info, FulfilledIntent>>,

#[account(seeds = [b"delegate", intent.user.key().as_ref()], bump)]
pub delegate: SystemAccount<'info>,

pub system_program: Program<'info, System>,
}

pub fn execute_proposal(ctx: Context<ExecuteProposal>) -> Result<()> {
pub fn execute_proposal<'info>(
Comment thread
PedroAraoz marked this conversation as resolved.
ctx: Context<'_, '_, '_, 'info, ExecuteProposal<'info>>,
) -> Result<()> {
let intent = &ctx.accounts.intent;
let proposal = &ctx.accounts.proposal;

let mut remaining_accounts_iter = ctx.remaining_accounts.iter();
let token_program = next_account_info(&mut remaining_accounts_iter)?;
let token_2022_program = next_account_info(&mut remaining_accounts_iter)?;

require_keys_eq!(
token_program.key(),
anchor_spl::token::ID,
SettlerError::IncorrectTokenProgram
);
require_keys_eq!(
token_2022_program.key(),
anchor_spl::token_2022::ID,
SettlerError::IncorrectTokenProgram
);

handle_intent_execution(
intent,
proposal,
&ctx.accounts.delegate.clone(),
&mut remaining_accounts_iter,
token_program,
token_2022_program,
ctx.bumps.delegate,
)?;

// TODO: Execute proposal

// TODO: Validate execution

// TODO: Emit events
intent.events.iter().for_each(|event| {
emit!(IntentEventEvent {
event: event.clone()
})
});

// TODO: Pay fees to Solver
pay_solver_fees(
&mut remaining_accounts_iter,
intent,
proposal,
token_program,
token_2022_program,
&ctx.accounts.delegate.clone(),
ctx.bumps.delegate,
)?;

Ok(())
}
Expand Down
4 changes: 3 additions & 1 deletion packages/svm/programs/settler/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,9 @@ pub mod settler {
instructions::create_proposal(ctx, instructions, fees, deadline, is_final)
}

pub fn execute_proposal(ctx: Context<ExecuteProposal>) -> Result<()> {
pub fn execute_proposal<'info>(
ctx: Context<'_, '_, '_, 'info, ExecuteProposal<'info>>,
) -> Result<()> {
instructions::execute_proposal(ctx)
}

Expand Down
9 changes: 3 additions & 6 deletions packages/svm/programs/settler/src/state/proposal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,14 @@ impl Proposal {
1 // bump
;

pub fn total_size(instructions: &Vec<ProposalInstruction>, fees_len: usize) -> Result<usize> {
pub fn total_size(instructions: &[ProposalInstruction], fees_len: usize) -> Result<usize> {
let size = add(8, Proposal::BASE_LEN)?;
let size = add(size, Proposal::instructions_size(instructions)?)?;
let size = add(size, Proposal::fees_size(fees_len)?)?;
Ok(size)
}

pub fn instructions_size(instructions: &Vec<ProposalInstruction>) -> Result<usize> {
pub fn instructions_size(instructions: &[ProposalInstruction]) -> Result<usize> {
let sum = instructions
.iter()
.try_fold(0usize, |acc, ix| add(acc, ix.size()))?;
Expand All @@ -43,10 +43,7 @@ impl Proposal {
add(4, mul(8, len)?)
}

pub fn extended_size(
size: usize,
more_instructions: &Vec<ProposalInstruction>,
) -> Result<usize> {
pub fn extended_size(size: usize, more_instructions: &[ProposalInstruction]) -> Result<usize> {
sub(
add(size, Proposal::instructions_size(more_instructions)?)?,
4,
Expand Down
3 changes: 3 additions & 0 deletions packages/svm/programs/settler/src/types/intent_data/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
pub mod transfer;

pub use transfer::*;
14 changes: 14 additions & 0 deletions packages/svm/programs/settler/src/types/intent_data/transfer.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
use anchor_lang::prelude::{borsh::BorshDeserialize, *};

#[derive(BorshDeserialize)]
pub struct SvmTransfer {
pub token: Vec<u8>,
pub amount: u64,
pub recipient: Vec<u8>,
}

#[derive(BorshDeserialize)]
pub struct SvmTransferIntentData {
pub chain_id: u32,
pub transfers: Vec<SvmTransfer>,
}
2 changes: 2 additions & 0 deletions packages/svm/programs/settler/src/types/mod.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
pub mod eip712_domain;
pub mod intent_data;
pub mod intent_event;
pub mod op_type;
pub mod token_fee;

pub use eip712_domain::*;
pub use intent_data::*;
pub use intent_event::*;
pub use op_type::*;
pub use token_fee::*;
Loading
Loading