Skip to content

Commit 166386b

Browse files
committed
feat(lazer): add treasury and fees to solana contract
1 parent a89055b commit 166386b

File tree

2 files changed

+89
-24
lines changed
  • lazer/contracts/solana/programs/pyth-lazer-solana-contract

2 files changed

+89
-24
lines changed

lazer/contracts/solana/programs/pyth-lazer-solana-contract/src/lib.rs

Lines changed: 67 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,9 @@
11
mod signature;
22

3-
pub mod storage {
4-
use anchor_lang::prelude::{pubkey, Pubkey};
5-
6-
pub const ID: Pubkey = pubkey!("3rdJbqfnagQ4yx9HXJViD4zc4xpiSqmFsKpPuSCQVyQL");
7-
8-
#[test]
9-
fn test_storage_id() {
10-
use {crate::STORAGE_SEED, anchor_lang::prelude::Pubkey};
11-
12-
assert_eq!(
13-
Pubkey::find_program_address(&[STORAGE_SEED], &super::ID).0,
14-
ID
15-
);
16-
}
17-
}
18-
193
use {
20-
anchor_lang::{prelude::*, solana_program::pubkey::PUBKEY_BYTES},
4+
crate::signature::VerifiedMessage,
5+
anchor_lang::solana_program::sysvar,
6+
anchor_lang::{prelude::*, solana_program::pubkey::PUBKEY_BYTES, system_program},
217
std::mem::size_of,
228
};
239

@@ -28,6 +14,21 @@ pub use {
2814

2915
declare_id!("pytd2yyk641x7ak7mkaasSJVXh6YYZnC7wTmtgAyxPt");
3016

17+
pub const STORAGE_ID: Pubkey = pubkey!("3rdJbqfnagQ4yx9HXJViD4zc4xpiSqmFsKpPuSCQVyQL");
18+
pub const TREASURY_ID: Pubkey = pubkey!("EN4aB3soE5iuCG2fGj2r5fksh4kLRVPV8g7N86vXm8WM");
19+
20+
#[test]
21+
fn test_ids() {
22+
assert_eq!(
23+
Pubkey::find_program_address(&[STORAGE_SEED], &ID).0,
24+
STORAGE_ID
25+
);
26+
assert_eq!(
27+
Pubkey::find_program_address(&[TREASURY_SEED], &ID).0,
28+
TREASURY_ID
29+
);
30+
}
31+
3132
pub const MAX_NUM_TRUSTED_SIGNERS: usize = 2;
3233

3334
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, AnchorSerialize, AnchorDeserialize)]
@@ -44,12 +45,14 @@ impl TrustedSignerInfo {
4445
pub struct Storage {
4546
pub top_authority: Pubkey,
4647
pub num_trusted_signers: u8,
48+
pub single_update_fee_in_lamports: u64,
4749
pub trusted_signers: [TrustedSignerInfo; MAX_NUM_TRUSTED_SIGNERS],
4850
}
4951

5052
impl Storage {
5153
const SERIALIZED_LEN: usize = PUBKEY_BYTES
5254
+ size_of::<u8>()
55+
+ size_of::<u64>()
5356
+ TrustedSignerInfo::SERIALIZED_LEN * MAX_NUM_TRUSTED_SIGNERS;
5457

5558
pub fn initialized_trusted_signers(&self) -> &[TrustedSignerInfo] {
@@ -58,15 +61,15 @@ impl Storage {
5861
}
5962

6063
pub const STORAGE_SEED: &[u8] = b"storage";
64+
pub const TREASURY_SEED: &[u8] = b"treasury";
6165

6266
#[program]
6367
pub mod pyth_lazer_solana_contract {
64-
use signature::VerifiedMessage;
65-
6668
use super::*;
6769

6870
pub fn initialize(ctx: Context<Initialize>, top_authority: Pubkey) -> Result<()> {
6971
ctx.accounts.storage.top_authority = top_authority;
72+
ctx.accounts.storage.single_update_fee_in_lamports = 1;
7073
Ok(())
7174
}
7275

@@ -128,6 +131,17 @@ pub mod pyth_lazer_solana_contract {
128131
signature_index: u8,
129132
message_offset: u16,
130133
) -> Result<VerifiedMessage> {
134+
system_program::transfer(
135+
CpiContext::new(
136+
ctx.accounts.system_program.to_account_info(),
137+
system_program::Transfer {
138+
from: ctx.accounts.payer.to_account_info(),
139+
to: ctx.accounts.treasury.to_account_info(),
140+
},
141+
),
142+
ctx.accounts.storage.single_update_fee_in_lamports,
143+
)?;
144+
131145
signature::verify_message(
132146
&ctx.accounts.storage,
133147
&ctx.accounts.sysvar,
@@ -155,6 +169,18 @@ pub struct Initialize<'info> {
155169
bump,
156170
)]
157171
pub storage: Account<'info, Storage>,
172+
#[account(
173+
init,
174+
payer = payer,
175+
space = 0,
176+
owner = system_program::ID,
177+
seeds = [TREASURY_SEED],
178+
bump,
179+
)]
180+
/// CHECK: this is a system program account but using anchor's `SystemAccount`
181+
/// results in invalid output from the Accounts proc macro. No extra checks
182+
/// are necessary because all necessary constraints are specified in the attribute.
183+
pub treasury: AccountInfo<'info>,
158184
pub system_program: Program<'info, System>,
159185
}
160186

@@ -172,10 +198,31 @@ pub struct Update<'info> {
172198

173199
#[derive(Accounts)]
174200
pub struct VerifyMessage<'info> {
201+
#[account(mut)]
202+
pub payer: Signer<'info>,
175203
#[account(
176204
seeds = [STORAGE_SEED],
177205
bump,
178206
)]
179207
pub storage: Account<'info, Storage>,
180-
pub sysvar: AccountInfo<'info>,
208+
#[account(
209+
mut,
210+
owner = system_program::ID,
211+
seeds = [TREASURY_SEED],
212+
bump,
213+
)]
214+
/// CHECK: this is a system program account but using anchor's `SystemAccount`
215+
/// results in invalid output from the Accounts proc macro. No extra checks
216+
/// are necessary because all necessary constraints are specified in the attribute.
217+
pub treasury: AccountInfo<'info>,
218+
pub system_program: Program<'info, System>,
219+
pub sysvar: Program<'info, Sysvar>,
220+
}
221+
222+
pub struct Sysvar;
223+
224+
impl Id for Sysvar {
225+
fn id() -> Pubkey {
226+
sysvar::ID
227+
}
181228
}

