Evan Conrad
Evan Conrad

Reputation: 4389

How do I close an account, empty the rent into a wrapped sol account, and then sync it?

I have an account that stores some data and is owned by my Solana program. I'd like to implement a Close instruction that "closes" the account and transfers the remaining native-SOL into a wrapped-SOL token account, and then call spl-token's sync_native instruction.

If I try to use the SystemProgram's Transfer instruction, I hit the error in the processor that says Transfer: from must not carry data.

So instead, I just do this:

let dest_starting_lamports = dest_account_info.lamports();
**dest_account_info.lamports.borrow_mut() = dest_starting_lamports
        .checked_add(source_account_info.lamports())
        .unwrap();

**source_account_info.lamports.borrow_mut() = 0;

However, if I later call sync_native via CPI anywhere in the same instruction, I get an error:

sum of account balances before and after instruction do not match

Is it possible to both modify the lamport values (transfer) of accounts AND call a CPI instruction? Or alternatively, is there a way to close the account with the SystemProgram?

Upvotes: 2

Views: 3971

Answers (3)

billy
billy

Reputation: 141

To add to Jon C's answer, this seems to be the relevant runtime issue: https://github.com/solana-labs/solana/issues/9711

In short, it seems like you must not have any CPIs after directly manipulating accounts' lamports or this error will be thrown. So put that code block in the last part of your instruction processor and it should be good

Upvotes: 1

Hamza Sajid
Hamza Sajid

Reputation: 45

Okay So here I want to figure it out that CPI in a single instructions causes conflict with each other as in my case I was using token program and system program in a single instruction and I figured it out that token program CPI should be done above the system program CPI.

Upvotes: 2

Jon C
Jon C

Reputation: 8462

This may be a bug in the runtime, because otherwise it looks like you're doing everything correctly. The only time this should fail is if dest_account_info and source_account_info are the same, but you mentioned that the sync_native is what caused the problem.

As a workaround, you can have sync_native done as a separate instruction in the transaction rather than as a CPI.

Upvotes: 1

Related Questions