11use anchor_lang:: prelude:: * ;
22use anchor_spl:: {
33 associated_token:: AssociatedToken ,
4- token:: Token ,
4+ token:: { close_account , CloseAccount , Token } ,
55 token_interface:: { TokenAccount , TokenInterface } ,
66} ;
77
@@ -52,6 +52,7 @@ pub struct ClaimPositionFee<'info> {
5252 /// CHECK:
5353 pub token_b_mint : UncheckedAccount < ' info > ,
5454
55+ /// WSOL account - can be owned by treasury or vault_authority (we'll use as temp account)
5556 #[ account(
5657 init_if_needed,
5758 payer = payer,
@@ -68,6 +69,7 @@ pub struct ClaimPositionFee<'info> {
6869 ) ]
6970 pub wewe_token_account : Box < InterfaceAccount < ' info , TokenAccount > > ,
7071
72+ /// WSOL account - can be owned by maker or vault_authority (we'll use as temp account)
7173 #[ account(
7274 init_if_needed,
7375 payer = payer,
@@ -118,6 +120,44 @@ pub struct ClaimPositionFee<'info> {
118120 /// CHECK:
119121 pub position_nft_account : UncheckedAccount < ' info > ,
120122
123+ /// CHECK: Temporary WSOL account for treasury unwrapping (PDA derived from token program)
124+ /// PDA: [b"temp_wsol", vault_authority, proposal, b"treasury"]
125+ #[ account(
126+ mut ,
127+ constraint = {
128+ let ( expected_pda, _) = Pubkey :: find_program_address(
129+ & [
130+ b"temp_wsol" ,
131+ vault_authority. key( ) . as_ref( ) ,
132+ proposal. key( ) . as_ref( ) ,
133+ b"treasury" ,
134+ ] ,
135+ & token_b_program. key( ) ,
136+ ) ;
137+ treasury_temp_wsol. key( ) == expected_pda
138+ } @ ProposalError :: IncorrectAccount
139+ ) ]
140+ pub treasury_temp_wsol : UncheckedAccount < ' info > ,
141+
142+ /// CHECK: Temporary WSOL account for maker unwrapping (PDA derived from token program)
143+ /// PDA: [b"temp_wsol", vault_authority, proposal, b"maker"]
144+ #[ account(
145+ mut ,
146+ constraint = {
147+ let ( expected_pda, _) = Pubkey :: find_program_address(
148+ & [
149+ b"temp_wsol" ,
150+ vault_authority. key( ) . as_ref( ) ,
151+ proposal. key( ) . as_ref( ) ,
152+ b"maker" ,
153+ ] ,
154+ & token_b_program. key( ) ,
155+ ) ;
156+ maker_temp_wsol. key( ) == expected_pda
157+ } @ ProposalError :: IncorrectAccount
158+ ) ]
159+ pub maker_temp_wsol : UncheckedAccount < ' info > ,
160+
121161 pub token_a_program : Interface < ' info , TokenInterface > ,
122162
123163 pub token_b_program : Interface < ' info , TokenInterface > ,
@@ -217,34 +257,91 @@ impl<'info> ClaimPositionFee<'info> {
217257 ) ?;
218258 }
219259
260+ // Unwrap WSOL (token_b) to SOL before transferring
261+ // We use PDA-derived temporary accounts (validated at account struct level)
220262 if treasury_b > 0 {
263+ // Transfer WSOL to temporary PDA account
221264 anchor_spl:: token:: transfer (
222265 CpiContext :: new_with_signer (
223266 self . token_b_program . to_account_info ( ) ,
224267 anchor_spl:: token:: Transfer {
225268 from : self . token_b_account . to_account_info ( ) ,
226- to : self . wewe_wsol_account . to_account_info ( ) ,
269+ to : self . treasury_temp_wsol . to_account_info ( ) ,
227270 authority : self . vault_authority . to_account_info ( ) ,
228271 } ,
229272 & [ & vault_authority_seeds[ ..] ] ,
230273 ) ,
231274 treasury_b,
232275 ) ?;
276+
277+ // Close the temporary WSOL account to unwrap it to SOL
278+ // The SOL (lamports) will be sent to the account owner (vault_authority)
279+ close_account (
280+ CpiContext :: new_with_signer (
281+ self . token_b_program . to_account_info ( ) ,
282+ CloseAccount {
283+ account : self . treasury_temp_wsol . to_account_info ( ) ,
284+ destination : self . vault_authority . to_account_info ( ) ,
285+ authority : self . vault_authority . to_account_info ( ) ,
286+ } ,
287+ & [ & vault_authority_seeds[ ..] ] ,
288+ ) ,
289+ ) ?;
290+
291+ // Transfer SOL from vault_authority to treasury
292+ anchor_lang:: system_program:: transfer (
293+ CpiContext :: new_with_signer (
294+ self . system_program . to_account_info ( ) ,
295+ anchor_lang:: system_program:: Transfer {
296+ from : self . vault_authority . to_account_info ( ) ,
297+ to : self . wewe_treasury . to_account_info ( ) ,
298+ } ,
299+ & [ & vault_authority_seeds[ ..] ] ,
300+ ) ,
301+ treasury_b,
302+ ) ?;
233303 }
234304
235305 if maker_b > 0 {
306+ // Transfer WSOL to temporary PDA account
236307 anchor_spl:: token:: transfer (
237308 CpiContext :: new_with_signer (
238309 self . token_b_program . to_account_info ( ) ,
239310 anchor_spl:: token:: Transfer {
240311 from : self . token_b_account . to_account_info ( ) ,
241- to : self . maker_wsol_account . to_account_info ( ) ,
312+ to : self . maker_temp_wsol . to_account_info ( ) ,
242313 authority : self . vault_authority . to_account_info ( ) ,
243314 } ,
244315 & [ & vault_authority_seeds[ ..] ] ,
245316 ) ,
246317 maker_b,
247318 ) ?;
319+
320+ // Close the temporary WSOL account to unwrap it to SOL
321+ close_account (
322+ CpiContext :: new_with_signer (
323+ self . token_b_program . to_account_info ( ) ,
324+ CloseAccount {
325+ account : self . maker_temp_wsol . to_account_info ( ) ,
326+ destination : self . vault_authority . to_account_info ( ) ,
327+ authority : self . vault_authority . to_account_info ( ) ,
328+ } ,
329+ & [ & vault_authority_seeds[ ..] ] ,
330+ ) ,
331+ ) ?;
332+
333+ // Transfer SOL from vault_authority to maker
334+ anchor_lang:: system_program:: transfer (
335+ CpiContext :: new_with_signer (
336+ self . system_program . to_account_info ( ) ,
337+ anchor_lang:: system_program:: Transfer {
338+ from : self . vault_authority . to_account_info ( ) ,
339+ to : self . maker . to_account_info ( ) ,
340+ } ,
341+ & [ & vault_authority_seeds[ ..] ] ,
342+ ) ,
343+ maker_b,
344+ ) ?;
248345 }
249346
250347 emit ! ( PositionFeeClaimed {
0 commit comments