diff --git a/.travis.yml b/.travis.yml index 382da31..e0ccd85 100644 --- a/.travis.yml +++ b/.travis.yml @@ -36,16 +36,12 @@ jobs: name: Lockup tests <<: *localnet script: - - docker exec dev make -C lockup init-test features=strict - -# Disabled because these tests require the shared memory program in the validator genesis, -# which currently requires a custom local setup. -# -# - <<: *defaults -# name: Registry tests -# <<: *localnet -# script: -# - docker exec dev make -C registry init-test + - docker exec dev make -C lockup init-test features=strict# + - <<: *defaults + name: Registry tests + <<: *localnet + script: + - docker exec dev make -C registry init-test - <<: *defaults name: Fmt and Common Tests script: diff --git a/registry/src/accounts/ring.rs b/common/src/accounts.rs similarity index 73% rename from registry/src/accounts/ring.rs rename to common/src/accounts.rs index 6c4d331..b9357e7 100644 --- a/registry/src/accounts/ring.rs +++ b/common/src/accounts.rs @@ -1,45 +1,53 @@ -// Use a macro to define the trait with a generic MESSAGE_SIZE, since -// Rust doesn't support arrays with generic lengths. +// Macro to generate an append only Ring buffer trait. Clients should use this +// to create ring buffer accounts, defining a fixed ITEM_SIZE, the maximum +// size for each entry in the ring. // -// Remove macro (and just use the trait ) once the following issue is addressed: +// Uses a macro to define the trait since Rust doesn't (yet) support arrays +// with generic lengths. +// +// Remove macro (and just use the trait) once the following issue is addressed: // https://github.com/rust-lang/rust/issues/43408 #[macro_export] macro_rules! ring { ($message_size:expr) => { - // + use arrayref::array_mut_ref; + const AUTHORITY_START: usize = 0; + // TODO: bump head + tail to be u64 instead of u32. const HEAD_START: usize = 32; const TAIL_START: usize = 36; - const MESSAGE_START: u32 = 40; + const ITEM_START: u32 = 40; - pub trait Ring<'a, T: BorshSerialize + BorshDeserialize> { - const MESSAGE_SIZE: u32 = $message_size; + pub trait Ring<'a> { + type Item: BorshSerialize + BorshDeserialize; + + const ITEM_SIZE: u32 = $message_size; fn buffer(&self) -> Rc>; fn capacity(&self) -> u32; fn buffer_size(capacity: u32) -> usize { - (Self::MESSAGE_SIZE as usize * capacity as usize) + MESSAGE_START as usize + (Self::ITEM_SIZE as usize * capacity as usize) + ITEM_START as usize } - fn append(&self, item: &T) -> Result<(), RegistryError> { + fn append(&self, item: &Self::Item) -> Result<(), ProgramError> { let mut data = item .try_to_vec() - .map_err(|_| RegistryErrorCode::WrongSerialization)?; + .map_err(|_| ProgramError::InvalidAccountData)?; - if data.len() > Self::MESSAGE_SIZE as usize { - return Err(RegistryErrorCode::RingInvalidMessageSize)?; + if data.len() > Self::ITEM_SIZE as usize { + return Err(ProgramError::InvalidAccountData)?; } let head = self.head()?; let tail = self.tail()?; // Scope into a block so that the refcell is dropped. { - let head_idx = (head * Self::MESSAGE_SIZE + MESSAGE_START) as usize; + let head_idx = (head * Self::ITEM_SIZE + ITEM_START) as usize; let buffer = self.buffer(); let mut acc_data = buffer.borrow_mut(); let dst = array_mut_ref![acc_data, head_idx, $message_size as usize]; - data.resize(Self::MESSAGE_SIZE as usize, 0); + data.resize(Self::ITEM_SIZE as usize, 0); dst.copy_from_slice(&data); } // If full, then move the tail as well. @@ -52,7 +60,7 @@ macro_rules! ring { } #[cfg(not(feature = "program"))] - fn messages_rev(&self) -> Result, RegistryError> { + fn messages_rev(&self) -> Result, ProgramError> { let buffer = self.buffer(); let data = buffer.borrow(); let head = self.head()?; @@ -72,11 +80,11 @@ macro_rules! ring { last -= 1; } - let start = (last * Self::MESSAGE_SIZE + MESSAGE_START) as usize; - let end = start + Self::MESSAGE_SIZE as usize; + let start = (last * Self::ITEM_SIZE + ITEM_START) as usize; + let end = start + Self::ITEM_SIZE as usize; - let m = T::deserialize(&mut &data[start..end]) - .map_err(|_| RegistryErrorCode::WrongSerialization)?; + let m = Self::Item::deserialize(&mut &data[start..end]) + .map_err(|_| ProgramError::InvalidAccountData)?; msgs.push(m); } @@ -98,25 +106,25 @@ macro_rules! ring { dst.copy_from_slice(authority.as_ref()); } - fn message_at(&self, cursor: u32) -> Result { + fn message_at(&self, cursor: u32) -> Result { let index = cursor % self.capacity(); let buffer = self.buffer(); let data = buffer.borrow(); - let mut dst = vec![0u8; Self::MESSAGE_SIZE as usize]; - let start = (MESSAGE_START + index * Self::MESSAGE_SIZE) as usize; - let end = start + Self::MESSAGE_SIZE as usize; + let mut dst = vec![0u8; Self::ITEM_SIZE as usize]; + let start = (ITEM_START + index * Self::ITEM_SIZE) as usize; + let end = start + Self::ITEM_SIZE as usize; dst.copy_from_slice(&data[start..end]); - T::deserialize(&mut dst.as_ref()) - .map_err(|_| RegistryErrorCode::WrongSerialization.into()) + Self::Item::deserialize(&mut dst.as_ref()) + .map_err(|_| ProgramError::InvalidAccountData) } // Head is the next available position in the ring buffer for // appending. - fn head(&self) -> Result { + fn head(&self) -> Result { Ok(self.head_cursor()? % self.capacity()) } - fn head_cursor(&self) -> Result { + fn head_cursor(&self) -> Result { let buffer = self.buffer(); let data = buffer.borrow(); let mut dst = [0u8; 4]; @@ -127,11 +135,11 @@ macro_rules! ring { // Tail is the first taken position in the ring buffer, // except when tail === head. In which case the buffer is empty. // When the buffer is full, tail == head + 1. - fn tail(&self) -> Result { + fn tail(&self) -> Result { Ok(self.tail_cursor()? % self.capacity()) } - fn tail_cursor(&self) -> Result { + fn tail_cursor(&self) -> Result { let buffer = self.buffer(); let data = buffer.borrow(); let mut dst = [0u8; 4]; @@ -139,19 +147,19 @@ macro_rules! ring { Ok(u32::from_le_bytes(dst)) } - fn increment_head(&self) -> Result<(), RegistryError> { + fn increment_head(&self) -> Result<(), ProgramError> { let head = self.head_cursor()?; self.set_head(head + 1)?; Ok(()) } - fn increment_tail(&self) -> Result<(), RegistryError> { + fn increment_tail(&self) -> Result<(), ProgramError> { let tail = self.tail_cursor()?; self.set_tail(tail + 1)?; Ok(()) } - fn set_head(&self, head: u32) -> Result<(), RegistryError> { + fn set_head(&self, head: u32) -> Result<(), ProgramError> { let buffer = self.buffer(); let mut data = buffer.borrow_mut(); let dst = array_mut_ref![data, HEAD_START, 4]; @@ -159,7 +167,7 @@ macro_rules! ring { Ok(()) } - fn set_tail(&self, tail: u32) -> Result<(), RegistryError> { + fn set_tail(&self, tail: u32) -> Result<(), ProgramError> { let buffer = self.buffer(); let mut data = buffer.borrow_mut(); let dst = array_mut_ref![data, TAIL_START, 4]; @@ -172,13 +180,10 @@ macro_rules! ring { #[cfg(test)] mod tests { - use crate::error::{RegistryError, RegistryErrorCode}; - use arrayref::array_mut_ref; use borsh::{BorshDeserialize, BorshSerialize}; use serum_common::pack::*; use solana_client_gen::solana_sdk::pubkey::Pubkey; use std::cell::RefCell; - use std::convert::Into; use std::rc::Rc; ring!(320); @@ -193,7 +198,9 @@ mod tests { } } - impl<'a> Ring<'a, Message> for MQueue<'a> { + impl<'a> Ring<'a> for MQueue<'a> { + type Item = Message; + fn buffer(&self) -> Rc> { self.storage.clone() } @@ -217,7 +224,7 @@ mod tests { let storage = Rc::new(RefCell::new(data)); let mqueue = MQueue::from(storage); - let authority = Pubkey::new_rand(); + let authority = Pubkey::new_unique(); mqueue.set_authority(&authority); assert_eq!(authority, mqueue.authority()); @@ -226,7 +233,7 @@ mod tests { // First pass: fill the message queue. for k in 0u32..mqueue.capacity() - 1 { let m = Message { - from: Pubkey::new_rand(), + from: Pubkey::new_unique(), ts: k as i64, content: "hello world".to_string(), }; @@ -246,7 +253,7 @@ mod tests { // Insert one to begin the wrap. let m = Message { - from: Pubkey::new_rand(), + from: Pubkey::new_unique(), ts: 0, content: "hello world".to_string(), }; @@ -260,7 +267,7 @@ mod tests { // Do another pass, overwriting all previous messages. for k in 0u32..mqueue.capacity() { let m = Message { - from: Pubkey::new_rand(), + from: Pubkey::new_unique(), ts: k as i64, content: "hello world".to_string(), }; diff --git a/common/src/lib.rs b/common/src/lib.rs index 2a71af0..9a6ff0c 100644 --- a/common/src/lib.rs +++ b/common/src/lib.rs @@ -4,6 +4,7 @@ pub mod client; #[macro_use] pub mod pack; +pub mod accounts; #[cfg(feature = "program")] pub mod program; diff --git a/common/src/pack.rs b/common/src/pack.rs index fc852f5..1678ff6 100644 --- a/common/src/pack.rs +++ b/common/src/pack.rs @@ -40,6 +40,7 @@ pub trait Pack: std::marker::Sized + std::fmt::Debug { /// Analogue to pack, performing a check on the size of the given byte /// array. + #[inline(never)] fn unpack(src: &[u8]) -> Result { let mut src_mut = src; Pack::unpack_unchecked(&mut src_mut).and_then(|r: Self| { @@ -64,6 +65,7 @@ pub trait Pack: std::marker::Sized + std::fmt::Debug { } /// Unsafe unpack. Doesn't check the size of the given input array. + #[inline(never)] fn unpack_unchecked_mut(input: &mut [u8], f: &mut F) -> Result where F: FnMut(&mut Self) -> Result, diff --git a/common/tests/src/lib.rs b/common/tests/src/lib.rs index b1a8e4d..8884404 100644 --- a/common/tests/src/lib.rs +++ b/common/tests/src/lib.rs @@ -23,7 +23,7 @@ pub static TEST_CLUSTER: &str = "TEST_CLUSTER"; pub fn genesis() -> Genesis { let client = client::(); - let spl_mint_decimals = 3; + let spl_mint_decimals = 6; // Initialize the SPL token representing SRM. let mint_authority = Keypair::from_bytes(&Keypair::to_bytes(client.payer().clone())).unwrap(); diff --git a/lockup/cli/src/lib.rs b/lockup/cli/src/lib.rs index 8bb667a..7298a14 100644 --- a/lockup/cli/src/lib.rs +++ b/lockup/cli/src/lib.rs @@ -1,4 +1,4 @@ -use anyhow::{anyhow, Result}; +use anyhow::Result; use clap::Clap; use serum_lockup::accounts::WhitelistEntry; use serum_lockup_client::*; diff --git a/lockup/client/src/inner.rs b/lockup/client/src/inner.rs index 8bc7598..55bb9d2 100644 --- a/lockup/client/src/inner.rs +++ b/lockup/client/src/inner.rs @@ -1,7 +1,7 @@ use crate::InitializeResponse; use serum_common::client::rpc; use serum_common::pack::Pack; -use serum_lockup::accounts::{vault, Safe, Whitelist}; +use serum_lockup::accounts::{Safe, Whitelist}; use serum_lockup::client::{Client as InnerClient, ClientError as InnerClientError}; use solana_client_gen::prelude::*; use solana_client_gen::solana_sdk; diff --git a/lockup/client/src/lib.rs b/lockup/client/src/lib.rs index 894983f..5caeeec 100644 --- a/lockup/client/src/lib.rs +++ b/lockup/client/src/lib.rs @@ -263,7 +263,6 @@ impl Client { stake_beneficiary, vesting, safe, - is_mega, // TODO: remove. } = req; let relay_data = { let instr = RegistryInstruction::Deposit { amount }; @@ -284,16 +283,14 @@ impl Client { ®istry_pid, ) .map_err(|_| anyhow!("unable to create vault authority"))?; - let whitelist_program_vault = match is_mega { - false => r.vault, - true => r.mega_vault, - }; + let v = self.vesting(&vesting)?; + let whitelist_program_vault = r_client.vault_for(&member, &v.vault, true)?; + let relay_accounts = vec![ AccountMeta::new(member, false), AccountMeta::new_readonly(stake_beneficiary.pubkey(), true), AccountMeta::new(entity, false), AccountMeta::new_readonly(registrar, false), - AccountMeta::new_readonly(solana_sdk::sysvar::clock::ID, false), ]; let resp = self.whitelist_withdraw(WhitelistWithdrawRequest { @@ -317,7 +314,6 @@ impl Client { ) -> Result { let RegistryWithdrawRequest { amount, - is_mega, // TODO: remove. registry_pid, registrar, member, @@ -346,16 +342,14 @@ impl Client { ®istry_pid, ) .map_err(|_| anyhow!("unable to create vault authority"))?; - let whitelist_program_vault = match is_mega { - false => r.vault, - true => r.mega_vault, - }; + let v = self.vesting(&vesting)?; + let whitelist_program_vault = r_client.vault_for(&member, &v.vault, true)?; + let relay_accounts = vec![ AccountMeta::new(member, false), AccountMeta::new_readonly(stake_beneficiary.pubkey(), true), AccountMeta::new(entity, false), AccountMeta::new_readonly(registrar, false), - AccountMeta::new_readonly(solana_sdk::sysvar::clock::ID, false), ]; let resp = self.whitelist_deposit(WhitelistDepositRequest { @@ -582,7 +576,6 @@ pub struct RegistryDepositRequest<'a> { pub safe: Pubkey, pub beneficiary: &'a Keypair, pub stake_beneficiary: &'a Keypair, - pub is_mega: bool, } pub struct RegistryDepositResponse { @@ -591,7 +584,6 @@ pub struct RegistryDepositResponse { pub struct RegistryWithdrawRequest<'a> { pub amount: u64, - pub is_mega: bool, pub registry_pid: Pubkey, pub registrar: Pubkey, pub member: Pubkey, diff --git a/lockup/program/Cargo.lock b/lockup/program/Cargo.lock index c0a7ce8..5936cef 100644 --- a/lockup/program/Cargo.lock +++ b/lockup/program/Cargo.lock @@ -37,7 +37,7 @@ version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "hermit-abi 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.80 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.81 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -53,11 +53,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "addr2line 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.80 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.81 (registry+https://github.com/rust-lang/crates.io-index)", "miniz_oxide 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "object 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-demangle 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.117 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.118 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -76,7 +76,7 @@ version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.117 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.118 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -123,7 +123,7 @@ version = "0.7.2" source = "git+https://github.com/project-serum/borsh?branch=serum#337732a185f052d5ee0424127b04b89d455ffa81" dependencies = [ "borsh-derive 0.7.2 (git+https://github.com/project-serum/borsh?branch=serum)", - "solana-sdk 1.4.11 (registry+https://github.com/rust-lang/crates.io-index)", + "solana-sdk 1.4.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -133,7 +133,7 @@ source = "git+https://github.com/project-serum/borsh?branch=serum#337732a185f052 dependencies = [ "borsh-derive-internal 0.7.2 (git+https://github.com/project-serum/borsh?branch=serum)", "borsh-schema-derive-internal 0.7.2 (git+https://github.com/project-serum/borsh?branch=serum)", - "syn 1.0.51 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.53 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -143,7 +143,7 @@ source = "git+https://github.com/project-serum/borsh?branch=serum#337732a185f052 dependencies = [ "proc-macro2 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.51 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.53 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -153,7 +153,7 @@ source = "git+https://github.com/project-serum/borsh?branch=serum#337732a185f052 dependencies = [ "proc-macro2 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.51 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.53 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -172,7 +172,7 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "feature-probe 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.117 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.118 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -229,7 +229,7 @@ name = "chrono" version = "0.4.19" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.80 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.81 (registry+https://github.com/rust-lang/crates.io-index)", "num-integer 0.1.44 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.44 (registry+https://github.com/rust-lang/crates.io-index)", @@ -250,7 +250,7 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen 0.2.68 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen 0.2.69 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -330,7 +330,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.51 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.53 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -354,7 +354,7 @@ name = "ed25519" version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.117 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.118 (registry+https://github.com/rust-lang/crates.io-index)", "signature 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -366,7 +366,7 @@ dependencies = [ "curve25519-dalek 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "ed25519 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.117 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.118 (registry+https://github.com/rust-lang/crates.io-index)", "sha2 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", "zeroize 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -465,7 +465,7 @@ dependencies = [ "proc-macro-hack 0.5.19 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.51 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.53 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -511,7 +511,7 @@ name = "generic-array" version = "0.14.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.117 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.118 (registry+https://github.com/rust-lang/crates.io-index)", "typenum 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "version_check 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -522,7 +522,7 @@ version = "0.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.80 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.81 (registry+https://github.com/rust-lang/crates.io-index)", "wasi 0.9.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -560,7 +560,7 @@ name = "hermit-abi" version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.80 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.81 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -686,7 +686,7 @@ name = "iovec" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.80 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.81 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -712,15 +712,15 @@ name = "jobserver" version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.80 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.81 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "js-sys" -version = "0.3.45" +version = "0.3.46" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "wasm-bindgen 0.2.68 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen 0.2.69 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -747,7 +747,7 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.80" +version = "0.2.81" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -801,7 +801,7 @@ name = "memmap" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.80 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.81 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -838,7 +838,7 @@ dependencies = [ [[package]] name = "mio" -version = "0.6.22" +version = "0.6.23" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", @@ -846,10 +846,10 @@ dependencies = [ "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.80 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.81 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", - "miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "net2 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)", + "miow 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "net2 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -860,28 +860,28 @@ version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.80 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.22 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.81 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.23 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "miow" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "net2 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)", + "net2 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "net2" -version = "0.2.35" +version = "0.2.36" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.80 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.81 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -892,7 +892,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.51 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.53 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -918,7 +918,7 @@ version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "hermit-abi 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.80 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.81 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -938,7 +938,7 @@ dependencies = [ "proc-macro-crate 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.51 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.53 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -978,7 +978,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.80 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.81 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.57 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1022,7 +1022,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.51 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.53 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1032,7 +1032,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.51 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.53 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1116,7 +1116,7 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "getrandom 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.80 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.81 (registry+https://github.com/rust-lang/crates.io-index)", "rand_chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1191,7 +1191,7 @@ dependencies = [ "hyper 0.13.9 (registry+https://github.com/rust-lang/crates.io-index)", "hyper-rustls 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)", "ipnet 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "js-sys 0.3.45 (registry+https://github.com/rust-lang/crates.io-index)", + "js-sys 0.3.46 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", "mime 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1199,16 +1199,16 @@ dependencies = [ "percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "pin-project-lite 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustls 0.18.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.117 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.59 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.118 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.60 (registry+https://github.com/rust-lang/crates.io-index)", "serde_urlencoded 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "tokio 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-rustls 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)", "url 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen 0.2.68 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-futures 0.4.18 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-test 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", - "web-sys 0.3.45 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen 0.2.69 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-futures 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-test 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", + "web-sys 0.3.46 (registry+https://github.com/rust-lang/crates.io-index)", "webpki-roots 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)", "winreg 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1220,10 +1220,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cc 1.0.49 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.80 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.81 (registry+https://github.com/rust-lang/crates.io-index)", "spin 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "untrusted 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "web-sys 0.3.45 (registry+https://github.com/rust-lang/crates.io-index)", + "web-sys 0.3.46 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1296,10 +1296,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde" -version = "1.0.117" +version = "1.0.118" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde_derive 1.0.117 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.118 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1307,27 +1307,27 @@ name = "serde_bytes" version = "0.11.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.117 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.118 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "serde_derive" -version = "1.0.117" +version = "1.0.118" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.51 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.53 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "serde_json" -version = "1.0.59" +version = "1.0.60" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "itoa 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "ryu 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.117 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.118 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1338,7 +1338,7 @@ dependencies = [ "form_urlencoded 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "itoa 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "ryu 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.117 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.118 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1347,8 +1347,8 @@ version = "0.1.0" dependencies = [ "arrayref 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "borsh 0.7.2 (git+https://github.com/project-serum/borsh?branch=serum)", - "serde 1.0.117 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-sdk 1.4.11 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.118 (registry+https://github.com/rust-lang/crates.io-index)", + "solana-sdk 1.4.14 (registry+https://github.com/rust-lang/crates.io-index)", "spl-token 2.0.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1372,8 +1372,8 @@ version = "0.1.0" dependencies = [ "serum-common 0.1.0", "serum-lockup 0.1.0", - "solana-program 1.4.11 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-sdk 1.4.11 (registry+https://github.com/rust-lang/crates.io-index)", + "solana-program 1.4.14 (registry+https://github.com/rust-lang/crates.io-index)", + "solana-sdk 1.4.14 (registry+https://github.com/rust-lang/crates.io-index)", "spl-token 2.0.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1423,7 +1423,7 @@ version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.80 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.81 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.57 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1434,13 +1434,13 @@ version = "0.1.0" dependencies = [ "bincode 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "serum-common 0.1.0", - "solana-sdk 1.4.11 (registry+https://github.com/rust-lang/crates.io-index)", + "solana-sdk 1.4.14 (registry+https://github.com/rust-lang/crates.io-index)", "thiserror 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "solana-crate-features" -version = "1.4.11" +version = "1.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "backtrace 0.3.55 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1450,20 +1450,20 @@ dependencies = [ "ed25519-dalek 1.0.0-pre.4 (registry+https://github.com/rust-lang/crates.io-index)", "either 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.80 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.81 (registry+https://github.com/rust-lang/crates.io-index)", "rand_chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "regex-syntax 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)", "reqwest 0.10.9 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.117 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.118 (registry+https://github.com/rust-lang/crates.io-index)", "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.51 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.53 (registry+https://github.com/rust-lang/crates.io-index)", "tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "solana-frozen-abi" -version = "1.4.11" +version = "1.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bs58 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1472,29 +1472,29 @@ dependencies = [ "log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", "memmap 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.117 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.117 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.118 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.118 (registry+https://github.com/rust-lang/crates.io-index)", "sha2 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-frozen-abi-macro 1.4.11 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-logger 1.4.11 (registry+https://github.com/rust-lang/crates.io-index)", + "solana-frozen-abi-macro 1.4.14 (registry+https://github.com/rust-lang/crates.io-index)", + "solana-logger 1.4.14 (registry+https://github.com/rust-lang/crates.io-index)", "thiserror 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "solana-frozen-abi-macro" -version = "1.4.11" +version = "1.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.51 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.53 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "solana-logger" -version = "1.4.11" +version = "1.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1504,7 +1504,7 @@ dependencies = [ [[package]] name = "solana-program" -version = "1.4.11" +version = "1.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bincode 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1520,20 +1520,20 @@ dependencies = [ "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "rustversion 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.117 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.118 (registry+https://github.com/rust-lang/crates.io-index)", "serde_bytes 0.11.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.117 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.118 (registry+https://github.com/rust-lang/crates.io-index)", "sha2 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-frozen-abi 1.4.11 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-frozen-abi-macro 1.4.11 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-logger 1.4.11 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-sdk-macro 1.4.11 (registry+https://github.com/rust-lang/crates.io-index)", + "solana-frozen-abi 1.4.14 (registry+https://github.com/rust-lang/crates.io-index)", + "solana-frozen-abi-macro 1.4.14 (registry+https://github.com/rust-lang/crates.io-index)", + "solana-logger 1.4.14 (registry+https://github.com/rust-lang/crates.io-index)", + "solana-sdk-macro 1.4.14 (registry+https://github.com/rust-lang/crates.io-index)", "thiserror 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "solana-sdk" -version = "1.4.11" +version = "1.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "assert_matches 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1559,31 +1559,31 @@ dependencies = [ "rand_chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "rustversion 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.117 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.118 (registry+https://github.com/rust-lang/crates.io-index)", "serde_bytes 0.11.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.117 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.59 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.118 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.60 (registry+https://github.com/rust-lang/crates.io-index)", "sha2 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", "sha3 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-crate-features 1.4.11 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-frozen-abi 1.4.11 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-frozen-abi-macro 1.4.11 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-logger 1.4.11 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-program 1.4.11 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-sdk-macro 1.4.11 (registry+https://github.com/rust-lang/crates.io-index)", + "solana-crate-features 1.4.14 (registry+https://github.com/rust-lang/crates.io-index)", + "solana-frozen-abi 1.4.14 (registry+https://github.com/rust-lang/crates.io-index)", + "solana-frozen-abi-macro 1.4.14 (registry+https://github.com/rust-lang/crates.io-index)", + "solana-logger 1.4.14 (registry+https://github.com/rust-lang/crates.io-index)", + "solana-program 1.4.14 (registry+https://github.com/rust-lang/crates.io-index)", + "solana-sdk-macro 1.4.14 (registry+https://github.com/rust-lang/crates.io-index)", "thiserror 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "solana-sdk-macro" -version = "1.4.11" +version = "1.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bs58 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", "rustversion 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.51 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.53 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1601,7 +1601,7 @@ dependencies = [ "num-traits 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", "num_enum 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "remove_dir_all 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-sdk 1.4.11 (registry+https://github.com/rust-lang/crates.io-index)", + "solana-sdk 1.4.14 (registry+https://github.com/rust-lang/crates.io-index)", "thiserror 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1627,7 +1627,7 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.51" +version = "1.0.53" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1642,7 +1642,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.51 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.53 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-xid 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1669,7 +1669,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.51 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.53 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1685,7 +1685,7 @@ name = "time" version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.80 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.81 (registry+https://github.com/rust-lang/crates.io-index)", "wasi 0.10.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1710,7 +1710,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.22 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.23 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.13.0 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-codec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-current-thread 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1737,7 +1737,7 @@ dependencies = [ "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 2.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.22 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.23 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.13.0 (registry+https://github.com/rust-lang/crates.io-index)", "pin-project-lite 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1800,7 +1800,7 @@ dependencies = [ "futures 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.22 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.23 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.13.0 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1837,7 +1837,7 @@ dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.22 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.23 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-reactor 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1877,7 +1877,7 @@ dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.22 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.23 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-codec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-reactor 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1891,9 +1891,9 @@ dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.80 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.81 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.22 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.23 (registry+https://github.com/rust-lang/crates.io-index)", "mio-uds 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-codec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1918,7 +1918,7 @@ name = "toml" version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.117 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.118 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2040,18 +2040,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "wasm-bindgen" -version = "0.2.68" +version = "0.2.69" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.117 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.59 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-macro 0.2.68 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.118 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.60 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-macro 0.2.69 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.68" +version = "0.2.69" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bumpalo 3.4.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2059,63 +2059,63 @@ dependencies = [ "log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.51 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-shared 0.2.68 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.53 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-shared 0.2.69 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.18" +version = "0.4.19" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "js-sys 0.3.45 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen 0.2.68 (registry+https://github.com/rust-lang/crates.io-index)", - "web-sys 0.3.45 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "js-sys 0.3.46 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen 0.2.69 (registry+https://github.com/rust-lang/crates.io-index)", + "web-sys 0.3.46 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.68" +version = "0.2.69" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-macro-support 0.2.68 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-macro-support 0.2.69 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.68" +version = "0.2.69" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.51 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-backend 0.2.68 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-shared 0.2.68 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.53 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-backend 0.2.69 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-shared 0.2.69 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.68" +version = "0.2.69" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "wasm-bindgen-test" -version = "0.3.18" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "console_error_panic_hook 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "js-sys 0.3.45 (registry+https://github.com/rust-lang/crates.io-index)", + "js-sys 0.3.46 (registry+https://github.com/rust-lang/crates.io-index)", "scoped-tls 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen 0.2.68 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-futures 0.4.18 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-test-macro 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen 0.2.69 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-futures 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-test-macro 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "wasm-bindgen-test-macro" -version = "0.3.18" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2124,11 +2124,11 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.45" +version = "0.3.46" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "js-sys 0.3.45 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen 0.2.68 (registry+https://github.com/rust-lang/crates.io-index)", + "js-sys 0.3.46 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen 0.2.69 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2217,7 +2217,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.51 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.53 (registry+https://github.com/rust-lang/crates.io-index)", "synstructure 0.12.4 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2309,11 +2309,11 @@ dependencies = [ "checksum itertools 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b" "checksum itoa 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "dc6f3ad7b9d11a0c00842ff8de1b60ee58661048eb8049ed33c73594f359d7e6" "checksum jobserver 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)" = "5c71313ebb9439f74b00d9d2dcec36440beaf57a6aa0623068441dd7cd81a7f2" -"checksum js-sys 0.3.45 (registry+https://github.com/rust-lang/crates.io-index)" = "ca059e81d9486668f12d455a4ea6daa600bd408134cd17e3d3fb5a32d1f016f8" +"checksum js-sys 0.3.46 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d7383929f7c9c7c2d0fa596f325832df98c3704f2c60553080f7127a58175" "checksum keccak 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "67c21572b4949434e4fc1e1978b99c5f77064153c59d998bf13ecd96fb5ecba7" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" "checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" -"checksum libc 0.2.80 (registry+https://github.com/rust-lang/crates.io-index)" = "4d58d1b70b004888f764dfbf6a26a3b0342a1632d33968e4a179d8011c760614" +"checksum libc 0.2.81 (registry+https://github.com/rust-lang/crates.io-index)" = "1482821306169ec4d07f6aca392a4681f66c75c9918aa49641a2595db64053cb" "checksum libsecp256k1 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "1fc1e2c808481a63dc6da2074752fdd4336a3c8fcc68b83db6f1fd5224ae7962" "checksum lock_api 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c4da24a77a3d8a6d4862d95f72e6fdb9c09a643ecdb402d754004a557f2bec75" "checksum log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)" = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b" @@ -2325,10 +2325,10 @@ dependencies = [ "checksum mime 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)" = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" "checksum mime_guess 2.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2684d4c2e97d99848d30b324b00c8fcc7e5c897b7cbb5819b09e7c90e8baf212" "checksum miniz_oxide 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0f2d26ec3309788e423cfbf68ad1800f061638098d76a83681af979dc4eda19d" -"checksum mio 0.6.22 (registry+https://github.com/rust-lang/crates.io-index)" = "fce347092656428bc8eaf6201042cb551b8d67855af7374542a92a0fbfcac430" +"checksum mio 0.6.23 (registry+https://github.com/rust-lang/crates.io-index)" = "4afd66f5b91bf2a3bc13fad0e21caedac168ca4c707504e75585648ae80e4cc4" "checksum mio-uds 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)" = "afcb699eb26d4332647cc848492bbc15eafb26f08d0304550d5aa1f612e066f0" -"checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" -"checksum net2 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)" = "3ebc3ec692ed7c9a255596c67808dee269f64655d8baf7b4f0638e51ba1d6853" +"checksum miow 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ebd808424166322d4a38da87083bfddd3ac4c131334ed55856112eb06d46944d" +"checksum net2 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)" = "d7cf75f38f16cb05ea017784dc6dbfd354f76c223dba37701734c4f5a9337d02" "checksum num-derive 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" "checksum num-integer 0.1.44 (registry+https://github.com/rust-lang/crates.io-index)" = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" "checksum num-traits 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" @@ -2379,10 +2379,10 @@ dependencies = [ "checksum sct 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e3042af939fca8c3453b7af0f1c66e533a15a86169e39de2657310ade8f98d3c" "checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" -"checksum serde 1.0.117 (registry+https://github.com/rust-lang/crates.io-index)" = "b88fa983de7720629c9387e9f517353ed404164b1e482c970a90c1a4aaf7dc1a" +"checksum serde 1.0.118 (registry+https://github.com/rust-lang/crates.io-index)" = "06c64263859d87aa2eb554587e2d23183398d617427327cf2b3d0ed8c69e4800" "checksum serde_bytes 0.11.5 (registry+https://github.com/rust-lang/crates.io-index)" = "16ae07dd2f88a366f15bd0632ba725227018c69a1c8550a927324f8eb8368bb9" -"checksum serde_derive 1.0.117 (registry+https://github.com/rust-lang/crates.io-index)" = "cbd1ae72adb44aab48f325a02444a5fc079349a8d804c1fc922aed3f7454c74e" -"checksum serde_json 1.0.59 (registry+https://github.com/rust-lang/crates.io-index)" = "dcac07dbffa1c65e7f816ab9eba78eb142c6d44410f4eeba1e26e4f5dfa56b95" +"checksum serde_derive 1.0.118 (registry+https://github.com/rust-lang/crates.io-index)" = "c84d3526699cd55261af4b941e4e725444df67aa4f9e6a3564f18030d12672df" +"checksum serde_json 1.0.60 (registry+https://github.com/rust-lang/crates.io-index)" = "1500e84d27fe482ed1dc791a56eddc2f230046a040fa908c08bda1d9fb615779" "checksum serde_urlencoded 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "edfa57a7f8d9c1d260a549e7224100f6c43d43f9103e06dd8b4095a9b2b43ce9" "checksum sha2 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a256f46ea78a0c0d9ff00077504903ac881a1dafdc20da66545699e7776b3e69" "checksum sha3 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f81199417d4e5de3f04b1e871023acea7389672c4135918f05aa9cbf2f2fa809" @@ -2390,19 +2390,19 @@ dependencies = [ "checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" "checksum smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "f7b0758c52e15a8b5e3691eae6cc559f08eee9406e548a4477ba4e67770a82b6" "checksum socket2 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)" = "2c29947abdee2a218277abeca306f25789c938e500ea5a9d4b12a5a504466902" -"checksum solana-crate-features 1.4.11 (registry+https://github.com/rust-lang/crates.io-index)" = "5177f65cb1c12481166d0f6c88fe07555240ac0d41cf1ccde94bbb060ff4a59f" -"checksum solana-frozen-abi 1.4.11 (registry+https://github.com/rust-lang/crates.io-index)" = "70986469bb4b6c00297daca48978894bb3dd5db67c960deb20ff6c2cc92a433c" -"checksum solana-frozen-abi-macro 1.4.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d21c3d3b1f997d3ed70799dbb364ee25ff6d379adb345163017b5f59917ace5d" -"checksum solana-logger 1.4.11 (registry+https://github.com/rust-lang/crates.io-index)" = "59a95106f81d3848cba067245f530eb2d24d6ad63abd93fcf374c59868b1caa9" -"checksum solana-program 1.4.11 (registry+https://github.com/rust-lang/crates.io-index)" = "a5c76bf8795867016f886444d8502e831c1c54a904e3f549b38bd784e52edf8b" -"checksum solana-sdk 1.4.11 (registry+https://github.com/rust-lang/crates.io-index)" = "2619e92eefaaecbaa043535fe7a9b8908a618f146fa54143258e9031bc63f2b9" -"checksum solana-sdk-macro 1.4.11 (registry+https://github.com/rust-lang/crates.io-index)" = "0252cf01ecf46e3a89a485937bbebc3cbb141d1c8609f55aa3845a2c80da3a44" +"checksum solana-crate-features 1.4.14 (registry+https://github.com/rust-lang/crates.io-index)" = "dc73ada8cddc62edf58dc09ef3cf4551259d0ca1c7ece5f102757279ec2afa95" +"checksum solana-frozen-abi 1.4.14 (registry+https://github.com/rust-lang/crates.io-index)" = "9e5ab6ad3dda6a3d95d19603eeedc65689d8125eafb3e23c6a1e01ab8a6ba60c" +"checksum solana-frozen-abi-macro 1.4.14 (registry+https://github.com/rust-lang/crates.io-index)" = "ffaa09aa938a67501479ed8a785071c6993f72c34e43f680db3ea7a2dadad9e7" +"checksum solana-logger 1.4.14 (registry+https://github.com/rust-lang/crates.io-index)" = "0d949157d0b23eaf5758b427d90741d2a90751c4e3dfee028f5726ab8b36e769" +"checksum solana-program 1.4.14 (registry+https://github.com/rust-lang/crates.io-index)" = "8e9c6cb16e8aa986bc0d2af8ec50628f7451bef9dac89924adf48302bd4fc755" +"checksum solana-sdk 1.4.14 (registry+https://github.com/rust-lang/crates.io-index)" = "85c38a02d501422070cd6a4d561b4ab1408e311c5a0b5af3a7bb01246da14f66" +"checksum solana-sdk-macro 1.4.14 (registry+https://github.com/rust-lang/crates.io-index)" = "475a680cd175f2e256452e007c6f8622d3a1ab97ab36d26303b35576e24f340c" "checksum spin 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" "checksum spl-token 2.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "eaa27ab75067c63b8804d9fff30bd2e8bfb5be448bea8067ed768381e70ca181" "checksum subtle 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee" "checksum subtle 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "343f3f510c2915908f155e94f17220b19ccfacf2a64a2a5d8004f2c3e311e7fd" "checksum syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)" = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5" -"checksum syn 1.0.51 (registry+https://github.com/rust-lang/crates.io-index)" = "3b4f34193997d92804d359ed09953e25d5138df6bcc055a71bf68ee89fdf9223" +"checksum syn 1.0.53 (registry+https://github.com/rust-lang/crates.io-index)" = "8833e20724c24de12bbaba5ad230ea61c3eafb05b881c7c9d3cfe8638b187e68" "checksum synstructure 0.12.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b834f2d66f734cb897113e34aaff2f1ab4719ca946f9a7358dba8f8064148701" "checksum termcolor 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4" "checksum thiserror 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)" = "0e9ae34b84616eedaaf1e9dd6026dbe00dcafa92aa0c8077cb69df1fcfe5e53e" @@ -2445,15 +2445,15 @@ dependencies = [ "checksum want 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" "checksum wasi 0.10.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)" = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" "checksum wasi 0.9.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)" = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" -"checksum wasm-bindgen 0.2.68 (registry+https://github.com/rust-lang/crates.io-index)" = "1ac64ead5ea5f05873d7c12b545865ca2b8d28adfc50a49b84770a3a97265d42" -"checksum wasm-bindgen-backend 0.2.68 (registry+https://github.com/rust-lang/crates.io-index)" = "f22b422e2a757c35a73774860af8e112bff612ce6cb604224e8e47641a9e4f68" -"checksum wasm-bindgen-futures 0.4.18 (registry+https://github.com/rust-lang/crates.io-index)" = "b7866cab0aa01de1edf8b5d7936938a7e397ee50ce24119aef3e1eaa3b6171da" -"checksum wasm-bindgen-macro 0.2.68 (registry+https://github.com/rust-lang/crates.io-index)" = "6b13312a745c08c469f0b292dd2fcd6411dba5f7160f593da6ef69b64e407038" -"checksum wasm-bindgen-macro-support 0.2.68 (registry+https://github.com/rust-lang/crates.io-index)" = "f249f06ef7ee334cc3b8ff031bfc11ec99d00f34d86da7498396dc1e3b1498fe" -"checksum wasm-bindgen-shared 0.2.68 (registry+https://github.com/rust-lang/crates.io-index)" = "1d649a3145108d7d3fbcde896a468d1bd636791823c9921135218ad89be08307" -"checksum wasm-bindgen-test 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)" = "34d1cdc8b98a557f24733d50a1199c4b0635e465eecba9c45b214544da197f64" -"checksum wasm-bindgen-test-macro 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)" = "e8fb9c67be7439ee8ab1b7db502a49c05e51e2835b66796c705134d9b8e1a585" -"checksum web-sys 0.3.45 (registry+https://github.com/rust-lang/crates.io-index)" = "4bf6ef87ad7ae8008e15a355ce696bed26012b7caa21605188cfd8214ab51e2d" +"checksum wasm-bindgen 0.2.69 (registry+https://github.com/rust-lang/crates.io-index)" = "3cd364751395ca0f68cafb17666eee36b63077fb5ecd972bbcd74c90c4bf736e" +"checksum wasm-bindgen-backend 0.2.69 (registry+https://github.com/rust-lang/crates.io-index)" = "1114f89ab1f4106e5b55e688b828c0ab0ea593a1ea7c094b141b14cbaaec2d62" +"checksum wasm-bindgen-futures 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)" = "1fe9756085a84584ee9457a002b7cdfe0bfff169f45d2591d8be1345a6780e35" +"checksum wasm-bindgen-macro 0.2.69 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6ac8995ead1f084a8dea1e65f194d0973800c7f571f6edd70adf06ecf77084" +"checksum wasm-bindgen-macro-support 0.2.69 (registry+https://github.com/rust-lang/crates.io-index)" = "b5a48c72f299d80557c7c62e37e7225369ecc0c963964059509fbafe917c7549" +"checksum wasm-bindgen-shared 0.2.69 (registry+https://github.com/rust-lang/crates.io-index)" = "7e7811dd7f9398f14cc76efd356f98f03aa30419dea46aa810d71e819fc97158" +"checksum wasm-bindgen-test 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)" = "0355fa0c1f9b792a09b6dcb6a8be24d51e71e6d74972f9eb4a44c4c004d24a25" +"checksum wasm-bindgen-test-macro 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)" = "27e07b46b98024c2ba2f9e83a10c2ef0515f057f2da299c1762a2017de80438b" +"checksum web-sys 0.3.46 (registry+https://github.com/rust-lang/crates.io-index)" = "222b1ef9334f92a21d3fb53dc3fd80f30836959a90f9274a626d7e06315ba3c3" "checksum webpki 0.21.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f1f50e1972865d6b1adb54167d1c8ed48606004c2c9d0ea5f1eeb34d95e863ef" "checksum webpki-roots 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0f20dea7535251981a9670857150d571846545088359b28e4951d350bdaf179f" "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" diff --git a/lockup/program/src/common/mod.rs b/lockup/program/src/common/mod.rs index af2c212..f0aaac8 100644 --- a/lockup/program/src/common/mod.rs +++ b/lockup/program/src/common/mod.rs @@ -7,25 +7,6 @@ use solana_sdk::pubkey::Pubkey; pub mod access_control; -// Prepends the program's unique TAG identifier before making the signed -// cross program invocation to a *trusted* program on the whitelist. -// -// The trusted program should perform three steps of validation: -// -// 1. Check for the TAG identifier in the first 8 bytes of the instruction data. -// If present, then authentication must be done on the following two steps. -// 2. Check accounts[1] is signed. -// 3. Check accounts[1] is the correct program derived address for the vesting -// account, i.e., signer seeds == [safe_address, beneficiary_address, nonce]. -// -// If all of these hold, a program can trust the instruction was invoked -// by a the lockup program on behalf of a vesting account. -// -// Importantly, it's the responsibility of the trusted program to maintain the -// locked invariant preserved by this program and to return the funds at an -// unspecified point in the future for unlocking. Any bug in the trusted program -// can result in locked funds becoming unlocked, so take care when adding to the -// whitelist. pub fn whitelist_cpi( mut instruction: Instruction, safe: &Pubkey, @@ -33,11 +14,6 @@ pub fn whitelist_cpi( vesting: &Vesting, accounts: &[AccountInfo], ) -> ProgramResult { - let mut data = serum_lockup::instruction::TAG.to_le_bytes().to_vec(); - data.extend(instruction.data); - - instruction.data = data; - let signer_seeds = vault::signer_seeds(safe, beneficiary_acc_info.key, &vesting.nonce); solana_sdk::program::invoke_signed(&instruction, accounts, &[&signer_seeds]) } diff --git a/lockup/program/src/create_vesting.rs b/lockup/program/src/create_vesting.rs index 80f412a..616001f 100644 --- a/lockup/program/src/create_vesting.rs +++ b/lockup/program/src/create_vesting.rs @@ -3,7 +3,7 @@ use serum_common::pack::Pack; use serum_common::program::invoke_token_transfer; use serum_lockup::accounts::{vault, Vesting}; use serum_lockup::error::{LockupError, LockupErrorCode}; -use solana_program::info; +use solana_program::msg; use solana_sdk::account_info::{next_account_info, AccountInfo}; use solana_sdk::pubkey::Pubkey; use spl_token::state::Account as TokenAccount; @@ -18,7 +18,7 @@ pub fn handler( deposit_amount: u64, nonce: u8, ) -> Result<(), LockupError> { - info!("handler: create_vesting"); + msg!("handler: create_vesting"); let acc_infos = &mut accounts.iter(); @@ -72,7 +72,7 @@ pub fn handler( } fn access_control(req: AccessControlRequest) -> Result { - info!("access-control: create_vesting"); + msg!("access-control: create_vesting"); let AccessControlRequest { program_id, @@ -151,7 +151,7 @@ fn access_control(req: AccessControlRequest) -> Result Result<(), LockupError> { - info!("state-transition: create_vesting"); + msg!("state-transition: create_vesting"); let StateTransitionRequest { clock_ts, diff --git a/lockup/src/lib.rs b/lockup/src/lib.rs index 1aeb947..14d7fc6 100644 --- a/lockup/src/lib.rs +++ b/lockup/src/lib.rs @@ -12,8 +12,6 @@ pub mod error; pub mod instruction { use super::*; - pub const TAG: u64 = 0x9c52b5632b5f74d2; - #[derive(Debug, BorshSerialize, BorshDeserialize, BorshSchema)] pub enum LockupInstruction { /// Accounts: diff --git a/registry/cli/src/lib.rs b/registry/cli/src/lib.rs index f47e5b5..914ce4a 100644 --- a/registry/cli/src/lib.rs +++ b/registry/cli/src/lib.rs @@ -44,6 +44,10 @@ pub enum SubCommand { reward_activation_threshold: u64, #[clap(short, long)] max_stake_per_entity: u64, + #[clap(short, long)] + stake_rate: u64, + #[clap(short = 'b', long)] + stake_rate_mega: u64, }, /// Creates and registers a delegated staked node entity. CreateEntity { @@ -115,6 +119,8 @@ pub fn run(opts: Opts) -> Result<()> { deactivation_timelock, reward_activation_threshold, max_stake_per_entity, + stake_rate, + stake_rate_mega, } => init( ctx, registry_pid, @@ -122,6 +128,8 @@ pub fn run(opts: Opts) -> Result<()> { deactivation_timelock, reward_activation_threshold, max_stake_per_entity, + stake_rate, + stake_rate_mega, ), SubCommand::CreateEntity { leader, @@ -193,7 +201,7 @@ fn create_entity_cmd( .map_err(|_| anyhow!("Unable to read leader keypair file"))?; let client = ctx.connect::(registry_pid)?; - let CreateEntityResponse { tx, entity } = client.create_entity(CreateEntityRequest { + let CreateEntityResponse { entity, .. } = client.create_entity(CreateEntityRequest { node_leader: &leader_kp, registrar, name, @@ -260,6 +268,8 @@ pub fn init( deactivation_timelock: i64, reward_activation_threshold: u64, max_stake_per_entity: u64, + stake_rate: u64, + stake_rate_mega: u64, ) -> Result<()> { let registry_pid = registry_pid.ok_or(anyhow!( "Please provide --pid when initializing a registrar" @@ -281,6 +291,8 @@ pub fn init( mega_mint: ctx.msrm_mint, reward_activation_threshold, max_stake_per_entity, + stake_rate, + stake_rate_mega, })?; println!( diff --git a/registry/client/src/inner.rs b/registry/client/src/inner.rs deleted file mode 100644 index a0c1e12..0000000 --- a/registry/client/src/inner.rs +++ /dev/null @@ -1,315 +0,0 @@ -use serum_common::client::rpc; -use serum_common::pack::Pack; -use serum_registry::accounts; -use serum_registry::accounts::reward_queue::{RewardEventQueue, Ring}; -use serum_registry::client::{Client as InnerClient, ClientError as InnerClientError}; -use solana_client_gen::prelude::*; -use solana_client_gen::solana_sdk; -use solana_client_gen::solana_sdk::instruction::{AccountMeta, Instruction}; -use solana_client_gen::solana_sdk::pubkey::Pubkey; -use solana_client_gen::solana_sdk::system_instruction; - -pub fn initialize( - client: &InnerClient, - mint: &Pubkey, - mega_mint: &Pubkey, - registrar_authority: &Pubkey, - withdrawal_timelock: i64, - deactivation_timelock_premium: i64, - reward_activation_threshold: u64, - max_stake_per_entity: u64, -) -> Result<(Signature, Pubkey, Pubkey, u8, Pubkey, Pubkey), InnerClientError> { - let reward_event_q = Keypair::generate(&mut OsRng); - let registrar_kp = Keypair::generate(&mut OsRng); - let (registrar_vault_authority, nonce) = - Pubkey::find_program_address(&[registrar_kp.pubkey().as_ref()], client.program()); - - // Create and initialize the vaults, both owned by the program-derived-address. - let srm_vault = rpc::create_token_account( - client.rpc(), - mint, - ®istrar_vault_authority, - client.payer(), - ) - .map_err(|e| InnerClientError::RawError(e.to_string()))?; - let msrm_vault = rpc::create_token_account( - client.rpc(), - mega_mint, - ®istrar_vault_authority, - client.payer(), - ) - .map_err(|e| InnerClientError::RawError(e.to_string()))?; - - let pool_vault = rpc::create_token_account( - client.rpc(), - mint, - ®istrar_vault_authority, - client.payer(), - ) - .map_err(|e| InnerClientError::RawError(e.to_string()))? - .pubkey(); - let mega_pool_vault = rpc::create_token_account( - client.rpc(), - mega_mint, - ®istrar_vault_authority, - client.payer(), - ) - .map_err(|e| InnerClientError::RawError(e.to_string()))? - .pubkey(); - let decimals = 6; // TODO: decide on this. - let pool_mint = rpc::new_mint( - client.rpc(), - client.payer(), - ®istrar_vault_authority, - decimals, - ) - .map_err(|e| InnerClientError::RawError(e.to_string()))? - .0 - .pubkey(); - - let mega_pool_mint = rpc::new_mint( - client.rpc(), - client.payer(), - ®istrar_vault_authority, - decimals, - ) - .map_err(|e| InnerClientError::RawError(e.to_string()))? - .0 - .pubkey(); - - // Build the instructions. - let ixs = { - let create_registrar_acc_instr = { - let lamports = client - .rpc() - .get_minimum_balance_for_rent_exemption(*accounts::registrar::SIZE as usize) - .map_err(InnerClientError::RpcError)?; - system_instruction::create_account( - &client.payer().pubkey(), - ®istrar_kp.pubkey(), - lamports, - *accounts::registrar::SIZE, - client.program(), - ) - }; - let create_reward_event_q_instr = { - let data_size = RewardEventQueue::buffer_size(RewardEventQueue::RING_CAPACITY); - let lamports = client - .rpc() - .get_minimum_balance_for_rent_exemption(data_size)?; - solana_sdk::system_instruction::create_account( - &client.payer().pubkey(), - &reward_event_q.pubkey(), - lamports, - data_size as u64, - client.program(), - ) - }; - - let initialize_registrar_instr = { - let accounts = [ - AccountMeta::new(registrar_kp.pubkey(), false), - // Deposit vaults. - AccountMeta::new_readonly(srm_vault.pubkey(), false), - AccountMeta::new_readonly(msrm_vault.pubkey(), false), - // Pool vaults. - AccountMeta::new_readonly(pool_vault, false), - AccountMeta::new_readonly(mega_pool_vault, false), - // Pool mints. - AccountMeta::new_readonly(pool_mint, false), - AccountMeta::new_readonly(mega_pool_mint, false), - AccountMeta::new(reward_event_q.pubkey(), false), - AccountMeta::new_readonly(solana_sdk::sysvar::rent::id(), false), - ]; - serum_registry::instruction::initialize( - *client.program(), - &accounts, - *registrar_authority, - nonce, - withdrawal_timelock, - deactivation_timelock_premium, - reward_activation_threshold, - max_stake_per_entity, - ) - }; - - vec![ - create_reward_event_q_instr, - create_registrar_acc_instr, - initialize_registrar_instr, - ] - }; - - let (recent_hash, _fee_calc) = client - .rpc() - .get_recent_blockhash() - .map_err(|e| InnerClientError::RawError(e.to_string()))?; - let tx = Transaction::new_signed_with_payer( - &ixs, - Some(&client.payer().pubkey()), - &vec![client.payer(), &reward_event_q, ®istrar_kp], - recent_hash, - ); - let sig = client - .rpc() - .send_and_confirm_transaction_with_spinner_and_config( - &tx, - client.options().commitment, - client.options().tx, - ) - .map_err(InnerClientError::RpcError)?; - Ok(( - sig, - registrar_kp.pubkey(), - reward_event_q.pubkey(), - nonce, - pool_vault, - mega_pool_vault, - )) -} - -pub fn create_entity( - client: &InnerClient, - registrar: Pubkey, - leader_kp: &Keypair, - name: String, - about: String, - image_url: String, - meta_entity_program_id: Pubkey, -) -> Result<(Signature, Pubkey), InnerClientError> { - let entity_kp = Keypair::generate(&mut OsRng); - let create_acc_instr = { - let lamports = client - .rpc() - .get_minimum_balance_for_rent_exemption(*accounts::entity::SIZE as usize) - .map_err(InnerClientError::RpcError)?; - system_instruction::create_account( - &client.payer().pubkey(), - &entity_kp.pubkey(), - lamports, - *accounts::entity::SIZE, - client.program(), - ) - }; - - let accounts = [ - AccountMeta::new(entity_kp.pubkey(), false), - AccountMeta::new_readonly(leader_kp.pubkey(), true), - AccountMeta::new_readonly(registrar, false), - AccountMeta::new_readonly(solana_sdk::sysvar::rent::ID, false), - ]; - - let metadata = Keypair::generate(&mut OsRng); - let mqueue = Keypair::generate(&mut OsRng); - let create_entity_instr = - serum_registry::instruction::create_entity(*client.program(), &accounts, metadata.pubkey()); - - let create_md_instrs = create_metadata_instructions( - client.rpc(), - &client.payer().pubkey(), - &metadata, - &mqueue, - &meta_entity_program_id, - &entity_kp.pubkey(), - name, - about, - image_url, - ); - let mut instructions = create_md_instrs; - instructions.extend_from_slice(&[create_acc_instr, create_entity_instr]); - - let signers = vec![leader_kp, &metadata, &mqueue, &entity_kp, client.payer()]; - let (recent_hash, _fee_calc) = client.rpc().get_recent_blockhash()?; - - let tx = Transaction::new_signed_with_payer( - &instructions, - Some(&client.payer().pubkey()), - &signers, - recent_hash, - ); - - client - .rpc() - .send_and_confirm_transaction_with_spinner_and_config( - &tx, - client.options().commitment, - client.options().tx, - ) - .map_err(InnerClientError::RpcError) - .map(|sig| (sig, entity_kp.pubkey())) -} - -// todo: remove -pub fn member_seed() -> &'static str { - "srm:registry:member" -} - -fn create_metadata_instructions( - client: &RpcClient, - payer: &Pubkey, - metadata: &Keypair, - mqueue: &Keypair, - program_id: &Pubkey, - entity: &Pubkey, - name: String, - about: String, - image_url: String, -) -> Vec { - let md = serum_meta_entity::accounts::Metadata { - initialized: false, - entity: Pubkey::new_from_array([0; 32]), - authority: *payer, - name: name.clone(), - about: about.clone(), - image_url: image_url.clone(), - chat: Pubkey::new_from_array([0; 32]), - }; - let metadata_size = md.size().unwrap(); - let lamports = client - .get_minimum_balance_for_rent_exemption(metadata_size as usize) - .unwrap(); - let create_metadata_instr = solana_sdk::system_instruction::create_account( - payer, - &metadata.pubkey(), - lamports, - metadata_size as u64, - program_id, - ); - - let mqueue_size = serum_meta_entity::accounts::MQueue::SIZE; - let lamports = client - .get_minimum_balance_for_rent_exemption(mqueue_size) - .unwrap(); - let create_mqueue_instr = solana_sdk::system_instruction::create_account( - payer, - &mqueue.pubkey(), - lamports, - mqueue_size as u64, - program_id, - ); - - let initialize_metadata_instr = { - let accounts = vec![AccountMeta::new(metadata.pubkey(), false)]; - let instr = serum_meta_entity::instruction::MetaEntityInstruction::Initialize { - entity: *entity, - authority: *payer, - name, - about, - image_url, - chat: mqueue.pubkey(), - }; - let mut data = vec![0u8; instr.size().unwrap() as usize]; - serum_meta_entity::instruction::MetaEntityInstruction::pack(instr, &mut data).unwrap(); - Instruction { - program_id: *program_id, - accounts, - data, - } - }; - - vec![ - create_metadata_instr, - create_mqueue_instr, - initialize_metadata_instr, - ] -} diff --git a/registry/client/src/lib.rs b/registry/client/src/lib.rs index 00a2336..1e8c61f 100644 --- a/registry/client/src/lib.rs +++ b/registry/client/src/lib.rs @@ -1,7 +1,9 @@ use serum_common::client::rpc; use serum_common::pack::*; +use serum_meta_entity::accounts::mqueue::{MQueue, Ring as MQueueRing}; +use serum_registry::accounts::reward_queue::{RewardEventQueue, Ring}; use serum_registry::accounts::{ - self, pending_withdrawal, vault, Entity, Member, PendingWithdrawal, Registrar, + self, pending_withdrawal, vault, BalanceSandbox, Entity, Member, PendingWithdrawal, Registrar, }; use serum_registry::client::{Client as InnerClient, ClientError as InnerClientError}; use solana_client_gen::prelude::*; @@ -13,8 +15,6 @@ use spl_token::state::Account as TokenAccount; use std::convert::Into; use thiserror::Error; -mod inner; - pub struct Client { inner: InnerClient, } @@ -30,31 +30,129 @@ impl Client { withdrawal_timelock, deactivation_timelock, max_stake_per_entity, + reward_activation_threshold, mint, mega_mint, - reward_activation_threshold, + stake_rate, + stake_rate_mega, } = req; - let (tx, registrar, reward_event_q, nonce, pool_vault, pool_vault_mega) = - inner::initialize( - &self.inner, - &mint, - &mega_mint, - ®istrar_authority, - withdrawal_timelock, - deactivation_timelock, - reward_activation_threshold, - max_stake_per_entity, - )?; + + let reward_event_q = Keypair::generate(&mut OsRng); + let registrar_kp = Keypair::generate(&mut OsRng); + let (registrar_vault_authority, nonce) = + Pubkey::find_program_address(&[registrar_kp.pubkey().as_ref()], self.inner.program()); + + let decimals = 6; // TODO: decide on this. + let pool_mint = rpc::new_mint( + self.rpc(), + self.inner.payer(), + ®istrar_vault_authority, + decimals, + ) + .map_err(|e| InnerClientError::RawError(e.to_string()))? + .0 + .pubkey(); + + let mega_pool_mint = rpc::new_mint( + self.rpc(), + self.inner.payer(), + ®istrar_vault_authority, + decimals, + ) + .map_err(|e| InnerClientError::RawError(e.to_string()))? + .0 + .pubkey(); + + // Build the instructions. + let ixs = { + let create_registrar_acc_instr = { + let lamports = self + .inner + .rpc() + .get_minimum_balance_for_rent_exemption(*accounts::registrar::SIZE as usize) + .map_err(InnerClientError::RpcError)?; + system_instruction::create_account( + &self.inner.payer().pubkey(), + ®istrar_kp.pubkey(), + lamports, + *accounts::registrar::SIZE, + self.inner.program(), + ) + }; + let create_reward_event_q_instr = { + let data_size = RewardEventQueue::buffer_size(RewardEventQueue::RING_CAPACITY); + let lamports = self + .inner + .rpc() + .get_minimum_balance_for_rent_exemption(data_size)?; + solana_sdk::system_instruction::create_account( + &self.inner.payer().pubkey(), + &reward_event_q.pubkey(), + lamports, + data_size as u64, + self.inner.program(), + ) + }; + + let initialize_registrar_instr = { + let accounts = [ + AccountMeta::new(registrar_kp.pubkey(), false), + AccountMeta::new_readonly(pool_mint, false), + AccountMeta::new_readonly(mega_pool_mint, false), + AccountMeta::new(reward_event_q.pubkey(), false), + AccountMeta::new_readonly(solana_sdk::sysvar::rent::id(), false), + ]; + serum_registry::instruction::initialize( + *self.inner.program(), + &accounts, + registrar_authority, + mint, + mega_mint, + nonce, + withdrawal_timelock, + deactivation_timelock, + reward_activation_threshold, + max_stake_per_entity, + stake_rate, + stake_rate_mega, + ) + }; + + vec![ + create_reward_event_q_instr, + create_registrar_acc_instr, + initialize_registrar_instr, + ] + }; + + let (recent_hash, _fee_calc) = self + .inner + .rpc() + .get_recent_blockhash() + .map_err(|e| InnerClientError::RawError(e.to_string()))?; + let tx = Transaction::new_signed_with_payer( + &ixs, + Some(&self.inner.payer().pubkey()), + &vec![self.inner.payer(), &reward_event_q, ®istrar_kp], + recent_hash, + ); + let sig = self + .inner + .rpc() + .send_and_confirm_transaction_with_spinner_and_config( + &tx, + self.inner.options().commitment, + self.inner.options().tx, + ) + .map_err(InnerClientError::RpcError)?; + Ok(InitializeResponse { - tx, - registrar, - reward_event_q, + tx: sig, + registrar: registrar_kp.pubkey(), + reward_event_q: reward_event_q.pubkey(), nonce, - pool_vault, - pool_vault_mega, }) } - pub fn create_entity( &self, req: CreateEntityRequest, @@ -67,16 +165,79 @@ impl Client { image_url, meta_entity_program_id, } = req; - let (tx, entity) = inner::create_entity( - &self.inner, - registrar, - node_leader, + let entity_kp = Keypair::generate(&mut OsRng); + let create_acc_instr = { + let lamports = self + .inner + .rpc() + .get_minimum_balance_for_rent_exemption(*accounts::entity::SIZE as usize) + .map_err(InnerClientError::RpcError)?; + system_instruction::create_account( + &self.inner.payer().pubkey(), + &entity_kp.pubkey(), + lamports, + *accounts::entity::SIZE, + self.inner.program(), + ) + }; + + let accounts = [ + AccountMeta::new(entity_kp.pubkey(), false), + AccountMeta::new_readonly(node_leader.pubkey(), true), + AccountMeta::new_readonly(registrar, false), + AccountMeta::new_readonly(solana_sdk::sysvar::rent::ID, false), + ]; + + let metadata = Keypair::generate(&mut OsRng); + let mqueue = Keypair::generate(&mut OsRng); + let create_entity_instr = serum_registry::instruction::create_entity( + *self.inner.program(), + &accounts, + metadata.pubkey(), + ); + + let create_md_instrs = create_metadata_instructions( + self.rpc(), + &self.inner.payer().pubkey(), + &metadata, + &mqueue, + &meta_entity_program_id, + &entity_kp.pubkey(), name, about, image_url, - meta_entity_program_id, - )?; - Ok(CreateEntityResponse { tx, entity }) + ); + let mut instructions = create_md_instrs; + instructions.extend_from_slice(&[create_acc_instr, create_entity_instr]); + + let signers = vec![ + node_leader, + &metadata, + &mqueue, + &entity_kp, + self.inner.payer(), + ]; + let (recent_hash, _fee_calc) = self.rpc().get_recent_blockhash()?; + + let tx = Transaction::new_signed_with_payer( + &instructions, + Some(&self.inner.payer().pubkey()), + &signers, + recent_hash, + ); + + self.inner + .rpc() + .send_and_confirm_transaction_with_spinner_and_config( + &tx, + self.inner.options().commitment, + self.inner.options().tx, + ) + .map_err(ClientError::RpcError) + .map(|sig| CreateEntityResponse { + tx: sig, + entity: entity_kp.pubkey(), + }) } pub fn update_entity( @@ -118,23 +279,29 @@ impl Client { let vault_authority = self.vault_authority(®istrar)?; let r = self.registrar(®istrar)?; - let pool_token = Keypair::generate(&mut OsRng); - let mega_pool_token = Keypair::generate(&mut OsRng); + let BalanceAccounts { + spt, + spt_mega, + vault, + vault_mega, + vault_stake, + vault_stake_mega, + vault_pw, + vault_pw_mega, + .. + } = self.create_member_accounts(&r, vault_authority)?; - let create_pool_token_instrs = rpc::create_token_account_instructions( - self.inner.rpc(), - pool_token.pubkey(), - &r.pool_mint, - &vault_authority, - self.inner.payer(), - )?; - let create_mega_pool_token_instrs = rpc::create_token_account_instructions( - self.inner.rpc(), - mega_pool_token.pubkey(), - &r.pool_mint_mega, - &vault_authority, - self.inner.payer(), - )?; + let BalanceAccounts { + spt: locked_spt, + spt_mega: locked_spt_mega, + vault: locked_vault, + vault_mega: locked_vault_mega, + vault_stake: locked_vault_stake, + vault_stake_mega: locked_vault_stake_mega, + vault_pw: locked_vault_pw, + vault_pw_mega: locked_vault_pw_mega, + .. + } = self.create_member_accounts(&r, vault_authority)?; let member_kp = Keypair::generate(&mut OsRng); let create_acc_instr = { @@ -158,28 +325,38 @@ impl Client { AccountMeta::new(entity, false), AccountMeta::new_readonly(registrar, false), AccountMeta::new_readonly(vault_authority, false), - AccountMeta::new_readonly(pool_token.pubkey(), false), - AccountMeta::new_readonly(mega_pool_token.pubkey(), false), AccountMeta::new_readonly(spl_token::ID, false), AccountMeta::new_readonly(solana_sdk::sysvar::rent::ID, false), + // Main. + AccountMeta::new_readonly(beneficiary.pubkey(), false), + AccountMeta::new(spt.pubkey(), false), + AccountMeta::new(spt_mega.pubkey(), false), + AccountMeta::new_readonly(vault.pubkey(), false), + AccountMeta::new_readonly(vault_mega.pubkey(), false), + AccountMeta::new_readonly(vault_stake.pubkey(), false), + AccountMeta::new_readonly(vault_stake_mega.pubkey(), false), + AccountMeta::new_readonly(vault_pw.pubkey(), false), + AccountMeta::new_readonly(vault_pw_mega.pubkey(), false), + // Locked. + AccountMeta::new_readonly(delegate, false), + AccountMeta::new(locked_spt.pubkey(), false), + AccountMeta::new(locked_spt_mega.pubkey(), false), + AccountMeta::new_readonly(locked_vault.pubkey(), false), + AccountMeta::new_readonly(locked_vault_mega.pubkey(), false), + AccountMeta::new_readonly(locked_vault_stake.pubkey(), false), + AccountMeta::new_readonly(locked_vault_stake_mega.pubkey(), false), + AccountMeta::new_readonly(locked_vault_pw.pubkey(), false), + AccountMeta::new_readonly(locked_vault_pw_mega.pubkey(), false), ]; let member_instr = - serum_registry::instruction::create_member(*self.inner.program(), &accounts, delegate); + serum_registry::instruction::create_member(*self.inner.program(), &accounts); let mut instructions = vec![]; - instructions.extend_from_slice(&create_pool_token_instrs); - instructions.extend_from_slice(&create_mega_pool_token_instrs); instructions.extend_from_slice(&[create_acc_instr, member_instr]); - let signers = vec![ - self.inner.payer(), - &member_kp, - beneficiary, - &pool_token, - &mega_pool_token, - ]; - let (recent_hash, _fee_calc) = self.inner.rpc().get_recent_blockhash()?; + let signers = vec![self.inner.payer(), &member_kp, beneficiary]; + let (recent_hash, _fee_calc) = self.rpc().get_recent_blockhash()?; let tx = Transaction::new_signed_with_payer( &instructions, @@ -202,6 +379,141 @@ impl Client { }) } + fn create_member_accounts( + &self, + r: &Registrar, + vault_authority: Pubkey, + ) -> Result { + let spt = Keypair::generate(&mut OsRng); + let spt_mega = Keypair::generate(&mut OsRng); + let vault = Keypair::generate(&mut OsRng); + let vault_mega = Keypair::generate(&mut OsRng); + let vault_stake = Keypair::generate(&mut OsRng); + let vault_stake_mega = Keypair::generate(&mut OsRng); + let vault_pw = Keypair::generate(&mut OsRng); + let vault_pw_mega = Keypair::generate(&mut OsRng); + let create_pool_token_ix = rpc::create_token_account_instructions( + self.rpc(), + spt.pubkey(), + &r.pool_mint, + &vault_authority, + self.inner.payer(), + )?; + let create_mega_pool_token_ix = rpc::create_token_account_instructions( + self.rpc(), + spt_mega.pubkey(), + &r.pool_mint_mega, + &vault_authority, + self.inner.payer(), + )?; + let create_vault_ix = rpc::create_token_account_instructions( + self.rpc(), + vault.pubkey(), + &r.mint, + &vault_authority, + self.inner.payer(), + )?; + let create_vault_mega_ix = rpc::create_token_account_instructions( + self.rpc(), + vault_mega.pubkey(), + &r.mega_mint, + &vault_authority, + self.inner.payer(), + )?; + let create_vault_stake_ix = rpc::create_token_account_instructions( + self.rpc(), + vault_stake.pubkey(), + &r.mint, + &vault_authority, + self.inner.payer(), + )?; + let create_vault_stake_mega_ix = rpc::create_token_account_instructions( + self.rpc(), + vault_stake_mega.pubkey(), + &r.mega_mint, + &vault_authority, + self.inner.payer(), + )?; + let create_vault_pw_ix = rpc::create_token_account_instructions( + self.rpc(), + vault_pw.pubkey(), + &r.mint, + &vault_authority, + self.inner.payer(), + )?; + let create_vault_pw_mega_ix = rpc::create_token_account_instructions( + self.rpc(), + vault_pw_mega.pubkey(), + &r.mega_mint, + &vault_authority, + self.inner.payer(), + )?; + + let mut instructions0 = vec![]; + instructions0.extend_from_slice(&create_pool_token_ix); + instructions0.extend_from_slice(&create_mega_pool_token_ix); + instructions0.extend_from_slice(&create_vault_ix); + instructions0.extend_from_slice(&create_vault_mega_ix); + + let mut instructions1 = vec![]; + instructions1.extend_from_slice(&create_vault_stake_ix); + instructions1.extend_from_slice(&create_vault_stake_mega_ix); + instructions1.extend_from_slice(&create_vault_pw_ix); + instructions1.extend_from_slice(&create_vault_pw_mega_ix); + + let signers0 = vec![self.inner.payer(), &spt, &spt_mega, &vault, &vault_mega]; + let signers1 = vec![ + self.inner.payer(), + &vault_stake, + &vault_stake_mega, + &vault_pw, + &vault_pw_mega, + ]; + let (recent_hash, _fee_calc) = self.rpc().get_recent_blockhash()?; + + let tx0 = Transaction::new_signed_with_payer( + &instructions0, + Some(&self.inner.payer().pubkey()), + &signers0, + recent_hash, + ); + let tx1 = Transaction::new_signed_with_payer( + &instructions1, + Some(&self.inner.payer().pubkey()), + &signers1, + recent_hash, + ); + + let _sig0 = self + .inner + .rpc() + .send_and_confirm_transaction_with_spinner_and_config( + &tx0, + self.inner.options().commitment, + self.inner.options().tx, + ) + .map_err(ClientError::RpcError)?; + let _sig1 = self + .inner + .rpc() + .send_and_confirm_transaction_with_spinner_and_config( + &tx1, + self.inner.options().commitment, + self.inner.options().tx, + ) + .map_err(ClientError::RpcError)?; + Ok(BalanceAccounts { + spt, + spt_mega, + vault, + vault_mega, + vault_stake, + vault_stake_mega, + vault_pw, + vault_pw_mega, + }) + } + pub fn deposit(&self, req: DepositRequest) -> Result { let DepositRequest { member, @@ -212,8 +524,9 @@ impl Client { registrar, amount, } = req; - let vault = self.vault_for(®istrar, &depositor)?; - let vault_acc = rpc::get_token_account::(self.inner.rpc(), &vault)?; + + let vault = self.vault_for(&member, &depositor, false)?; + let vault_acc = rpc::get_token_account::(self.rpc(), &vault)?; let accounts = vec![ // Whitelist relay interface, AccountMeta::new(depositor, false), @@ -226,7 +539,6 @@ impl Client { AccountMeta::new_readonly(beneficiary.pubkey(), true), AccountMeta::new(entity, false), AccountMeta::new_readonly(registrar, false), - AccountMeta::new_readonly(solana_sdk::sysvar::clock::ID, false), ]; let signers = [self.payer(), beneficiary, depositor_authority]; @@ -247,8 +559,8 @@ impl Client { registrar, amount, } = req; - let vault = self.vault_for(®istrar, &depositor)?; - let vault_acc = rpc::get_token_account::(self.inner.rpc(), &vault)?; + let vault = self.vault_for(&member, &depositor, false)?; + let vault_acc = rpc::get_token_account::(self.rpc(), &vault)?; let accounts = vec![ // Whitelist relay interface. AccountMeta::new(depositor, false), @@ -261,7 +573,6 @@ impl Client { AccountMeta::new_readonly(beneficiary.pubkey(), true), AccountMeta::new(entity, false), AccountMeta::new_readonly(registrar, false), - AccountMeta::new_readonly(solana_sdk::sysvar::clock::ID, false), ]; let signers = [self.payer(), beneficiary]; @@ -280,24 +591,33 @@ impl Client { registrar, pool_token_amount, mega, // TODO: remove. + balance_id, } = req; let r = self.registrar(®istrar)?; - let (vault, pool_vault, pool_mint) = { - if mega { - (r.mega_vault, r.pool_vault_mega, r.pool_mint_mega) - } else { - (r.vault, r.pool_vault, r.pool_mint) - } + let m = self.member(&member)?; + let b = m + .balances + .iter() + .filter(|b| b.owner == balance_id) + .collect::>(); + let balances = b.first().unwrap(); + + let (pool_mint, spt, vault, vault_stake) = match mega { + false => ( + r.pool_mint, + balances.spt, + balances.vault, + balances.vault_stake, + ), + true => ( + r.pool_mint_mega, + balances.spt_mega, + balances.vault_mega, + balances.vault_stake_mega, + ), }; + let vault_authority = self.vault_authority(®istrar)?; - let m_acc = self.member(&member)?; - let spt = { - if mega { - m_acc.spt_mega - } else { - m_acc.spt - } - }; let accounts = vec![ AccountMeta::new(member, false), @@ -306,7 +626,7 @@ impl Client { AccountMeta::new_readonly(registrar, false), AccountMeta::new(vault, false), AccountMeta::new_readonly(vault_authority, false), - AccountMeta::new(pool_vault, false), + AccountMeta::new(vault_stake, false), AccountMeta::new(pool_mint, false), AccountMeta::new(spt, false), AccountMeta::new_readonly(solana_sdk::sysvar::clock::ID, false), @@ -315,9 +635,9 @@ impl Client { let signers = [self.payer(), beneficiary]; - let tx = self - .inner - .stake_with_signers(&signers, &accounts, pool_token_amount)?; + let tx = + self.inner + .stake_with_signers(&signers, &accounts, pool_token_amount, balance_id)?; Ok(StakeResponse { tx }) } @@ -333,26 +653,34 @@ impl Client { beneficiary, spt_amount, mega, // TODO: remove. + balance_id, } = req; let pending_withdrawal = Keypair::generate(&mut OsRng); let r = self.registrar(®istrar)?; - let (vault, pool_vault, pool_mint) = { - if mega { - (r.mega_vault, r.pool_vault_mega, r.pool_mint_mega) - } else { - (r.vault, r.pool_vault, r.pool_mint) - } + let m = self.member(&member)?; + let b = m + .balances + .iter() + .filter(|b| b.owner == balance_id) + .collect::>(); + let balances = b.first().unwrap(); + + let (pool_mint, spt, vault_pw, vault_stake) = match mega { + false => ( + r.pool_mint, + balances.spt, + balances.vault_pending_withdrawal, + balances.vault_stake, + ), + true => ( + r.pool_mint_mega, + balances.spt_mega, + balances.vault_pending_withdrawal_mega, + balances.vault_stake_mega, + ), }; let vault_authority = self.vault_authority(®istrar)?; - let m_acc = self.member(&member)?; - let spt = { - if mega { - m_acc.spt_mega - } else { - m_acc.spt - } - }; let accs = vec![ AccountMeta::new(pending_withdrawal.pubkey(), false), @@ -361,9 +689,9 @@ impl Client { AccountMeta::new_readonly(beneficiary.pubkey(), true), AccountMeta::new(entity, false), AccountMeta::new_readonly(registrar, false), - AccountMeta::new(vault, false), + AccountMeta::new(vault_pw, false), AccountMeta::new_readonly(vault_authority, false), - AccountMeta::new(pool_vault, false), + AccountMeta::new(vault_stake, false), AccountMeta::new(pool_mint, false), AccountMeta::new(spt, false), AccountMeta::new_readonly(solana_sdk::sysvar::clock::ID, false), @@ -389,6 +717,7 @@ impl Client { *self.program(), &accs, spt_amount, + balance_id, ); [ create_pending_withdrawal_instr, @@ -433,11 +762,32 @@ impl Client { beneficiary, pending_withdrawal, } = req; + let m = self.member(&member)?; + let pw = self.pending_withdrawal(&pending_withdrawal)?; + let b = m + .balances + .iter() + .filter(|b| b.owner == pw.balance_id) + .collect::>(); + let balances = b.first().unwrap(); + + let mega = pw.pool == self.registrar(®istrar)?.mega_mint; + let (vault, vault_pw) = match mega { + false => (balances.vault, balances.vault_pending_withdrawal), + true => (balances.vault_mega, balances.vault_pending_withdrawal_mega), + }; + + let vault_authority = self.vault_authority(®istrar)?; + let accs = vec![ AccountMeta::new(pending_withdrawal, false), AccountMeta::new(member, false), + AccountMeta::new(vault, false), + AccountMeta::new(vault_pw, false), + AccountMeta::new(vault_authority, false), AccountMeta::new_readonly(beneficiary.pubkey(), true), AccountMeta::new(entity, false), + AccountMeta::new_readonly(spl_token::ID, false), AccountMeta::new_readonly(registrar, false), AccountMeta::new_readonly(solana_sdk::sysvar::clock::ID, false), ]; @@ -482,6 +832,7 @@ impl Client { beneficiary, registrar, } = req; + let m = self.member(&member)?; let accs = vec![ AccountMeta::new(member, false), AccountMeta::new_readonly(beneficiary.pubkey(), true), @@ -489,6 +840,13 @@ impl Client { AccountMeta::new(entity, false), AccountMeta::new(new_entity, false), AccountMeta::new_readonly(solana_sdk::sysvar::clock::ID, false), + AccountMeta::new_readonly(self.vault_authority(®istrar)?, false), + AccountMeta::new_readonly(m.balances[0].owner, false), + AccountMeta::new_readonly(m.balances[0].vault_stake, false), + AccountMeta::new_readonly(m.balances[0].vault_stake_mega, false), + AccountMeta::new_readonly(m.balances[1].owner, false), + AccountMeta::new_readonly(m.balances[1].vault_stake, false), + AccountMeta::new_readonly(m.balances[1].vault_stake_mega, false), ]; let tx = self .inner @@ -500,11 +858,11 @@ impl Client { // Account accessors. impl Client { pub fn registrar(&self, registrar: &Pubkey) -> Result { - rpc::get_account::(self.inner.rpc(), registrar).map_err(Into::into) + rpc::get_account::(self.rpc(), registrar).map_err(Into::into) } pub fn entity(&self, entity: &Pubkey) -> Result { - rpc::get_account_unchecked::(self.inner.rpc(), entity).map_err(Into::into) + rpc::get_account_unchecked::(self.rpc(), entity).map_err(Into::into) } pub fn vault_authority(&self, registrar: &Pubkey) -> Result { let r = self.registrar(registrar)?; @@ -512,43 +870,76 @@ impl Client { .map_err(|_| ClientError::Any(anyhow::anyhow!("invalid vault authority"))) } pub fn member(&self, member: &Pubkey) -> Result { - rpc::get_account::(self.inner.rpc(), &member).map_err(Into::into) + rpc::get_account::(self.rpc(), &member).map_err(Into::into) } pub fn member_seed() -> &'static str { - inner::member_seed() + "srm:registry:member" } - pub fn vault_for(&self, registrar: &Pubkey, depositor: &Pubkey) -> Result { - let depositor = rpc::get_token_account::(self.inner.rpc(), depositor)?; - let r = self.registrar(®istrar)?; + pub fn vault_for( + &self, + member: &Pubkey, + depositor: &Pubkey, + locked: bool, // todo use balance_id instead + ) -> Result { + let depositor = rpc::get_token_account::(self.rpc(), depositor)?; + let member = self.member(member)?; + let balances = match locked { + true => &member.balances[1], + false => &member.balances[0], + }; - let vault = self.current_deposit_vault(registrar)?; + let vault = rpc::get_token_account::(self.rpc(), &balances.vault)?; if vault.mint == depositor.mint { - return Ok(r.vault); + return Ok(balances.vault); } - let mega_vault = self.current_deposit_mega_vault(registrar)?; + let mega_vault = rpc::get_token_account::(self.rpc(), &balances.vault_mega)?; if mega_vault.mint == depositor.mint { - return Ok(r.mega_vault); + return Ok(balances.vault_mega); } Err(ClientError::Any(anyhow::anyhow!("invalid depositor mint"))) } - pub fn current_deposit_vault(&self, registrar: &Pubkey) -> Result { - let r = self.registrar(registrar)?; - rpc::get_token_account::(self.inner.rpc(), &r.vault).map_err(Into::into) + + pub fn current_deposit_vault( + &self, + member: &Pubkey, + locked: bool, + ) -> Result { + let m = self.member(member)?; + let balances = match locked { + true => &m.balances[1], + false => &m.balances[0], + }; + rpc::get_token_account::(self.rpc(), &balances.vault).map_err(Into::into) } + pub fn current_deposit_mega_vault( &self, - registrar: &Pubkey, + member: &Pubkey, + locked: bool, ) -> Result { - let r = self.registrar(registrar)?; - rpc::get_token_account::(self.inner.rpc(), &r.mega_vault).map_err(Into::into) - } - pub fn pool_token(&self, member: &Pubkey) -> Result, ClientError> { let m = self.member(member)?; - let account = rpc::get_token_account(self.inner.rpc(), &m.spt)?; + let balances = match locked { + true => &m.balances[1], + false => &m.balances[0], + }; + rpc::get_token_account::(self.rpc(), &balances.vault_mega).map_err(Into::into) + } + + pub fn pool_token( + &self, + member: &Pubkey, + locked: bool, + ) -> Result, ClientError> { + let m = self.member(member)?; + let balances = match locked { + true => &m.balances[1], + false => &m.balances[0], + }; + let account = rpc::get_token_account(self.rpc(), &balances.spt)?; Ok(ProgramAccount { - public_key: m.spt_mega, + public_key: balances.spt_mega, account, }) } @@ -556,30 +947,64 @@ impl Client { pub fn mega_pool_token( &self, member: &Pubkey, + locked: bool, ) -> Result, ClientError> { let m = self.member(member)?; - let account = rpc::get_token_account(self.inner.rpc(), &m.spt_mega)?; + let balances = match locked { + true => &m.balances[1], + false => &m.balances[0], + }; + let account = rpc::get_token_account(self.rpc(), &balances.spt_mega)?; Ok(ProgramAccount { - public_key: m.spt_mega, + public_key: balances.spt_mega, account, }) } - pub fn stake_pool_asset_vault(&self, registrar: &Pubkey) -> Result { - let r = self.registrar(registrar)?; - rpc::get_token_account::(self.inner.rpc(), &r.pool_vault).map_err(Into::into) + + pub fn stake_pool_asset_vault( + &self, + member: &Pubkey, + locked: bool, + ) -> Result { + let m = self.member(member)?; + let balances = match locked { + true => &m.balances[1], + false => &m.balances[0], + }; + rpc::get_token_account::(self.rpc(), &balances.vault_stake) + .map_err(Into::into) } - pub fn stake_mega_pool_asset_vaults( + pub fn stake_mega_pool_asset_vault( &self, - registrar: &Pubkey, + member: &Pubkey, + locked: bool, ) -> Result { - let r = self.registrar(registrar)?; - rpc::get_token_account::(self.inner.rpc(), &r.pool_vault_mega) + let m = self.member(member)?; + let balances = match locked { + true => &m.balances[1], + false => &m.balances[0], + }; + rpc::get_token_account::(self.rpc(), &balances.vault_stake_mega) + .map_err(Into::into) + } + + pub fn pending_withdrawal_vault( + &self, + member: &Pubkey, + locked: bool, + ) -> Result { + let m = self.member(member)?; + let balances = match locked { + true => &m.balances[1], + false => &m.balances[0], + }; + rpc::get_token_account::(self.rpc(), &balances.vault_pending_withdrawal) .map_err(Into::into) } pub fn pending_withdrawal(&self, pw: &Pubkey) -> Result { - rpc::get_account::(self.inner.rpc(), pw).map_err(Into::into) + rpc::get_account::(self.rpc(), pw).map_err(Into::into) } } @@ -609,22 +1034,92 @@ impl ClientGen for Client { } } +fn create_metadata_instructions( + client: &RpcClient, + payer: &Pubkey, + metadata: &Keypair, + mqueue: &Keypair, + program_id: &Pubkey, + entity: &Pubkey, + name: String, + about: String, + image_url: String, +) -> Vec { + let md = serum_meta_entity::accounts::Metadata { + initialized: false, + entity: Pubkey::new_from_array([0; 32]), + authority: *payer, + name: name.clone(), + about: about.clone(), + image_url: image_url.clone(), + chat: Pubkey::new_from_array([0; 32]), + }; + let metadata_size = md.size().unwrap(); + let lamports = client + .get_minimum_balance_for_rent_exemption(metadata_size as usize) + .unwrap(); + let create_metadata_instr = solana_sdk::system_instruction::create_account( + payer, + &metadata.pubkey(), + lamports, + metadata_size as u64, + program_id, + ); + + let mqueue_size = MQueue::buffer_size(MQueue::RING_CAPACITY); + let lamports = client + .get_minimum_balance_for_rent_exemption(mqueue_size) + .unwrap(); + let create_mqueue_instr = solana_sdk::system_instruction::create_account( + payer, + &mqueue.pubkey(), + lamports, + mqueue_size as u64, + program_id, + ); + + let initialize_metadata_instr = { + let accounts = vec![AccountMeta::new(metadata.pubkey(), false)]; + let instr = serum_meta_entity::instruction::MetaEntityInstruction::Initialize { + entity: *entity, + authority: *payer, + name, + about, + image_url, + chat: mqueue.pubkey(), + }; + let mut data = vec![0u8; instr.size().unwrap() as usize]; + serum_meta_entity::instruction::MetaEntityInstruction::pack(instr, &mut data).unwrap(); + Instruction { + program_id: *program_id, + accounts, + data, + } + }; + + vec![ + create_metadata_instr, + create_mqueue_instr, + initialize_metadata_instr, + ] +} + pub struct InitializeRequest { pub registrar_authority: Pubkey, pub withdrawal_timelock: i64, pub deactivation_timelock: i64, pub max_stake_per_entity: u64, + pub reward_activation_threshold: u64, pub mint: Pubkey, pub mega_mint: Pubkey, - pub reward_activation_threshold: u64, + pub stake_rate: u64, + pub stake_rate_mega: u64, } pub struct InitializeResponse { pub tx: Signature, pub registrar: Pubkey, pub reward_event_q: Pubkey, - pub pool_vault: Pubkey, - pub pool_vault_mega: Pubkey, pub nonce: u8, } @@ -673,6 +1168,7 @@ pub struct StakeRequest<'a> { pub registrar: Pubkey, pub pool_token_amount: u64, pub mega: bool, + pub balance_id: Pubkey, } pub struct StakeResponse { @@ -713,6 +1209,7 @@ pub struct StartStakeWithdrawalRequest<'a> { pub beneficiary: &'a Keypair, pub spt_amount: u64, pub mega: bool, + pub balance_id: Pubkey, } pub struct StartStakeWithdrawalResponse { @@ -753,3 +1250,14 @@ pub enum ClientError { #[error("Any error: {0}")] Any(#[from] anyhow::Error), } + +struct BalanceAccounts { + spt: Keypair, + spt_mega: Keypair, + vault: Keypair, + vault_mega: Keypair, + vault_stake: Keypair, + vault_stake_mega: Keypair, + vault_pw: Keypair, + vault_pw_mega: Keypair, +} diff --git a/registry/meta-entity/program/Cargo.lock b/registry/meta-entity/program/Cargo.lock index c924b71..8563aa9 100644 --- a/registry/meta-entity/program/Cargo.lock +++ b/registry/meta-entity/program/Cargo.lock @@ -37,7 +37,7 @@ version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "hermit-abi 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.80 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.81 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -53,11 +53,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "addr2line 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.80 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.81 (registry+https://github.com/rust-lang/crates.io-index)", "miniz_oxide 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "object 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-demangle 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.117 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.118 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -76,7 +76,7 @@ version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.117 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.118 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -123,7 +123,7 @@ version = "0.7.2" source = "git+https://github.com/project-serum/borsh?branch=serum#337732a185f052d5ee0424127b04b89d455ffa81" dependencies = [ "borsh-derive 0.7.2 (git+https://github.com/project-serum/borsh?branch=serum)", - "solana-sdk 1.4.13 (registry+https://github.com/rust-lang/crates.io-index)", + "solana-sdk 1.4.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -172,7 +172,7 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "feature-probe 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.117 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.118 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -229,7 +229,7 @@ name = "chrono" version = "0.4.19" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.80 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.81 (registry+https://github.com/rust-lang/crates.io-index)", "num-integer 0.1.44 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.44 (registry+https://github.com/rust-lang/crates.io-index)", @@ -354,7 +354,7 @@ name = "ed25519" version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.117 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.118 (registry+https://github.com/rust-lang/crates.io-index)", "signature 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -366,7 +366,7 @@ dependencies = [ "curve25519-dalek 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "ed25519 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.117 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.118 (registry+https://github.com/rust-lang/crates.io-index)", "sha2 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", "zeroize 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -511,7 +511,7 @@ name = "generic-array" version = "0.14.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.117 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.118 (registry+https://github.com/rust-lang/crates.io-index)", "typenum 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "version_check 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -522,7 +522,7 @@ version = "0.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.80 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.81 (registry+https://github.com/rust-lang/crates.io-index)", "wasi 0.9.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -560,7 +560,7 @@ name = "hermit-abi" version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.80 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.81 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -686,7 +686,7 @@ name = "iovec" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.80 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.81 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -712,7 +712,7 @@ name = "jobserver" version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.80 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.81 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -747,7 +747,7 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.80" +version = "0.2.81" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -801,7 +801,7 @@ name = "memmap" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.80 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.81 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -838,7 +838,7 @@ dependencies = [ [[package]] name = "mio" -version = "0.6.22" +version = "0.6.23" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", @@ -846,7 +846,7 @@ dependencies = [ "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.80 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.81 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", "miow 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", @@ -860,8 +860,8 @@ version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.80 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.22 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.81 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.23 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -881,7 +881,7 @@ version = "0.2.36" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.80 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.81 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -918,7 +918,7 @@ version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "hermit-abi 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.80 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.81 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -978,7 +978,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.80 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.81 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.57 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1116,7 +1116,7 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "getrandom 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.80 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.81 (registry+https://github.com/rust-lang/crates.io-index)", "rand_chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1199,8 +1199,8 @@ dependencies = [ "percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "pin-project-lite 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustls 0.18.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.117 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.59 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.118 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.60 (registry+https://github.com/rust-lang/crates.io-index)", "serde_urlencoded 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "tokio 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-rustls 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1220,7 +1220,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cc 1.0.49 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.80 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.81 (registry+https://github.com/rust-lang/crates.io-index)", "spin 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "untrusted 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "web-sys 0.3.46 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1296,10 +1296,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde" -version = "1.0.117" +version = "1.0.118" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde_derive 1.0.117 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.118 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1307,12 +1307,12 @@ name = "serde_bytes" version = "0.11.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.117 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.118 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "serde_derive" -version = "1.0.117" +version = "1.0.118" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1322,12 +1322,12 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.59" +version = "1.0.60" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "itoa 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "ryu 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.117 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.118 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1338,7 +1338,7 @@ dependencies = [ "form_urlencoded 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "itoa 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "ryu 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.117 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.118 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1347,8 +1347,8 @@ version = "0.1.0" dependencies = [ "arrayref 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "borsh 0.7.2 (git+https://github.com/project-serum/borsh?branch=serum)", - "serde 1.0.117 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-sdk 1.4.13 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.118 (registry+https://github.com/rust-lang/crates.io-index)", + "solana-sdk 1.4.14 (registry+https://github.com/rust-lang/crates.io-index)", "spl-token 2.0.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1372,8 +1372,8 @@ version = "0.1.0" dependencies = [ "serum-common 0.1.0", "serum-meta-entity 0.1.0", - "solana-program 1.4.13 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-sdk 1.4.13 (registry+https://github.com/rust-lang/crates.io-index)", + "solana-program 1.4.14 (registry+https://github.com/rust-lang/crates.io-index)", + "solana-sdk 1.4.14 (registry+https://github.com/rust-lang/crates.io-index)", "spl-token 2.0.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1423,7 +1423,7 @@ version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.80 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.81 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.57 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1434,13 +1434,13 @@ version = "0.1.0" dependencies = [ "bincode 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "serum-common 0.1.0", - "solana-sdk 1.4.13 (registry+https://github.com/rust-lang/crates.io-index)", + "solana-sdk 1.4.14 (registry+https://github.com/rust-lang/crates.io-index)", "thiserror 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "solana-crate-features" -version = "1.4.13" +version = "1.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "backtrace 0.3.55 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1450,11 +1450,11 @@ dependencies = [ "ed25519-dalek 1.0.0-pre.4 (registry+https://github.com/rust-lang/crates.io-index)", "either 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.80 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.81 (registry+https://github.com/rust-lang/crates.io-index)", "rand_chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "regex-syntax 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)", "reqwest 0.10.9 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.117 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.118 (registry+https://github.com/rust-lang/crates.io-index)", "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)", "syn 1.0.53 (registry+https://github.com/rust-lang/crates.io-index)", "tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1463,7 +1463,7 @@ dependencies = [ [[package]] name = "solana-frozen-abi" -version = "1.4.13" +version = "1.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bs58 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1472,17 +1472,17 @@ dependencies = [ "log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", "memmap 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.117 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.117 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.118 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.118 (registry+https://github.com/rust-lang/crates.io-index)", "sha2 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-frozen-abi-macro 1.4.13 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-logger 1.4.13 (registry+https://github.com/rust-lang/crates.io-index)", + "solana-frozen-abi-macro 1.4.14 (registry+https://github.com/rust-lang/crates.io-index)", + "solana-logger 1.4.14 (registry+https://github.com/rust-lang/crates.io-index)", "thiserror 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "solana-frozen-abi-macro" -version = "1.4.13" +version = "1.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1494,7 +1494,7 @@ dependencies = [ [[package]] name = "solana-logger" -version = "1.4.13" +version = "1.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1504,7 +1504,7 @@ dependencies = [ [[package]] name = "solana-program" -version = "1.4.13" +version = "1.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bincode 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1520,20 +1520,20 @@ dependencies = [ "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "rustversion 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.117 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.118 (registry+https://github.com/rust-lang/crates.io-index)", "serde_bytes 0.11.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.117 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.118 (registry+https://github.com/rust-lang/crates.io-index)", "sha2 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-frozen-abi 1.4.13 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-frozen-abi-macro 1.4.13 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-logger 1.4.13 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-sdk-macro 1.4.13 (registry+https://github.com/rust-lang/crates.io-index)", + "solana-frozen-abi 1.4.14 (registry+https://github.com/rust-lang/crates.io-index)", + "solana-frozen-abi-macro 1.4.14 (registry+https://github.com/rust-lang/crates.io-index)", + "solana-logger 1.4.14 (registry+https://github.com/rust-lang/crates.io-index)", + "solana-sdk-macro 1.4.14 (registry+https://github.com/rust-lang/crates.io-index)", "thiserror 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "solana-sdk" -version = "1.4.13" +version = "1.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "assert_matches 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1559,24 +1559,24 @@ dependencies = [ "rand_chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "rustversion 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.117 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.118 (registry+https://github.com/rust-lang/crates.io-index)", "serde_bytes 0.11.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.117 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.59 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.118 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.60 (registry+https://github.com/rust-lang/crates.io-index)", "sha2 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", "sha3 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-crate-features 1.4.13 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-frozen-abi 1.4.13 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-frozen-abi-macro 1.4.13 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-logger 1.4.13 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-program 1.4.13 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-sdk-macro 1.4.13 (registry+https://github.com/rust-lang/crates.io-index)", + "solana-crate-features 1.4.14 (registry+https://github.com/rust-lang/crates.io-index)", + "solana-frozen-abi 1.4.14 (registry+https://github.com/rust-lang/crates.io-index)", + "solana-frozen-abi-macro 1.4.14 (registry+https://github.com/rust-lang/crates.io-index)", + "solana-logger 1.4.14 (registry+https://github.com/rust-lang/crates.io-index)", + "solana-program 1.4.14 (registry+https://github.com/rust-lang/crates.io-index)", + "solana-sdk-macro 1.4.14 (registry+https://github.com/rust-lang/crates.io-index)", "thiserror 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "solana-sdk-macro" -version = "1.4.13" +version = "1.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bs58 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1601,7 +1601,7 @@ dependencies = [ "num-traits 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", "num_enum 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "remove_dir_all 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-sdk 1.4.13 (registry+https://github.com/rust-lang/crates.io-index)", + "solana-sdk 1.4.14 (registry+https://github.com/rust-lang/crates.io-index)", "thiserror 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1685,7 +1685,7 @@ name = "time" version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.80 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.81 (registry+https://github.com/rust-lang/crates.io-index)", "wasi 0.10.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1710,7 +1710,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.22 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.23 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.13.0 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-codec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-current-thread 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1737,7 +1737,7 @@ dependencies = [ "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 2.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.22 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.23 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.13.0 (registry+https://github.com/rust-lang/crates.io-index)", "pin-project-lite 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1800,7 +1800,7 @@ dependencies = [ "futures 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.22 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.23 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.13.0 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1837,7 +1837,7 @@ dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.22 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.23 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-reactor 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1877,7 +1877,7 @@ dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.22 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.23 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-codec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-reactor 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1891,9 +1891,9 @@ dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.80 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.81 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.22 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.23 (registry+https://github.com/rust-lang/crates.io-index)", "mio-uds 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-codec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1918,7 +1918,7 @@ name = "toml" version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.117 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.118 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2044,8 +2044,8 @@ version = "0.2.69" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.117 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.59 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.118 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.60 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-bindgen-macro 0.2.69 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2313,7 +2313,7 @@ dependencies = [ "checksum keccak 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "67c21572b4949434e4fc1e1978b99c5f77064153c59d998bf13ecd96fb5ecba7" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" "checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" -"checksum libc 0.2.80 (registry+https://github.com/rust-lang/crates.io-index)" = "4d58d1b70b004888f764dfbf6a26a3b0342a1632d33968e4a179d8011c760614" +"checksum libc 0.2.81 (registry+https://github.com/rust-lang/crates.io-index)" = "1482821306169ec4d07f6aca392a4681f66c75c9918aa49641a2595db64053cb" "checksum libsecp256k1 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "1fc1e2c808481a63dc6da2074752fdd4336a3c8fcc68b83db6f1fd5224ae7962" "checksum lock_api 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c4da24a77a3d8a6d4862d95f72e6fdb9c09a643ecdb402d754004a557f2bec75" "checksum log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)" = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b" @@ -2325,7 +2325,7 @@ dependencies = [ "checksum mime 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)" = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" "checksum mime_guess 2.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2684d4c2e97d99848d30b324b00c8fcc7e5c897b7cbb5819b09e7c90e8baf212" "checksum miniz_oxide 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0f2d26ec3309788e423cfbf68ad1800f061638098d76a83681af979dc4eda19d" -"checksum mio 0.6.22 (registry+https://github.com/rust-lang/crates.io-index)" = "fce347092656428bc8eaf6201042cb551b8d67855af7374542a92a0fbfcac430" +"checksum mio 0.6.23 (registry+https://github.com/rust-lang/crates.io-index)" = "4afd66f5b91bf2a3bc13fad0e21caedac168ca4c707504e75585648ae80e4cc4" "checksum mio-uds 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)" = "afcb699eb26d4332647cc848492bbc15eafb26f08d0304550d5aa1f612e066f0" "checksum miow 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ebd808424166322d4a38da87083bfddd3ac4c131334ed55856112eb06d46944d" "checksum net2 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)" = "d7cf75f38f16cb05ea017784dc6dbfd354f76c223dba37701734c4f5a9337d02" @@ -2379,10 +2379,10 @@ dependencies = [ "checksum sct 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e3042af939fca8c3453b7af0f1c66e533a15a86169e39de2657310ade8f98d3c" "checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" -"checksum serde 1.0.117 (registry+https://github.com/rust-lang/crates.io-index)" = "b88fa983de7720629c9387e9f517353ed404164b1e482c970a90c1a4aaf7dc1a" +"checksum serde 1.0.118 (registry+https://github.com/rust-lang/crates.io-index)" = "06c64263859d87aa2eb554587e2d23183398d617427327cf2b3d0ed8c69e4800" "checksum serde_bytes 0.11.5 (registry+https://github.com/rust-lang/crates.io-index)" = "16ae07dd2f88a366f15bd0632ba725227018c69a1c8550a927324f8eb8368bb9" -"checksum serde_derive 1.0.117 (registry+https://github.com/rust-lang/crates.io-index)" = "cbd1ae72adb44aab48f325a02444a5fc079349a8d804c1fc922aed3f7454c74e" -"checksum serde_json 1.0.59 (registry+https://github.com/rust-lang/crates.io-index)" = "dcac07dbffa1c65e7f816ab9eba78eb142c6d44410f4eeba1e26e4f5dfa56b95" +"checksum serde_derive 1.0.118 (registry+https://github.com/rust-lang/crates.io-index)" = "c84d3526699cd55261af4b941e4e725444df67aa4f9e6a3564f18030d12672df" +"checksum serde_json 1.0.60 (registry+https://github.com/rust-lang/crates.io-index)" = "1500e84d27fe482ed1dc791a56eddc2f230046a040fa908c08bda1d9fb615779" "checksum serde_urlencoded 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "edfa57a7f8d9c1d260a549e7224100f6c43d43f9103e06dd8b4095a9b2b43ce9" "checksum sha2 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a256f46ea78a0c0d9ff00077504903ac881a1dafdc20da66545699e7776b3e69" "checksum sha3 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f81199417d4e5de3f04b1e871023acea7389672c4135918f05aa9cbf2f2fa809" @@ -2390,13 +2390,13 @@ dependencies = [ "checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" "checksum smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "f7b0758c52e15a8b5e3691eae6cc559f08eee9406e548a4477ba4e67770a82b6" "checksum socket2 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)" = "2c29947abdee2a218277abeca306f25789c938e500ea5a9d4b12a5a504466902" -"checksum solana-crate-features 1.4.13 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4eb08ecfd2fd47ec6a2d7df75f1458df42a0c8ead7183d29e7783eefc14db2" -"checksum solana-frozen-abi 1.4.13 (registry+https://github.com/rust-lang/crates.io-index)" = "4045fd99e316de4adbb56e00fd77d33f967c2abdc2e7b55135fb6c62aeec66bf" -"checksum solana-frozen-abi-macro 1.4.13 (registry+https://github.com/rust-lang/crates.io-index)" = "7dd60ef025b6f0c6313eb6881a5404e7762a5ec2f5c7ed9619f7822497a75893" -"checksum solana-logger 1.4.13 (registry+https://github.com/rust-lang/crates.io-index)" = "7e7a3dea8ebbc7f9dbf14769de133698f4c8e5b6f5ef9f64413448fabf99b3b8" -"checksum solana-program 1.4.13 (registry+https://github.com/rust-lang/crates.io-index)" = "30cda72e46a55252daf389774c7bf20fa5fa33007ccfae0539232941d4dbd3c4" -"checksum solana-sdk 1.4.13 (registry+https://github.com/rust-lang/crates.io-index)" = "342803d2815702cb08f69337a757507680a5d0770c49400c305159f12adab153" -"checksum solana-sdk-macro 1.4.13 (registry+https://github.com/rust-lang/crates.io-index)" = "4ccc308a3cd4793dfc02fdccedd60a5aaba2b4909ae9bce36994dafaf90278a2" +"checksum solana-crate-features 1.4.14 (registry+https://github.com/rust-lang/crates.io-index)" = "dc73ada8cddc62edf58dc09ef3cf4551259d0ca1c7ece5f102757279ec2afa95" +"checksum solana-frozen-abi 1.4.14 (registry+https://github.com/rust-lang/crates.io-index)" = "9e5ab6ad3dda6a3d95d19603eeedc65689d8125eafb3e23c6a1e01ab8a6ba60c" +"checksum solana-frozen-abi-macro 1.4.14 (registry+https://github.com/rust-lang/crates.io-index)" = "ffaa09aa938a67501479ed8a785071c6993f72c34e43f680db3ea7a2dadad9e7" +"checksum solana-logger 1.4.14 (registry+https://github.com/rust-lang/crates.io-index)" = "0d949157d0b23eaf5758b427d90741d2a90751c4e3dfee028f5726ab8b36e769" +"checksum solana-program 1.4.14 (registry+https://github.com/rust-lang/crates.io-index)" = "8e9c6cb16e8aa986bc0d2af8ec50628f7451bef9dac89924adf48302bd4fc755" +"checksum solana-sdk 1.4.14 (registry+https://github.com/rust-lang/crates.io-index)" = "85c38a02d501422070cd6a4d561b4ab1408e311c5a0b5af3a7bb01246da14f66" +"checksum solana-sdk-macro 1.4.14 (registry+https://github.com/rust-lang/crates.io-index)" = "475a680cd175f2e256452e007c6f8622d3a1ab97ab36d26303b35576e24f340c" "checksum spin 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" "checksum spl-token 2.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "eaa27ab75067c63b8804d9fff30bd2e8bfb5be448bea8067ed768381e70ca181" "checksum subtle 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee" diff --git a/registry/meta-entity/program/src/lib.rs b/registry/meta-entity/program/src/lib.rs index c417b1b..ec44074 100644 --- a/registry/meta-entity/program/src/lib.rs +++ b/registry/meta-entity/program/src/lib.rs @@ -36,8 +36,8 @@ fn entry(program_id: &Pubkey, accounts: &[AccountInfo], instruction_data: &[u8]) chat, image_url, } => update::handler(program_id, accounts, name, about, image_url, chat), - MetaEntityInstruction::SendMessage { data } => { - send_message::handler(program_id, accounts, data) + MetaEntityInstruction::SendMessage { msg } => { + send_message::handler(program_id, accounts, msg) } }; diff --git a/registry/meta-entity/program/src/send_message.rs b/registry/meta-entity/program/src/send_message.rs index d6c08f1..494a049 100644 --- a/registry/meta-entity/program/src/send_message.rs +++ b/registry/meta-entity/program/src/send_message.rs @@ -1,4 +1,5 @@ -use serum_meta_entity::accounts::MQueue; +use serum_meta_entity::accounts::mqueue::Ring; +use serum_meta_entity::accounts::{MQueue, Message}; use serum_meta_entity::error::MetaEntityError; use solana_sdk::account_info::{next_account_info, AccountInfo}; use solana_sdk::info; @@ -7,7 +8,7 @@ use solana_sdk::pubkey::Pubkey; pub fn handler( _program_id: &Pubkey, accounts: &[AccountInfo], - data: Vec, + msg: Message, ) -> Result<(), MetaEntityError> { info!("handler: send_message"); let acc_infos = &mut accounts.iter(); @@ -15,7 +16,7 @@ pub fn handler( let mqueue_acc_info = next_account_info(acc_infos)?; let mqueue = MQueue::from(mqueue_acc_info.data.clone()); - mqueue.append(data)?; + mqueue.append(&msg)?; Ok(()) } diff --git a/registry/meta-entity/src/accounts/mod.rs b/registry/meta-entity/src/accounts/mod.rs index 2c8dd95..dd5e8e4 100644 --- a/registry/meta-entity/src/accounts/mod.rs +++ b/registry/meta-entity/src/accounts/mod.rs @@ -2,4 +2,4 @@ pub mod metadata; pub mod mqueue; pub use metadata::Metadata; -pub use mqueue::MQueue; +pub use mqueue::{MQueue, Message}; diff --git a/registry/meta-entity/src/accounts/mqueue.rs b/registry/meta-entity/src/accounts/mqueue.rs index f91f5cc..9084087 100644 --- a/registry/meta-entity/src/accounts/mqueue.rs +++ b/registry/meta-entity/src/accounts/mqueue.rs @@ -1,166 +1,39 @@ -use crate::error::{MetaEntityError, MetaEntityErrorCode}; -use arrayref::array_mut_ref; -use borsh::{BorshDeserialize, BorshSerialize}; +use borsh::{BorshDeserialize, BorshSchema, BorshSerialize}; use serum_common::pack::*; -use solana_client_gen::solana_sdk::account_info::AccountInfo; use solana_client_gen::solana_sdk::pubkey::Pubkey; -#[cfg(feature = "program")] -use solana_sdk::info; use std::cell::RefCell; -use std::convert::Into; use std::rc::Rc; -#[cfg(not(feature = "program"))] -macro_rules! info { - ($($i:expr),*) => { { ($($i),*) } }; -} +// Size of each entry in the ring buffer. +const RING_ITEM_SIZE: u32 = 320; -// TODO: make head and tail monotonically increasing instead of resetting at 0. +// Generate the Ring trait. +serum_common::ring!(RING_ITEM_SIZE); -// Message queue as ring buffer. -// -// Data layout: -// -// HEAD (u32) || TAIL (u32) || || || ... pub struct MQueue<'a> { pub storage: Rc>, } impl<'a> MQueue<'a> { - // Data storage index at which the messages start. - pub const MESSAGE_START: u32 = 8; - - // 280 + 32 + 8. - // - // Ends up being 236 chars wtih borsh overhead. - pub const MESSAGE_SIZE: u32 = 320; - - // Max number of messages in the queue before overwriting the tail. - pub const MAX_MESSAGES: u32 = 500; - - // Byte size of the entire account. - pub const SIZE: usize = (MQueue::MESSAGE_SIZE as usize * MQueue::MAX_MESSAGES as usize) - + MQueue::MESSAGE_START as usize; + pub const RING_CAPACITY: u32 = 500; pub fn from(storage: Rc>) -> Self { Self { storage } } +} - pub fn append(&self, mut data: Vec) -> Result<(), MetaEntityError> { - if data.len() > MQueue::MESSAGE_SIZE as usize { - return Err(MetaEntityErrorCode::InvalidMessageSize)?; - } - let head = self.head()?; - let tail = self.tail()?; +impl<'a> Ring<'a> for MQueue<'a> { + type Item = Message; - // Scope into a block so that the refcell is dropped. - { - let head_idx = (head * MQueue::MESSAGE_SIZE + MQueue::MESSAGE_START) as usize; - let mut acc_data = self.storage.borrow_mut(); - let dst = array_mut_ref![acc_data, head_idx, MQueue::MESSAGE_SIZE as usize]; - data.resize(MQueue::MESSAGE_SIZE as usize, 0); - dst.copy_from_slice(&data); - } - // If full, then move the tail as well. - if (head + 1) % MQueue::MAX_MESSAGES == tail { - self.increment_tail(); - } - self.increment_head(); - - Ok(()) + fn buffer(&self) -> Rc> { + self.storage.clone() } - - pub fn messages_rev(&self) -> Result, MetaEntityError> { - let data = self.storage.borrow(); - let head = self.head()?; - let tail = self.tail()?; - - // Empty. - if head == tail { - return Ok(vec![]); - } - - let mut msgs = vec![]; - let mut last = head; - while tail != last { - if last == 0 { - last = MQueue::MAX_MESSAGES - 1; - } else { - last -= 1; - } - - let start = (last * MQueue::MESSAGE_SIZE + MQueue::MESSAGE_START) as usize; - let end = start + MQueue::MESSAGE_SIZE as usize; - - let m = Message::unpack_unchecked(&mut &data[start..end])?; - msgs.push(m); - } - - Ok(msgs) - } - - pub fn message_at(&self, cursor: u32) -> Result { - let data = self.storage.borrow(); - let mut dst = [0u8; MQueue::MESSAGE_SIZE as usize]; - let start = (MQueue::MESSAGE_START + cursor * MQueue::MESSAGE_SIZE) as usize; - let end = start + MQueue::MESSAGE_SIZE as usize; - dst.copy_from_slice(&data[start..end]); - let mut dst_slice: &[u8] = &dst; - Message::unpack_unchecked(&mut dst_slice).map_err(Into::into) - } - - fn head(&self) -> Result { - let data = self.storage.borrow(); - let mut dst = [0u8; 4]; - dst.copy_from_slice(&data[..4]); - Ok(u32::from_le_bytes(dst)) - } - - fn tail(&self) -> Result { - let data = self.storage.borrow(); - let mut dst = [0u8; 4]; - dst.copy_from_slice(&data[4..8]); - Ok(u32::from_le_bytes(dst)) - } - - fn increment_head(&self) -> Result<(), MetaEntityError> { - let mut head = self.head()?; - if head == MQueue::MAX_MESSAGES - 1 { - head = 0; - } else { - head += 1; - } - self.set_head(head)?; - Ok(()) - } - - fn increment_tail(&self) -> Result<(), MetaEntityError> { - let mut tail = self.tail()?; - if tail == MQueue::MAX_MESSAGES - 1 { - tail = 0; - } else { - tail += 1; - } - self.set_tail(tail)?; - Ok(()) - } - - fn set_head(&self, head: u32) -> Result<(), MetaEntityError> { - let mut data = self.storage.borrow_mut(); - let dst = array_mut_ref![data, 0, 4]; - dst.copy_from_slice(&head.to_le_bytes()); - Ok(()) - } - - fn set_tail(&self, tail: u32) -> Result<(), MetaEntityError> { - let mut data = self.storage.borrow_mut(); - let dst = array_mut_ref![data, 4, 4]; - dst.copy_from_slice(&tail.to_le_bytes()); - Ok(()) + fn capacity(&self) -> u32 { + MQueue::RING_CAPACITY } } -#[derive(Debug, BorshSerialize, BorshDeserialize, PartialEq)] +#[derive(Debug, BorshSerialize, BorshDeserialize, BorshSchema, PartialEq)] pub struct Message { from: Pubkey, ts: i64, @@ -168,68 +41,3 @@ pub struct Message { } serum_common::packable!(Message); - -#[cfg(test)] -mod tests { - use super::*; - #[test] - fn mqueue() { - let mut data: &mut [u8] = &mut vec![0u8; MQueue::SIZE]; - let storage = Rc::new(RefCell::new(data)); - let mqueue = MQueue::from(storage); - let mut messages = vec![]; - - // First pass: fill the message queue. - for k in 0u32..MQueue::MAX_MESSAGES - 1 { - let m = Message { - from: Pubkey::new_rand(), - ts: k as i64, - content: "hello world".to_string(), - }; - mqueue.append(m.try_to_vec().unwrap()); - messages.insert(0, m); - - assert_eq!(mqueue.messages_rev().unwrap(), messages); - assert_eq!(mqueue.tail().unwrap(), 0); - assert_eq!(mqueue.head().unwrap(), k + 1); - } - - // Buffer is now full. Adding more will overwrite previous messages. - // Head is always one behind the tail now, so technically we waste - // a slot. - assert_eq!(mqueue.tail().unwrap(), 0); - assert_eq!(mqueue.head().unwrap(), MQueue::MAX_MESSAGES - 1); - - // Insert one to begin the wrap. - let m = Message { - from: Pubkey::new_rand(), - ts: 0, - content: "hello world".to_string(), - }; - mqueue.append(m.try_to_vec().unwrap()); - messages.pop(); - messages.insert(0, m); - assert_eq!(mqueue.messages_rev().unwrap(), messages); - assert_eq!(mqueue.tail().unwrap(), 1); - assert_eq!(mqueue.head().unwrap(), 0); - - // Do another pass, overwriting all previous messages. - for k in 0u32..MQueue::MAX_MESSAGES { - let m = Message { - from: Pubkey::new_rand(), - ts: k as i64, - content: "hello world".to_string(), - }; - mqueue.append(m.try_to_vec().unwrap()); - messages.pop(); - messages.insert(0, m); - assert_eq!(mqueue.messages_rev().unwrap(), messages); - assert_eq!(mqueue.tail().unwrap(), (k + 2) % MQueue::MAX_MESSAGES); - assert_eq!(mqueue.head().unwrap(), (k + 1) % MQueue::MAX_MESSAGES); - } - - // Back where we started. - assert_eq!(mqueue.tail().unwrap(), 1); - assert_eq!(mqueue.head().unwrap(), 0); - } -} diff --git a/registry/meta-entity/src/lib.rs b/registry/meta-entity/src/lib.rs index 200fed5..3d0f5af 100644 --- a/registry/meta-entity/src/lib.rs +++ b/registry/meta-entity/src/lib.rs @@ -28,7 +28,7 @@ pub mod instruction { chat: Option, }, SendMessage { - data: Vec, + msg: accounts::Message, }, } } diff --git a/registry/program/Cargo.lock b/registry/program/Cargo.lock index a714b6a..f5c432b 100644 --- a/registry/program/Cargo.lock +++ b/registry/program/Cargo.lock @@ -19,7 +19,7 @@ version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "hermit-abi 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.80 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.81 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -34,7 +34,7 @@ version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.117 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.118 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -62,7 +62,7 @@ version = "0.7.2" source = "git+https://github.com/project-serum/borsh?branch=serum#337732a185f052d5ee0424127b04b89d455ffa81" dependencies = [ "borsh-derive 0.7.2 (git+https://github.com/project-serum/borsh?branch=serum)", - "solana-sdk 1.4.13 (registry+https://github.com/rust-lang/crates.io-index)", + "solana-sdk 1.4.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -106,7 +106,7 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "feature-probe 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.117 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.118 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -208,7 +208,7 @@ name = "generic-array" version = "0.14.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.117 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.118 (registry+https://github.com/rust-lang/crates.io-index)", "typenum 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "version_check 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -219,7 +219,7 @@ version = "0.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.80 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.81 (registry+https://github.com/rust-lang/crates.io-index)", "wasi 0.9.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -228,7 +228,7 @@ name = "hermit-abi" version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.80 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.81 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -268,7 +268,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "libc" -version = "0.2.80" +version = "0.2.81" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -289,7 +289,7 @@ name = "memmap" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.80 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.81 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -385,7 +385,7 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "getrandom 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.80 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.81 (registry+https://github.com/rust-lang/crates.io-index)", "rand_chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -468,10 +468,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde" -version = "1.0.117" +version = "1.0.118" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde_derive 1.0.117 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.118 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -479,12 +479,12 @@ name = "serde_bytes" version = "0.11.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.117 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.118 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "serde_derive" -version = "1.0.117" +version = "1.0.118" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", @@ -498,8 +498,8 @@ version = "0.1.0" dependencies = [ "arrayref 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "borsh 0.7.2 (git+https://github.com/project-serum/borsh?branch=serum)", - "serde 1.0.117 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-sdk 1.4.13 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.118 (registry+https://github.com/rust-lang/crates.io-index)", + "solana-sdk 1.4.14 (registry+https://github.com/rust-lang/crates.io-index)", "spl-token 2.0.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -539,8 +539,8 @@ dependencies = [ "serum-common 0.1.0", "serum-lockup 0.1.0", "serum-registry 0.1.0", - "solana-program 1.4.13 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-sdk 1.4.13 (registry+https://github.com/rust-lang/crates.io-index)", + "solana-program 1.4.14 (registry+https://github.com/rust-lang/crates.io-index)", + "solana-sdk 1.4.14 (registry+https://github.com/rust-lang/crates.io-index)", "spl-token 2.0.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -561,13 +561,13 @@ version = "0.1.0" dependencies = [ "bincode 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "serum-common 0.1.0", - "solana-sdk 1.4.13 (registry+https://github.com/rust-lang/crates.io-index)", + "solana-sdk 1.4.14 (registry+https://github.com/rust-lang/crates.io-index)", "thiserror 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "solana-frozen-abi" -version = "1.4.13" +version = "1.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bs58 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -576,17 +576,17 @@ dependencies = [ "log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", "memmap 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.117 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.117 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.118 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.118 (registry+https://github.com/rust-lang/crates.io-index)", "sha2 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-frozen-abi-macro 1.4.13 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-logger 1.4.13 (registry+https://github.com/rust-lang/crates.io-index)", + "solana-frozen-abi-macro 1.4.14 (registry+https://github.com/rust-lang/crates.io-index)", + "solana-logger 1.4.14 (registry+https://github.com/rust-lang/crates.io-index)", "thiserror 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "solana-frozen-abi-macro" -version = "1.4.13" +version = "1.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -598,7 +598,7 @@ dependencies = [ [[package]] name = "solana-logger" -version = "1.4.13" +version = "1.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -608,7 +608,7 @@ dependencies = [ [[package]] name = "solana-program" -version = "1.4.13" +version = "1.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bincode 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -624,20 +624,20 @@ dependencies = [ "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "rustversion 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.117 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.118 (registry+https://github.com/rust-lang/crates.io-index)", "serde_bytes 0.11.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.117 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.118 (registry+https://github.com/rust-lang/crates.io-index)", "sha2 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-frozen-abi 1.4.13 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-frozen-abi-macro 1.4.13 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-logger 1.4.13 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-sdk-macro 1.4.13 (registry+https://github.com/rust-lang/crates.io-index)", + "solana-frozen-abi 1.4.14 (registry+https://github.com/rust-lang/crates.io-index)", + "solana-frozen-abi-macro 1.4.14 (registry+https://github.com/rust-lang/crates.io-index)", + "solana-logger 1.4.14 (registry+https://github.com/rust-lang/crates.io-index)", + "solana-sdk-macro 1.4.14 (registry+https://github.com/rust-lang/crates.io-index)", "thiserror 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "solana-sdk" -version = "1.4.13" +version = "1.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bincode 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -653,20 +653,20 @@ dependencies = [ "pbkdf2 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "rustversion 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.117 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.118 (registry+https://github.com/rust-lang/crates.io-index)", "serde_bytes 0.11.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.117 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.118 (registry+https://github.com/rust-lang/crates.io-index)", "sha2 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-frozen-abi 1.4.13 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-frozen-abi-macro 1.4.13 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-program 1.4.13 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-sdk-macro 1.4.13 (registry+https://github.com/rust-lang/crates.io-index)", + "solana-frozen-abi 1.4.14 (registry+https://github.com/rust-lang/crates.io-index)", + "solana-frozen-abi-macro 1.4.14 (registry+https://github.com/rust-lang/crates.io-index)", + "solana-program 1.4.14 (registry+https://github.com/rust-lang/crates.io-index)", + "solana-sdk-macro 1.4.14 (registry+https://github.com/rust-lang/crates.io-index)", "thiserror 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "solana-sdk-macro" -version = "1.4.13" +version = "1.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bs58 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -686,7 +686,7 @@ dependencies = [ "num-traits 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", "num_enum 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "remove_dir_all 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-sdk 1.4.13 (registry+https://github.com/rust-lang/crates.io-index)", + "solana-sdk 1.4.14 (registry+https://github.com/rust-lang/crates.io-index)", "thiserror 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -749,7 +749,7 @@ name = "toml" version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.117 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.118 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -839,7 +839,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum humantime 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f" "checksum itertools 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b" "checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" -"checksum libc 0.2.80 (registry+https://github.com/rust-lang/crates.io-index)" = "4d58d1b70b004888f764dfbf6a26a3b0342a1632d33968e4a179d8011c760614" +"checksum libc 0.2.81 (registry+https://github.com/rust-lang/crates.io-index)" = "1482821306169ec4d07f6aca392a4681f66c75c9918aa49641a2595db64053cb" "checksum log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)" = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b" "checksum memchr 2.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525" "checksum memmap 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6585fd95e7bb50d6cc31e20d4cf9afb4e2ba16c5846fc76793f11218da9c475b" @@ -865,16 +865,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum rustversion 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "cb5d2a036dc6d2d8fd16fde3498b04306e29bd193bf306a57427019b823d5acd" "checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" -"checksum serde 1.0.117 (registry+https://github.com/rust-lang/crates.io-index)" = "b88fa983de7720629c9387e9f517353ed404164b1e482c970a90c1a4aaf7dc1a" +"checksum serde 1.0.118 (registry+https://github.com/rust-lang/crates.io-index)" = "06c64263859d87aa2eb554587e2d23183398d617427327cf2b3d0ed8c69e4800" "checksum serde_bytes 0.11.5 (registry+https://github.com/rust-lang/crates.io-index)" = "16ae07dd2f88a366f15bd0632ba725227018c69a1c8550a927324f8eb8368bb9" -"checksum serde_derive 1.0.117 (registry+https://github.com/rust-lang/crates.io-index)" = "cbd1ae72adb44aab48f325a02444a5fc079349a8d804c1fc922aed3f7454c74e" +"checksum serde_derive 1.0.118 (registry+https://github.com/rust-lang/crates.io-index)" = "c84d3526699cd55261af4b941e4e725444df67aa4f9e6a3564f18030d12672df" "checksum sha2 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a256f46ea78a0c0d9ff00077504903ac881a1dafdc20da66545699e7776b3e69" -"checksum solana-frozen-abi 1.4.13 (registry+https://github.com/rust-lang/crates.io-index)" = "4045fd99e316de4adbb56e00fd77d33f967c2abdc2e7b55135fb6c62aeec66bf" -"checksum solana-frozen-abi-macro 1.4.13 (registry+https://github.com/rust-lang/crates.io-index)" = "7dd60ef025b6f0c6313eb6881a5404e7762a5ec2f5c7ed9619f7822497a75893" -"checksum solana-logger 1.4.13 (registry+https://github.com/rust-lang/crates.io-index)" = "7e7a3dea8ebbc7f9dbf14769de133698f4c8e5b6f5ef9f64413448fabf99b3b8" -"checksum solana-program 1.4.13 (registry+https://github.com/rust-lang/crates.io-index)" = "30cda72e46a55252daf389774c7bf20fa5fa33007ccfae0539232941d4dbd3c4" -"checksum solana-sdk 1.4.13 (registry+https://github.com/rust-lang/crates.io-index)" = "342803d2815702cb08f69337a757507680a5d0770c49400c305159f12adab153" -"checksum solana-sdk-macro 1.4.13 (registry+https://github.com/rust-lang/crates.io-index)" = "4ccc308a3cd4793dfc02fdccedd60a5aaba2b4909ae9bce36994dafaf90278a2" +"checksum solana-frozen-abi 1.4.14 (registry+https://github.com/rust-lang/crates.io-index)" = "9e5ab6ad3dda6a3d95d19603eeedc65689d8125eafb3e23c6a1e01ab8a6ba60c" +"checksum solana-frozen-abi-macro 1.4.14 (registry+https://github.com/rust-lang/crates.io-index)" = "ffaa09aa938a67501479ed8a785071c6993f72c34e43f680db3ea7a2dadad9e7" +"checksum solana-logger 1.4.14 (registry+https://github.com/rust-lang/crates.io-index)" = "0d949157d0b23eaf5758b427d90741d2a90751c4e3dfee028f5726ab8b36e769" +"checksum solana-program 1.4.14 (registry+https://github.com/rust-lang/crates.io-index)" = "8e9c6cb16e8aa986bc0d2af8ec50628f7451bef9dac89924adf48302bd4fc755" +"checksum solana-sdk 1.4.14 (registry+https://github.com/rust-lang/crates.io-index)" = "85c38a02d501422070cd6a4d561b4ab1408e311c5a0b5af3a7bb01246da14f66" +"checksum solana-sdk-macro 1.4.14 (registry+https://github.com/rust-lang/crates.io-index)" = "475a680cd175f2e256452e007c6f8622d3a1ab97ab36d26303b35576e24f340c" "checksum spl-token 2.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "eaa27ab75067c63b8804d9fff30bd2e8bfb5be448bea8067ed768381e70ca181" "checksum subtle 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee" "checksum subtle 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "343f3f510c2915908f155e94f17220b19ccfacf2a64a2a5d8004f2c3e311e7fd" diff --git a/registry/program/src/claim_locked_reward.rs b/registry/program/src/claim_locked_reward.rs index 61ec677..5ddc421 100644 --- a/registry/program/src/claim_locked_reward.rs +++ b/registry/program/src/claim_locked_reward.rs @@ -1,13 +1,14 @@ use serum_common::pack::Pack; use serum_lockup::instruction::LockupInstruction; use serum_registry::access_control; -use serum_registry::accounts::{EntityState, LockedRewardVendor, Member, Registrar}; +use serum_registry::accounts::{EntityState, LockedRewardVendor, Member}; use serum_registry::error::{RegistryError, RegistryErrorCode}; -use solana_program::info; +use solana_program::msg; use solana_sdk::account_info::{next_account_info, AccountInfo}; use solana_sdk::instruction::{AccountMeta, Instruction}; use solana_sdk::pubkey::Pubkey; use solana_sdk::sysvar; +use spl_token::state::Account as TokenAccount; #[inline(never)] pub fn handler( @@ -16,7 +17,7 @@ pub fn handler( cursor: u32, nonce: u8, ) -> Result<(), RegistryError> { - info!("handler: claim_locked_reward"); + msg!("handler: claim_locked_reward"); let acc_infos = &mut accounts.iter(); @@ -34,9 +35,15 @@ pub fn handler( let rent_acc_info = next_account_info(acc_infos)?; let clock_acc_info = next_account_info(acc_infos)?; + let mut spt_acc_infos = vec![]; + while acc_infos.len() > 0 { + spt_acc_infos.push(next_account_info(acc_infos)?); + } + let AccessControlResponse { - ref registrar, ref vendor, + ref spts, + ref clock, } = access_control(AccessControlRequest { program_id, registrar_acc_info, @@ -44,6 +51,8 @@ pub fn handler( member_acc_info, vendor_acc_info, cursor, + spt_acc_infos, + clock_acc_info, })?; Member::unpack_mut( @@ -54,7 +63,6 @@ pub fn handler( nonce, member, vendor, - registrar, registrar_acc_info, vendor_acc_info, vendor_vault_authority_acc_info, @@ -66,6 +74,8 @@ pub fn handler( token_program_acc_info, rent_acc_info, clock_acc_info, + clock, + spts, }) .map_err(Into::into) }, @@ -75,7 +85,7 @@ pub fn handler( } fn access_control(req: AccessControlRequest) -> Result { - info!("access-control: claim_locked_reward"); + msg!("access-control: claim_locked_reward"); let AccessControlRequest { program_id, @@ -84,12 +94,15 @@ fn access_control(req: AccessControlRequest) -> Result Result>()?; // ClaimLockedReward specific. // @@ -120,11 +150,15 @@ fn access_control(req: AccessControlRequest) -> Result Result<(), RegistryError> { - info!("state-transition: claim_locked_reward"); + msg!("state-transition: claim_locked_reward"); let StateTransitionRequest { cursor, @@ -133,7 +167,6 @@ fn state_transition(req: StateTransitionRequest) -> Result<(), RegistryError> { safe_acc_info, lockup_program_acc_info, vendor_vault_authority_acc_info, - registrar, registrar_acc_info, vendor_acc_info, vesting_acc_info, @@ -143,66 +176,73 @@ fn state_transition(req: StateTransitionRequest) -> Result<(), RegistryError> { rent_acc_info, clock_acc_info, nonce, + spts, + clock, } = req; // Create vesting account with proportion of the reward. - let spt = { - if vendor.pool == registrar.pool_vault { - member.balances.spt_amount - } else { - member.balances.spt_mega_amount - } - }; - let amount = spt + let spt_total = spts.iter().map(|a| a.amount).fold(0, |a, b| a + b); + let amount = spt_total .checked_div(vendor.pool_token_supply) .unwrap() .checked_mul(vendor.total) .unwrap(); - let ix = { - let instr = LockupInstruction::CreateVesting { - beneficiary: member.beneficiary, - end_ts: vendor.end_ts, - period_count: vendor.period_count, - deposit_amount: amount, - nonce, - }; - let mut data = vec![0u8; instr.size()? as usize]; - LockupInstruction::pack(instr, &mut data)?; - Instruction { - program_id: *lockup_program_acc_info.key, - accounts: vec![ - AccountMeta::new(*vesting_acc_info.key, false), - AccountMeta::new(vendor.vault, false), - AccountMeta::new_readonly(*vendor_vault_authority_acc_info.key, true), - AccountMeta::new(*vesting_vault_acc_info.key, false), - AccountMeta::new_readonly(*safe_acc_info.key, false), - AccountMeta::new_readonly(spl_token::ID, false), - AccountMeta::new_readonly(sysvar::rent::ID, false), - AccountMeta::new_readonly(sysvar::clock::ID, false), - ], - data, + // Lockup program requires the timestamp to be <= clock's timestamp. + // So update if the time has already passed. + let end_ts = { + if vendor.end_ts <= clock.unix_timestamp + 60 { + clock.unix_timestamp + 60 + } else { + vendor.end_ts } }; - let signer_seeds = &[ - registrar_acc_info.key.as_ref(), - vendor_acc_info.key.as_ref(), - &[vendor.nonce], - ]; - solana_sdk::program::invoke_signed( - &ix, - &[ - vesting_acc_info.clone(), - vendor_vault_acc_info.clone(), - vendor_vault_authority_acc_info.clone(), - vesting_vault_acc_info.clone(), - safe_acc_info.clone(), - token_program_acc_info.clone(), - rent_acc_info.clone(), - clock_acc_info.clone(), - lockup_program_acc_info.clone(), - ], - &[signer_seeds], - )?; + if amount > 0 { + let ix = { + let instr = LockupInstruction::CreateVesting { + beneficiary: member.beneficiary, + end_ts, + period_count: vendor.period_count, + deposit_amount: amount, + nonce, + }; + let mut data = vec![0u8; instr.size()? as usize]; + LockupInstruction::pack(instr, &mut data)?; + Instruction { + program_id: *lockup_program_acc_info.key, + accounts: vec![ + AccountMeta::new(*vesting_acc_info.key, false), + AccountMeta::new(vendor.vault, false), + AccountMeta::new_readonly(*vendor_vault_authority_acc_info.key, true), + AccountMeta::new(*vesting_vault_acc_info.key, false), + AccountMeta::new_readonly(*safe_acc_info.key, false), + AccountMeta::new_readonly(spl_token::ID, false), + AccountMeta::new_readonly(sysvar::rent::ID, false), + AccountMeta::new_readonly(sysvar::clock::ID, false), + ], + data, + } + }; + let signer_seeds = &[ + registrar_acc_info.key.as_ref(), + vendor_acc_info.key.as_ref(), + &[vendor.nonce], + ]; + solana_sdk::program::invoke_signed( + &ix, + &[ + vesting_acc_info.clone(), + vendor_vault_acc_info.clone(), + vendor_vault_authority_acc_info.clone(), + vesting_vault_acc_info.clone(), + safe_acc_info.clone(), + token_program_acc_info.clone(), + rent_acc_info.clone(), + clock_acc_info.clone(), + lockup_program_acc_info.clone(), + ], + &[signer_seeds], + )?; + } // Move member rewards cursor. member.rewards_cursor = cursor + 1; @@ -217,19 +257,22 @@ struct AccessControlRequest<'a, 'b> { member_acc_info: &'a AccountInfo<'b>, registrar_acc_info: &'a AccountInfo<'b>, vendor_acc_info: &'a AccountInfo<'b>, + spt_acc_infos: Vec<&'a AccountInfo<'b>>, + clock_acc_info: &'a AccountInfo<'b>, } struct AccessControlResponse { - registrar: Registrar, vendor: LockedRewardVendor, + spts: Vec, + clock: sysvar::clock::Clock, } struct StateTransitionRequest<'a, 'b, 'c> { cursor: u32, nonce: u8, + clock: &'c sysvar::clock::Clock, member: &'c mut Member, vendor: &'c LockedRewardVendor, - registrar: &'c Registrar, registrar_acc_info: &'a AccountInfo<'b>, vendor_acc_info: &'a AccountInfo<'b>, vendor_vault_authority_acc_info: &'a AccountInfo<'b>, @@ -241,4 +284,5 @@ struct StateTransitionRequest<'a, 'b, 'c> { token_program_acc_info: &'a AccountInfo<'b>, rent_acc_info: &'a AccountInfo<'b>, clock_acc_info: &'a AccountInfo<'b>, + spts: &'c [TokenAccount], } diff --git a/registry/program/src/claim_unlocked_reward.rs b/registry/program/src/claim_unlocked_reward.rs index dd7b27b..f806b65 100644 --- a/registry/program/src/claim_unlocked_reward.rs +++ b/registry/program/src/claim_unlocked_reward.rs @@ -1,11 +1,12 @@ use serum_common::pack::Pack; use serum_common::program::invoke_token_transfer; use serum_registry::access_control; -use serum_registry::accounts::{EntityState, Member, Registrar, UnlockedRewardVendor}; +use serum_registry::accounts::{EntityState, Member, UnlockedRewardVendor}; use serum_registry::error::{RegistryError, RegistryErrorCode}; -use solana_program::info; +use solana_program::msg; use solana_sdk::account_info::{next_account_info, AccountInfo}; use solana_sdk::pubkey::Pubkey; +use spl_token::state::Account as TokenAccount; #[inline(never)] pub fn handler( @@ -13,7 +14,7 @@ pub fn handler( accounts: &[AccountInfo], cursor: u32, ) -> Result<(), RegistryError> { - info!("handler: claim_unlocked_reward"); + msg!("handler: claim_unlocked_reward"); let acc_infos = &mut accounts.iter(); @@ -26,9 +27,14 @@ pub fn handler( let token_acc_info = next_account_info(acc_infos)?; let token_program_acc_info = next_account_info(acc_infos)?; + let mut spt_acc_infos = vec![]; + while acc_infos.len() > 0 { + spt_acc_infos.push(next_account_info(acc_infos)?); + } + let AccessControlResponse { - ref registrar, ref vendor, + ref spts, } = access_control(AccessControlRequest { program_id, registrar_acc_info, @@ -37,6 +43,7 @@ pub fn handler( vendor_acc_info, token_acc_info, cursor, + spt_acc_infos, })?; Member::unpack_mut( @@ -46,13 +53,13 @@ pub fn handler( cursor, member, vendor, - registrar, registrar_acc_info, vendor_acc_info, vendor_vault_authority_acc_info, vendor_vault_acc_info, token_acc_info, token_program_acc_info, + spts, }) .map_err(Into::into) }, @@ -62,7 +69,7 @@ pub fn handler( } fn access_control(req: AccessControlRequest) -> Result { - info!("access-control: claim_unlocked_reward"); + msg!("access-control: claim_unlocked_reward"); let AccessControlRequest { program_id, @@ -72,6 +79,7 @@ fn access_control(req: AccessControlRequest) -> Result Result>()?; // ClaimLockedReward specific. // @@ -110,34 +135,28 @@ fn access_control(req: AccessControlRequest) -> Result Result<(), RegistryError> { - info!("state-transition: claim_unlocked_reward"); + msg!("state-transition: claim_unlocked_reward"); let StateTransitionRequest { cursor, member, vendor, token_acc_info, - registrar, registrar_acc_info, vendor_acc_info, vendor_vault_acc_info, vendor_vault_authority_acc_info, token_program_acc_info, + spts, } = req; // Transfer proportion of the reward to the user. - let spt = { - if vendor.pool == registrar.pool_vault { - member.balances.spt_amount - } else { - member.balances.spt_mega_amount - } - }; - let amount = spt + let spt_total = spts.iter().map(|a| a.amount).fold(0, |a, b| a + b); + let amount = spt_total .checked_div(vendor.pool_token_supply) .unwrap() .checked_mul(vendor.total) @@ -171,18 +190,19 @@ struct AccessControlRequest<'a, 'b> { registrar_acc_info: &'a AccountInfo<'b>, vendor_acc_info: &'a AccountInfo<'b>, token_acc_info: &'a AccountInfo<'b>, + spt_acc_infos: Vec<&'a AccountInfo<'b>>, } struct AccessControlResponse { vendor: UnlockedRewardVendor, - registrar: Registrar, + spts: Vec, } struct StateTransitionRequest<'a, 'b, 'c> { cursor: u32, member: &'c mut Member, vendor: &'c UnlockedRewardVendor, - registrar: &'c Registrar, + spts: &'c [TokenAccount], registrar_acc_info: &'a AccountInfo<'b>, vendor_acc_info: &'a AccountInfo<'b>, vendor_vault_authority_acc_info: &'a AccountInfo<'b>, diff --git a/registry/program/src/common/entity.rs b/registry/program/src/common/entity.rs index 05f3711..ec9a93b 100644 --- a/registry/program/src/common/entity.rs +++ b/registry/program/src/common/entity.rs @@ -31,7 +31,7 @@ where &mut entity_acc_info.try_borrow_mut_data()?, &mut |entity: &mut Entity| { let clock = access_control::clock(&clock_acc_info)?; - let registrar = access_control::registrar(®istrar_acc_info, program_id)?; + let registrar = access_control::registrar(registrar_acc_info, program_id)?; let _ = access_control::entity_check( entity, entity_acc_info, diff --git a/registry/program/src/create_entity.rs b/registry/program/src/create_entity.rs index b49f0b5..cf5b974 100644 --- a/registry/program/src/create_entity.rs +++ b/registry/program/src/create_entity.rs @@ -2,7 +2,7 @@ use serum_common::pack::Pack; use serum_registry::access_control; use serum_registry::accounts::{Entity, EntityState}; use serum_registry::error::{RegistryError, RegistryErrorCode}; -use solana_program::info; +use solana_program::msg; use solana_sdk::account_info::{next_account_info, AccountInfo}; use solana_sdk::pubkey::Pubkey; @@ -12,18 +12,18 @@ pub fn handler( accounts: &[AccountInfo], metadata: Pubkey, ) -> Result<(), RegistryError> { - info!("handler: create_entity"); + msg!("handler: create_entity"); let acc_infos = &mut accounts.iter(); let entity_acc_info = next_account_info(acc_infos)?; - let entity_leader_acc_info = next_account_info(acc_infos)?; + let leader_acc_info = next_account_info(acc_infos)?; let registrar_acc_info = next_account_info(acc_infos)?; let rent_acc_info = next_account_info(acc_infos)?; access_control(AccessControlRequest { entity_acc_info, - entity_leader_acc_info, + leader_acc_info, registrar_acc_info, rent_acc_info, program_id, @@ -33,10 +33,10 @@ pub fn handler( &mut entity_acc_info.try_borrow_mut_data()?, &mut |entity: &mut Entity| { state_transition(StateTransitionRequest { - leader: entity_leader_acc_info.key, entity, - registrar_acc_info, metadata, + leader_acc_info, + registrar_acc_info, }) .map_err(Into::into) }, @@ -46,18 +46,18 @@ pub fn handler( } fn access_control(req: AccessControlRequest) -> Result<(), RegistryError> { - info!("access-control: create_entity"); + msg!("access-control: create_entity"); let AccessControlRequest { entity_acc_info, - entity_leader_acc_info, + leader_acc_info, registrar_acc_info, rent_acc_info, program_id, } = req; // Node leader authorization. - if !entity_leader_acc_info.is_signer { + if !leader_acc_info.is_signer { return Err(RegistryErrorCode::Unauthorized)?; } @@ -85,18 +85,18 @@ fn access_control(req: AccessControlRequest) -> Result<(), RegistryError> { #[inline(always)] fn state_transition(req: StateTransitionRequest) -> Result<(), RegistryError> { - info!("state-transition: create_entity"); + msg!("state-transition: create_entity"); let StateTransitionRequest { entity, - leader, + leader_acc_info, registrar_acc_info, metadata, } = req; entity.initialized = true; entity.registrar = *registrar_acc_info.key; - entity.leader = *leader; + entity.leader = *leader_acc_info.key; entity.balances = Default::default(); entity.state = EntityState::Inactive; entity.metadata = metadata; @@ -106,7 +106,7 @@ fn state_transition(req: StateTransitionRequest) -> Result<(), RegistryError> { struct AccessControlRequest<'a, 'b> { entity_acc_info: &'a AccountInfo<'b>, - entity_leader_acc_info: &'a AccountInfo<'b>, + leader_acc_info: &'a AccountInfo<'b>, rent_acc_info: &'a AccountInfo<'b>, registrar_acc_info: &'a AccountInfo<'b>, program_id: &'a Pubkey, @@ -114,7 +114,7 @@ struct AccessControlRequest<'a, 'b> { struct StateTransitionRequest<'a, 'b, 'c> { registrar_acc_info: &'a AccountInfo<'b>, - leader: &'a Pubkey, + leader_acc_info: &'a AccountInfo<'b>, entity: &'c mut Entity, metadata: Pubkey, } diff --git a/registry/program/src/create_member.rs b/registry/program/src/create_member.rs index a1c51bc..ebd7423 100644 --- a/registry/program/src/create_member.rs +++ b/registry/program/src/create_member.rs @@ -1,22 +1,15 @@ use serum_common::pack::Pack; -use serum_registry::access_control; -use serum_registry::accounts::{vault, Member, MemberBalances, Registrar}; +use serum_registry::access_control::{self, BalanceSandboxAccInfo}; +use serum_registry::accounts::{vault, BalanceSandbox, Member, Registrar}; use serum_registry::error::{RegistryError, RegistryErrorCode}; -use solana_program::info; +use solana_program::msg; use solana_sdk::account_info::{next_account_info, AccountInfo}; -use solana_sdk::program_option::COption; -use solana_sdk::program_pack::Pack as TokenPack; use solana_sdk::pubkey::Pubkey; use spl_token::instruction as token_instruction; -use spl_token::state::Account as TokenAccount; #[inline(never)] -pub fn handler( - program_id: &Pubkey, - accounts: &[AccountInfo], - delegate: Pubkey, -) -> Result<(), RegistryError> { - info!("handler: create_member"); +pub fn handler(program_id: &Pubkey, accounts: &[AccountInfo]) -> Result<(), RegistryError> { + msg!("handler: create_member"); let acc_infos = &mut accounts.iter(); @@ -25,12 +18,24 @@ pub fn handler( let entity_acc_info = next_account_info(acc_infos)?; let registrar_acc_info = next_account_info(acc_infos)?; let registry_signer_acc_info = next_account_info(acc_infos)?; - let spt_acc_info = next_account_info(acc_infos)?; - let spt_mega_acc_info = next_account_info(acc_infos)?; let token_program_acc_info = next_account_info(acc_infos)?; let rent_acc_info = next_account_info(acc_infos)?; + let mut balances = vec![]; + while acc_infos.len() > 0 { + balances.push(BalanceSandboxAccInfo { + owner_acc_info: next_account_info(acc_infos)?, + spt_acc_info: next_account_info(acc_infos)?, + spt_mega_acc_info: next_account_info(acc_infos)?, + vault_acc_info: next_account_info(acc_infos)?, + vault_mega_acc_info: next_account_info(acc_infos)?, + vault_stake_acc_info: next_account_info(acc_infos)?, + vault_stake_mega_acc_info: next_account_info(acc_infos)?, + vault_pw_acc_info: next_account_info(acc_infos)?, + vault_pw_mega_acc_info: next_account_info(acc_infos)?, + }) + } - let AccessControlResponse { registrar } = access_control(AccessControlRequest { + let AccessControlResponse { ref registrar } = access_control(AccessControlRequest { beneficiary_acc_info, member_acc_info, entity_acc_info, @@ -38,24 +43,20 @@ pub fn handler( registry_signer_acc_info, rent_acc_info, program_id, - spt_acc_info, - spt_mega_acc_info, + balances: &balances, })?; - Member::unpack_unchecked_mut( &mut member_acc_info.try_borrow_mut_data()?, &mut |member: &mut Member| { state_transition(StateTransitionRequest { beneficiary_acc_info, member, - delegate, entity_acc_info, registrar_acc_info, - registrar: ®istrar, + registrar, registry_signer_acc_info, - spt_acc_info, - spt_mega_acc_info, token_program_acc_info, + balances: &balances, }) .map_err(Into::into) }, @@ -66,7 +67,7 @@ pub fn handler( #[inline(never)] fn access_control(req: AccessControlRequest) -> Result { - info!("access-control: create_member"); + msg!("access-control: create_member"); let AccessControlRequest { beneficiary_acc_info, @@ -76,8 +77,7 @@ fn access_control(req: AccessControlRequest) -> Result Result Result Result<(), RegistryError> { - info!("state-transition: create_member"); + msg!("state-transition: create_member"); let StateTransitionRequest { beneficiary_acc_info, member, - delegate, entity_acc_info, registrar_acc_info, registrar, registry_signer_acc_info, - spt_acc_info, - spt_mega_acc_info, token_program_acc_info, + balances, } = req; - approve_delegate( - beneficiary_acc_info, - token_program_acc_info, - registrar_acc_info, - registrar, - registry_signer_acc_info, - spt_acc_info, - )?; - - approve_delegate( - beneficiary_acc_info, - token_program_acc_info, - registrar_acc_info, - registrar, - registry_signer_acc_info, - spt_mega_acc_info, - )?; - member.initialized = true; member.registrar = *registrar_acc_info.key; member.entity = *entity_acc_info.key; member.beneficiary = *beneficiary_acc_info.key; - member.balances = MemberBalances::new(*beneficiary_acc_info.key, delegate); - member.spt = *spt_acc_info.key; - member.spt_mega = *spt_mega_acc_info.key; + member.balances = balances + .iter() + .map(|b| { + approve_delegate( + beneficiary_acc_info, + token_program_acc_info, + registrar_acc_info, + registrar, + registry_signer_acc_info, + b.spt_acc_info, + )?; + approve_delegate( + beneficiary_acc_info, + token_program_acc_info, + registrar_acc_info, + registrar, + registry_signer_acc_info, + b.spt_mega_acc_info, + )?; + Ok(BalanceSandbox { + owner: *b.owner_acc_info.key, + spt: *b.spt_acc_info.key, + spt_mega: *b.spt_mega_acc_info.key, + vault: *b.vault_acc_info.key, + vault_mega: *b.vault_mega_acc_info.key, + vault_stake: *b.vault_stake_acc_info.key, + vault_stake_mega: *b.vault_stake_mega_acc_info.key, + vault_pending_withdrawal: *b.vault_pw_acc_info.key, + vault_pending_withdrawal_mega: *b.vault_pw_mega_acc_info.key, + }) + }) + .collect::, RegistryError>>()?; Ok(()) } @@ -184,11 +185,11 @@ fn approve_delegate<'a, 'b, 'c>( registrar_acc_info: &'a AccountInfo<'b>, registrar: &'c Registrar, registry_signer_acc_info: &'a AccountInfo<'b>, - spt_acc_info: &'a AccountInfo<'b>, + member_spt_acc_info: &'a AccountInfo<'b>, ) -> Result<(), RegistryError> { let approve_instr = token_instruction::approve( &spl_token::ID, - spt_acc_info.key, + member_spt_acc_info.key, &beneficiary_acc_info.key, registry_signer_acc_info.key, &[], @@ -197,7 +198,7 @@ fn approve_delegate<'a, 'b, 'c>( solana_sdk::program::invoke_signed( &approve_instr, &[ - spt_acc_info.clone(), + member_spt_acc_info.clone(), beneficiary_acc_info.clone(), registry_signer_acc_info.clone(), token_program_acc_info.clone(), @@ -211,16 +212,15 @@ fn approve_delegate<'a, 'b, 'c>( Ok(()) } -struct AccessControlRequest<'a, 'b> { - beneficiary_acc_info: &'a AccountInfo<'b>, +struct AccessControlRequest<'a, 'b, 'c> { member_acc_info: &'a AccountInfo<'b>, + beneficiary_acc_info: &'a AccountInfo<'b>, entity_acc_info: &'a AccountInfo<'b>, registrar_acc_info: &'a AccountInfo<'b>, registry_signer_acc_info: &'a AccountInfo<'b>, rent_acc_info: &'a AccountInfo<'b>, - spt_acc_info: &'a AccountInfo<'b>, - spt_mega_acc_info: &'a AccountInfo<'b>, program_id: &'a Pubkey, + balances: &'c [BalanceSandboxAccInfo<'a, 'b>], } struct AccessControlResponse { @@ -231,11 +231,9 @@ struct StateTransitionRequest<'a, 'b, 'c> { beneficiary_acc_info: &'a AccountInfo<'b>, registrar_acc_info: &'a AccountInfo<'b>, entity_acc_info: &'a AccountInfo<'b>, - spt_acc_info: &'a AccountInfo<'b>, - spt_mega_acc_info: &'a AccountInfo<'b>, registry_signer_acc_info: &'a AccountInfo<'b>, token_program_acc_info: &'a AccountInfo<'b>, registrar: &'c Registrar, member: &'c mut Member, - delegate: Pubkey, + balances: &'c [BalanceSandboxAccInfo<'a, 'b>], } diff --git a/registry/program/src/deposit.rs b/registry/program/src/deposit.rs index 79ad2bd..3257193 100644 --- a/registry/program/src/deposit.rs +++ b/registry/program/src/deposit.rs @@ -1,23 +1,17 @@ -use crate::common::entity::{with_entity, EntityContext}; -use serum_common::pack::Pack; use serum_common::program::invoke_token_transfer; use serum_registry::access_control; -use serum_registry::accounts::{Entity, Member, Registrar}; use serum_registry::error::{RegistryError, RegistryErrorCode}; -use solana_program::info; +use solana_program::msg; use solana_sdk::account_info::{next_account_info, AccountInfo}; use solana_sdk::pubkey::Pubkey; -use solana_sdk::sysvar::clock::Clock; -use spl_token::state::Account as TokenAccount; #[inline(never)] pub fn handler( program_id: &Pubkey, accounts: &[AccountInfo], amount: u64, - delegate: bool, ) -> Result<(), RegistryError> { - info!("handler: deposit"); + msg!("handler: deposit"); let acc_infos = &mut accounts.iter(); @@ -25,64 +19,39 @@ pub fn handler( let depositor_acc_info = next_account_info(acc_infos)?; let depositor_authority_acc_info = next_account_info(acc_infos)?; let token_program_acc_info = next_account_info(acc_infos)?; - let vault_acc_info = next_account_info(acc_infos)?; - let vault_authority_acc_info = next_account_info(acc_infos)?; + let member_vault_acc_info = next_account_info(acc_infos)?; + let member_vault_authority_acc_info = next_account_info(acc_infos)?; // Program specfic. let member_acc_info = next_account_info(acc_infos)?; let beneficiary_acc_info = next_account_info(acc_infos)?; let entity_acc_info = next_account_info(acc_infos)?; let registrar_acc_info = next_account_info(acc_infos)?; - let clock_acc_info = next_account_info(acc_infos)?; - let ctx = EntityContext { - registrar_acc_info, + access_control(AccessControlRequest { + depositor_authority_acc_info, + depositor_acc_info, + member_acc_info, + beneficiary_acc_info, entity_acc_info, - clock_acc_info, + member_vault_acc_info, + member_vault_authority_acc_info, program_id, - }; - with_entity(ctx, &mut |entity: &mut Entity, - registrar: &Registrar, - _: &Clock| { - let AccessControlResponse { depositor } = access_control(AccessControlRequest { - depositor_authority_acc_info, - depositor_acc_info, - member_acc_info, - beneficiary_acc_info, - entity_acc_info, - vault_acc_info, - vault_authority_acc_info, - program_id, - registrar_acc_info, - registrar, - delegate, - })?; - - Member::unpack_mut( - &mut member_acc_info.try_borrow_mut_data()?, - &mut |member: &mut Member| { - state_transition(StateTransitionRequest { - entity, - member, - amount, - depositor_authority_acc_info, - depositor_acc_info, - depositor, - token_program_acc_info, - registrar, - vault_acc_info, - }) - .map_err(Into::into) - }, - ) - .map_err(Into::into) + registrar_acc_info, + })?; + state_transition(StateTransitionRequest { + amount, + depositor_authority_acc_info, + depositor_acc_info, + token_program_acc_info, + member_vault_acc_info, })?; Ok(()) } -fn access_control(req: AccessControlRequest) -> Result { - info!("access-control: deposit"); +fn access_control(req: AccessControlRequest) -> Result<(), RegistryError> { + msg!("access-control: deposit"); let AccessControlRequest { depositor_authority_acc_info, @@ -90,12 +59,10 @@ fn access_control(req: AccessControlRequest) -> Result Result Result<(), RegistryError> { - info!("state-transition: deposit"); + msg!("state-transition: deposit"); let StateTransitionRequest { - entity, - member, amount, depositor_authority_acc_info, depositor_acc_info, - depositor, - vault_acc_info, + member_vault_acc_info, token_program_acc_info, - registrar, } = req; - // Transfer tokens. + // Transfer tokens in. invoke_token_transfer( depositor_acc_info, - vault_acc_info, + member_vault_acc_info, depositor_authority_acc_info, token_program_acc_info, &[], amount, )?; - // Bookkeeping. - let is_mega = registrar.is_mega(*vault_acc_info.key)?; - member.did_deposit(amount, is_mega, depositor.owner); - entity.did_deposit(amount, is_mega); - Ok(()) } -struct AccessControlRequest<'a, 'b, 'c> { +struct AccessControlRequest<'a, 'b> { depositor_authority_acc_info: &'a AccountInfo<'b>, depositor_acc_info: &'a AccountInfo<'b>, member_acc_info: &'a AccountInfo<'b>, beneficiary_acc_info: &'a AccountInfo<'b>, entity_acc_info: &'a AccountInfo<'b>, - vault_acc_info: &'a AccountInfo<'b>, registrar_acc_info: &'a AccountInfo<'b>, - vault_authority_acc_info: &'a AccountInfo<'b>, + member_vault_acc_info: &'a AccountInfo<'b>, + member_vault_authority_acc_info: &'a AccountInfo<'b>, program_id: &'a Pubkey, - registrar: &'c Registrar, - delegate: bool, } -struct AccessControlResponse { - depositor: TokenAccount, -} - -struct StateTransitionRequest<'a, 'b, 'c> { - vault_acc_info: &'a AccountInfo<'b>, +struct StateTransitionRequest<'a, 'b> { + member_vault_acc_info: &'a AccountInfo<'b>, depositor_authority_acc_info: &'a AccountInfo<'b>, depositor_acc_info: &'a AccountInfo<'b>, token_program_acc_info: &'a AccountInfo<'b>, - registrar: &'c Registrar, - entity: &'c mut Entity, - member: &'c mut Member, - depositor: TokenAccount, amount: u64, } diff --git a/registry/program/src/drop_locked_reward.rs b/registry/program/src/drop_locked_reward.rs index e084312..5d6fd52 100644 --- a/registry/program/src/drop_locked_reward.rs +++ b/registry/program/src/drop_locked_reward.rs @@ -4,7 +4,7 @@ use serum_registry::access_control; use serum_registry::accounts::reward_queue::Ring; use serum_registry::accounts::{LockedRewardVendor, RewardEvent, RewardEventQueue}; use serum_registry::error::{RegistryError, RegistryErrorCode}; -use solana_program::info; +use solana_program::msg; use solana_sdk::account_info::next_account_info; use solana_sdk::account_info::AccountInfo; use solana_sdk::program_pack::Pack as TokenPack; @@ -24,7 +24,7 @@ pub fn handler( period_count: u64, nonce: u8, ) -> Result<(), RegistryError> { - info!("handler: drop_locked_reward"); + msg!("handler: drop_locked_reward"); let acc_infos = &mut accounts.iter(); @@ -32,21 +32,19 @@ pub fn handler( let registrar_acc_info = next_account_info(acc_infos)?; let depositor_acc_info = next_account_info(acc_infos)?; let depositor_owner_acc_info = next_account_info(acc_infos)?; - let pool_vault_acc_info = next_account_info(acc_infos)?; - let pool_token_mint_acc_info = next_account_info(acc_infos)?; + let pool_mint_acc_info = next_account_info(acc_infos)?; let vendor_acc_info = next_account_info(acc_infos)?; let vendor_vault_acc_info = next_account_info(acc_infos)?; let token_program_acc_info = next_account_info(acc_infos)?; let clock_acc_info = next_account_info(acc_infos)?; let AccessControlResponse { - pool_token_mint, + pool_mint, ref clock, } = access_control(AccessControlRequest { program_id, registrar_acc_info, - pool_vault_acc_info, - pool_token_mint_acc_info, + pool_mint_acc_info, vendor_acc_info, vendor_vault_acc_info, clock_acc_info, @@ -70,11 +68,11 @@ pub fn handler( vendor_vault_acc_info, reward_event_q_acc_info, registrar_acc_info, - pool_vault_acc_info, depositor_acc_info, depositor_owner_acc_info, token_program_acc_info, - pool_token_mint, + pool_mint, + pool_mint_acc_info, clock, period_count, }) @@ -86,13 +84,12 @@ pub fn handler( } fn access_control(req: AccessControlRequest) -> Result { - info!("access-control: drop_locked_reward"); + msg!("access-control: drop_locked_reward"); let AccessControlRequest { program_id, registrar_acc_info, - pool_vault_acc_info, - pool_token_mint_acc_info, + pool_mint_acc_info, vendor_acc_info, vendor_vault_acc_info, clock_acc_info, @@ -109,28 +106,13 @@ fn access_control(req: AccessControlRequest) -> Result Result Result<(), RegistryError> { - info!("state-transition: drop_locked_reward"); + msg!("state-transition: drop_locked_reward"); let StateTransitionRequest { nonce, @@ -178,11 +157,11 @@ fn state_transition(req: StateTransitionRequest) -> Result<(), RegistryError> { vendor_vault_acc_info, reward_event_q_acc_info, registrar_acc_info, - pool_vault_acc_info, depositor_acc_info, depositor_owner_acc_info, token_program_acc_info, - pool_token_mint, + pool_mint, + pool_mint_acc_info, clock, period_count, end_ts, @@ -198,7 +177,7 @@ fn state_transition(req: StateTransitionRequest) -> Result<(), RegistryError> { let cursor = reward_event_q.head_cursor()?; reward_event_q.append(&RewardEvent::LockedAlloc { from: *depositor_owner_acc_info.key, - pool: *pool_vault_acc_info.key, + pool: *pool_mint_acc_info.key, total, vendor: *vendor_acc_info.key, mint, @@ -219,8 +198,8 @@ fn state_transition(req: StateTransitionRequest) -> Result<(), RegistryError> { vendor.registrar = *registrar_acc_info.key; vendor.vault = *vendor_vault_acc_info.key; vendor.nonce = nonce; - vendor.pool = *pool_vault_acc_info.key; - vendor.pool_token_supply = pool_token_mint.supply; + vendor.pool = *pool_mint_acc_info.key; + vendor.pool_token_supply = pool_mint.supply; vendor.reward_event_q_cursor = cursor; vendor.start_ts = clock.unix_timestamp; vendor.end_ts = end_ts; @@ -235,8 +214,7 @@ fn state_transition(req: StateTransitionRequest) -> Result<(), RegistryError> { struct AccessControlRequest<'a, 'b> { program_id: &'a Pubkey, registrar_acc_info: &'a AccountInfo<'b>, - pool_vault_acc_info: &'a AccountInfo<'b>, - pool_token_mint_acc_info: &'a AccountInfo<'b>, + pool_mint_acc_info: &'a AccountInfo<'b>, vendor_acc_info: &'a AccountInfo<'b>, vendor_vault_acc_info: &'a AccountInfo<'b>, clock_acc_info: &'a AccountInfo<'b>, @@ -247,7 +225,7 @@ struct AccessControlRequest<'a, 'b> { } struct AccessControlResponse { - pool_token_mint: Mint, + pool_mint: Mint, clock: Clock, } @@ -264,9 +242,9 @@ struct StateTransitionRequest<'a, 'b, 'c> { vendor_vault_acc_info: &'a AccountInfo<'b>, registrar_acc_info: &'a AccountInfo<'b>, reward_event_q_acc_info: &'a AccountInfo<'b>, - pool_vault_acc_info: &'a AccountInfo<'b>, + pool_mint_acc_info: &'a AccountInfo<'b>, depositor_acc_info: &'a AccountInfo<'b>, depositor_owner_acc_info: &'a AccountInfo<'b>, token_program_acc_info: &'a AccountInfo<'b>, - pool_token_mint: Mint, + pool_mint: Mint, } diff --git a/registry/program/src/drop_unlocked_reward.rs b/registry/program/src/drop_unlocked_reward.rs index ae16392..b9b1ba8 100644 --- a/registry/program/src/drop_unlocked_reward.rs +++ b/registry/program/src/drop_unlocked_reward.rs @@ -4,7 +4,7 @@ use serum_registry::access_control; use serum_registry::accounts::reward_queue::Ring; use serum_registry::accounts::{RewardEvent, RewardEventQueue, UnlockedRewardVendor}; use serum_registry::error::{RegistryError, RegistryErrorCode}; -use solana_program::info; +use solana_program::msg; use solana_sdk::account_info::next_account_info; use solana_sdk::account_info::AccountInfo; use solana_sdk::program_pack::Pack as TokenPack; @@ -22,7 +22,7 @@ pub fn handler( expiry_receiver: Pubkey, nonce: u8, ) -> Result<(), RegistryError> { - info!("handler: drop_unlocked_reward"); + msg!("handler: drop_unlocked_reward"); let acc_infos = &mut accounts.iter(); @@ -30,8 +30,7 @@ pub fn handler( let registrar_acc_info = next_account_info(acc_infos)?; let depositor_acc_info = next_account_info(acc_infos)?; let depositor_owner_acc_info = next_account_info(acc_infos)?; - let pool_vault_acc_info = next_account_info(acc_infos)?; - let pool_token_mint_acc_info = next_account_info(acc_infos)?; + let pool_mint_acc_info = next_account_info(acc_infos)?; let vendor_acc_info = next_account_info(acc_infos)?; let vendor_vault_acc_info = next_account_info(acc_infos)?; let token_program_acc_info = next_account_info(acc_infos)?; @@ -43,8 +42,7 @@ pub fn handler( } = access_control(AccessControlRequest { program_id, registrar_acc_info, - pool_vault_acc_info, - pool_token_mint_acc_info, + pool_mint_acc_info, vendor_acc_info, vendor_vault_acc_info, clock_acc_info, @@ -62,7 +60,6 @@ pub fn handler( expiry_ts, expiry_receiver, vendor, - pool_vault_acc_info, vendor_acc_info, vendor_vault_acc_info, reward_event_q_acc_info, @@ -70,6 +67,7 @@ pub fn handler( depositor_acc_info, depositor_owner_acc_info, token_program_acc_info, + pool_mint_acc_info, pool_token_mint, clock, }) @@ -81,13 +79,12 @@ pub fn handler( } fn access_control(req: AccessControlRequest) -> Result { - info!("access-control: drop_unlocked_reward"); + msg!("access-control: drop_unlocked_reward"); let AccessControlRequest { program_id, registrar_acc_info, - pool_vault_acc_info, - pool_token_mint_acc_info, + pool_mint_acc_info, vendor_acc_info, vendor_vault_acc_info, clock_acc_info, @@ -103,28 +100,13 @@ fn access_control(req: AccessControlRequest) -> Result Result Result<(), RegistryError> { - info!("state-transition: drop_unlocked_reward"); + msg!("state-transition: drop_unlocked_reward"); let StateTransitionRequest { nonce, @@ -169,7 +151,7 @@ fn state_transition(req: StateTransitionRequest) -> Result<(), RegistryError> { vendor_vault_acc_info, reward_event_q_acc_info, registrar_acc_info, - pool_vault_acc_info, + pool_mint_acc_info, depositor_acc_info, depositor_owner_acc_info, token_program_acc_info, @@ -187,7 +169,7 @@ fn state_transition(req: StateTransitionRequest) -> Result<(), RegistryError> { let cursor = reward_event_q.head_cursor()?; reward_event_q.append(&RewardEvent::UnlockedAlloc { from: *depositor_owner_acc_info.key, - pool: *pool_vault_acc_info.key, + pool: *pool_mint_acc_info.key, total, vendor: *vendor_acc_info.key, mint, @@ -208,7 +190,7 @@ fn state_transition(req: StateTransitionRequest) -> Result<(), RegistryError> { vendor.registrar = *registrar_acc_info.key; vendor.vault = *vendor_vault_acc_info.key; vendor.nonce = nonce; - vendor.pool = *pool_vault_acc_info.key; + vendor.pool = *pool_mint_acc_info.key; vendor.pool_token_supply = pool_token_mint.supply; vendor.reward_event_q_cursor = cursor; vendor.start_ts = clock.unix_timestamp; @@ -222,8 +204,7 @@ fn state_transition(req: StateTransitionRequest) -> Result<(), RegistryError> { struct AccessControlRequest<'a, 'b> { program_id: &'a Pubkey, registrar_acc_info: &'a AccountInfo<'b>, - pool_vault_acc_info: &'a AccountInfo<'b>, - pool_token_mint_acc_info: &'a AccountInfo<'b>, + pool_mint_acc_info: &'a AccountInfo<'b>, vendor_acc_info: &'a AccountInfo<'b>, vendor_vault_acc_info: &'a AccountInfo<'b>, clock_acc_info: &'a AccountInfo<'b>, @@ -248,7 +229,7 @@ struct StateTransitionRequest<'a, 'b, 'c> { vendor_vault_acc_info: &'a AccountInfo<'b>, registrar_acc_info: &'a AccountInfo<'b>, reward_event_q_acc_info: &'a AccountInfo<'b>, - pool_vault_acc_info: &'a AccountInfo<'b>, + pool_mint_acc_info: &'a AccountInfo<'b>, depositor_acc_info: &'a AccountInfo<'b>, depositor_owner_acc_info: &'a AccountInfo<'b>, token_program_acc_info: &'a AccountInfo<'b>, diff --git a/registry/program/src/end_stake_withdrawal.rs b/registry/program/src/end_stake_withdrawal.rs index 329776d..633c69a 100644 --- a/registry/program/src/end_stake_withdrawal.rs +++ b/registry/program/src/end_stake_withdrawal.rs @@ -1,55 +1,56 @@ use serum_common::pack::Pack; +use serum_common::program::invoke_token_transfer; use serum_registry::access_control; -use serum_registry::accounts::{Entity, Member, PendingWithdrawal}; +use serum_registry::accounts::{vault, BalanceSandbox, PendingWithdrawal, Registrar}; use serum_registry::error::{RegistryError, RegistryErrorCode}; -use solana_program::info; +use solana_program::msg; use solana_sdk::account_info::{next_account_info, AccountInfo}; use solana_sdk::pubkey::Pubkey; use std::convert::Into; #[inline(never)] pub fn handler(program_id: &Pubkey, accounts: &[AccountInfo]) -> Result<(), RegistryError> { - info!("handler: end_stake_withdrawl"); + msg!("handler: end_stake_withdrawl"); let acc_infos = &mut accounts.iter(); let pending_withdrawal_acc_info = next_account_info(acc_infos)?; let member_acc_info = next_account_info(acc_infos)?; + let member_vault_acc_info = next_account_info(acc_infos)?; + let member_vault_pw_acc_info = next_account_info(acc_infos)?; + let member_vault_authority_acc_info = next_account_info(acc_infos)?; let beneficiary_acc_info = next_account_info(acc_infos)?; let entity_acc_info = next_account_info(acc_infos)?; + let token_program_acc_info = next_account_info(acc_infos)?; let registrar_acc_info = next_account_info(acc_infos)?; let clock_acc_info = next_account_info(acc_infos)?; - let AccessControlResponse { is_mega } = access_control(AccessControlRequest { + let AccessControlResponse { ref registrar } = access_control(AccessControlRequest { registrar_acc_info, pending_withdrawal_acc_info, beneficiary_acc_info, member_acc_info, + member_vault_acc_info, + member_vault_pw_acc_info, entity_acc_info, clock_acc_info, program_id, + member_vault_authority_acc_info, })?; - Entity::unpack_unchecked_mut( - &mut entity_acc_info.try_borrow_mut_data()?, - &mut |entity: &mut Entity| { - Member::unpack_mut( - &mut member_acc_info.try_borrow_mut_data()?, - &mut |member: &mut Member| { - PendingWithdrawal::unpack_mut( - &mut pending_withdrawal_acc_info.try_borrow_mut_data()?, - &mut |pending_withdrawal: &mut PendingWithdrawal| { - state_transition(StateTransitionRequest { - pending_withdrawal, - entity, - member, - is_mega, - }) - .map_err(Into::into) - }, - ) - }, - ) + PendingWithdrawal::unpack_mut( + &mut pending_withdrawal_acc_info.try_borrow_mut_data()?, + &mut |pending_withdrawal: &mut PendingWithdrawal| { + state_transition(StateTransitionRequest { + pending_withdrawal, + registrar, + registrar_acc_info, + member_vault_acc_info, + member_vault_pw_acc_info, + member_vault_authority_acc_info, + token_program_acc_info, + }) + .map_err(Into::into) }, )?; @@ -58,7 +59,7 @@ pub fn handler(program_id: &Pubkey, accounts: &[AccountInfo]) -> Result<(), Regi #[inline(always)] fn access_control(req: AccessControlRequest) -> Result { - info!("access-control: end_stake_withdrawal"); + msg!("access-control: end_stake_withdrawal"); let AccessControlRequest { registrar_acc_info, @@ -68,6 +69,9 @@ fn access_control(req: AccessControlRequest) -> Result Result Result>(); + let balances = b.first().ok_or(RegistryErrorCode::InvalidBalanceSandbox)?; + + let (_, is_mega_vault) = access_control::member_vault( + &member, + member_vault_acc_info, + member_vault_authority_acc_info, + registrar_acc_info, + ®istrar, + program_id, + &balances.owner, + )?; + let (_, is_mega_vault_pw) = access_control::member_vault_pending_withdrawal( + &member, + member_vault_pw_acc_info, + member_vault_authority_acc_info, + registrar_acc_info, + ®istrar, + program_id, + &balances.owner, + )?; + let is_mega = { - if pending_withdrawal.pool == registrar.pool_vault { + if pending_withdrawal.pool == registrar.pool_mint { false - } else if pending_withdrawal.pool == registrar.pool_vault_mega { + } else if pending_withdrawal.pool == registrar.pool_mint_mega { true } else { return Err(RegistryErrorCode::InvariantViolation)?; } }; + if is_mega != is_mega_vault || is_mega != is_mega_vault_pw { + return Err(RegistryErrorCode::InvalidVault)?; + } // EndStakeWithdrawal specific. if clock.unix_timestamp < pending_withdrawal.end_ts { return Err(RegistryErrorCode::WithdrawalTimelockNotPassed)?; } - Ok(AccessControlResponse { is_mega }) + Ok(AccessControlResponse { registrar }) } fn state_transition(req: StateTransitionRequest) -> Result<(), RegistryError> { - info!("state-transition: end_stake_withdrawal"); + msg!("state-transition: end_stake_withdrawal"); let StateTransitionRequest { pending_withdrawal, - entity, - member, - is_mega, + registrar, + registrar_acc_info, + member_vault_acc_info, + member_vault_pw_acc_info, + member_vault_authority_acc_info, + token_program_acc_info, } = req; - member.spt_did_unstake_end(pending_withdrawal.spt_amount, is_mega); - entity.spt_did_unstake_end(pending_withdrawal.spt_amount, is_mega); + invoke_token_transfer( + member_vault_pw_acc_info, + member_vault_acc_info, + member_vault_authority_acc_info, + token_program_acc_info, + &[&vault::signer_seeds( + registrar_acc_info.key, + ®istrar.nonce, + )], + pending_withdrawal.amount, + )?; + pending_withdrawal.burned = true; Ok(()) @@ -128,18 +174,24 @@ struct AccessControlRequest<'a, 'b> { pending_withdrawal_acc_info: &'a AccountInfo<'b>, beneficiary_acc_info: &'a AccountInfo<'b>, member_acc_info: &'a AccountInfo<'b>, + member_vault_acc_info: &'a AccountInfo<'b>, + member_vault_pw_acc_info: &'a AccountInfo<'b>, + member_vault_authority_acc_info: &'a AccountInfo<'b>, entity_acc_info: &'a AccountInfo<'b>, clock_acc_info: &'a AccountInfo<'b>, program_id: &'a Pubkey, } struct AccessControlResponse { - is_mega: bool, + registrar: Registrar, } -struct StateTransitionRequest<'a> { - pending_withdrawal: &'a mut PendingWithdrawal, - entity: &'a mut Entity, - member: &'a mut Member, - is_mega: bool, +struct StateTransitionRequest<'a, 'b, 'c> { + registrar_acc_info: &'a AccountInfo<'b>, + member_vault_acc_info: &'a AccountInfo<'b>, + member_vault_pw_acc_info: &'a AccountInfo<'b>, + member_vault_authority_acc_info: &'a AccountInfo<'b>, + token_program_acc_info: &'a AccountInfo<'b>, + pending_withdrawal: &'c mut PendingWithdrawal, + registrar: &'c Registrar, } diff --git a/registry/program/src/initialize.rs b/registry/program/src/initialize.rs index ca6cfaa..826ec8f 100644 --- a/registry/program/src/initialize.rs +++ b/registry/program/src/initialize.rs @@ -1,35 +1,33 @@ use serum_common::pack::Pack; use serum_registry::access_control; use serum_registry::accounts::reward_queue::{RewardEventQueue, Ring}; -use serum_registry::accounts::Registrar; +use serum_registry::accounts::{vault, Registrar}; use serum_registry::error::{RegistryError, RegistryErrorCode}; -use solana_program::info; +use solana_program::msg; use solana_sdk::account_info::{next_account_info, AccountInfo}; +use solana_sdk::program_option::COption; use solana_sdk::pubkey::Pubkey; #[inline(never)] pub fn handler( program_id: &Pubkey, accounts: &[AccountInfo], + mint: Pubkey, + mint_mega: Pubkey, authority: Pubkey, nonce: u8, withdrawal_timelock: i64, deactivation_timelock: i64, reward_activation_threshold: u64, max_stake_per_entity: u64, + stake_rate: u64, + stake_rate_mega: u64, ) -> Result<(), RegistryError> { - info!("handler: initialize"); + msg!("handler: initialize"); let acc_infos = &mut accounts.iter(); let registrar_acc_info = next_account_info(acc_infos)?; - // Deposit vaults. - let vault_acc_info = next_account_info(acc_infos)?; - let mega_vault_acc_info = next_account_info(acc_infos)?; - // Pool Vaults. - let pool_vault_acc_info = next_account_info(acc_infos)?; - let pool_vault_mega_acc_info = next_account_info(acc_infos)?; - // Pool mints. let pool_mint_acc_info = next_account_info(acc_infos)?; let pool_mint_mega_acc_info = next_account_info(acc_infos)?; let reward_event_q_acc_info = next_account_info(acc_infos)?; @@ -38,10 +36,6 @@ pub fn handler( access_control(AccessControlRequest { registrar_acc_info, rent_acc_info, - vault_acc_info, - mega_vault_acc_info, - pool_vault_acc_info, - pool_vault_mega_acc_info, pool_mint_acc_info, pool_mint_mega_acc_info, program_id, @@ -55,10 +49,8 @@ pub fn handler( state_transition(StateTransitionRequest { registrar, authority, - vault_acc_info, - mega_vault_acc_info, - pool_vault_acc_info, - pool_vault_mega_acc_info, + mint, + mint_mega, pool_mint_acc_info, pool_mint_mega_acc_info, withdrawal_timelock, @@ -68,6 +60,8 @@ pub fn handler( max_stake_per_entity, reward_event_q_acc_info, registrar_acc_info, + stake_rate, + stake_rate_mega, }) .map_err(Into::into) }, @@ -77,15 +71,11 @@ pub fn handler( } fn access_control(req: AccessControlRequest) -> Result<(), RegistryError> { - info!("access-control: initialize"); + msg!("access-control: initialize"); let AccessControlRequest { registrar_acc_info, rent_acc_info, - vault_acc_info, - mega_vault_acc_info, - pool_vault_acc_info, - pool_vault_mega_acc_info, pool_mint_acc_info, pool_mint_mega_acc_info, program_id, @@ -115,17 +105,18 @@ fn access_control(req: AccessControlRequest) -> Result<(), RegistryError> { } } - // TODO: validate all pool vaults. - - // Vaults (initialized but not yet on the Registrar). - access_control::vault_init(vault_acc_info, registrar_acc_info, &rent, nonce, program_id)?; - access_control::vault_init( - mega_vault_acc_info, - registrar_acc_info, - &rent, - nonce, + let pool_mint = access_control::mint(pool_mint_acc_info)?; + let pool_mint_mega = access_control::mint(pool_mint_mega_acc_info)?; + let vault_authority = Pubkey::create_program_address( + &vault::signer_seeds(registrar_acc_info.key, &nonce), program_id, - )?; + ) + .map_err(|_| RegistryErrorCode::InvalidVaultNonce)?; + if pool_mint.mint_authority != COption::Some(vault_authority) + || pool_mint_mega.mint_authority != COption::Some(vault_authority) + { + return Err(RegistryErrorCode::InvalidVaultAuthority)?; + } // Reward q must not yet be owned. let event_q = RewardEventQueue::from(reward_event_q_acc_info.data.clone()); @@ -138,24 +129,24 @@ fn access_control(req: AccessControlRequest) -> Result<(), RegistryError> { #[inline(always)] fn state_transition(req: StateTransitionRequest) -> Result<(), RegistryError> { - info!("state-transition: initialize"); + msg!("state-transition: initialize"); let StateTransitionRequest { registrar, authority, withdrawal_timelock, - vault_acc_info, - mega_vault_acc_info, nonce, deactivation_timelock, reward_activation_threshold, - pool_vault_acc_info, - pool_vault_mega_acc_info, pool_mint_acc_info, pool_mint_mega_acc_info, max_stake_per_entity, reward_event_q_acc_info, registrar_acc_info, + mint, + mint_mega, + stake_rate, + stake_rate_mega, } = req; registrar.initialized = true; @@ -163,15 +154,15 @@ fn state_transition(req: StateTransitionRequest) -> Result<(), RegistryError> { registrar.withdrawal_timelock = withdrawal_timelock; registrar.deactivation_timelock = deactivation_timelock; registrar.max_stake_per_entity = max_stake_per_entity; - registrar.vault = *vault_acc_info.key; - registrar.mega_vault = *mega_vault_acc_info.key; registrar.nonce = nonce; registrar.reward_activation_threshold = reward_activation_threshold; - registrar.pool_vault = *pool_vault_acc_info.key; - registrar.pool_vault_mega = *pool_vault_mega_acc_info.key; registrar.pool_mint = *pool_mint_acc_info.key; registrar.pool_mint_mega = *pool_mint_mega_acc_info.key; registrar.reward_event_q = *reward_event_q_acc_info.key; + registrar.mint = mint; + registrar.mega_mint = mint_mega; + registrar.stake_rate = stake_rate; + registrar.stake_rate_mega = stake_rate_mega; let event_q = RewardEventQueue::from(reward_event_q_acc_info.data.clone()); event_q.set_authority(registrar_acc_info.key); @@ -182,11 +173,7 @@ fn state_transition(req: StateTransitionRequest) -> Result<(), RegistryError> { struct AccessControlRequest<'a, 'b> { registrar_acc_info: &'a AccountInfo<'b>, rent_acc_info: &'a AccountInfo<'b>, - vault_acc_info: &'a AccountInfo<'b>, - mega_vault_acc_info: &'a AccountInfo<'b>, reward_event_q_acc_info: &'a AccountInfo<'b>, - pool_vault_acc_info: &'a AccountInfo<'b>, - pool_vault_mega_acc_info: &'a AccountInfo<'b>, pool_mint_acc_info: &'a AccountInfo<'b>, pool_mint_mega_acc_info: &'a AccountInfo<'b>, program_id: &'a Pubkey, @@ -194,12 +181,8 @@ struct AccessControlRequest<'a, 'b> { } struct StateTransitionRequest<'a, 'b, 'c> { - vault_acc_info: &'a AccountInfo<'b>, - mega_vault_acc_info: &'a AccountInfo<'b>, reward_event_q_acc_info: &'a AccountInfo<'b>, registrar_acc_info: &'a AccountInfo<'b>, - pool_vault_acc_info: &'a AccountInfo<'b>, - pool_vault_mega_acc_info: &'a AccountInfo<'b>, pool_mint_acc_info: &'a AccountInfo<'b>, pool_mint_mega_acc_info: &'a AccountInfo<'b>, registrar: &'c mut Registrar, @@ -209,4 +192,8 @@ struct StateTransitionRequest<'a, 'b, 'c> { withdrawal_timelock: i64, max_stake_per_entity: u64, nonce: u8, + mint: Pubkey, + mint_mega: Pubkey, + stake_rate: u64, + stake_rate_mega: u64, } diff --git a/registry/program/src/lib.rs b/registry/program/src/lib.rs index 2370544..9fa14cc 100644 --- a/registry/program/src/lib.rs +++ b/registry/program/src/lib.rs @@ -27,41 +27,34 @@ mod withdraw; solana_program::entrypoint!(entry); fn entry(program_id: &Pubkey, accounts: &[AccountInfo], instruction_data: &[u8]) -> ProgramResult { - // The lockup program prepends the instruction_data with a tag to tell - // whitelisted programs that funds are locked, since the instruction data - // is completely opaque to the lockup program. Without this measure, - // one would effectively be able to transfer funds from the lockup program - // freely and use those funds without restriction. - let (is_locked, instruction_data) = { - if instruction_data.len() <= 8 - || instruction_data[..8] != serum_lockup::instruction::TAG.to_le_bytes() - { - (false, instruction_data) - } else { - (true, &instruction_data[8..]) - } - }; - let instruction: RegistryInstruction = RegistryInstruction::unpack(instruction_data) .map_err(|_| RegistryError::ErrorCode(RegistryErrorCode::WrongSerialization))?; let result = match instruction { RegistryInstruction::Initialize { authority, + mint, + mint_mega, nonce, withdrawal_timelock, deactivation_timelock, reward_activation_threshold, max_stake_per_entity, + stake_rate, + stake_rate_mega, } => initialize::handler( program_id, accounts, + mint, + mint_mega, authority, nonce, withdrawal_timelock, deactivation_timelock, reward_activation_threshold, max_stake_per_entity, + stake_rate, + stake_rate_mega, ), RegistryInstruction::UpdateRegistrar { new_authority, @@ -84,21 +77,17 @@ fn entry(program_id: &Pubkey, accounts: &[AccountInfo], instruction_data: &[u8]) RegistryInstruction::UpdateEntity { leader, metadata } => { update_entity::handler(program_id, accounts, leader, metadata) } - RegistryInstruction::CreateMember { delegate } => { - create_member::handler(program_id, accounts, delegate) + RegistryInstruction::CreateMember => create_member::handler(program_id, accounts), + RegistryInstruction::UpdateMember { metadata } => { + update_member::handler(program_id, accounts, metadata) } - RegistryInstruction::UpdateMember { delegate, metadata } => { - update_member::handler(program_id, accounts, delegate, metadata) + RegistryInstruction::Deposit { amount } => deposit::handler(program_id, accounts, amount), + RegistryInstruction::Withdraw { amount } => withdraw::handler(program_id, accounts, amount), + RegistryInstruction::Stake { amount, balance_id } => { + stake::handler(program_id, accounts, amount, balance_id) } - RegistryInstruction::Deposit { amount } => { - deposit::handler(program_id, accounts, amount, is_locked) - } - RegistryInstruction::Withdraw { amount } => { - withdraw::handler(program_id, accounts, amount, is_locked) - } - RegistryInstruction::Stake { amount } => stake::handler(program_id, accounts, amount), - RegistryInstruction::StartStakeWithdrawal { amount } => { - start_stake_withdrawal::handler(program_id, accounts, amount) + RegistryInstruction::StartStakeWithdrawal { amount, balance_id } => { + start_stake_withdrawal::handler(program_id, accounts, amount, balance_id) } RegistryInstruction::EndStakeWithdrawal => { end_stake_withdrawal::handler(program_id, accounts) diff --git a/registry/program/src/stake.rs b/registry/program/src/stake.rs index ab40148..c9585e0 100644 --- a/registry/program/src/stake.rs +++ b/registry/program/src/stake.rs @@ -4,7 +4,7 @@ use serum_common::program::{invoke_mint_tokens, invoke_token_transfer}; use serum_registry::access_control; use serum_registry::accounts::{vault, Entity, Member, Registrar}; use serum_registry::error::{RegistryError, RegistryErrorCode}; -use solana_program::info; +use solana_program::msg; use solana_sdk::account_info::{next_account_info, AccountInfo}; use solana_sdk::pubkey::Pubkey; use solana_sdk::sysvar::clock::Clock; @@ -14,8 +14,9 @@ pub fn handler( program_id: &Pubkey, accounts: &[AccountInfo], spt_amount: u64, + ref balance_id: Pubkey, ) -> Result<(), RegistryError> { - info!("handler: stake"); + msg!("handler: stake"); let acc_infos = &mut accounts.iter(); @@ -23,9 +24,9 @@ pub fn handler( let beneficiary_acc_info = next_account_info(acc_infos)?; let entity_acc_info = next_account_info(acc_infos)?; let registrar_acc_info = next_account_info(acc_infos)?; - let vault_acc_info = next_account_info(acc_infos)?; - let vault_authority_acc_info = next_account_info(acc_infos)?; - let pool_vault_acc_info = next_account_info(acc_infos)?; + let member_vault_acc_info = next_account_info(acc_infos)?; + let member_vault_authority_acc_info = next_account_info(acc_infos)?; + let member_vault_stake_acc_info = next_account_info(acc_infos)?; let pool_mint_acc_info = next_account_info(acc_infos)?; let spt_acc_info = next_account_info(acc_infos)?; let clock_acc_info = next_account_info(acc_infos)?; @@ -49,11 +50,12 @@ pub fn handler( program_id, registrar, registrar_acc_info, - vault_acc_info, - vault_authority_acc_info, - pool_vault_acc_info, + member_vault_acc_info, + member_vault_authority_acc_info, + member_vault_stake_acc_info, pool_mint_acc_info, spt_acc_info, + balance_id, })?; Member::unpack_mut( &mut member_acc_info.try_borrow_mut_data()?, @@ -66,9 +68,9 @@ pub fn handler( is_mega, registrar, registrar_acc_info, - vault_acc_info, - vault_authority_acc_info, - pool_vault_acc_info, + member_vault_acc_info, + member_vault_authority_acc_info, + member_vault_stake_acc_info, spt_acc_info, token_program_acc_info, pool_mint_acc_info, @@ -81,7 +83,7 @@ pub fn handler( } fn access_control(req: AccessControlRequest) -> Result { - info!("access-control: stake"); + msg!("access-control: stake"); let AccessControlRequest { member_acc_info, @@ -92,13 +94,16 @@ fn access_control(req: AccessControlRequest) -> Result 0); + // Beneficiary authorization. if !beneficiary_acc_info.is_signer { return Err(RegistryErrorCode::Unauthorized)?; @@ -112,45 +117,50 @@ fn access_control(req: AccessControlRequest) -> Result registrar.max_stake_per_entity { - return Err(RegistryErrorCode::EntityMaxStake)?; - } + } + // Will this new stake put the entity over the maximum allowable limit? + if entity.stake_will_max(spt_amount, is_mega, ®istrar) { + return Err(RegistryErrorCode::EntityMaxStake)?; } Ok(AccessControlResponse { is_mega }) } fn state_transition(req: StateTransitionRequest) -> Result<(), RegistryError> { - info!("state-transition: stake"); + msg!("state-transition: stake"); let StateTransitionRequest { entity, @@ -159,9 +169,9 @@ fn state_transition(req: StateTransitionRequest) -> Result<(), RegistryError> { is_mega, registrar_acc_info, registrar, - vault_acc_info, - vault_authority_acc_info, - pool_vault_acc_info, + member_vault_acc_info, + member_vault_authority_acc_info, + member_vault_stake_acc_info, spt_acc_info, token_program_acc_info, pool_mint_acc_info, @@ -170,29 +180,37 @@ fn state_transition(req: StateTransitionRequest) -> Result<(), RegistryError> { let signer_seeds = vault::signer_seeds(registrar_acc_info.key, ®istrar.nonce); - // Mint pool tokens. + // Mint pool tokens to member. invoke_mint_tokens( pool_mint_acc_info, spt_acc_info, - vault_authority_acc_info, + member_vault_authority_acc_info, token_program_acc_info, &[&signer_seeds], spt_amount, )?; - // Transfer from the deposit vault to pool vault. + // Convert from stake token units to srm/msrm units. + let token_amount = { + let rate = match is_mega { + false => registrar.stake_rate, + true => registrar.stake_rate_mega, + }; + spt_amount.checked_mul(rate).unwrap() + }; + + // Transfer from deposit vault to stake vault. invoke_token_transfer( - vault_acc_info, - pool_vault_acc_info, - vault_authority_acc_info, + member_vault_acc_info, + member_vault_stake_acc_info, + member_vault_authority_acc_info, token_program_acc_info, &[&signer_seeds], - spt_amount, + token_amount, )?; // Bookeeping. member.last_stake_ts = clock.unix_timestamp; - member.spt_did_stake(spt_amount, is_mega)?; entity.spt_did_stake(spt_amount, is_mega)?; Ok(()) @@ -203,15 +221,16 @@ struct AccessControlRequest<'a, 'b, 'c> { beneficiary_acc_info: &'a AccountInfo<'b>, entity_acc_info: &'a AccountInfo<'b>, registrar_acc_info: &'a AccountInfo<'b>, - vault_acc_info: &'a AccountInfo<'b>, - vault_authority_acc_info: &'a AccountInfo<'b>, - pool_vault_acc_info: &'a AccountInfo<'b>, + member_vault_acc_info: &'a AccountInfo<'b>, + member_vault_authority_acc_info: &'a AccountInfo<'b>, + member_vault_stake_acc_info: &'a AccountInfo<'b>, spt_acc_info: &'a AccountInfo<'b>, pool_mint_acc_info: &'a AccountInfo<'b>, program_id: &'a Pubkey, registrar: &'c Registrar, entity: &'c Entity, spt_amount: u64, + balance_id: &'c Pubkey, } struct AccessControlResponse { @@ -226,9 +245,9 @@ struct StateTransitionRequest<'a, 'b, 'c> { is_mega: bool, registrar: &'c Registrar, registrar_acc_info: &'a AccountInfo<'b>, - vault_acc_info: &'a AccountInfo<'b>, - vault_authority_acc_info: &'a AccountInfo<'b>, - pool_vault_acc_info: &'a AccountInfo<'b>, + member_vault_acc_info: &'a AccountInfo<'b>, + member_vault_authority_acc_info: &'a AccountInfo<'b>, + member_vault_stake_acc_info: &'a AccountInfo<'b>, spt_acc_info: &'a AccountInfo<'b>, token_program_acc_info: &'a AccountInfo<'b>, pool_mint_acc_info: &'a AccountInfo<'b>, diff --git a/registry/program/src/start_stake_withdrawal.rs b/registry/program/src/start_stake_withdrawal.rs index 8f880ed..d6562b9 100644 --- a/registry/program/src/start_stake_withdrawal.rs +++ b/registry/program/src/start_stake_withdrawal.rs @@ -3,9 +3,9 @@ use serum_common::pack::Pack; use serum_common::program::{invoke_burn_tokens, invoke_token_transfer}; use serum_registry::access_control; use serum_registry::accounts::vault; -use serum_registry::accounts::{Entity, Member, PendingWithdrawal, Registrar}; +use serum_registry::accounts::{Entity, PendingWithdrawal, Registrar}; use serum_registry::error::{RegistryError, RegistryErrorCode}; -use solana_program::info; +use solana_program::msg; use solana_sdk::account_info::{next_account_info, AccountInfo}; use solana_sdk::pubkey::Pubkey; use solana_sdk::sysvar::clock::Clock; @@ -15,8 +15,9 @@ pub fn handler( program_id: &Pubkey, accounts: &[AccountInfo], spt_amount: u64, + ref balance_id: Pubkey, ) -> Result<(), RegistryError> { - info!("handler: start_stake_withdrawal"); + msg!("handler: start_stake_withdrawal"); let acc_infos = &mut accounts.iter(); @@ -26,9 +27,9 @@ pub fn handler( let beneficiary_acc_info = next_account_info(acc_infos)?; let entity_acc_info = next_account_info(acc_infos)?; let registrar_acc_info = next_account_info(acc_infos)?; - let vault_acc_info = next_account_info(acc_infos)?; - let vault_authority_acc_info = next_account_info(acc_infos)?; - let pool_vault_acc_info = next_account_info(acc_infos)?; + let member_vault_pw_acc_info = next_account_info(acc_infos)?; + let member_vault_authority_acc_info = next_account_info(acc_infos)?; + let member_vault_stake_acc_info = next_account_info(acc_infos)?; let pool_mint_acc_info = next_account_info(acc_infos)?; let spt_acc_info = next_account_info(acc_infos)?; let clock_acc_info = next_account_info(acc_infos)?; @@ -52,39 +53,35 @@ pub fn handler( entity_acc_info, rent_acc_info, program_id, - vault_acc_info, - vault_authority_acc_info, - pool_vault_acc_info, + member_vault_pw_acc_info, + member_vault_authority_acc_info, + member_vault_stake_acc_info, pool_mint_acc_info, spt_acc_info, registrar, + balance_id, })?; PendingWithdrawal::unpack_mut( &mut pending_withdrawal_acc_info.try_borrow_mut_data()?, &mut |pending_withdrawal: &mut PendingWithdrawal| { - Member::unpack_mut( - &mut member_acc_info.try_borrow_mut_data()?, - &mut |member: &mut Member| { - state_transition(StateTransitionRequest { - pending_withdrawal, - registrar, - member, - entity, - member_acc_info, - clock, - spt_amount, - tok_program_acc_info, - registrar_acc_info, - vault_acc_info, - vault_authority_acc_info, - pool_vault_acc_info, - pool_mint_acc_info, - spt_acc_info, - is_mega, - }) - .map_err(Into::into) - }, - ) + state_transition(StateTransitionRequest { + pending_withdrawal, + registrar, + entity, + member_acc_info, + clock, + spt_amount, + tok_program_acc_info, + registrar_acc_info, + member_vault_pw_acc_info, + member_vault_authority_acc_info, + member_vault_stake_acc_info, + pool_mint_acc_info, + spt_acc_info, + is_mega, + balance_id, + }) + .map_err(Into::into) }, ) .map_err(Into::into) @@ -94,7 +91,7 @@ pub fn handler( } fn access_control(req: AccessControlRequest) -> Result { - info!("access-control: start_stake_withdrawal"); + msg!("access-control: start_stake_withdrawal"); let AccessControlRequest { registrar_acc_info, @@ -104,12 +101,13 @@ fn access_control(req: AccessControlRequest) -> Result Result Result Result<(), RegistryError> { - info!("state-transition: start_stake_withdrawal"); + msg!("state-transition: start_stake_withdrawal"); let StateTransitionRequest { pending_withdrawal, registrar, entity, - member, member_acc_info, clock, spt_amount, - vault_acc_info, - vault_authority_acc_info, - pool_vault_acc_info, + member_vault_pw_acc_info, + member_vault_authority_acc_info, + member_vault_stake_acc_info, pool_mint_acc_info, spt_acc_info, tok_program_acc_info, registrar_acc_info, is_mega, + balance_id, } = req; let signer_seeds = vault::signer_seeds(registrar_acc_info.key, ®istrar.nonce); @@ -184,24 +198,32 @@ fn state_transition(req: StateTransitionRequest) -> Result<(), RegistryError> { invoke_burn_tokens( spt_acc_info, pool_mint_acc_info, - vault_authority_acc_info, + member_vault_authority_acc_info, tok_program_acc_info, &[&signer_seeds], spt_amount, )?; - // Transfer from pool vault to deposit vault. + // Convert from stake token units to srm/msrm units. + let token_amount = { + let rate = match is_mega { + false => registrar.stake_rate, + true => registrar.stake_rate_mega, + }; + spt_amount.checked_mul(rate).unwrap() + }; + + // Transfer from stake vault to pending vault. invoke_token_transfer( - pool_vault_acc_info, - vault_acc_info, - vault_authority_acc_info, + member_vault_stake_acc_info, + member_vault_pw_acc_info, + member_vault_authority_acc_info, tok_program_acc_info, &[&signer_seeds], - spt_amount, + token_amount, )?; // Bookeeping. - member.spt_did_unstake_start(spt_amount, is_mega); entity.spt_did_unstake_start(spt_amount, is_mega); // Print pending withdrawal receipt. @@ -210,8 +232,9 @@ fn state_transition(req: StateTransitionRequest) -> Result<(), RegistryError> { pending_withdrawal.member = *member_acc_info.key; pending_withdrawal.start_ts = clock.unix_timestamp; pending_withdrawal.end_ts = clock.unix_timestamp + registrar.deactivation_timelock; - pending_withdrawal.spt_amount = spt_amount; - pending_withdrawal.pool = *pool_vault_acc_info.key; + pending_withdrawal.amount = token_amount; + pending_withdrawal.pool = *pool_mint_acc_info.key; + pending_withdrawal.balance_id = *balance_id; Ok(()) } @@ -223,13 +246,14 @@ struct AccessControlRequest<'a, 'b, 'c> { member_acc_info: &'a AccountInfo<'b>, entity_acc_info: &'a AccountInfo<'b>, rent_acc_info: &'a AccountInfo<'b>, - vault_acc_info: &'a AccountInfo<'b>, - vault_authority_acc_info: &'a AccountInfo<'b>, - pool_vault_acc_info: &'a AccountInfo<'b>, + member_vault_pw_acc_info: &'a AccountInfo<'b>, + member_vault_authority_acc_info: &'a AccountInfo<'b>, + member_vault_stake_acc_info: &'a AccountInfo<'b>, pool_mint_acc_info: &'a AccountInfo<'b>, spt_acc_info: &'a AccountInfo<'b>, program_id: &'a Pubkey, registrar: &'c Registrar, + balance_id: &'c Pubkey, } struct AccessControlResponse { @@ -239,17 +263,17 @@ struct AccessControlResponse { struct StateTransitionRequest<'a, 'b, 'c> { member_acc_info: &'a AccountInfo<'b>, registrar_acc_info: &'a AccountInfo<'b>, - vault_acc_info: &'a AccountInfo<'b>, - vault_authority_acc_info: &'a AccountInfo<'b>, + member_vault_pw_acc_info: &'a AccountInfo<'b>, + member_vault_authority_acc_info: &'a AccountInfo<'b>, tok_program_acc_info: &'a AccountInfo<'b>, - pool_vault_acc_info: &'a AccountInfo<'b>, + member_vault_stake_acc_info: &'a AccountInfo<'b>, pool_mint_acc_info: &'a AccountInfo<'b>, spt_acc_info: &'a AccountInfo<'b>, pending_withdrawal: &'c mut PendingWithdrawal, entity: &'c mut Entity, - member: &'c mut Member, registrar: &'c Registrar, clock: &'c Clock, spt_amount: u64, is_mega: bool, + balance_id: &'c Pubkey, } diff --git a/registry/program/src/switch_entity.rs b/registry/program/src/switch_entity.rs index 32dbaf5..304c9be 100644 --- a/registry/program/src/switch_entity.rs +++ b/registry/program/src/switch_entity.rs @@ -1,16 +1,17 @@ use serum_common::pack::*; use serum_registry::access_control; -use serum_registry::accounts::{Entity, Member, Registrar}; +use serum_registry::accounts::{Entity, EntityState, Member, Registrar}; use serum_registry::error::{RegistryError, RegistryErrorCode}; -use solana_program::info; +use solana_program::msg; use solana_sdk::account_info::{next_account_info, AccountInfo}; use solana_sdk::pubkey::Pubkey; use solana_sdk::sysvar::clock::Clock; +use spl_token::state::Account as TokenAccount; use std::convert::Into; #[inline(never)] pub fn handler(program_id: &Pubkey, accounts: &[AccountInfo]) -> Result<(), RegistryError> { - info!("handler: switch_entity"); + msg!("handler: switch_entity"); let acc_infos = &mut accounts.iter(); @@ -20,8 +21,21 @@ pub fn handler(program_id: &Pubkey, accounts: &[AccountInfo]) -> Result<(), Regi let curr_entity_acc_info = next_account_info(acc_infos)?; let new_entity_acc_info = next_account_info(acc_infos)?; let clock_acc_info = next_account_info(acc_infos)?; + let vault_authority_acc_info = next_account_info(acc_infos)?; + let mut asset_acc_infos = vec![]; + while acc_infos.len() > 0 { + asset_acc_infos.push(AssetAccInfos { + owner_acc_info: next_account_info(acc_infos)?, + vault_stake_acc_info: next_account_info(acc_infos)?, + vault_stake_mega_acc_info: next_account_info(acc_infos)?, + }) + } - let AccessControlResponse { registrar, clock } = access_control(AccessControlRequest { + let AccessControlResponse { + ref assets, + ref registrar, + ref clock, + } = access_control(AccessControlRequest { member_acc_info, beneficiary_acc_info, program_id, @@ -29,6 +43,8 @@ pub fn handler(program_id: &Pubkey, accounts: &[AccountInfo]) -> Result<(), Regi curr_entity_acc_info, new_entity_acc_info, clock_acc_info, + asset_acc_infos, + vault_authority_acc_info, })?; Member::unpack_mut( @@ -45,8 +61,9 @@ pub fn handler(program_id: &Pubkey, accounts: &[AccountInfo]) -> Result<(), Regi curr_entity, new_entity, member, - registrar: ®istrar, - clock: &clock, + registrar, + clock, + assets, }) .map_err(Into::into) }, @@ -59,8 +76,9 @@ pub fn handler(program_id: &Pubkey, accounts: &[AccountInfo]) -> Result<(), Regi Ok(()) } +#[inline(never)] fn access_control(req: AccessControlRequest) -> Result { - info!("access-control: switch_entity"); + msg!("access-control: switch_entity"); let AccessControlRequest { member_acc_info, @@ -70,6 +88,8 @@ fn access_control(req: AccessControlRequest) -> Result Result Result = asset_acc_infos + .iter() + .map(|a| *a.owner_acc_info.key) + .collect(); + balance_ids.sort(); + balance_ids.dedup(); + if balance_ids.len() != member.balances.len() { + return Err(RegistryErrorCode::InvalidAssetsLen)?; + } + // BPF exploads when mapping so use a for loop. + let mut assets = vec![]; + for a in &asset_acc_infos { + let (vault_stake, is_mega) = access_control::member_vault_stake( + &member, + a.vault_stake_acc_info, + vault_authority_acc_info, + registrar_acc_info, + ®istrar, + program_id, + a.owner_acc_info.key, + )?; + assert!(!is_mega); + let (vault_stake_mega, is_mega) = access_control::member_vault_stake( + &member, + a.vault_stake_mega_acc_info, + vault_authority_acc_info, + registrar_acc_info, + ®istrar, + program_id, + a.owner_acc_info.key, + )?; + assert!(is_mega); + assets.push(Assets { + vault_stake, + vault_stake_mega, + }) + } - Ok(AccessControlResponse { registrar, clock }) + Ok(AccessControlResponse { + assets, + registrar, + clock, + }) } -#[inline(always)] +#[inline(never)] fn state_transition(req: StateTransitionRequest) -> Result<(), RegistryError> { - info!("state-transition: switch_entity"); + msg!("state-transition: switch_entity"); let StateTransitionRequest { new_entity_acc_info, @@ -104,16 +165,35 @@ fn state_transition(req: StateTransitionRequest) -> Result<(), RegistryError> { new_entity, registrar, clock, + assets, } = req; - curr_entity.remove(member); - new_entity.add(member); + // Bump the last stake timestamp to prevent people from switching from + // inactive to active entities to retrieve a reward when they shouldn't. + if curr_entity.state == EntityState::Inactive { + member.last_stake_ts = clock.unix_timestamp; + } - curr_entity.transition_activation_if_needed(registrar, clock); - new_entity.transition_activation_if_needed(registrar, clock); + // Bookepping. + // + // Move all the assets to the new entity. + // + // Note that the assets don't actually move, as the member vaults are + // untouched. + for a in assets { + // Remove. + curr_entity.balances.spt_amount -= a.vault_stake.amount; + curr_entity.balances.spt_mega_amount -= a.vault_stake_mega.amount; + // Add. + new_entity.balances.spt_amount += a.vault_stake.amount; + new_entity.balances.spt_mega_amount += a.vault_stake_mega.amount; + } member.entity = *new_entity_acc_info.key; - member.last_stake_ts = clock.unix_timestamp; + + // Trigger activation FSM. + curr_entity.transition_activation_if_needed(registrar, clock); + new_entity.transition_activation_if_needed(registrar, clock); Ok(()) } @@ -125,12 +205,15 @@ struct AccessControlRequest<'a, 'b> { curr_entity_acc_info: &'a AccountInfo<'b>, new_entity_acc_info: &'a AccountInfo<'b>, clock_acc_info: &'a AccountInfo<'b>, + vault_authority_acc_info: &'a AccountInfo<'b>, program_id: &'a Pubkey, + asset_acc_infos: Vec>, } struct AccessControlResponse { registrar: Registrar, clock: Clock, + assets: Vec, } struct StateTransitionRequest<'a, 'b, 'c> { @@ -140,4 +223,16 @@ struct StateTransitionRequest<'a, 'b, 'c> { new_entity: &'c mut Entity, member: &'c mut Member, clock: &'c Clock, + assets: &'c [Assets], +} + +struct Assets { + vault_stake: TokenAccount, + vault_stake_mega: TokenAccount, +} + +struct AssetAccInfos<'a, 'b> { + owner_acc_info: &'a AccountInfo<'b>, + vault_stake_acc_info: &'a AccountInfo<'b>, + vault_stake_mega_acc_info: &'a AccountInfo<'b>, } diff --git a/registry/program/src/update_entity.rs b/registry/program/src/update_entity.rs index cb3bf33..f95bc87 100644 --- a/registry/program/src/update_entity.rs +++ b/registry/program/src/update_entity.rs @@ -2,7 +2,7 @@ use serum_common::pack::Pack; use serum_registry::access_control; use serum_registry::accounts::Entity; use serum_registry::error::{RegistryError, RegistryErrorCode}; -use solana_program::info; +use solana_program::msg; use solana_sdk::account_info::{next_account_info, AccountInfo}; use solana_sdk::pubkey::Pubkey; @@ -13,7 +13,7 @@ pub fn handler( leader: Option, metadata: Option, ) -> Result<(), RegistryError> { - info!("handler: update_entity"); + msg!("handler: update_entity"); let acc_infos = &mut accounts.iter(); @@ -44,7 +44,7 @@ pub fn handler( } fn access_control(req: AccessControlRequest) -> Result<(), RegistryError> { - info!("access-control: update_entity"); + msg!("access-control: update_entity"); let AccessControlRequest { entity_acc_info, @@ -68,7 +68,7 @@ fn access_control(req: AccessControlRequest) -> Result<(), RegistryError> { } fn state_transition(req: StateTransitionRequest) -> Result<(), RegistryError> { - info!("state-transition: update_entity"); + msg!("state-transition: update_entity"); let StateTransitionRequest { entity, diff --git a/registry/program/src/update_member.rs b/registry/program/src/update_member.rs index 1616f15..58f74a4 100644 --- a/registry/program/src/update_member.rs +++ b/registry/program/src/update_member.rs @@ -2,7 +2,7 @@ use serum_common::pack::*; use serum_registry::access_control; use serum_registry::accounts::Member; use serum_registry::error::{RegistryError, RegistryErrorCode}; -use solana_program::info; +use solana_program::msg; use solana_sdk::account_info::{next_account_info, AccountInfo}; use solana_sdk::pubkey::Pubkey; use std::convert::Into; @@ -11,10 +11,9 @@ use std::convert::Into; pub fn handler( program_id: &Pubkey, accounts: &[AccountInfo], - delegate: Option, metadata: Option, ) -> Result<(), RegistryError> { - info!("handler: update_member"); + msg!("handler: update_member"); let acc_infos = &mut accounts.iter(); @@ -24,19 +23,13 @@ pub fn handler( access_control(AccessControlRequest { member_acc_info, beneficiary_acc_info, - delegate, program_id, })?; Member::unpack_mut( &mut member_acc_info.try_borrow_mut_data()?, &mut |member: &mut Member| { - state_transition(StateTransitionRequest { - member, - delegate, - metadata, - }) - .map_err(Into::into) + state_transition(StateTransitionRequest { member, metadata }).map_err(Into::into) }, )?; @@ -44,12 +37,11 @@ pub fn handler( } fn access_control(req: AccessControlRequest) -> Result<(), RegistryError> { - info!("access-control: update_member"); + msg!("access-control: update_member"); let AccessControlRequest { member_acc_info, beneficiary_acc_info, - delegate, program_id, } = req; @@ -59,31 +51,16 @@ fn access_control(req: AccessControlRequest) -> Result<(), RegistryError> { } // Account validation. - let member = access_control::member(member_acc_info, beneficiary_acc_info, program_id)?; - - // UpdateMember specific. - if delegate.is_some() { - // Can't overwrite the delegate if we haven't returned it's deposit. - if !member.balances.delegate.is_empty() { - return Err(RegistryErrorCode::DelegateInUse)?; - } - } + let _member = access_control::member(member_acc_info, beneficiary_acc_info, program_id)?; Ok(()) } fn state_transition(req: StateTransitionRequest) -> Result<(), RegistryError> { - info!("state-transition: update_member"); + msg!("state-transition: update_member"); - let StateTransitionRequest { - member, - delegate, - metadata, - } = req; + let StateTransitionRequest { member, metadata } = req; - if let Some(d) = delegate { - member.set_delegate(d); - } if let Some(m) = metadata { member.metadata = m; } @@ -95,11 +72,9 @@ struct AccessControlRequest<'a, 'b> { member_acc_info: &'a AccountInfo<'b>, beneficiary_acc_info: &'a AccountInfo<'b>, program_id: &'a Pubkey, - delegate: Option, } struct StateTransitionRequest<'a> { member: &'a mut Member, - delegate: Option, metadata: Option, } diff --git a/registry/program/src/update_registrar.rs b/registry/program/src/update_registrar.rs index 613364f..ba56456 100644 --- a/registry/program/src/update_registrar.rs +++ b/registry/program/src/update_registrar.rs @@ -2,7 +2,7 @@ use serum_common::pack::Pack; use serum_registry::access_control; use serum_registry::accounts::Registrar; use serum_registry::error::RegistryError; -use solana_program::info; +use solana_program::msg; use solana_sdk::account_info::{next_account_info, AccountInfo}; use solana_sdk::pubkey::Pubkey; @@ -16,7 +16,7 @@ pub fn handler( reward_activation_threshold: Option, max_stake_per_entity: Option, ) -> Result<(), RegistryError> { - info!("handler: initialize"); + msg!("handler: initialize"); let acc_infos = &mut accounts.iter(); @@ -48,7 +48,7 @@ pub fn handler( } fn access_control(req: AccessControlRequest) -> Result<(), RegistryError> { - info!("access-control: update_registrar"); + msg!("access-control: update_registrar"); let AccessControlRequest { registrar_acc_info, @@ -64,7 +64,7 @@ fn access_control(req: AccessControlRequest) -> Result<(), RegistryError> { #[inline(always)] fn state_transition(req: StateTransitionRequest) -> Result<(), RegistryError> { - info!("state-transition: update_registrar"); + msg!("state-transition: update_registrar"); let StateTransitionRequest { registrar, diff --git a/registry/program/src/withdraw.rs b/registry/program/src/withdraw.rs index 4b2c05b..48629d7 100644 --- a/registry/program/src/withdraw.rs +++ b/registry/program/src/withdraw.rs @@ -1,23 +1,18 @@ -use crate::common::entity::{with_entity, EntityContext}; -use serum_common::pack::Pack; use serum_common::program::invoke_token_transfer; use serum_registry::access_control; -use serum_registry::accounts::{vault, Entity, Member, Registrar}; +use serum_registry::accounts::{vault, Registrar}; use serum_registry::error::{RegistryError, RegistryErrorCode}; -use solana_program::info; +use solana_program::msg; use solana_sdk::account_info::{next_account_info, AccountInfo}; use solana_sdk::pubkey::Pubkey; -use solana_sdk::sysvar::clock::Clock; -use spl_token::state::Account as TokenAccount; #[inline(never)] pub fn handler( program_id: &Pubkey, accounts: &[AccountInfo], amount: u64, - delegate: bool, ) -> Result<(), RegistryError> { - info!("handler: withdraw"); + msg!("handler: withdraw"); let acc_infos = &mut accounts.iter(); @@ -25,79 +20,54 @@ pub fn handler( let depositor_acc_info = next_account_info(acc_infos)?; let depositor_authority_acc_info = next_account_info(acc_infos)?; let token_program_acc_info = next_account_info(acc_infos)?; - let vault_acc_info = next_account_info(acc_infos)?; - let vault_authority_acc_info = next_account_info(acc_infos)?; + let member_vault_acc_info = next_account_info(acc_infos)?; + let member_vault_authority_acc_info = next_account_info(acc_infos)?; // Program specfic. let member_acc_info = next_account_info(acc_infos)?; let beneficiary_acc_info = next_account_info(acc_infos)?; let entity_acc_info = next_account_info(acc_infos)?; let registrar_acc_info = next_account_info(acc_infos)?; - let clock_acc_info = next_account_info(acc_infos)?; - let ctx = EntityContext { + let AccessControlResponse { ref registrar } = access_control(AccessControlRequest { + member_vault_authority_acc_info, + depositor_acc_info, + member_acc_info, + beneficiary_acc_info, entity_acc_info, - registrar_acc_info, - clock_acc_info, + member_vault_acc_info, program_id, - }; - with_entity(ctx, &mut |entity: &mut Entity, - registrar: &Registrar, - _: &Clock| { - let AccessControlResponse { ref depositor } = access_control(AccessControlRequest { - vault_authority_acc_info, - depositor_acc_info, - member_acc_info, - beneficiary_acc_info, - entity_acc_info, - vault_acc_info, - program_id, - registrar_acc_info, - registrar, - depositor_authority_acc_info, - amount, - delegate, - })?; - Member::unpack_mut( - &mut member_acc_info.try_borrow_mut_data()?, - &mut |member: &mut Member| { - state_transition(StateTransitionRequest { - entity, - member, - amount, - registrar: ®istrar, - registrar_acc_info, - vault_acc_info, - vault_authority_acc_info, - depositor_acc_info, - token_program_acc_info, - depositor, - }) - .map_err(Into::into) - }, - ) - .map_err(Into::into) + registrar_acc_info, + depositor_authority_acc_info, + amount, + })?; + state_transition(StateTransitionRequest { + amount, + registrar, + registrar_acc_info, + member_vault_acc_info, + member_vault_authority_acc_info, + depositor_acc_info, + token_program_acc_info, })?; Ok(()) } fn access_control(req: AccessControlRequest) -> Result { - info!("access-control: withdraw"); + msg!("access-control: withdraw"); let AccessControlRequest { - vault_authority_acc_info, + member_vault_authority_acc_info, depositor_acc_info, member_acc_info, beneficiary_acc_info, entity_acc_info, - vault_acc_info, + member_vault_acc_info, registrar_acc_info, - registrar, depositor_authority_acc_info, program_id, amount, - delegate, } = req; // Authorization. @@ -109,57 +79,52 @@ fn access_control(req: AccessControlRequest) -> Result Result<(), RegistryError> { - info!("state-transition: withdraw"); + msg!("state-transition: withdraw"); let StateTransitionRequest { - entity, - member, amount, registrar, registrar_acc_info, - vault_authority_acc_info, + member_vault_authority_acc_info, depositor_acc_info, - depositor, - vault_acc_info, + member_vault_acc_info, token_program_acc_info, } = req; - // Transfer funds from the program vault back to the original depositor. + // Transfer tokens out. invoke_token_transfer( - vault_acc_info, + member_vault_acc_info, depositor_acc_info, - vault_authority_acc_info, + member_vault_authority_acc_info, token_program_acc_info, &[&vault::signer_seeds( registrar_acc_info.key, @@ -168,43 +133,32 @@ fn state_transition(req: StateTransitionRequest) -> Result<(), RegistryError> { amount, )?; - let is_mega = registrar.is_mega(*vault_acc_info.key)?; - member.did_withdraw(amount, is_mega, depositor.owner); - entity.did_withdraw(amount, is_mega); - - info!("state-transition: success"); - Ok(()) } -struct AccessControlRequest<'a, 'b, 'c> { +struct AccessControlRequest<'a, 'b> { registrar_acc_info: &'a AccountInfo<'b>, - vault_authority_acc_info: &'a AccountInfo<'b>, + member_vault_authority_acc_info: &'a AccountInfo<'b>, depositor_acc_info: &'a AccountInfo<'b>, depositor_authority_acc_info: &'a AccountInfo<'b>, member_acc_info: &'a AccountInfo<'b>, beneficiary_acc_info: &'a AccountInfo<'b>, entity_acc_info: &'a AccountInfo<'b>, - vault_acc_info: &'a AccountInfo<'b>, + member_vault_acc_info: &'a AccountInfo<'b>, program_id: &'a Pubkey, - registrar: &'c Registrar, amount: u64, - delegate: bool, } struct AccessControlResponse { - depositor: TokenAccount, + registrar: Registrar, } struct StateTransitionRequest<'a, 'b, 'c> { registrar_acc_info: &'a AccountInfo<'b>, - vault_acc_info: &'a AccountInfo<'b>, - vault_authority_acc_info: &'a AccountInfo<'b>, + member_vault_acc_info: &'a AccountInfo<'b>, + member_vault_authority_acc_info: &'a AccountInfo<'b>, depositor_acc_info: &'a AccountInfo<'b>, token_program_acc_info: &'a AccountInfo<'b>, - entity: &'c mut Entity, - member: &'c mut Member, registrar: &'c Registrar, - depositor: &'c TokenAccount, amount: u64, } diff --git a/registry/src/access_control.rs b/registry/src/access_control.rs index 47f0a4c..eac1deb 100644 --- a/registry/src/access_control.rs +++ b/registry/src/access_control.rs @@ -1,7 +1,7 @@ use crate::accounts::reward_queue::Ring; use crate::accounts::{ - vault, Entity, LockedRewardVendor, Member, PendingWithdrawal, Registrar, RewardEventQueue, - UnlockedRewardVendor, + vault, BalanceSandbox, Entity, LockedRewardVendor, Member, PendingWithdrawal, Registrar, + RewardEventQueue, UnlockedRewardVendor, }; use crate::error::{RegistryError, RegistryErrorCode}; use serum_common::pack::*; @@ -12,6 +12,7 @@ use solana_client_gen::solana_sdk::pubkey::Pubkey; use solana_client_gen::solana_sdk::sysvar::clock::Clock; use solana_client_gen::solana_sdk::sysvar::rent::Rent; use solana_client_gen::solana_sdk::sysvar::Sysvar; +use solana_sdk::program_option::COption; use spl_token::state::{Account as TokenAccount, Mint}; #[inline] @@ -41,6 +42,7 @@ pub fn registrar(acc_info: &AccountInfo, program_id: &Pubkey) -> Result, - is_delegate: bool, -) -> Result<(), RegistryError> { - if is_delegate && *delegate_owner_acc_info.unwrap().key != member.balances.delegate.owner { - return Err(RegistryErrorCode::MemberDelegateMismatch)?; - } - Ok(()) -} - pub fn member( acc_info: &AccountInfo, beneficiary_acc_info: &AccountInfo, @@ -178,6 +169,115 @@ pub fn member_raw( Ok(m) } +#[inline(never)] +pub fn member_vault( + member: &Member, + member_vault_acc_info: &AccountInfo, + member_vault_authority_acc_info: &AccountInfo, + registrar_acc_info: &AccountInfo, + registrar: &Registrar, + program_id: &Pubkey, + balance_id: &Pubkey, +) -> Result<(TokenAccount, bool), RegistryError> { + let member_vault = vault_authenticated( + member_vault_acc_info, + member_vault_authority_acc_info, + registrar_acc_info, + ®istrar, + program_id, + )?; + let b = member + .balances + .iter() + .filter(|b| &b.owner == balance_id) + .collect::>(); + let balances = b.first().ok_or(RegistryErrorCode::InvalidBalanceSandbox)?; + + let is_mega = { + if &balances.vault != member_vault_acc_info.key + && &balances.vault_mega != member_vault_acc_info.key + { + return Err(RegistryErrorCode::InvalidVault)?; + } + member_vault_acc_info.key == &balances.vault_mega + }; + + Ok((member_vault, is_mega)) +} + +#[inline(never)] +pub fn member_vault_stake( + member: &Member, + member_vault_acc_info: &AccountInfo, + member_vault_authority_acc_info: &AccountInfo, + registrar_acc_info: &AccountInfo, + registrar: &Registrar, + program_id: &Pubkey, + balance_id: &Pubkey, +) -> Result<(TokenAccount, bool), RegistryError> { + let member_vault = vault_authenticated( + member_vault_acc_info, + member_vault_authority_acc_info, + registrar_acc_info, + ®istrar, + program_id, + )?; + + let b = member + .balances + .iter() + .filter(|b| &b.owner == balance_id) + .collect::>(); + let balances = b.first().ok_or(RegistryErrorCode::InvalidBalanceSandbox)?; + + let is_mega = { + if member_vault_acc_info.key != &balances.vault_stake + && member_vault_acc_info.key != &balances.vault_stake_mega + { + return Err(RegistryErrorCode::InvalidStakeVault)?; + } + member_vault_acc_info.key == &balances.vault_stake_mega + }; + + Ok((member_vault, is_mega)) +} + +pub fn member_vault_pending_withdrawal( + member: &Member, + member_vault_acc_info: &AccountInfo, + member_vault_authority_acc_info: &AccountInfo, + registrar_acc_info: &AccountInfo, + registrar: &Registrar, + program_id: &Pubkey, + balance_id: &Pubkey, +) -> Result<(TokenAccount, bool), RegistryError> { + let member_vault = vault_authenticated( + member_vault_acc_info, + member_vault_authority_acc_info, + registrar_acc_info, + ®istrar, + program_id, + )?; + + let b = member + .balances + .iter() + .filter(|b| &b.owner == balance_id) + .collect::>(); + let balances = b.first().ok_or(RegistryErrorCode::InvalidBalanceSandbox)?; + + let is_mega = { + if member_vault_acc_info.key != &balances.vault_pending_withdrawal + && member_vault_acc_info.key != &balances.vault_pending_withdrawal_mega + { + return Err(RegistryErrorCode::InvalidPendingWithdrawalVault)?; + } + member_vault_acc_info.key == &balances.vault_pending_withdrawal_mega + }; + + Ok((member_vault, is_mega)) +} + pub fn reward_event_q<'a, 'b, 'c>( reward_event_q_acc_info: &'a AccountInfo<'b>, registrar_acc_info: &'a AccountInfo<'b>, @@ -197,23 +297,6 @@ pub fn reward_event_q<'a, 'b, 'c>( Ok(q) } -pub fn pool_vault( - pool_vault_acc_info: &AccountInfo, - registrar: &Registrar, -) -> Result<(TokenAccount, bool), RegistryError> { - let v = token_account(pool_vault_acc_info)?; - - if pool_vault_acc_info.key != ®istrar.pool_vault - && pool_vault_acc_info.key != ®istrar.pool_vault_mega - { - return Err(RegistryErrorCode::InvalidVault)?; - } - - let is_mega = pool_vault_acc_info.key == ®istrar.pool_vault_mega; - - Ok((v, is_mega)) -} - pub fn pool_mint( pool_mint_acc_info: &AccountInfo, registrar: &Registrar, @@ -234,25 +317,33 @@ pub fn pool_mint( Ok(mint) } -pub fn pool_token( +pub fn member_pool_token( + member: &Member, pool_token_acc_info: &AccountInfo, pool_mint_acc_info: &AccountInfo, - member: &Member, + balance_id: &Pubkey, is_mega: bool, ) -> Result { + let b = member + .balances + .iter() + .filter(|b| &b.owner == balance_id) + .collect::>(); + let balances = b.first().ok_or(RegistryErrorCode::InvalidBalanceSandbox)?; + if is_mega { - if &member.spt_mega != pool_token_acc_info.key { + if &balances.spt_mega != pool_token_acc_info.key { return Err(RegistryErrorCode::InvalidPoolToken)?; } } else { - if &member.spt != pool_token_acc_info.key { + if &balances.spt != pool_token_acc_info.key { return Err(RegistryErrorCode::InvalidPoolToken)?; } } let token = token_account(pool_token_acc_info)?; if &token.mint != pool_mint_acc_info.key { - return Err(RegistryErrorCode::InvalidPoolTokenMint)?; + return Err(RegistryErrorCode::InvalidPoolToken)?; } Ok(token) @@ -274,16 +365,12 @@ pub fn vault_authenticated( Ok(v) } -pub fn vault( +fn vault( acc_info: &AccountInfo, registrar_acc_info: &AccountInfo, registrar: &Registrar, program_id: &Pubkey, ) -> Result { - if registrar.vault != *acc_info.key && registrar.mega_vault != *acc_info.key { - return Err(RegistryErrorCode::RegistrarVaultMismatch)?; - } - let vault = TokenAccount::unpack(&acc_info.try_borrow_data()?)?; let expected_vault_auth = Pubkey::create_program_address( @@ -298,13 +385,76 @@ pub fn vault( Ok(vault) } +pub fn vault_pair( + vault_acc_info: &AccountInfo, + vault_mega_acc_info: &AccountInfo, + registrar_acc_info: &AccountInfo, + registrar: &Registrar, + rent: &Rent, + program_id: &Pubkey, +) -> Result<(), RegistryError> { + let v = vault_init( + vault_acc_info, + registrar_acc_info, + rent, + registrar.nonce, + program_id, + )?; + let v_mega = vault_init( + vault_mega_acc_info, + registrar_acc_info, + rent, + registrar.nonce, + program_id, + )?; + + if v.mint != registrar.mint { + return Err(RegistryErrorCode::InvalidMint)?; + } + if v_mega.mint != registrar.mega_mint { + return Err(RegistryErrorCode::InvalidMint)?; + } + Ok(()) +} + +pub fn pool_token_pair( + spt_acc_info: &AccountInfo, + spt_mega_acc_info: &AccountInfo, + registrar: &Registrar, + registry_signer_acc_info: &AccountInfo, +) -> Result<(), RegistryError> { + let spt = TokenAccount::unpack(&spt_acc_info.try_borrow_data()?)?; + let spt_mega = TokenAccount::unpack(&spt_mega_acc_info.try_borrow_data()?)?; + // Pool token owner must be the program derived address. + // Delegate must be None, since it will be set in this instruction. + if spt.delegate != COption::None { + return Err(RegistryErrorCode::SptDelegateAlreadySet)?; + } + if spt.owner != *registry_signer_acc_info.key { + return Err(RegistryErrorCode::InvalidStakeTokenOwner)?; + } + if spt.mint != registrar.pool_mint { + return Err(RegistryErrorCode::InvalidMint)?; + } + if spt_mega.delegate != COption::None { + return Err(RegistryErrorCode::SptDelegateAlreadySet)?; + } + if spt_mega.owner != *registry_signer_acc_info.key { + return Err(RegistryErrorCode::InvalidStakeTokenOwner)?; + } + if spt_mega.mint != registrar.pool_mint_mega { + return Err(RegistryErrorCode::InvalidMint)?; + } + Ok(()) +} + pub fn vault_init( vault_acc_info: &AccountInfo, registrar_acc_info: &AccountInfo, rent: &Rent, nonce: u8, program_id: &Pubkey, -) -> Result<(), RegistryError> { +) -> Result { let vault_authority = Pubkey::create_program_address( &vault::signer_seeds(registrar_acc_info.key, &nonce), program_id, @@ -317,7 +467,7 @@ pub fn vault_init( if !rent.is_exempt(vault_acc_info.lamports(), vault_acc_info.try_data_len()?) { return Err(RegistryErrorCode::NotRentExempt)?; } - Ok(()) + Ok(vault) } pub fn pending_withdrawal( @@ -373,6 +523,78 @@ pub fn unlocked_reward_vendor( Ok(vendor) } +pub fn balance_sandbox( + balances: &[BalanceSandboxAccInfo], + registrar_acc_info: &AccountInfo, + registrar: &Registrar, + registry_signer_acc_info: &AccountInfo, + rent: &Rent, + program_id: &Pubkey, +) -> Result<(), RegistryError> { + // Only allow two sets of balances for now (main and locked). + if balances.len() != 2 { + return Err(RegistryErrorCode::InvalidAssetsLen)?; + } + // Check the given balance assets are all unique accounts. + let mut all_accounts = vec![]; + for b in balances { + // Pool Tokens. + pool_token_pair( + b.spt_acc_info, + b.spt_mega_acc_info, + registrar, + registry_signer_acc_info, + )?; + + // Deposits. + vault_pair( + b.vault_acc_info, + b.vault_mega_acc_info, + registrar_acc_info, + ®istrar, + &rent, + program_id, + )?; + // Stake. + vault_pair( + b.vault_stake_acc_info, + b.vault_stake_mega_acc_info, + registrar_acc_info, + ®istrar, + &rent, + program_id, + )?; + // Pending withdrawals. + vault_pair( + b.vault_pw_acc_info, + b.vault_pw_mega_acc_info, + registrar_acc_info, + ®istrar, + &rent, + program_id, + )?; + + all_accounts.extend_from_slice(&[ + b.owner_acc_info.key, + b.spt_acc_info.key, + b.spt_mega_acc_info.key, + b.vault_acc_info.key, + b.vault_mega_acc_info.key, + b.vault_stake_acc_info.key, + b.vault_stake_mega_acc_info.key, + b.vault_pw_acc_info.key, + b.vault_pw_mega_acc_info.key, + ]); + } + let given_len = all_accounts.len(); + all_accounts.sort(); + all_accounts.dedup(); + if given_len != all_accounts.len() { + return Err(RegistryErrorCode::InvalidAssetsLen)?; + } + Ok(()) +} + pub fn token(acc_info: &AccountInfo, authority: &Pubkey) -> Result { let token = token_account(acc_info)?; if token.owner != *authority { @@ -413,3 +635,15 @@ pub fn mint(acc_info: &AccountInfo) -> Result { Mint::unpack(&acc_info.try_borrow_data()?).map_err(Into::into) } + +pub struct BalanceSandboxAccInfo<'a, 'b> { + pub owner_acc_info: &'a AccountInfo<'b>, + pub spt_acc_info: &'a AccountInfo<'b>, + pub spt_mega_acc_info: &'a AccountInfo<'b>, + pub vault_acc_info: &'a AccountInfo<'b>, + pub vault_mega_acc_info: &'a AccountInfo<'b>, + pub vault_stake_acc_info: &'a AccountInfo<'b>, + pub vault_stake_mega_acc_info: &'a AccountInfo<'b>, + pub vault_pw_acc_info: &'a AccountInfo<'b>, + pub vault_pw_mega_acc_info: &'a AccountInfo<'b>, +} diff --git a/registry/src/accounts/entity.rs b/registry/src/accounts/entity.rs index e5226b6..9488a5b 100644 --- a/registry/src/accounts/entity.rs +++ b/registry/src/accounts/entity.rs @@ -1,4 +1,4 @@ -use crate::accounts::{Member, Registrar}; +use crate::accounts::Registrar; use crate::error::RegistryError; use borsh::{BorshDeserialize, BorshSchema, BorshSerialize}; use serum_common::pack::*; @@ -12,6 +12,12 @@ lazy_static::lazy_static! { .expect("Entity has a fixed size"); } +// Conversion from base unit of SRM to base unit of MSRM. +// +// SRM has 6 decimals. MSRM ~ 1_000_000 SRM => 1 unit of +// the MSRM mint == 10**6 * 1_000_000 units of the SRM mint. +const MSRM_SRM_RATE: u64 = 1_000_000_000_000; + #[derive(Clone, Debug, BorshSerialize, BorshDeserialize, BorshSchema)] pub struct Entity { /// Set when this entity is registered. @@ -45,47 +51,11 @@ impl Default for Entity { } impl Entity { - pub fn remove(&mut self, member: &mut Member) { - self.balances.current_deposit -= member.balances.current_deposit; - self.balances.current_mega_deposit -= member.balances.current_mega_deposit; - self.balances.spt_amount -= member.balances.spt_amount; - self.balances.spt_mega_amount -= member.balances.spt_mega_amount; - } - - pub fn add(&mut self, member: &mut Member) { - self.balances.current_deposit += member.balances.current_deposit; - self.balances.current_mega_deposit += member.balances.current_mega_deposit; - self.balances.spt_amount += member.balances.spt_amount; - self.balances.spt_mega_amount += member.balances.spt_mega_amount; - } - - pub fn activation_amount(&self) -> u64 { - self.amount_equivalent() + self.current_deposit_equivalent() - } - - pub fn did_deposit(&mut self, amount: u64, mega: bool) { - if mega { - self.balances.current_mega_deposit += amount; - } else { - self.balances.current_deposit += amount; - } - } - - pub fn did_withdraw(&mut self, amount: u64, mega: bool) { - if mega { - self.balances.current_mega_deposit -= amount; - } else { - self.balances.current_deposit -= amount; - } - } - pub fn spt_did_stake(&mut self, amount: u64, is_mega: bool) -> Result<(), RegistryError> { if is_mega { self.balances.spt_mega_amount += amount; - self.balances.current_mega_deposit -= amount; } else { self.balances.spt_amount += amount; - self.balances.current_deposit -= amount; } Ok(()) @@ -99,19 +69,11 @@ impl Entity { } } - pub fn spt_did_unstake_end(&mut self, amount: u64, is_mega: bool) { - if is_mega { - self.balances.current_mega_deposit += amount; - } else { - self.balances.current_deposit += amount; - } - } - #[inline(never)] pub fn transition_activation_if_needed(&mut self, registrar: &Registrar, clock: &Clock) { match self.state { EntityState::Inactive => { - if self.meets_activation_requirements(registrar) { + if self.meets_activation_requirements() { self.state = EntityState::Active; } } @@ -122,12 +84,12 @@ impl Entity { if clock.unix_timestamp > deactivation_start_ts + timelock { self.state = EntityState::Inactive; } - if self.meets_activation_requirements(registrar) { + if self.meets_activation_requirements() { self.state = EntityState::Active; } } EntityState::Active => { - if !self.meets_activation_requirements(registrar) { + if !self.meets_activation_requirements() { self.state = EntityState::PendingDeactivation { deactivation_start_ts: clock.unix_timestamp, timelock: registrar.deactivation_timelock, @@ -137,27 +99,40 @@ impl Entity { } } - /// Returns true if this Entity is capable of being "activated", i.e., can - /// enter the staking pool. - pub fn meets_activation_requirements(&self, registrar: &Registrar) -> bool { - self.activation_amount() >= registrar.reward_activation_threshold - && (self.balances.spt_mega_amount >= 1 || self.balances.current_mega_deposit >= 1) + pub fn meets_activation_requirements(&self) -> bool { + self.balances.spt_mega_amount >= 1 } - pub fn slash(&mut self, spt_amount: u64, mega: bool) { - if mega { - self.balances.spt_mega_amount -= spt_amount; - } else { - self.balances.spt_amount -= spt_amount; - } - } - - pub fn amount_equivalent(&self) -> u64 { - self.balances.spt_amount + self.balances.spt_mega_amount * 1_000_000 - } - - fn current_deposit_equivalent(&self) -> u64 { - self.balances.current_deposit + self.balances.current_mega_deposit * 1_000_000 + pub fn stake_will_max(&self, spt_amount: u64, is_mega: bool, registrar: &Registrar) -> bool { + let spt_value = { + if is_mega { + spt_amount + .checked_mul(registrar.stake_rate_mega) + .unwrap() + .checked_mul(MSRM_SRM_RATE) + .unwrap() + } else { + spt_amount.checked_mul(registrar.stake_rate).unwrap() + } + }; + let amount_equivalent = spt_value + .checked_add( + self.balances + .spt_amount + .checked_mul(registrar.stake_rate) + .unwrap(), + ) + .unwrap() + .checked_add( + self.balances + .spt_mega_amount + .checked_mul(registrar.stake_rate_mega) + .unwrap() + .checked_mul(MSRM_SRM_RATE) + .unwrap(), + ) + .unwrap(); + amount_equivalent > registrar.max_stake_per_entity } } @@ -168,9 +143,6 @@ pub struct Balances { // Denominated in staking pool tokens. pub spt_amount: u64, pub spt_mega_amount: u64, - // Denominated in SRM/MSRM. - pub current_deposit: u64, - pub current_mega_deposit: u64, } #[derive(Clone, Debug, BorshSerialize, BorshDeserialize, BorshSchema, PartialEq)] diff --git a/registry/src/accounts/member.rs b/registry/src/accounts/member.rs index 0ae37f7..5851ae6 100644 --- a/registry/src/accounts/member.rs +++ b/registry/src/accounts/member.rs @@ -1,5 +1,4 @@ -use crate::error::{RegistryError, RegistryErrorCode}; -use borsh::{BorshDeserialize, BorshSchema, BorshSerialize}; +use borsh::{BorshDeserialize, BorshSerialize}; use serum_common::pack::*; use solana_client_gen::solana_sdk::pubkey::Pubkey; @@ -10,7 +9,7 @@ lazy_static::lazy_static! { .expect("Member has a fixed size"); } -#[derive(Default, Debug, BorshSerialize, BorshDeserialize)] +#[derive(Debug, BorshSerialize, BorshDeserialize)] pub struct Member { /// Set by the program on creation. pub initialized: bool, @@ -20,226 +19,58 @@ pub struct Member { pub beneficiary: Pubkey, /// Entity providing membership. pub entity: Pubkey, - /// SRM, MSRM, and staking pool token balances. - pub balances: MemberBalances, /// Arbitrary metadata account owned by any program. pub metadata: Pubkey, - /// Staking pool token account. - pub spt: Pubkey, - /// Mega staking pool token account. - pub spt_mega: Pubkey, + /// Sets of balances owned by the Member. Two for now: main and locked. + pub balances: Vec, /// Next position in the rewards event queue to process. pub rewards_cursor: u32, - /// The clock timestamp of the last time this account staked/unstaked. + /// The clock timestamp of the last time this account staked or switched + /// entities. + // TODO: For v2 we should keep a queue tracking each time the member staked + // or unstaked. Then reward vendors can deduce the amount members + // had staked at time of reward. For now, we use the last_stake_ts + // as an overly harsh mechanism for ensuring rewards are only + // given to those that were staked at the right time. pub last_stake_ts: i64, } -impl Member { - pub fn can_afford(&self, spt_amount: u64, mega: bool) -> bool { - if mega { - if self.balances.current_mega_deposit < spt_amount { - return false; - } - } else { - if self.balances.current_deposit < spt_amount { - return false; - } - } - true - } - - pub fn can_withdraw( - &self, - amount: u64, - mega: bool, - owner: Pubkey, - ) -> Result { - let delegate = self.balances.delegate.owner == owner; - - // In both cases, we need to be able to 1) cover the withdrawal - // with our *current* stake intent vault balances and also - // cover any future withdrawals needed to cover the cost basis - // of the delegate account. That is, all locked SRM/MSRM coming into the - // program must eventually go back. - if mega { - if amount > self.balances.current_mega_deposit { - return Err(RegistryErrorCode::InsufficientStakeIntentBalance)?; - } - if !delegate { - let remaining_msrm = - self.balances.spt_mega_amount + self.balances.current_mega_deposit - amount; - if remaining_msrm < self.balances.delegate.mega_deposit { - return Err(RegistryErrorCode::InsufficientBalance)?; - } - } - } else { - if amount > self.balances.current_deposit { - return Err(RegistryErrorCode::InsufficientStakeIntentBalance)?; - } - if !delegate { - let remaining_srm = - self.balances.spt_amount + self.balances.current_deposit - amount; - if remaining_srm < self.balances.delegate.deposit { - return Err(RegistryErrorCode::InsufficientBalance)?; - } - } - } - - Ok(true) - } - - pub fn stake_is_empty(&self) -> bool { - self.balances.spt_amount == 0 && self.balances.spt_mega_amount == 0 - } - - pub fn set_delegate(&mut self, delegate: Pubkey) { - assert!(self.balances.delegate.deposit == 0); - assert!(self.balances.delegate.mega_deposit == 0); - self.balances.delegate = OriginalDeposit::new(delegate); - } - - pub fn did_deposit(&mut self, amount: u64, mega: bool, owner: Pubkey) { - if mega { - self.balances.current_mega_deposit += amount; - } else { - self.balances.current_deposit += amount; - } - - let delegate = owner == self.balances.delegate.owner; - if delegate { - if mega { - self.balances.delegate.mega_deposit += amount; - } else { - self.balances.delegate.deposit += amount; - } - } else { - if mega { - self.balances.main.mega_deposit += amount; - } else { - self.balances.main.deposit += amount; - } +impl Default for Member { + fn default() -> Member { + Member { + initialized: false, + registrar: Pubkey::new_from_array([0; 32]), + beneficiary: Pubkey::new_from_array([0; 32]), + entity: Pubkey::new_from_array([0; 32]), + metadata: Pubkey::new_from_array([0; 32]), + balances: vec![BalanceSandbox::default(), BalanceSandbox::default()], + rewards_cursor: 0, + last_stake_ts: 0, } } +} - pub fn did_withdraw(&mut self, amount: u64, mega: bool, owner: Pubkey) { - if mega { - self.balances.current_mega_deposit -= amount; - } else { - self.balances.current_deposit -= amount; - } - - let delegate = owner == self.balances.delegate.owner; - if delegate { - if mega { - self.balances.delegate.mega_deposit -= amount; - } else { - self.balances.delegate.deposit -= amount; - } - } else { - if mega { - self.balances.main.mega_deposit -= amount; - } else { - self.balances.main.deposit -= amount; - } - } - } - - pub fn spt_did_stake(&mut self, amount: u64, mega: bool) -> Result<(), RegistryError> { - if mega { - self.balances.spt_mega_amount = - self.balances.spt_mega_amount.checked_add(amount).unwrap(); - self.balances.current_mega_deposit = self - .balances - .current_mega_deposit - .checked_sub(amount) - .unwrap(); - } else { - self.balances.spt_amount = self.balances.spt_amount.checked_add(amount).unwrap(); - self.balances.current_deposit = - self.balances.current_deposit.checked_sub(amount).unwrap(); - } - - Ok(()) - } - - pub fn spt_did_unstake_start(&mut self, spt_amount: u64, mega: bool) { - if mega { - self.balances.spt_mega_amount = self - .balances - .spt_mega_amount - .checked_sub(spt_amount) - .unwrap(); - } else { - self.balances.spt_amount = self.balances.spt_amount.checked_sub(spt_amount).unwrap(); - } - } - - pub fn spt_did_unstake_end(&mut self, amount: u64, is_mega: bool) { - if is_mega { - self.balances.current_mega_deposit += amount; - } else { - self.balances.current_deposit += amount; - } - } +// BalanceSandbox defines isolated funds that can only be deposited/withdrawn +// into the program if the `owner` signs off on the transaction. +// +// Once controlled by the program, the associated `Member` account's beneficiary +// can send funds to/from any of the accounts within the sandbox, e.g., to +// stake. +#[derive(Default, Debug, BorshSerialize, BorshDeserialize)] +pub struct BalanceSandbox { + pub owner: Pubkey, + // Staking pool token. + pub spt: Pubkey, + pub spt_mega: Pubkey, + // Free balance (deposit) vaults. + pub vault: Pubkey, + pub vault_mega: Pubkey, + // Stake vaults. + pub vault_stake: Pubkey, + pub vault_stake_mega: Pubkey, + // Pending withdrawal vaults. + pub vault_pending_withdrawal: Pubkey, + pub vault_pending_withdrawal_mega: Pubkey, } serum_common::packable!(Member); - -#[derive(Default, Debug, BorshSerialize, BorshDeserialize, BorshSchema)] -pub struct MemberBalances { - // The amount of SPT tokens in the SRM pool. - pub spt_amount: u64, - // The amount of SPT tokens in the MSRM pool. - pub spt_mega_amount: u64, - // SRM in the current_deposit vault. - pub current_deposit: u64, - // MSRM in the current_deposit vault. - pub current_mega_deposit: u64, - // Original deposit. - pub main: OriginalDeposit, - // Original deposit from delegate. - pub delegate: OriginalDeposit, -} - -impl MemberBalances { - pub fn new(beneficiary: Pubkey, delegate: Pubkey) -> Self { - Self { - spt_amount: 0, - spt_mega_amount: 0, - current_deposit: 0, - current_mega_deposit: 0, - main: OriginalDeposit::new(beneficiary), - delegate: OriginalDeposit::new(delegate), - } - } - - pub fn stake_is_empty(&self) -> bool { - self.spt_amount + self.spt_mega_amount == 0 - } -} - -// OriginalDeposit tracks the amount of tokens originally deposited into a Member -// account. These funds might be in either the deposit vault or the pool. -// -// It is used to track the amount of funds that must be returned to delegate -// programs, e.g., the lockup program. -#[derive(Default, Debug, BorshSerialize, BorshDeserialize, BorshSchema)] -pub struct OriginalDeposit { - pub owner: Pubkey, - pub deposit: u64, - pub mega_deposit: u64, -} - -impl OriginalDeposit { - pub fn new(owner: Pubkey) -> Self { - Self { - owner, - deposit: 0, - mega_deposit: 0, - } - } - - pub fn is_empty(&self) -> bool { - self.deposit + self.mega_deposit == 0 - } -} diff --git a/registry/src/accounts/mod.rs b/registry/src/accounts/mod.rs index f170377..bb82012 100644 --- a/registry/src/accounts/mod.rs +++ b/registry/src/accounts/mod.rs @@ -4,13 +4,12 @@ pub mod member; pub mod pending_withdrawal; pub mod registrar; pub mod reward_queue; -mod ring; pub mod unlocked_reward_vendor; pub mod vault; pub use entity::{Entity, EntityState}; pub use locked_reward_vendor::LockedRewardVendor; -pub use member::{Member, MemberBalances}; +pub use member::{BalanceSandbox, Member}; pub use pending_withdrawal::PendingWithdrawal; pub use registrar::Registrar; pub use reward_queue::{RewardEvent, RewardEventQueue}; diff --git a/registry/src/accounts/pending_withdrawal.rs b/registry/src/accounts/pending_withdrawal.rs index 21c574e..2602a73 100644 --- a/registry/src/accounts/pending_withdrawal.rs +++ b/registry/src/accounts/pending_withdrawal.rs @@ -23,8 +23,9 @@ pub struct PendingWithdrawal { pub start_ts: i64, /// Timestamp when the pending withdrawal completes. pub end_ts: i64, - /// The number of staking pool tokens redeemed. - pub spt_amount: u64, + /// The number of tokens redeemed from the staking pool. + pub amount: u64, + pub balance_id: Pubkey, } serum_common::packable!(PendingWithdrawal); diff --git a/registry/src/accounts/registrar.rs b/registry/src/accounts/registrar.rs index d20e5c5..20db3d4 100644 --- a/registry/src/accounts/registrar.rs +++ b/registry/src/accounts/registrar.rs @@ -1,4 +1,3 @@ -use crate::error::{RegistryError, RegistryErrorCode}; use borsh::{BorshDeserialize, BorshSchema, BorshSerialize}; use serum_common::pack::*; use solana_client_gen::solana_sdk::pubkey::Pubkey; @@ -29,32 +28,21 @@ pub struct Registrar { /// Number of seconds it takes for an Entity to be "deactivated", from the /// moment it's SRM/MSRM amount drops below the required threshold. pub deactivation_timelock: i64, - /// + /// Global event queue for reward vendoring. pub reward_event_q: Pubkey, - /// Vault holding deposit tokens. - pub vault: Pubkey, - /// Vault holding deposit mega tokens. - pub mega_vault: Pubkey, - /// Address of the SRM staking pool. - pub pool_vault: Pubkey, - /// Address of the MSRM staking pool. - pub pool_vault_mega: Pubkey, - /// + /// Mint of the tokens that can be staked. + pub mint: Pubkey, + /// Mint of the mega tokens that can be staked. + pub mega_mint: Pubkey, + /// Staking pool token mint. pub pool_mint: Pubkey, - /// + /// Staking pool (mega) token mint. pub pool_mint_mega: Pubkey, -} - -impl Registrar { - pub fn is_mega(&self, key: Pubkey) -> Result { - if key == self.vault { - Ok(false) - } else if key == self.mega_vault { - Ok(true) - } else { - Err(RegistryErrorCode::InvalidVault.into()) - } - } + /// The amount of tokens (not decimal) that must be staked to get a single + /// staking pool token. + pub stake_rate: u64, + /// Stake rate for the mega pool. + pub stake_rate_mega: u64, } serum_common::packable!(Registrar); diff --git a/registry/src/accounts/reward_queue.rs b/registry/src/accounts/reward_queue.rs index 96ab8b6..04af2b5 100644 --- a/registry/src/accounts/reward_queue.rs +++ b/registry/src/accounts/reward_queue.rs @@ -1,17 +1,14 @@ -use crate::error::{RegistryError, RegistryErrorCode}; -use arrayref::array_mut_ref; use borsh::{BorshDeserialize, BorshSerialize}; use serum_common::pack::*; use solana_client_gen::solana_sdk::pubkey::Pubkey; use std::cell::RefCell; -use std::convert::Into; use std::rc::Rc; // Largest reward variant size. const MAX_RING_ITEM_SIZE: u32 = 137; // Generate the Ring trait. -crate::ring!(MAX_RING_ITEM_SIZE); +serum_common::ring!(MAX_RING_ITEM_SIZE); pub struct RewardEventQueue<'a> { pub storage: Rc>, @@ -25,7 +22,9 @@ impl<'a> RewardEventQueue<'a> { } } -impl<'a> Ring<'a, RewardEvent> for RewardEventQueue<'a> { +impl<'a> Ring<'a> for RewardEventQueue<'a> { + type Item = RewardEvent; + fn buffer(&self) -> Rc> { self.storage.clone() } @@ -60,11 +59,11 @@ mod tests { #[test] fn measure() { let e = RewardEvent::LockedAlloc { - from: Pubkey::new_rand(), + from: Pubkey::new_unique(), total: 0, - pool: Pubkey::new_rand(), - vendor: Pubkey::new_rand(), - mint: Pubkey::new_rand(), + pool: Pubkey::new_unique(), + vendor: Pubkey::new_unique(), + mint: Pubkey::new_unique(), }; println!("TEST: {:?}", e.try_to_vec().unwrap().len()); } diff --git a/registry/src/error.rs b/registry/src/error.rs index 1d95bef..4ae6957 100644 --- a/registry/src/error.rs +++ b/registry/src/error.rs @@ -76,6 +76,10 @@ pub enum RegistryErrorCode { InvalidPoolToken = 62, InvariantViolation = 63, InsufficientReward = 64, + InvalidBalanceSandbox = 65, + InvalidSpt = 66, + InvalidPendingWithdrawalVault = 67, + InvalidStakeVault = 68, Unknown = 1000, } diff --git a/registry/src/lib.rs b/registry/src/lib.rs index c24b16f..014cf50 100644 --- a/registry/src/lib.rs +++ b/registry/src/lib.rs @@ -25,11 +25,15 @@ pub mod instruction { /// 6. `[]` Rent sysvar. Initialize { authority: Pubkey, + mint: Pubkey, + mint_mega: Pubkey, nonce: u8, withdrawal_timelock: i64, deactivation_timelock: i64, reward_activation_threshold: u64, max_stake_per_entity: u64, + stake_rate: u64, + stake_rate_mega: u64, }, /// Accounts: /// @@ -67,16 +71,12 @@ pub mod instruction { /// 2. `[]` Staking pool token. /// 3. `[]` Mega staking pool token. /// 4. `[]` Rent sysvar. - CreateMember { delegate: Pubkey }, + CreateMember, /// Accounts: /// /// 0. `[writable]` Member. /// 1. `[signer]` Beneficiary. - UpdateMember { - /// Delegate's OriginalDeposit must be 0, if updated. - delegate: Option, - metadata: Option, - }, + UpdateMember { metadata: Option }, /// Accounts: /// /// 0. `[writable]` Member. @@ -105,8 +105,6 @@ pub mod instruction { /// 7. `[]` Clock. /// 8. `[]` Vault (either the MSRM or SRM vault depending on /// depositor's mint). - /// - /// .. GetBasket pool accounts. Deposit { amount: u64 }, /// Accounts: /// @@ -126,8 +124,6 @@ pub mod instruction { /// 8. `[]` Clock. /// 9. `[]` Vault (either the MSRM or SRM vault depending on /// depositor's mint). - /// - /// .. GetBasket pool accounts. Withdraw { amount: u64 }, /// Accounts: /// @@ -137,9 +133,7 @@ pub mod instruction { /// 3. `[]` Registrar. /// 4. `[]` Clock sysvar. /// 5. `[]` Token program. - /// - /// .. Execute pool accounts. - Stake { amount: u64 }, + Stake { amount: u64, balance_id: Pubkey }, /// Accounts: /// /// 0. `[writable] PendingWithdrawal. @@ -151,12 +145,7 @@ pub mod instruction { /// 7. `[]` Token program. /// 8. `[]` Clock sysvar. /// 9. `[]` Rent sysvar. - /// - /// .. Execute pool accounts. - /// - /// -1. `[]` Generation (optional). Can be provided when - /// withdrawing from an *inactive* entity. - StartStakeWithdrawal { amount: u64 }, + StartStakeWithdrawal { amount: u64, balance_id: Pubkey }, /// Accounts: /// /// 0. `[writable] PendingWithdrawal. diff --git a/registry/tests/lifecycle.rs b/registry/tests/lifecycle.rs index 8729074..c5de112 100644 --- a/registry/tests/lifecycle.rs +++ b/registry/tests/lifecycle.rs @@ -42,10 +42,7 @@ fn lifecycle() { let registrar_authority = Keypair::generate(&mut OsRng); let InitializeResponse { - registrar, - nonce, - pool_vault, - .. + registrar, nonce, .. } = client .initialize(InitializeRequest { registrar_authority: registrar_authority.pubkey(), @@ -55,17 +52,18 @@ fn lifecycle() { mega_mint: msrm_mint.pubkey(), reward_activation_threshold, max_stake_per_entity, + stake_rate: 1, + stake_rate_mega: 1, }) .unwrap(); + // Verify initialization. - { - let registrar = client.registrar(®istrar).unwrap(); - assert_eq!(registrar.initialized, true); - assert_eq!(registrar.authority, registrar_authority.pubkey()); - } + let _registrar = client.registrar(®istrar).unwrap(); + assert_eq!(_registrar.initialized, true); + assert_eq!(_registrar.authority, registrar_authority.pubkey()); // Initialize the lockup program, vesting account, and whitelist the - // registrar so that we can stake locked srm. + // registrar so that we can stake lockedacc srm. let (l_client, safe, vesting, vesting_beneficiary) = { let l_pid: Pubkey = std::env::var("TEST_LOCKUP_PROGRAM_ID") .unwrap() @@ -135,7 +133,7 @@ fn lifecycle() { // Update entity. { - let new_leader = Pubkey::new_rand(); + let new_leader = Pubkey::new_unique(); let _ = client .update_entity(UpdateEntityRequest { entity, @@ -169,12 +167,6 @@ fn lifecycle() { assert_eq!(member_account.initialized, true); assert_eq!(member_account.entity, entity); assert_eq!(member_account.beneficiary, beneficiary.pubkey()); - assert_eq!( - member_account.balances.delegate.owner, - vesting_vault_authority, - ); - assert_eq!(member_account.balances.spt_amount, 0); - assert_eq!(member_account.balances.spt_mega_amount, 0); member }; @@ -194,7 +186,7 @@ fn lifecycle() { amount: current_deposit_amount, }) .unwrap(); - let vault = client.current_deposit_vault(®istrar).unwrap(); + let vault = client.current_deposit_vault(&member, false).unwrap(); assert_eq!(current_deposit_amount, vault.amount); let god_acc = rpc::get_token_account::(client.rpc(), &god.pubkey()).unwrap(); assert_eq!(god_acc.amount, god_balance_before - current_deposit_amount); @@ -212,7 +204,7 @@ fn lifecycle() { amount: current_deposit_amount, }) .unwrap(); - let vault = client.current_deposit_vault(®istrar).unwrap(); + let vault = client.current_deposit_vault(&member, false).unwrap(); assert_eq!(0, vault.amount); let god_acc = rpc::get_token_account::(client.rpc(), &god.pubkey()).unwrap(); assert_eq!(god_acc.amount, god_balance_before); @@ -224,7 +216,6 @@ fn lifecycle() { l_client .registry_deposit(RegistryDepositRequest { amount: current_deposit_amount, - is_mega: false, registry_pid: *client.program(), registrar, member, @@ -235,7 +226,7 @@ fn lifecycle() { safe, }) .unwrap(); - let vault = client.current_deposit_vault(®istrar).unwrap(); + let vault = client.current_deposit_vault(&member, true).unwrap(); assert_eq!(current_deposit_amount, vault.amount); let l_vault = l_client.vault_for(&vesting).unwrap(); assert_eq!(l_vault_amount - current_deposit_amount, l_vault.amount); @@ -246,7 +237,6 @@ fn lifecycle() { l_client .registry_withdraw(RegistryWithdrawRequest { amount: current_deposit_amount, - is_mega: false, registry_pid: *client.program(), registrar, member, @@ -257,7 +247,7 @@ fn lifecycle() { safe, }) .unwrap(); - let vault = client.current_deposit_vault(®istrar).unwrap(); + let vault = client.current_deposit_vault(&member, true).unwrap(); assert_eq!(0, vault.amount); let l_vault = l_client.vault_for(&vesting).unwrap(); assert_eq!(l_vault_amount, l_vault.amount); @@ -288,9 +278,10 @@ fn lifecycle() { beneficiary, pool_token_amount: 1, mega: true, + balance_id: client.payer().pubkey(), }) .unwrap(); - let user_pool_token_acc = client.mega_pool_token(&member).unwrap().account; + let user_pool_token_acc = client.mega_pool_token(&member, false).unwrap().account; assert_eq!(user_pool_token_acc.amount, 1); assert_eq!( user_pool_token_acc.owner, @@ -300,7 +291,7 @@ fn lifecycle() { user_pool_token_acc.delegate, COption::Some(beneficiary.pubkey()), ); - let msrm_vault = client.stake_mega_pool_asset_vaults(®istrar).unwrap(); + let msrm_vault = client.stake_mega_pool_asset_vault(&member, false).unwrap(); assert_eq!(msrm_vault.amount, 1); } @@ -328,9 +319,10 @@ fn lifecycle() { beneficiary, pool_token_amount: current_deposit_amount, mega: false, + balance_id: client.payer().pubkey(), }) .unwrap(); - let user_pool_token_acc = client.pool_token(&member).unwrap().account; + let user_pool_token_acc = client.pool_token(&member, false).unwrap().account; assert_eq!(user_pool_token_acc.amount, current_deposit_amount); assert_eq!( user_pool_token_acc.owner, @@ -341,10 +333,10 @@ fn lifecycle() { COption::Some(beneficiary.pubkey()), ); - let pool_vault_acc = client.stake_pool_asset_vault(®istrar).unwrap(); + let pool_vault_acc = client.stake_pool_asset_vault(&member, false).unwrap(); assert_eq!(pool_vault_acc.amount, current_deposit_amount); - let vault = client.current_deposit_vault(®istrar).unwrap(); + let vault = client.current_deposit_vault(&member, false).unwrap(); assert_eq!(vault.amount, 0); // Stake withdrawal start. @@ -360,22 +352,22 @@ fn lifecycle() { beneficiary, spt_amount: current_deposit_amount, mega: false, + balance_id: client.payer().pubkey(), }) .unwrap(); - let member_acc = client.member(&member).unwrap(); - assert_eq!(member_acc.balances.spt_amount, 0); - assert_eq!(member_acc.balances.current_deposit, 0); + let vault = client.current_deposit_vault(&member, false).unwrap(); + assert_eq!(vault.amount, 0); - let vault = client.current_deposit_vault(®istrar).unwrap(); - assert_eq!(vault.amount, current_deposit_amount); - - let user_pool_token = client.pool_token(&member).unwrap().account; + let user_pool_token = client.pool_token(&member, false).unwrap().account; assert_eq!(user_pool_token.amount, 0); - let pool_vault_acc = client.stake_pool_asset_vault(®istrar).unwrap(); + let pool_vault_acc = client.stake_pool_asset_vault(&member, false).unwrap(); assert_eq!(pool_vault_acc.amount, 0); + let pending_withdrawal_vault = client.pending_withdrawal_vault(&member, false).unwrap(); + assert_eq!(pending_withdrawal_vault.amount, current_deposit_amount); + // PendingWithdrawal. let pending_withdrawal_acc = client.pending_withdrawal(&pending_withdrawal).unwrap(); assert_eq!(pending_withdrawal_acc.initialized, true); @@ -384,8 +376,8 @@ fn lifecycle() { pending_withdrawal_acc.end_ts, pending_withdrawal_acc.start_ts + deactivation_timelock ); - assert_eq!(pending_withdrawal_acc.spt_amount, current_deposit_amount); - assert_eq!(pending_withdrawal_acc.pool, pool_vault); + assert_eq!(pending_withdrawal_acc.amount, current_deposit_amount); + assert_eq!(pending_withdrawal_acc.pool, _registrar.pool_mint); pending_withdrawal }; @@ -402,12 +394,9 @@ fn lifecycle() { pending_withdrawal, }) .unwrap(); - let vault = client.current_deposit_vault(®istrar).unwrap(); + let vault = client.current_deposit_vault(&member, false).unwrap(); assert_eq!(vault.amount, current_deposit_amount); - - let member = client.member(&member).unwrap(); - assert_eq!(member.balances.spt_amount, 0); - assert_eq!(member.balances.current_deposit, current_deposit_amount); + assert_eq!(client.pool_token(&member, false).unwrap().account.amount, 0); } // Withdraw MSRM. diff --git a/scripts/deploy-staking.sh b/scripts/deploy-staking.sh index 695e364..8b3c555 100755 --- a/scripts/deploy-staking.sh +++ b/scripts/deploy-staking.sh @@ -9,6 +9,15 @@ CLUSTER=l #CLUSTER=devnet +DEACTIVATION_TIMELOCK=60 +WITHDRAWAL_TIMELOCK=60 +# 100_000_000 million SRM (6 decimals) +MAX_STAKE_PER_ENTITY=100000000000000 +# 1 SRM to stake. +STAKE_RATE=1000000 +# 1 MSRM to stake. +STAKE_RATE_MEGA=1 +REWARD_ACTIVATION_THRESHOLD=1 main() { # First generate the genesis state, with the SRM/MSRM mints and @@ -54,10 +63,12 @@ main() { --msrm-mint $msrm_mint \ registry --pid $registry_pid \ init \ - --deactivation-timelock 60 \ - --reward-activation-threshold 1 \ - --withdrawal-timelock 60 \ - --max-stake-per-entity 100000000) + --deactivation-timelock $DEACTIVATION_TIMELOCK \ + --reward-activation-threshold $REWARD_ACTIVATION_THRESHOLD \ + --withdrawal-timelock $WITHDRAWAL_TIMELOCK \ + --max-stake-per-entity $MAX_STAKE_PER_ENTITY \ + --stake-rate $STAKE_RATE \ + --stake-rate-mega $STAKE_RATE_MEGA) local registrar=$(echo $rInit | jq .registrar -r) local registrar_nonce=$(echo $rInit | jq .nonce -r) local reward_q=$(echo $rInit | jq .rewardEventQueue -r)