Skip to content

Commit b3ec823

Browse files
committed
add fee quoter
1 parent 150cf14 commit b3ec823

File tree

43 files changed

+2449
-251
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+2449
-251
lines changed

chains/solana/Makefile

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,15 @@ lint-go-fix:
4141

4242
.PHONY: anchor-go-gen
4343
anchor-go-gen:
44-
cd ./contracts && rm -rf ./gobindings && anchor build && cd .. && ./scripts/anchor-go-gen.sh
44+
rm -rf ./gobindings && cd ./contracts && anchor build && cd .. && ./scripts/anchor-go-gen.sh
45+
46+
.PHONY: rematch-ids
47+
rematch-ids:
48+
./scripts/rematch-ids.sh
49+
50+
.PHONY: reclaim-sol
51+
reclaim-sol:
52+
./scripts/reclaim-sol.sh
4553

4654
.PHONY: format
4755
format:

chains/solana/contracts/Anchor.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,12 @@ seeds = false
66
skip-lint = false
77

88
[programs.devnet]
9+
failing_receiver = "Dri11EwVRViqqkjs7SWV3d3ejcanBGMNrcGhD6HVn756"
910
firedrill_compound = "Dri11NnBPbx85w8a47ZXBZa3Hi7E2xvHAA9Xpyk7UivQ"
1011
firedrill_entrypoint = "Dri11c6TXJXELaZUgQtyw3doxbn7bGXQ6z5LRZ8bMPbc"
12+
firedrill_feequoter = "3d1KhA6K2L6pbzpuhYGHTcsj1B4f3r86wJRE81brYTQW"
1113
firedrill_offramp = "Dri11kiWR5f1oTn5NLm3wmfaDq3cYauR92wrsTxNaudt"
1214
firedrill_token = "Dri11r4S1hY8iMpxNh6UoYZ9hsGgmGUUyZ3zxUb2rpc2"
13-
failing_receiver = "Dri11EwVRViqqkjs7SWV3d3ejcanBGMNrcGhD6HVn756"
1415

1516
[registry]
1617
url = "https://api.apr.dev"

chains/solana/contracts/Cargo.lock

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

chains/solana/contracts/crate/shared/src/seed.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Fixed seeds - different contexts must use different PDA seeds
22
pub const ENTRYPOINT: &[u8] = b"entrypoint";
33
pub const OFFRAMP: &[u8] = b"offramp";
4-
pub const ONRAMP: &[u8] = b"onramp";
4+
pub const FEE_QUOTER: &[u8] = b"fee_quoter";
55
pub const COMPOUND: &[u8] = b"compound";
66
pub const TOKEN: &[u8] = b"token";
77
pub const CONFIG: &[u8] = b"config";

chains/solana/contracts/programs/failing_receiver/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use anchor_lang::prelude::*;
22

3-
declare_id!("Dri11e51CFemqdySVVhmJbRzKeyVBJjch49RF2zH6Nt6");
3+
declare_id!("GG8nuxEhBqkxoQU9AF4jg39GYufEyzMabJbbDoLkeYwL");
44

