Skip to content

Commit

Permalink
Implement close examples
Browse files Browse the repository at this point in the history
  • Loading branch information
armaniferrante committed Jan 12, 2022
1 parent d92ebdd commit 244d8ce
Show file tree
Hide file tree
Showing 10 changed files with 235 additions and 6 deletions.
14 changes: 14 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 19 additions & 0 deletions programs/9-closing-accounts/insecure-still-still/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
[package]
name = "closing-accounts-insecure-still-still"
version = "0.1.0"
description = "Created with Anchor"
edition = "2018"

[lib]
crate-type = ["cdylib", "lib"]
name = "closing_accounts_insecure_still"

[features]
no-entrypoint = []
no-idl = []
no-log-ix-name = []
cpi = ["no-entrypoint"]
default = []

[dependencies]
anchor-lang = "0.20.1"
2 changes: 2 additions & 0 deletions programs/9-closing-accounts/insecure-still-still/Xargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[target.bpfel-unknown-unknown.dependencies.std]
features = []
45 changes: 45 additions & 0 deletions programs/9-closing-accounts/insecure-still-still/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
use anchor_lang::prelude::*;
use std::io::Write;
use std::ops::DerefMut;

declare_id!("Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS");

#[program]
pub mod closing_accounts_insecure_still_still {
use super::*;

pub fn close(ctx: Context<Close>) -> ProgramResult {
let account = ctx.accounts.account.to_account_info();

let dest_starting_lamports = ctx.accounts.destination.lamports();

**ctx.accounts.destination.lamports.borrow_mut() = dest_starting_lamports
.checked_add(account.lamports())
.unwrap();
**account.lamports.borrow_mut() = 0;

let mut data = account.try_borrow_mut_data()?;
for byte in data.deref_mut().iter_mut() {
*byte = 0;
}

let dst: &mut [u8] = &mut data;
let mut cursor = std::io::Cursor::new(dst);
cursor
.write_all(&anchor_lang::__private::CLOSED_ACCOUNT_DISCRIMINATOR)
.unwrap();

Ok(())
}
}

#[derive(Accounts)]
pub struct Close<'info> {
account: Account<'info, Data>,
destination: AccountInfo<'info>,
}

#[account]
pub struct Data {
data: u64,
}
19 changes: 19 additions & 0 deletions programs/9-closing-accounts/insecure-still/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
[package]
name = "closing-accounts-insecure-still"
version = "0.1.0"
description = "Created with Anchor"
edition = "2018"

[lib]
crate-type = ["cdylib", "lib"]
name = "closing_accounts_insecure_still"

[features]
no-entrypoint = []
no-idl = []
no-log-ix-name = []
cpi = ["no-entrypoint"]
default = []

[dependencies]
anchor-lang = "0.20.1"
2 changes: 2 additions & 0 deletions programs/9-closing-accounts/insecure-still/Xargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[target.bpfel-unknown-unknown.dependencies.std]
features = []
45 changes: 45 additions & 0 deletions programs/9-closing-accounts/insecure-still/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
use anchor_lang::prelude::*;
use std::ops::DerefMut;

declare_id!("Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS");

#[program]
pub mod closing_accounts_insecure_still {
use super::*;

pub fn close(ctx: Context<Close>) -> ProgramResult {
let account = ctx.accounts.account.to_account_info();

let dest_starting_lamports = ctx.accounts.destination.lamports();

**ctx.accounts.destination.lamports.borrow_mut() = dest_starting_lamports
.checked_add(account.lamports())
.unwrap();
**account.lamports.borrow_mut() = 0;

let mut data = account.try_borrow_mut_data()?;
for byte in data.deref_mut().iter_mut() {
*byte = 0;
}

Ok(())
}
}

#[derive(Accounts)]
pub struct Initialize<'info> {
#[account(zero)]
account: Account<'info, Data>,
authority: Signer<'info>,
}

#[derive(Accounts)]
pub struct Close<'info> {
account: Account<'info, Data>,
destination: AccountInfo<'info>,
}

