-
Notifications
You must be signed in to change notification settings - Fork 18
Expand file tree
/
Copy pathvalidator_claim_fees.rs
More file actions
91 lines (80 loc) · 2.76 KB
/
validator_claim_fees.rs
File metadata and controls
91 lines (80 loc) · 2.76 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
use borsh::BorshDeserialize;
use solana_program::{
account_info::AccountInfo, entrypoint::ProgramResult, msg,
program_error::ProgramError, pubkey::Pubkey, rent::Rent,
};
use crate::{
args::ValidatorClaimFeesArgs,
consts::PROTOCOL_FEES_PERCENTAGE,
error::DlpError,
processor::utils::loaders::{
load_initialized_protocol_fees_vault,
load_initialized_validator_fees_vault, load_signer,
},
};
/// Process validator request to claim fees from the fees vault
///
/// Accounts:
///
/// 0: `[signer]` the validator account.
/// 1: `[writable]` the fees vault PDA.
/// 2: `[writable]` the validator fees vault PDA.
///
/// Requirements:
///
/// - protocol fees vault is initialized
/// - validator fees vault is initialized
/// - validators fees vault needs to hold enough lamports to claim
///
/// 1. Transfer lamports from validator fees_vault PDA to the validator authority
pub fn process_validator_claim_fees(
_program_id: &Pubkey,
accounts: &[AccountInfo],
data: &[u8],
) -> ProgramResult {
let args = ValidatorClaimFeesArgs::try_from_slice(data)?;
// Load Accounts
let [validator, fees_vault, validator_fees_vault] = accounts else {
return Err(ProgramError::NotEnoughAccountKeys);
};
load_signer(validator, "validator")?;
load_initialized_protocol_fees_vault(fees_vault, true)?;
load_initialized_validator_fees_vault(
validator,
validator_fees_vault,
true,
)?;
// Calculate the amount to transfer
let min_rent = Rent::default().minimum_balance(8);
let amount = args
.amount
.unwrap_or(validator_fees_vault.lamports() - min_rent);
// Ensure vault has enough lamports
if validator_fees_vault.lamports() - min_rent < amount {
msg!(
"Vault ({}) has insufficient funds: {} < {}",
validator_fees_vault.key,
validator_fees_vault.lamports() - min_rent,
amount
);
return Err(ProgramError::InsufficientFunds);
}
// Calculate fees and remaining amount
let protocol_fees = (amount * u64::from(PROTOCOL_FEES_PERCENTAGE)) / 100;
let remaining_amount = amount.saturating_sub(protocol_fees);
// Transfer fees to fees_vault
**fees_vault.try_borrow_mut_lamports()? = fees_vault
.lamports()
.checked_add(protocol_fees)
.ok_or(DlpError::Overflow)?;
// Transfer remaining amount from validator_fees_vault to validator
**validator_fees_vault.try_borrow_mut_lamports()? = validator_fees_vault
.lamports()
.checked_sub(amount)
.ok_or(ProgramError::InsufficientFunds)?;
**validator.try_borrow_mut_lamports()? = validator
.lamports()
.checked_add(remaining_amount)
.ok_or(DlpError::Overflow)?;
Ok(())
}