55
#[program]
66
pub mod failing_receiver {

chains/solana/contracts/programs/firedrill_compound/src/lib.rs

Lines changed: 81 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,52 @@ use shared::seed;
44
pub mod messages;
55
use crate::messages::*;
66

7+
pub mod state;
8+
use crate::state::*;
9+
710
use ethnum::U256;
811

9-
declare_id!("9foztXMAs3Zdgx7ZkxDksb2S6piKE6R5G9iM5oAuVwFP");
12+
declare_id!("mjNGiAfCXTWqcD5TSy1wJ65g3kmwepud9NYxj1B36oy");
1013

1114
// FiredrillCompound is Router, OnRamp, RMNRemote, FeeQuoter and TokenAdminRegistry
1215
#[program]
1316
pub mod firedrill_compound {
1417
use super::*;
1518

16-
pub fn initialize(ctx: Context<Initialize>, token: Pubkey, chain_selector: u64) -> Result<()> {
19+
pub fn initialize(ctx: Context<Initialize>, chain_selector: u64, fee_quoter: Pubkey, token: Pubkey) -> Result<()> {
1720
let compound = &mut ctx.accounts.compound;
1821
compound.chain_selector = chain_selector;
1922
compound.owner = ctx.accounts.authority.key();
23+
compound.fee_quoter = fee_quoter;
2024
compound.token = token;
25+
26+
ctx.accounts.config.set_inner(Config {
27+
version: 1,
28+
default_code_version: CodeVersion::V1,
29+
owner: ctx.accounts.authority.key(),
30+
proposed_owner: Pubkey::default(),
31+
svm_chain_selector: chain_selector,
32+
fee_quoter,
33+
rmn_remote: ID,
34+
link_token_mint: token,
35+
fee_aggregator: ID,
36+
});
37+
38+
ctx.accounts.dest_chain.set_inner(DestChain {
39+
version: 1,
40+
chain_selector,
41+
state: DestChainState {
42+
sequence_number: 1,
43+
sequence_number_to_restore: 1,
44+
restore_on_action: RestoreOnAction::None,
45+
},
46+
config: DestChainConfig {
47+
lane_code_version: CodeVersion::V1,
48+
allowed_senders: vec![],
49+
allow_list_enabled: false,
50+
},
51+
});
52+
2153
Ok(())
2254
}
2355

@@ -53,38 +85,66 @@ pub mod firedrill_compound {
5385

5486
Ok(())
5587
}
56-
57-
pub fn emit_usd_per_token_updated(ctx: Context<EmitUsdPerToken>) -> Result<()> {
58-
let compound = &ctx.accounts.compound;
59-
60-
let token = compound.token;
61-
let mut value = [0u8; 28];
62-
let val = 1u128.to_le_bytes(); // 16 bytes
63-
value[..16].copy_from_slice(&val);
64-
let timestamp = Clock::get()?.unix_timestamp;
65-
66-
emit!(UsdPerTokenUpdated {
67-
token,
68-
value,
69-
timestamp,
70-
});
71-
72-
Ok(())
73-
}
7488
}
7589

7690
#[account]
7791
pub struct FiredrillCompound {
7892
pub chain_selector: u64,
7993
pub owner: Pubkey,
94+
pub fee_quoter: Pubkey,
8095
pub token: Pubkey,
8196
}
8297

98+
#[account]
99+
#[derive(InitSpace, Debug)]
100+
pub struct DestChain {
101+
// Config for SVM2Any
102+
pub version: u8,
103+
pub chain_selector: u64, // Chain selector used for the seed
104+
pub state: DestChainState, // values that are updated automatically
105+
pub config: DestChainConfig, // values configured by an admin
106+
}
107+
108+
#[account]
109+
#[derive(InitSpace, Debug)]
110+
pub struct Config {
111+
pub version: u8,
112+
113+
pub default_code_version: CodeVersion,
114+
115+
pub svm_chain_selector: u64,
116+
pub owner: Pubkey,
117+
pub proposed_owner: Pubkey,
118+
pub fee_quoter: Pubkey,
119+
pub rmn_remote: Pubkey,
120+
pub link_token_mint: Pubkey,
121+
pub fee_aggregator: Pubkey, // Allowed address to withdraw billed fees to (will use ATAs derived from it)
122+
}
123+
83124
#[derive(Accounts)]
125+
#[instruction(chain_selector: u64, fee_quoter: Pubkey, token: Pubkey)]
84126
pub struct Initialize<'info> {
85-
#[account(init, seeds = [seed::COMPOUND], bump, payer = authority, space = 8 + 8 + 32 + 32)]
127+
#[account(init, seeds = [seed::COMPOUND], bump, payer = authority, space = 8 + 8 + 32 + 32 + 32)]
86128
pub compound: Account<'info, FiredrillCompound>,
87129

130+
#[account(
131+
init,
132+
seeds = [seed::CONFIG],
133+
bump,
134+
payer = authority,
135+
space = 8 + Config::INIT_SPACE,
136+
)]
137+
pub config: Account<'info, Config>,
138+
139+
#[account(
140+
init,
141+
seeds = [seed::DEST_CHAIN_STATE, chain_selector.to_le_bytes().as_ref()],
142+
bump,
143+
payer = authority,
144+
space = 8 + DestChain::INIT_SPACE + 4, // 4 = empty Vec<Pubkey> len prefix
145+
)]
146+
pub dest_chain: Account<'info, DestChain>,
147+
88148
#[account(mut)]
89149
pub authority: Signer<'info>,
90150

@@ -98,23 +158,9 @@ pub struct EmitMessage<'info> {
98158
pub owner: Signer<'info>,
99159
}
100160

