diff --git a/contracts/vesting_contracts/src/factory.rs b/contracts/vesting_contracts/src/factory.rs new file mode 100644 index 0000000..1155436 --- /dev/null +++ b/contracts/vesting_contracts/src/factory.rs @@ -0,0 +1,144 @@ +#![no_std] +use soroban_sdk::{ + contract, contractimpl, contractmeta, Address, BytesN, Env, Vec, Symbol +}; +use crate::{VestingContract, Vault}; + +// Contract metadata for the factory +contractmeta!( + key = "Description", + val = "Factory contract for deploying vesting vault contracts" +); + +#[contract] +pub struct VestingFactory; + +// Storage keys for factory +const DEPLOYED_CONTRACTS: Symbol = Symbol::new(&"DEPLOYED_CONTRACTS"); +const Wasm_HASH: Symbol = Symbol::new(&"WASM_HASH"); + +#[contractimpl] +impl VestingFactory { + /// Initialize the factory with the WASM hash of the vesting contract + pub fn initialize(env: Env, wasm_hash: BytesN<32>) { + // Store the WASM hash for future deployments + env.storage().instance().set(&Wasm_HASH, &wasm_hash); + + // Initialize the deployed contracts list + let deployed_contracts: Vec
= Vec::new(&env); + env.storage().instance().set(&DEPLOYED_CONTRACTS, &deployed_contracts); + } + + /// Deploy a new vesting contract for an organization + pub fn deploy_new_vault_contract(env: Env, admin: Address, initial_supply: i128) -> Address { + // Get the stored WASM hash + let wasm_hash: BytesN<32> = env.storage().instance() + .get(&Wasm_HASH) + .unwrap_or_else(|| panic!("Factory not initialized - WASM hash not set")); + + // Generate a unique salt based on admin address and current timestamp + let salt = env.crypto().sha256(&admin.to_bytes()); + let timestamp_bytes = env.ledger().timestamp().to_be_bytes(); + let mut salt_bytes = salt.to_array(); + for i in 0..8 { + salt_bytes[i] ^= timestamp_bytes[i]; + } + let unique_salt = BytesN::from_array(&env, &salt_bytes); + + // Deploy the new contract using the factory pattern + let deployed_address = env.deployer() + .with_current_contract_salt() + .deploy(wasm_hash); + + // Initialize the newly deployed contract + let client = VestingContract::new(&env, &deployed_address); + client.initialize(&admin, &initial_supply); + + // Store the deployed contract address + let mut deployed_contracts: Vec = env.storage().instance() + .get(&DEPLOYED_CONTRACTS) + .unwrap_or_else(|| Vec::new(&env)); + deployed_contracts.push_back(deployed_address.clone()); + env.storage().instance().set(&DEPLOYED_CONTRACTS, &deployed_contracts); + + deployed_address + } + + /// Get all deployed contract addresses + pub fn get_deployed_contracts(env: Env) -> Vec { + env.storage().instance() + .get(&DEPLOYED_CONTRACTS) + .unwrap_or_else(|| Vec::new(&env)) + } + + /// Get the WASM hash stored in the factory + pub fn get_wasm_hash(env: Env) -> Option