Skip to content

Commit 1568dac

Browse files
committed
updates
1 parent 90b5c46 commit 1568dac

File tree

14 files changed

+474
-119
lines changed

14 files changed

+474
-119
lines changed
5.94 MB
Binary file not shown.

project-7-token-vesting/README.md

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,22 @@
1-
# developer-bootcamp-2024
1+
# developer-bootcamp-2024
2+
3+
## Token Vesting
4+
5+
This dApp allows for any project to use the UI and create a vesting account and set up individual employee vesting information. It also allows for any employee to claim all currently available tokens.
6+
7+
### Program Functions
8+
9+
- `create_vesting_account`: Initializes a vesting account for a company and initializes a vesting token account to hold the entire token allocation.
10+
- `create_employee_vesting`: Initializes a vesting schedule for an employee adn initializes an employee token account to receive their unlocked allocation.
11+
- `claim_tokens`: Allows an employee to claim all vested tokens that have unlocked.
12+
13+
### Account Structures
14+
15+
- `CreateEmployeeAccount`: Account structure for creating an employee vesting account.
16+
- `CreateVestingAccount`: Account structure for creating a company's vesting account.
17+
- `ClaimTokens`: Account structure for claiming tokens.
18+
19+
### Data Structures
20+
21+
- `EmployeeAccount`: Stores details about an employee's vesting schedule.
22+
- `VestingAccount`: Stores details about a company's vesting account.

project-7-token-vesting/vesting/anchor/Anchor.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ seeds = false
55
skip-lint = false
66

77
[programs.localnet]
8-
basic = "7FDB7bi9YNFgXP58kzAmQLVJdec29PH7zLrJGbsVzWW5"
8+
basic = "7PeeRxWzyjSsYcfi6mfJ8fATbzxDpndLfzSn9kNwViGT"
99

1010
[registry]
1111
url = "https://api.apr.dev"
Lines changed: 227 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,238 @@
11
use anchor_lang::prelude::*;
2+
pub use anchor_spl::associated_token::AssociatedToken;
3+
pub use anchor_spl::token_interface::{self, Mint, TokenAccount, TokenInterface, TransferChecked};
24

3-
declare_id!("7FDB7bi9YNFgXP58kzAmQLVJdec29PH7zLrJGbsVzWW5");
5+
declare_id!("7AGmMcgd1SjoMsCcXAAYwRgB9ihCyM8cZqjsUqriNRQt");
46