101-
#[derive(Accounts)]
102-
pub struct EmitUsdPerToken<'info> {
103-
#[account(mut, has_one = owner)]
104-
pub compound: Account<'info, FiredrillCompound>,
105-
pub owner: Signer<'info>,
106-
}
107-
108161
#[event]
109162
pub struct CCIPMessageSent {
110163
pub dest_chain_selector: u64,
111164
pub sequence_number: u64,
112165
pub message: SVM2AnyRampMessage,
113166
}
114-
115-
#[event]
116-
pub struct UsdPerTokenUpdated {
117-
pub token: Pubkey,
118-
pub value: [u8; 28],
119-
pub timestamp: i64,
120-
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
use std::fmt::Display;
2+
3+
use anchor_lang::prelude::borsh::{BorshDeserialize, BorshSerialize};
4+
use anchor_lang::prelude::*;
5+
6+
#[derive(Debug, PartialEq, Eq, Clone, Copy, InitSpace, BorshSerialize, BorshDeserialize)]
7+
#[repr(u8)]
8+
pub enum CodeVersion {
9+
Default = 0,
10+
V1,
11+
}
12+
13+
impl Display for CodeVersion {
14+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
15+
match self {
16+
CodeVersion::Default => write!(f, "Default"),
17+
CodeVersion::V1 => write!(f, "V1"),
18+
}
19+
}
20+
}
21+
22+
#[derive(Clone, AnchorSerialize, AnchorDeserialize, InitSpace, Debug, PartialEq, Eq, Copy)]
23+
pub enum RestoreOnAction {
24+
None, // initial case, there's no saved sequence number to restore
25+
Upgrade, // after a rollback, the saved sequence number must be restored on the following upgrade
26+
Rollback, // after an upgrade, the saved sequence number must be restored on the following rollback
27+
}
28+
29+
impl Display for RestoreOnAction {
30+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
31+
match self {
32+
RestoreOnAction::None => write!(f, "None"),
33+
RestoreOnAction::Upgrade => write!(f, "Upgrade"),
34+
RestoreOnAction::Rollback => write!(f, "Rollback"),
35+
}
36+
}
37+
}
38+
39+
#[derive(Clone, AnchorSerialize, AnchorDeserialize, InitSpace, Debug, PartialEq, Eq, Copy)]
40+
pub struct DestChainState {
41+
pub sequence_number: u64, // The last used sequence number. On upgrades, this is reset to 0.
42+
43+
// The following property is used to support one rollback operation, in which the sequence number of
44+
// the previous OnRamp version is restored. The upgrade/rollback is done per-lane (i.e. per dest chain).
45+
// If it's 0, that means that it is not possible to rollback to the previous version. As version upgrades
46+
// are not often, we won't need to rollback multiple versions.
47+
pub sequence_number_to_restore: u64, // The last used sequence number in the previous onramp version
48+
pub restore_on_action: RestoreOnAction,
49+
}
50+
51+
#[derive(Clone, AnchorSerialize, AnchorDeserialize, InitSpace, Debug)]
52+
pub struct DestChainConfig {
53+
// The code version of the lane, in case we need to shift traffic to new logic for a single lane to test an upgrade
54+
pub lane_code_version: CodeVersion,
55+
56+
// list of senders authorized to send messages to this destination chain.
57+
// Note: The attribute name `max_len` is slightly misleading: it is not in any
58+
// way limiting the actual length of the vector during initialization; it just
59+
// helps the InitSpace derive macro work out the initial space. We can leave it at
60+
// zero and calculate the actual length in the instruction context.
61+
#[max_len(0)]
62+
pub allowed_senders: Vec<Pubkey>,
63+
pub allow_list_enabled: bool,
64+
}
65+
66+
impl DestChainConfig {
67+
pub fn space(&self) -> usize {
68+
Self::INIT_SPACE + self.dynamic_space()
69+
}
70+
71+
pub fn dynamic_space(&self) -> usize {
72+
self.allowed_senders.len() * std::mem::size_of::<Pubkey>()
73+
}
74+
}

chains/solana/contracts/programs/firedrill_entrypoint/src/lib.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use anchor_lang::prelude::*;
22
use shared::seed;
33

4-
declare_id!("Dri11jJrhAN5DEr3b47WqFh6jvskcq4TT8ZWBJuvCphX");
4+
declare_id!("351TRJhiMuGnf9YJjhyVA1HHGDAUbwq1U7ppQQZNhsqj");
55

66
#[program]
77
pub mod firedrill_entrypoint {
@@ -12,6 +12,7 @@ pub mod firedrill_entrypoint {
1212
chain_selector: u64,
1313
token: Pubkey,
1414
off_ramp: Pubkey,
15+
fee_quoter: Pubkey,
1516
compound: Pubkey,
1617
receiver: Pubkey,
1718
) -> Result<()> {
@@ -20,6 +21,7 @@ pub mod firedrill_entrypoint {
2021
state.chain_selector = chain_selector;
2122
state.token = token;
2223
state.off_ramp = off_ramp;
24+
state.fee_quoter = fee_quoter;
2325
state.compound = compound;
2426
state.receiver = receiver;
2527
state.send_last = 0;
@@ -34,6 +36,7 @@ pub struct FiredrillEntrypoint {
3436
pub chain_selector: u64,
3537
pub token: Pubkey,
3638
pub off_ramp: Pubkey,
39+
pub fee_quoter: Pubkey,
3740
pub compound: Pubkey,
3841
pub receiver: Pubkey,
3942
pub send_last: u8,
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
[package]
2+
name = "firedrill_feequoter"
3+
version = "0.1.0"
4+
description = "Created with Anchor"
5+
edition = "2021"
6+
7+
[lib]
8+
crate-type = ["cdylib", "lib"]
9+
name = "firedrill_feequoter"
10+
11+
[features]
12+
no-entrypoint = []
13+
no-idl = []
14+
no-log-ix-name = []
15+
cpi = ["no-entrypoint"]
16+
default = []
17+
18+
[dependencies]
19+
solana-program = "1.17.25" # pin solana to 1.17
20+
anchor-lang = { version = "0.29.0", features = ["init-if-needed"] }
21+
anchor-spl = "0.29.0"
22+
shared = { path = "../../crate/shared" }
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[target.bpfel-unknown-unknown.dependencies.std]
2+
features = []

0 commit comments

Comments
 (0)