diff --git a/contracts/programs/ocr2/src/context.rs b/contracts/programs/ocr2/src/context.rs index d83a430c0..520bde481 100644 --- a/contracts/programs/ocr2/src/context.rs +++ b/contracts/programs/ocr2/src/context.rs @@ -49,6 +49,14 @@ pub struct Close<'info> { #[account(mut)] pub receiver: SystemAccount<'info>, pub authority: Signer<'info>, + + #[account(mut, address = state.load()?.config.token_vault)] + pub token_vault: Account<'info, TokenAccount>, + /// CHECK: This is a PDA + #[account(seeds = [b"vault", state.key().as_ref()], bump = state.load()?.vault_nonce)] + pub vault_authority: AccountInfo<'info>, + + pub token_program: Program<'info, Token>, } #[derive(Accounts)] diff --git a/contracts/programs/ocr2/src/lib.rs b/contracts/programs/ocr2/src/lib.rs index 516348537..0d82d7da9 100644 --- a/contracts/programs/ocr2/src/lib.rs +++ b/contracts/programs/ocr2/src/lib.rs @@ -53,7 +53,16 @@ pub mod ocr2 { } #[access_control(owner(&ctx.accounts.state, &ctx.accounts.authority))] - pub fn close(ctx: Context) -> Result<()> { + pub fn close<'info>(ctx: Context<'_, '_, '_, 'info, Close<'info>>) -> Result<()> { + // Pay out any remaining balances + pay_oracles_impl( + ctx.accounts.state.clone(), + ctx.accounts.token_program.to_account_info(), + ctx.accounts.token_vault.to_account_info(), + ctx.accounts.vault_authority.clone(), + ctx.remaining_accounts, + )?; + // NOTE: Close is handled by anchor on exit due to the `close` attribute Ok(()) } diff --git a/contracts/tests/ocr2.spec.ts b/contracts/tests/ocr2.spec.ts index b7b0862ff..c7a7de385 100644 --- a/contracts/tests/ocr2.spec.ts +++ b/contracts/tests/ocr2.spec.ts @@ -484,7 +484,7 @@ describe("ocr2", async () => { tokenVault, mintAuthority.publicKey, [mintAuthority], - 1000000000 + 100000000000000 ); // TODO: listen for SetConfig event @@ -949,12 +949,23 @@ describe("ocr2", async () => { await provider.connection.getAccountInfo(provider.wallet.publicKey) ).lamports; + // fetch payees + let account = await program.account.state.fetch(state.publicKey); + let currentOracles = account.oracles.xs.slice(0, account.oracles.len); + let payees = currentOracles.map((oracle) => { + return { pubkey: oracle.payee, isWritable: true, isSigner: false }; + }); + await program.rpc.close({ accounts: { state: state.publicKey, receiver: provider.wallet.publicKey, authority: owner.publicKey, + tokenVault: tokenVault, + vaultAuthority: vaultAuthority, + tokenProgram: TOKEN_PROGRAM_ID, }, + remainingAccounts: payees, }); let afterBalance = (