57
#[program]
6-
pub mod basic {
8+
mod vesting_contract {
79
use super::*;
810

9-
pub fn greet(_ctx: Context<Initialize>) -> Result<()> {
10-
msg!("GM!");
11+
pub fn create_vesting_account(
12+
ctx: Context<CreateVestingAccount>,
13+
company_name: String,
14+
) -> Result<()> {
15+
let vesting_account = &mut ctx.accounts.vesting_account;
16+
vesting_account.owner = *ctx.accounts.signer.key;
17+
vesting_account.company_name = company_name;
18+
vesting_account.bump = ctx.bumps.vesting_account;
19+
20+
let mint_account = ctx.accounts.mint.to_account_info();
21+
vesting_account.token_mint = *mint_account.key;
22+
vesting_account.token_decimals = ctx.accounts.mint.decimals;
23+
24+
Ok(())
25+
}
26+
27+
pub fn create_employee_vesting(
28+
ctx: Context<CreateEmployeeAccount>,
29+
beneficiary: Pubkey,
30+
start_time: i64,
31+
end_time: i64,
32+
total_amount: i64,
33+
cliff_time: i64,
34+
) -> Result<()> {
35+
let employee_account = &mut ctx.accounts.employee_account;
36+
employee_account.beneficiary = beneficiary;
37+
employee_account.start_time = start_time;
38+
employee_account.end_time = end_time;
39+
employee_account.total_amount = total_amount;
40+
employee_account.total_withdrawn = 0;
41+
employee_account.cliff_time = cliff_time;
42+
employee_account.bump = ctx.bumps.employee_account;
43+
employee_account.vesting_account = *ctx.accounts.vesting_account.to_account_info().key;
44+
45+
Ok(())
46+
}
47+
48+
pub fn claim_tokens(
49+
ctx: Context<ClaimTokens>,
50+
_beneficiary: Pubkey,
51+
_company_name: String,
52+
) -> Result<()> {
53+
let employee_account = &mut ctx.accounts.employee_account;
54+
let now = Clock::get()?.unix_timestamp;
55+
let mint_key = ctx.accounts.mint.key();
56+
57+
// let seeds: &[&[u8]; 3] = &[b"vesting_auth", mint_key.as_ref(), &[ctx.bumps.mint_auth]];
58+
// let signer_seeds = &[&seeds[..]];
59+
60+
// Check if the current time is before the cliff time
61+
if now < employee_account.cliff_time {
62+
return Err(ErrorCode::ClaimNotAvailableYet.into());
63+
}
64+
65+
// Calculate the vested amount
66+
let time_since_start = now.saturating_sub(employee_account.start_time);
67+
let total_vesting_time = employee_account
68+
.end_time
69+
.saturating_sub(employee_account.start_time);
70+
let vested_amount = if now >= employee_account.end_time {
71+
employee_account.total_amount
72+
} else {
73+
employee_account.total_amount * (time_since_start) / (total_vesting_time)
74+
};
75+
76+
//Calculate the amount that can be withdrawn
77+
let claimable_amount = vested_amount.saturating_sub(employee_account.total_withdrawn);
78+
79+
// Check if there is anything left to claim
80+
if claimable_amount == 0 {
81+
return Err(ErrorCode::NothingToClaim.into());
82+
}
83+
84+
let transfer_cpi_accounts = TransferChecked {
85+
from: ctx.accounts.treasury_token_account.to_account_info(),
86+
mint: ctx.accounts.mint.to_account_info(),
87+
to: ctx.accounts.employee_token_account.to_account_info(),
88+
authority: ctx.accounts.treasury_token_account.to_account_info(),
89+
};
90+
91+
let cpi_program = ctx.accounts.token_program.to_account_info();
92+
let cpi_context = CpiContext::new(cpi_program, transfer_cpi_accounts);
93+
let decimals = ctx.accounts.vesting_account.token_decimals;
94+
95+
token_interface::transfer_checked(cpi_context, claimable_amount as u64, decimals)?;
96+
97+
employee_account.total_withdrawn += claimable_amount;
98+
1199
Ok(())
12100
}
13101
}
14102

15103
#[derive(Accounts)]
16-
pub struct Initialize {}
104+
#[instruction(beneficiary: Pubkey)]
105+
pub struct CreateEmployeeAccount<'info> {
106+
#[account(mut)]
107+
pub signer: Signer<'info>,
108+
109+
#[account(
110+
init,
111+
constraint = vesting_account.owner == *signer.key,
112+
space = 8 + EmployeeAccount::INIT_SPACE,
113+
payer = signer,
114+
seeds = [b"employee_vesting".as_ref(), beneficiary.as_ref(), vesting_account.to_account_info().key.as_ref()],
115+
bump,
116+
)]
117+
pub employee_account: Account<'info, EmployeeAccount>,
118+
119+
pub mint: InterfaceAccount<'info, Mint>,
120+
121+
#[account(
122+
init,
123+
constraint = vesting_account.owner == *signer.key,
124+
token::mint = mint,
125+
token::authority = employee_token_account,
126+
payer = signer,
127+
seeds = [b"employee_tokens".as_ref(), beneficiary.as_ref(), vesting_account.to_account_info().key.as_ref()],
128+
bump,
129+
)]
130+
pub employee_token_account: InterfaceAccount<'info, TokenAccount>,
131+
pub token_program: Interface<'info, TokenInterface>,
132+
pub system_program: Program<'info, System>,
133+
pub associated_token_program: Program<'info, AssociatedToken>,
134+
pub vesting_account: Account<'info, VestingAccount>,
135+
}
136+
137+
#[derive(Accounts)]
138+
#[instruction(company_name: String)]
139+
pub struct CreateVestingAccount<'info> {
140+
#[account(mut)]
141+
pub signer: Signer<'info>,
142+
143+
#[account(
144+
init,
145+
space = 8 + VestingAccount::INIT_SPACE,
146+
payer = signer,
147+
seeds = [company_name.as_ref()],
148+
bump,
149+
)]
150+
pub vesting_account: Account<'info, VestingAccount>,
151+
152+
pub mint: InterfaceAccount<'info, Mint>,
153+
154+
#[account(
155+
init,
156+
token::mint = mint,
157+
token::authority = treasury_token_account,
158+
payer = signer,
159+
seeds = [b"vesting_treasury".as_ref(), company_name.as_ref()],
160+
bump,
161+
)]
162+
pub treasury_token_account: InterfaceAccount<'info, TokenAccount>,
163+
pub token_program: Interface<'info, TokenInterface>,
164+
pub system_program: Program<'info, System>,
165+
pub associated_token_program: Program<'info, AssociatedToken>,
166+
}
167+
168+
#[derive(Accounts)]
169+
#[instruction(beneficiary: Pubkey, company_name: String)]
170+
pub struct ClaimTokens<'info> {
171+
#[account(mut)]
172+
pub signer: Signer<'info>,
173+
pub mint: InterfaceAccount<'info, Mint>,
174+
#[account(
175+
mut,
176+
seeds = [b"employee_vesting".as_ref(), beneficiary.as_ref(), vesting_account.to_account_info().key.as_ref()],
177+
bump,
178+
)]
179+
pub employee_account: Account<'info, EmployeeAccount>,
180+
#[account(
181+
mut,
182+
seeds = [company_name.as_ref()],
183+
bump,
184+
)]
185+
pub vesting_account: Account<'info, VestingAccount>,
186+
#[account(
187+
mut,
188+
token::mint = mint,
189+
token::authority = treasury_token_account,
190+
seeds = [b"vesting_treasury".as_ref(), company_name.as_ref()],
191+
bump,
192+
)]
193+
pub treasury_token_account: InterfaceAccount<'info, TokenAccount>,
194+
195+
#[account(
196+
mut,
197+
token::mint = mint,
198+
token::authority = employee_token_account,
199+
seeds = [b"employee_tokens".as_ref(), beneficiary.as_ref(), vesting_account.to_account_info().key.as_ref()],
200+
bump,
201+
)]
202+
pub employee_token_account: InterfaceAccount<'info, TokenAccount>,
203+
pub token_program: Interface<'info, TokenInterface>,
204+
pub system_program: Program<'info, System>,
205+
pub associated_token_program: Program<'info, AssociatedToken>,
206+
}
207+
208+
#[account]
209+
#[derive(InitSpace)]
210+
pub struct EmployeeAccount {
211+
pub beneficiary: Pubkey,
212+
pub start_time: i64,
213+
pub end_time: i64,
214+
pub total_amount: i64,
215+
pub total_withdrawn: i64,
216+
pub cliff_time: i64,
217+
pub vesting_account: Pubkey,
218+
pub bump: u8,
219+
}
220+
221+
#[account]
222+
#[derive(InitSpace)]
223+
pub struct VestingAccount {
224+
pub owner: Pubkey,
225+
pub token_mint: Pubkey,
226+
pub token_decimals: u8,
227+
#[max_len(50)]
228+
pub company_name: String,
229+
pub bump: u8,
230+
}
231+
232+
#[error_code]
233+
pub enum ErrorCode {
234+
#[msg("Claiming is not available yet.")]
235+
ClaimNotAvailableYet,
236+
#[msg("There is nothing to claim.")]
237+
NothingToClaim,
238+
}

project-9-lending/lending/README.md

Lines changed: 0 additions & 96 deletions
This file was deleted.

project-9-lending/lending/anchor/programs/basic/src/lib.rs

Lines changed: 0 additions & 16 deletions
This file was deleted.
File renamed without changes.
File renamed without changes.
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
/// Max number of collateral and liquidity reserve accounts combined for an obligation
2+
pub const MAX_OBLIGATION_RESERVES: usize = 10;
3+
/// Percentage of an obligation that can be repaid during each liquidation call
4+
pub const LIQUIDATION_CLOSE_FACTOR: u8 = 50;
5+
/// Obligation borrow amount that is small enough to close out
6+
pub const LIQUIDATION_CLOSE_AMOUNT: u64 = 2;

0 commit comments

Comments
 (0)