Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
30 changes: 0 additions & 30 deletions project-8-token-vesting/anchor/.eslintrc.json

This file was deleted.

12 changes: 12 additions & 0 deletions project-8-token-vesting/anchor/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
.anchor
.DS_Store
target/debug
target/deploy
target/release
target/sbf-solana-solana
target/test-ledger
target/.rustc_info.json
**/*.rs.bk
node_modules
test-ledger
.yarn
7 changes: 7 additions & 0 deletions project-8-token-vesting/anchor/.prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.anchor
.DS_Store
target
node_modules
dist
build
test-ledger
29 changes: 0 additions & 29 deletions project-8-token-vesting/anchor/.swcrc

This file was deleted.

11 changes: 6 additions & 5 deletions project-8-token-vesting/anchor/Anchor.toml
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
[toolchain]
anchor_version = "0.30.1"

[features]
resolution = true
skip-lint = false

[programs.localnet]
vesting = "GFdLg11UBR8ZeePW43ZyD1gY4z4UQ96LPa22YBgnn4z8"
[programs.devnet]
vesting = "BnRyuRkBiWQ6D3Tsu5n4AuzzHjSbFHBcXKs63e51p1ft"

[registry]
url = "https://api.apr.dev"
url = "https://api.devnet.solana.com"

[provider]
cluster = "Localnet"
cluster = "Devnet"
wallet = "~/.config/solana/id.json"

[scripts]
test = "../node_modules/.bin/nx run anchor:jest"
test = "../node_modules/.bin/jest --preset ts-jest"

[test]
startup_wait = 5000
Expand Down
11 changes: 0 additions & 11 deletions project-8-token-vesting/anchor/README.md

This file was deleted.

30 changes: 0 additions & 30 deletions project-8-token-vesting/anchor/jest.config.ts

This file was deleted.

5 changes: 3 additions & 2 deletions project-8-token-vesting/anchor/migrations/deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@
// single deploy script that's invoked from the CLI, injecting a provider
// configured from the workspace's Anchor.toml.

import * as anchor from '@coral-xyz/anchor';
const anchor = require("@coral-xyz/anchor");
import { AnchorProvider } from '@coral-xyz/anchor'

module.exports = async function (provider) {
module.exports = async function (provider: AnchorProvider) {
// Configure client to use the provider.
anchor.setProvider(provider);

Expand Down
15 changes: 0 additions & 15 deletions project-8-token-vesting/anchor/package.json

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
[package]
name = "vesting"
name = "dapptokenvesting"
version = "0.1.0"
description = "Created with Anchor"
edition = "2021"

[lib]
crate-type = ["cdylib", "lib"]
name = "vesting"
name = "dapptokenvesting"

[features]
default = []
cpi = ["no-entrypoint"]
no-entrypoint = []
no-idl = []
no-log-ix-name = []
cpi = ["no-entrypoint"]
default = []
idl-build = ["anchor-lang/idl-build", "anchor-spl/idl-build"]
idl-build = ["anchor-lang/idl-build","anchor-spl/idl-build"]

[dependencies]
anchor-lang = { version="0.30.1", features=["init-if-needed"] }
anchor-lang = { version = "0.30.1", features = ["init-if-needed"] }
anchor-spl = "0.30.1"
solana-program = "1.18.17"
solana-program = "1.18.17"
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
use anchor_lang::prelude::*;
use anchor_spl::associated_token::AssociatedToken;
use anchor_spl::token_interface::{ self, Mint, TokenAccount, TokenInterface, TransferChecked };
use anchor_spl::token_interface::{self, Mint, TokenAccount, TokenInterface, TransferChecked};

declare_id!("GFdLg11UBR8ZeePW43ZyD1gY4z4UQ96LPa22YBgnn4z8");
declare_id!("BnRyuRkBiWQ6D3Tsu5n4AuzzHjSbFHBcXKs63e51p1ft");
#[program]
pub mod vesting {
use super::*;

pub fn create_vesting_account(
ctx: Context<CreateVestingAccount>,
company_name: String
company_name: String,
initial_fund_amount: u64,
) -> Result<()> {
*ctx.accounts.vesting_account = VestingAccount {
owner: ctx.accounts.signer.key(),
Expand All @@ -20,6 +21,24 @@ pub mod vesting {
bump: ctx.bumps.vesting_account,
};

let cpi_accounts = TransferChecked {
from: ctx
.accounts
.signer_associated_token_account
.to_account_info(),
mint: ctx.accounts.mint.to_account_info(),
to: ctx.accounts.treasury_token_account.to_account_info(),
authority: ctx.accounts.signer.to_account_info(),
};

let cpi_program = ctx.accounts.token_program.to_account_info();
let cpi_ctx = CpiContext::new(cpi_program, cpi_accounts);

token_interface::transfer_checked(
cpi_ctx,
initial_fund_amount,
ctx.accounts.mint.decimals,
)?;
Ok(())
}

Expand All @@ -28,7 +47,7 @@ pub mod vesting {
start_time: i64,
end_time: i64,
total_amount: i64,
cliff_time: i64
cliff_time: i64,
) -> Result<()> {
*ctx.accounts.employee_account = EmployeeAccount {
beneficiary: ctx.accounts.beneficiary.key(),
Expand All @@ -46,49 +65,61 @@ pub mod vesting {

pub fn claim_tokens(ctx: Context<ClaimTokens>, _company_name: String) -> Result<()> {
let employee_account = &mut ctx.accounts.employee_account;

let now = Clock::get()?.unix_timestamp;

// Check if the current time is before the cliff time

if now < employee_account.cliff_time {
return Err(ErrorCode::ClaimNotAvailableYet.into());
}
// Calculate the vested amount

let time_since_start = now.saturating_sub(employee_account.start_time);
let total_vesting_time = employee_account.end_time.saturating_sub(
employee_account.start_time
);
let total_vesting_time = employee_account
.end_time
.saturating_sub(employee_account.start_time);

let vested_amount = if now >= employee_account.end_time {
employee_account.total_amount
} else {
(employee_account.total_amount * time_since_start) / total_vesting_time
};

//Calculate the amount that can be withdrawn

let claimable_amount = vested_amount.saturating_sub(employee_account.total_withdrawn);
// Check if there is anything left to claim
if claimable_amount == 0 {

if claimable_amount <= 0 {
return Err(ErrorCode::NothingToClaim.into());
}

let decimals = ctx.accounts.mint.decimals;
if claimable_amount < 0 {
return Err(ErrorCode::InvalidClaimAmount.into());
}

let claimable_amount_scaled = (claimable_amount as u64)
.checked_mul(10_u64.pow(decimals as u32))
.ok_or(ErrorCode::InvalidClaimAmount)?;

let transfer_cpi_accounts = TransferChecked {
from: ctx.accounts.treasury_token_account.to_account_info(),
mint: ctx.accounts.mint.to_account_info(),
to: ctx.accounts.employee_token_account.to_account_info(),
authority: ctx.accounts.treasury_token_account.to_account_info(),
};

let cpi_program = ctx.accounts.token_program.to_account_info();
let signer_seeds: &[&[&[u8]]] = &[
&[
b"vesting_treasury",
ctx.accounts.vesting_account.company_name.as_ref(),
&[ctx.accounts.vesting_account.treasury_bump],
],
];
let cpi_context = CpiContext::new(cpi_program, transfer_cpi_accounts).with_signer(
signer_seeds
);
let decimals = ctx.accounts.mint.decimals;
token_interface::transfer_checked(cpi_context, claimable_amount as u64, decimals)?;

let signer_seeds: &[&[&[u8]]] = &[&[
b"vesting_treasury",
ctx.accounts.vesting_account.company_name.as_ref(),
&[ctx.accounts.vesting_account.treasury_bump],
]];

let cpi_context =
CpiContext::new(cpi_program, transfer_cpi_accounts).with_signer(signer_seeds);

token_interface::transfer_checked(cpi_context, claimable_amount_scaled, decimals)?;

employee_account.total_withdrawn += claimable_amount;

Ok(())
}
}
Expand All @@ -98,6 +129,12 @@ pub mod vesting {
pub struct CreateVestingAccount<'info> {
#[account(mut)]
pub signer: Signer<'info>,
#[account(
mut,
associated_token::mint = mint,
associated_token::authority = signer
)]
pub signer_associated_token_account: InterfaceAccount<'info, TokenAccount>,
#[account(
init,
space = 8 + VestingAccount::INIT_SPACE,
Expand Down Expand Up @@ -202,8 +239,10 @@ pub struct EmployeeAccount {

#[error_code]
pub enum ErrorCode {
#[msg("Claiming is not available yet.")]
#[msg("Claiming is not available yet. ")]
ClaimNotAvailableYet,
#[msg("There is nothing to claim.")]
NothingToClaim,
#[msg("Claimed Amount is invalid. ")]
InvalidClaimAmount,
}
Loading