From b7a6c7909e75f3bb243496784f43533e25789f34 Mon Sep 17 00:00:00 2001 From: Emanuele Cesena Date: Mon, 8 Apr 2024 18:27:22 -0700 Subject: [PATCH] update manager --- .../programs/glam/src/instructions/manager.rs | 9 ++++- anchor/programs/glam/src/lib.rs | 3 +- anchor/programs/glam/src/state/fund.rs | 2 + anchor/target/idl/glam.json | 10 +++++ anchor/target/types/glam.ts | 20 ++++++++++ anchor/tests/glam_investor.spec.ts | 40 +++++++++++++++++++ 6 files changed, 81 insertions(+), 3 deletions(-) diff --git a/anchor/programs/glam/src/instructions/manager.rs b/anchor/programs/glam/src/instructions/manager.rs index a246446d..43c6e46a 100644 --- a/anchor/programs/glam/src/instructions/manager.rs +++ b/anchor/programs/glam/src/instructions/manager.rs @@ -7,9 +7,9 @@ use crate::error::ManagerError; use crate::state::fund::*; #[derive(Accounts)] -#[instruction(name: String)] +#[instruction(symbol: String)] pub struct InitializeFund<'info> { - #[account(init, seeds = [b"fund".as_ref(), manager.key().as_ref(), name.as_ref()], bump, payer = manager, space = 8 + Fund::INIT_SIZE + ShareClassMetadata::INIT_SIZE)] + #[account(init, seeds = [b"fund".as_ref(), manager.key().as_ref(), symbol.as_ref()], bump, payer = manager, space = 8 + Fund::INIT_SIZE + ShareClassMetadata::INIT_SIZE)] pub fund: Box>, #[account(init, seeds = [b"treasury".as_ref(), fund.key().as_ref()], bump, payer = manager, space = 8 + Treasury::INIT_SIZE)] @@ -66,6 +66,7 @@ pub fn initialize_fund_handler<'c: 'info, 'info>( let treasury = &mut ctx.accounts.treasury; fund.manager = ctx.accounts.manager.key(); + fund.creator = fund.manager; fund.treasury = treasury.key(); fund.name = fund_name; fund.symbol = fund_symbol; @@ -326,6 +327,7 @@ pub struct UpdateFund<'info> { pub fn update_fund_handler<'c: 'info, 'info>( ctx: Context<'_, '_, 'c, 'info, UpdateFund<'info>>, name: Option, + manager: Option, uri: Option, asset_weights: Option>, activate: Option, @@ -336,6 +338,9 @@ pub fn update_fund_handler<'c: 'info, 'info>( require!(name.as_bytes().len() <= 50, ManagerError::InvalidFundName); fund.name = name; } + if let Some(manager) = manager { + fund.manager = manager; + } if let Some(uri) = uri { require!(uri.as_bytes().len() <= 100, ManagerError::InvalidFundName); fund.uri = uri; diff --git a/anchor/programs/glam/src/lib.rs b/anchor/programs/glam/src/lib.rs index 8469ca04..0b1ec809 100644 --- a/anchor/programs/glam/src/lib.rs +++ b/anchor/programs/glam/src/lib.rs @@ -39,11 +39,12 @@ pub mod glam { pub fn update<'c: 'info, 'info>( ctx: Context<'_, '_, 'c, 'info, UpdateFund<'info>>, name: Option, + manager: Option, uri: Option, asset_weights: Option>, activate: Option, ) -> Result<()> { - manager::update_fund_handler(ctx, name, uri, asset_weights, activate) + manager::update_fund_handler(ctx, name, manager, uri, asset_weights, activate) } pub fn close(ctx: Context) -> Result<()> { manager::close_handler(ctx) diff --git a/anchor/programs/glam/src/state/fund.rs b/anchor/programs/glam/src/state/fund.rs index 020adafa..5b768602 100644 --- a/anchor/programs/glam/src/state/fund.rs +++ b/anchor/programs/glam/src/state/fund.rs @@ -8,6 +8,7 @@ pub const MAX_FUND_URI: usize = 100; #[account] pub struct Fund { + pub creator: Pubkey, // 32 pub manager: Pubkey, // 32 pub treasury: Pubkey, // 32 pub assets_len: u8, // 1 @@ -27,6 +28,7 @@ pub struct Fund { } impl Fund { pub const INIT_SIZE: usize = 32 + + 32 + 32 + 1 + (32 + 4) * MAX_ASSETS diff --git a/anchor/target/idl/glam.json b/anchor/target/idl/glam.json index e6c32750..7842aed9 100644 --- a/anchor/target/idl/glam.json +++ b/anchor/target/idl/glam.json @@ -100,6 +100,12 @@ "option": "string" } }, + { + "name": "manager", + "type": { + "option": "publicKey" + } + }, { "name": "uri", "type": { @@ -538,6 +544,10 @@ "type": { "kind": "struct", "fields": [ + { + "name": "creator", + "type": "publicKey" + }, { "name": "manager", "type": "publicKey" diff --git a/anchor/target/types/glam.ts b/anchor/target/types/glam.ts index a47a2463..bb279a6a 100644 --- a/anchor/target/types/glam.ts +++ b/anchor/target/types/glam.ts @@ -100,6 +100,12 @@ export type Glam = { "option": "string" } }, + { + "name": "manager", + "type": { + "option": "publicKey" + } + }, { "name": "uri", "type": { @@ -538,6 +544,10 @@ export type Glam = { "type": { "kind": "struct", "fields": [ + { + "name": "creator", + "type": "publicKey" + }, { "name": "manager", "type": "publicKey" @@ -903,6 +913,12 @@ export const IDL: Glam = { "option": "string" } }, + { + "name": "manager", + "type": { + "option": "publicKey" + } + }, { "name": "uri", "type": { @@ -1341,6 +1357,10 @@ export const IDL: Glam = { "type": { "kind": "struct", "fields": [ + { + "name": "creator", + "type": "publicKey" + }, { "name": "manager", "type": "publicKey" diff --git a/anchor/tests/glam_investor.spec.ts b/anchor/tests/glam_investor.spec.ts index 31cfa405..72fd8482 100644 --- a/anchor/tests/glam_investor.spec.ts +++ b/anchor/tests/glam_investor.spec.ts @@ -783,4 +783,44 @@ describe("glam_investor", () => { // in reality it will be less due to fees but toFixed(2) rounds it up expect((Number(shares.supply) / 1e9).toFixed(2)).toEqual("2.50"); }); + + it("Update fund", async () => { + const newFundName = "Updated fund name"; + const newManager = Keypair.generate(); + await program.methods + .update(newFundName, newManager.publicKey, null, null, true) + .accounts({ + fund: fundPDA, + manager: manager.publicKey + }) + .rpc({ commitment }); + let fund = await program.account.fund.fetch(fundPDA); + expect(fund.name).toEqual(newFundName); + expect(fund.manager).toEqual(newManager.publicKey); + + try { + await program.methods + .update(newFundName, manager.publicKey, null, null, true) + .accounts({ + fund: fundPDA, + manager: manager.publicKey + }) + .rpc({ commitment }); + } catch(e) { + expect(e.message).toContain("Error: not authorized"); + } + + await program.methods + .update(newFundName, manager.publicKey, null, null, true) + .accounts({ + fund: fundPDA, + manager: newManager.publicKey + }) + .signers([newManager]) + .rpc({ commitment }); + fund = await program.account.fund.fetch(fundPDA); + expect(fund.name).toEqual(newFundName); + expect(fund.manager).toEqual(manager.publicKey); + }); + });