I want to transfer ownership of my program owned account to the system account.
From the docs, I understand that ...
Only the owner of the account may change owner.
- And only if the account is writable.
- And only if the account is not executable.
- And only if the data is zero-initialized or empty.
Without requiring a signature, I should be able to change ownership of account A from program B to the system program, as long as the ownership transfer takes place in program B since it owns account A.
Account A should be mutable and be zero initialized.
// ANCHOR 0.25
pub fn transfer_owner(ctx: Context<TransferOwner>) -> Result<()> {
let transfer_account = &mut ctx.accounts.account_to_transfer;
let acc_info = transfer_account.to_account_info();
acc_info.assign(&system_program::id());
Ok(())
}
#[derive(Accounts)]
pub struct TransferOwner<'info> {
// zero init the data
#[account(
mut,
realloc = 40 ,
realloc::payer = payer,
realloc::zero = true,
)]
pub account_to_transfer: Account<'info, OwnedAccount>,
#[account(mut)]
pub payer: Signer<'info>,
pub system_program: Program<'info, System>,
}
Yet whenever I call this I get
Transaction simulation failed: Error processing Instruction 0: instruction illegally modified the program id of an account
const transferOwnerTx = await program.methods
.transferOwner()
.accounts({
accountToTransfer: transferKeypair.publicKey,
payer: fundingKeypair.publicKey,
})
.signers([fundingKeypair])
.rpc();
I can guarantee that the transferKeypair
is owned by my program.
Adding signature doesn't change anything, which makes sense because its up to my program implementation to decide if I want that verification. Here I don't.
(I renamed some variables in the code snippet, regardless of errors in that I can also guarantee my error isn't typo related)
Any ideas? I know transferring ownership unsafely like this doesn't have many usecases but I wanted to test out the full permissions of non-spl/native program owned accounts.