lazer/contracts/solana/programs/pyth-lazer-solana-contract/tests/test1.rs

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ async fn test1() {
3737
.data(),
3838
vec![
3939
AccountMeta::new(payer.pubkey(), true),
40-
AccountMeta::new(pyth_lazer_solana_contract::storage::ID, false),
40+
AccountMeta::new(pyth_lazer_solana_contract::STORAGE_ID, false),
41+
AccountMeta::new(pyth_lazer_solana_contract::TREASURY_ID, false),
4142
AccountMeta::new_readonly(system_program::ID, false),
4243
],
4344
)],
@@ -68,7 +69,7 @@ async fn test1() {
6869
.data(),
6970
vec![
7071
AccountMeta::new(payer.pubkey(), true),
71-
AccountMeta::new(pyth_lazer_solana_contract::storage::ID, false),
72+
AccountMeta::new(pyth_lazer_solana_contract::STORAGE_ID, false),
7273
],
7374
)],
7475
Some(&payer.pubkey()),
@@ -90,7 +91,12 @@ async fn test1() {
9091
message_offset,
9192
));
9293

93-
println!("ok1");
94+
let treasury_starting_lamports = banks_client
95+
.get_account(pyth_lazer_solana_contract::TREASURY_ID)
96+
.await
97+
.unwrap()
98+
.unwrap()
99+
.lamports;
94100
let mut transaction_verify = Transaction::new_with_payer(
95101
&[
96102
Instruction::new_with_bytes(
@@ -108,7 +114,10 @@ async fn test1() {
108114
}
109115
.data(),
110116
vec![
111-
AccountMeta::new_readonly(pyth_lazer_solana_contract::storage::ID, false),
117+
AccountMeta::new(payer.pubkey(), true),
118+
AccountMeta::new_readonly(pyth_lazer_solana_contract::STORAGE_ID, false),
119+
AccountMeta::new(pyth_lazer_solana_contract::TREASURY_ID, false),
120+
AccountMeta::new_readonly(system_program::ID, false),
112121
AccountMeta::new_readonly(sysvar::instructions::ID, false),
113122
],
114123
),
@@ -120,4 +129,13 @@ async fn test1() {
120129
.process_transaction(transaction_verify)
121130
.await
122131
.unwrap();
132+
assert_eq!(
133+
banks_client
134+
.get_account(pyth_lazer_solana_contract::TREASURY_ID)
135+
.await
136+
.unwrap()
137+
.unwrap()
138+
.lamports,
139+
treasury_starting_lamports + 1
140+
);
123141
}

0 commit comments

Comments
 (0)