1
+ use anchor_lang:: prelude:: * ;
2
+ use anchor_spl:: token_interface:: { Mint , TokenAccount , TokenInterface , TransferChecked , transfer_checked} ;
3
+ use crate :: { constants:: { SEED_POOL , SEED_REWARD_TOKEN_ACCOUNT } , events:: AddedRewardEvent , state:: Pool , utils:: update_reward} ;
4
+ use crate :: errors:: ErrorCode ;
5
+
6
+ #[ derive( Accounts ) ]
7
+ pub struct AddReward < ' info > {
8
+ #[ account( mut ) ]
9
+ signer : Signer < ' info > ,
10
+
11
+ pub mint : InterfaceAccount < ' info , Mint > ,
12
+ #[ account(
13
+ mint:: token_program = reward_token_program,
14
+ ) ]
15
+ pub reward_mint : InterfaceAccount < ' info , Mint > ,
16
+
17
+ #[ account(
18
+ mut ,
19
+ seeds = [ SEED_POOL , mint. key( ) . as_ref( ) , reward_mint. key( ) . as_ref( ) ] ,
20
+ bump = pool. bump,
21
+ ) ]
22
+ pub pool : Account < ' info , Pool > ,
23
+
24
+ #[ account(
25
+ init_if_needed,
26
+ payer = signer,
27
+ seeds = [ SEED_REWARD_TOKEN_ACCOUNT , pool. key( ) . as_ref( ) ] ,
28
+ token:: mint = reward_mint,
29
+ token:: authority = pool_reward_token_account,
30
+ token:: token_program = reward_token_program,
31
+ bump,
32
+ ) ]
33
+ pub pool_reward_token_account : InterfaceAccount < ' info , TokenAccount > ,
34
+
35
+ #[ account(
36
+ mut ,
37
+ associated_token:: mint = reward_mint,
38
+ associated_token:: authority = signer,
39
+ associated_token:: token_program = reward_token_program,
40
+ ) ]
41
+ pub user_reward_token_account : InterfaceAccount < ' info , TokenAccount > ,
42
+
43
+ pub reward_token_program : Interface < ' info , TokenInterface > ,
44
+ pub system_program : Program < ' info , System > ,
45
+ }
46
+
47
+ pub fn process_add_reward ( ctx : Context < AddReward > , amount : u64 ) -> Result < ( ) > {
48
+ require ! ( amount > 0 , ErrorCode :: ZeroAmount ) ;
49
+
50
+ let pool = & mut ctx. accounts . pool ;
51
+
52
+ require ! ( pool. mint == ctx. accounts. mint. key( ) , ErrorCode :: InvalidMint ) ;
53
+
54
+ let current_timestamp = Clock :: get ( ) ?. unix_timestamp as u64 ;
55
+
56
+ require ! ( ctx. accounts. signer. key( ) == pool. distributor, ErrorCode :: NotDistributor ) ;
57
+
58
+ // Initializing pool_reward_token_account if not initialized
59
+ if pool. reward_token_account == Pubkey :: default ( ) {
60
+ pool. reward_token_account = ctx. accounts . pool_reward_token_account . key ( ) ;
61
+ pool. bump_reward_token_account = ctx. bumps . pool_reward_token_account
62
+ }
63
+
64
+ update_reward ( pool, None ) ?;
65
+
66
+ if current_timestamp >= pool. period_finish {
67
+ pool. reward_rate = amount. saturating_div ( pool. duration ) ;
68
+ } else {
69
+ let remaining: u64 = pool. period_finish . saturating_sub ( current_timestamp) ;
70
+ let leftover: u64 = remaining. saturating_mul ( pool. reward_rate ) ;
71
+ pool. reward_rate = ( amount. saturating_add ( leftover) ) . saturating_div ( pool. duration ) ;
72
+ }
73
+
74
+ require ! ( pool. reward_rate > 0 , ErrorCode :: ZeroRewardRate ) ;
75
+
76
+ pool. last_updated = current_timestamp;
77
+ pool. period_finish = current_timestamp. saturating_add ( pool. duration ) ;
78
+
79
+ // Do Transfer
80
+ let transfer_cpi_accounts = TransferChecked {
81
+ from : ctx. accounts . user_reward_token_account . to_account_info ( ) ,
82
+ to : ctx. accounts . pool_reward_token_account . to_account_info ( ) ,
83
+ authority : ctx. accounts . signer . to_account_info ( ) ,
84
+ mint : ctx. accounts . reward_mint . to_account_info ( ) ,
85
+ } ;
86
+
87
+ let cpi_program = ctx. accounts . reward_token_program . to_account_info ( ) ;
88
+ let cpi_ctx = CpiContext :: new ( cpi_program, transfer_cpi_accounts) ;
89
+
90
+ transfer_checked ( cpi_ctx, amount, ctx. accounts . reward_mint . decimals ) ?;
91
+
92
+ let new_pool_reward_amount = pool. duration . saturating_mul ( pool. reward_rate ) ;
93
+
94
+ emit ! ( AddedRewardEvent { pool: pool. key( ) , contributor: ctx. accounts. signer. key( ) , reward_token_program: ctx. accounts. reward_token_program. key( ) , amount: amount, new_pool_reward_amount: new_pool_reward_amount, timestamp: current_timestamp } ) ;
95
+
96
+ Ok ( ( ) )
97
+ }
0 commit comments