#[account]
pub struct Data {
data: u64,
}
20 changes: 18 additions & 2 deletions programs/9-closing-accounts/insecure/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,26 @@ declare_id!("Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS");
#[program]
pub mod closing_accounts_insecure {
use super::*;
pub fn initialize(ctx: Context<Initialize>) -> ProgramResult {

pub fn close(ctx: Context<Close>) -> ProgramResult {
let dest_starting_lamports = ctx.accounts.destination.lamports();

**ctx.accounts.destination.lamports.borrow_mut() = dest_starting_lamports
.checked_add(ctx.accounts.account.to_account_info().lamports())
.unwrap();
**ctx.accounts.account.to_account_info().lamports.borrow_mut() = 0;

Ok(())
}
}

#[derive(Accounts)]
pub struct Initialize {}
pub struct Close<'info> {
account: Account<'info, Data>,
destination: AccountInfo<'info>,
}

#[account]
pub struct Data {
data: u64,
}
14 changes: 12 additions & 2 deletions programs/9-closing-accounts/recommended/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,20 @@ declare_id!("Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS");
#[program]
pub mod closing_accounts_recommended {
use super::*;
pub fn initialize(ctx: Context<Initialize>) -> ProgramResult {

pub fn close(ctx: Context<Close>) -> ProgramResult {
Ok(())
}
}

#[derive(Accounts)]
pub struct Initialize {}
pub struct Close<'info> {
#[account(mut, close = destination)]
account: Account<'info, Data>,
destination: AccountInfo<'info>,
}

#[account]
pub struct Data {
data: u64,
}
61 changes: 59 additions & 2 deletions programs/9-closing-accounts/secure/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,71 @@
use anchor_lang::__private::CLOSED_ACCOUNT_DISCRIMINATOR;
use anchor_lang::prelude::*;
use std::io::{Cursor, Write};
use std::ops::DerefMut;

declare_id!("Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS");

#[program]
pub mod closing_accounts_secure {
use super::*;
pub fn initialize(ctx: Context<Initialize>) -> ProgramResult {

pub fn close(ctx: Context<Close>) -> ProgramResult {
let dest_starting_lamports = ctx.accounts.destination.lamports();

let account = ctx.accounts.account.to_account_info();
**ctx.accounts.destination.lamports.borrow_mut() = dest_starting_lamports
.checked_add(account.lamports())
.unwrap();
**account.lamports.borrow_mut() = 0;

let mut data = account.try_borrow_mut_data()?;
for byte in data.deref_mut().iter_mut() {
*byte = 0;
}

let dst: &mut [u8] = &mut data;
let mut cursor = Cursor::new(dst);
cursor.write_all(&CLOSED_ACCOUNT_DISCRIMINATOR).unwrap();

Ok(())
}

pub fn force_defund(ctx: Context<ForceDefund>) -> ProgramResult {
let account = &ctx.accounts.account;

let data = account.try_borrow_data()?;
assert!(data.len() > 8);

let mut discriminator = [0u8; 8];
discriminator.copy_from_slice(&data[0..8]);
if discriminator == CLOSED_ACCOUNT_DISCRIMINATOR {
return Err(ProgramError::InvalidAccountData);
}

let dest_starting_lamports = ctx.accounts.destination.lamports();

**ctx.accounts.destination.lamports.borrow_mut() = dest_starting_lamports
.checked_add(account.lamports())
.unwrap();
**account.lamports.borrow_mut() = 0;

Ok(())
}
}

#[derive(Accounts)]
pub struct Initialize {}
pub struct Close<'info> {
account: Account<'info, Data>,
destination: AccountInfo<'info>,
}

#[derive(Accounts)]
pub struct ForceDefund<'info> {
account: AccountInfo<'info>,
destination: AccountInfo<'info>,
}

#[account]
pub struct Data {
data: u64,
}

0 comments on commit 244d8ce

Please sign in to comment.