registry: Member balance isolation

This commit is contained in:
armaniferrante 2020-12-03 12:09:58 -08:00
parent f7651516fd
commit 08acb76d3d
No known key found for this signature in database
GPG Key ID: 58BEF301E91F7828
51 changed files with 2304 additions and 2242 deletions

View File

@ -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:

View File

@ -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.
//
// 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<RefCell<&'a mut [u8]>>;
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<Vec<T>, RegistryError> {
fn messages_rev(&self) -> Result<Vec<Self::Item>, 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<T, RegistryError> {
fn message_at(&self, cursor: u32) -> Result<Self::Item, ProgramError> {
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<u32, RegistryError> {
fn head(&self) -> Result<u32, ProgramError> {
Ok(self.head_cursor()? % self.capacity())
}
fn head_cursor(&self) -> Result<u32, RegistryError> {
fn head_cursor(&self) -> Result<u32, ProgramError> {
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<u32, RegistryError> {
fn tail(&self) -> Result<u32, ProgramError> {
Ok(self.tail_cursor()? % self.capacity())
}
fn tail_cursor(&self) -> Result<u32, RegistryError> {
fn tail_cursor(&self) -> Result<u32, ProgramError> {
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<RefCell<&'a mut [u8]>> {
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(),
};

View File

@ -4,6 +4,7 @@
pub mod client;
#[macro_use]
pub mod pack;
pub mod accounts;
#[cfg(feature = "program")]
pub mod program;

View File

@ -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<Self, ProgramError> {
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<F, U>(input: &mut [u8], f: &mut F) -> Result<U, ProgramError>
where
F: FnMut(&mut Self) -> Result<U, ProgramError>,

View File

@ -23,7 +23,7 @@ pub static TEST_CLUSTER: &str = "TEST_CLUSTER";
pub fn genesis<T: ClientGen>() -> Genesis<T> {
let client = client::<T>();
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();

View File

@ -1,4 +1,4 @@
use anyhow::{anyhow, Result};
use anyhow::Result;
use clap::Clap;
use serum_lockup::accounts::WhitelistEntry;
use serum_lockup_client::*;

View File

@ -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;

View File

@ -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 {
&registry_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<RegistryWithdrawResponse, ClientError> {
let RegistryWithdrawRequest {
amount,
is_mega, // TODO: remove.
registry_pid,
registrar,
member,
@ -346,16 +342,14 @@ impl Client {
&registry_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,

View File

@ -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"

View File

@ -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])
}

View File

@ -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<AccessControlResponse, LockupError> {
info!("access-control: create_vesting");
msg!("access-control: create_vesting");
let AccessControlRequest {
program_id,
@ -151,7 +151,7 @@ fn access_control(req: AccessControlRequest) -> Result<AccessControlResponse, Lo
}
fn state_transition(req: StateTransitionRequest) -> Result<(), LockupError> {
info!("state-transition: create_vesting");
msg!("state-transition: create_vesting");
let StateTransitionRequest {
clock_ts,

View File

@ -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:

View File

@ -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::<Client>(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!(

View File

@ -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,
&registrar_vault_authority,
client.payer(),
)
.map_err(|e| InnerClientError::RawError(e.to_string()))?;
let msrm_vault = rpc::create_token_account(
client.rpc(),
mega_mint,
&registrar_vault_authority,
client.payer(),
)
.map_err(|e| InnerClientError::RawError(e.to_string()))?;
let pool_vault = rpc::create_token_account(
client.rpc(),
mint,
&registrar_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,
&registrar_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(),
&registrar_vault_authority,
decimals,
)
.map_err(|e| InnerClientError::RawError(e.to_string()))?
.0
.pubkey();
let mega_pool_mint = rpc::new_mint(
client.rpc(),
client.payer(),
&registrar_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(),
&registrar_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, &registrar_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<Instruction> {
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,
]
}

File diff suppressed because it is too large Load Diff

View File

@ -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"

View File

@ -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)
}
};

View File

@ -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<u8>,
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(())
}

View File

@ -2,4 +2,4 @@ pub mod metadata;
pub mod mqueue;
pub use metadata::Metadata;
pub use mqueue::MQueue;
pub use mqueue::{MQueue, Message};

View File

@ -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) || <MESSAGE_0> || <MESSAGE_1> || ... <MESSAGE_N>
pub struct MQueue<'a> {
pub storage: Rc<RefCell<&'a mut [u8]>>,
}
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<RefCell<&'a mut [u8]>>) -> Self {
Self { storage }
}
pub fn append(&self, mut data: Vec<u8>) -> Result<(), MetaEntityError> {
if data.len() > MQueue::MESSAGE_SIZE as usize {
return Err(MetaEntityErrorCode::InvalidMessageSize)?;
}
let head = self.head()?;
let tail = self.tail()?;
// 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(())
}
pub fn messages_rev(&self) -> Result<Vec<Message>, MetaEntityError> {
let data = self.storage.borrow();
let head = self.head()?;
let tail = self.tail()?;
impl<'a> Ring<'a> for MQueue<'a> {
type Item = Message;
// Empty.
if head == tail {
return Ok(vec![]);
fn buffer(&self) -> Rc<RefCell<&'a mut [u8]>> {
self.storage.clone()
}
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<Message, MetaEntityError> {
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<u32, MetaEntityError> {
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<u32, MetaEntityError> {
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);
}
}

View File

@ -28,7 +28,7 @@ pub mod instruction {
chat: Option<Pubkey>,
},
SendMessage {
data: Vec<u8>,
msg: accounts::Message,
},
}
}

View File

@ -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"

View File

@ -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<AccessControlResponse, RegistryError> {
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<AccessControlResponse, Re
entity_acc_info,
member_acc_info,
vendor_acc_info,
spt_acc_infos,
clock_acc_info,
} = req;
// Authorization: none required. This operation is purely beneficial for
// the member account.
// Account validation.
let clock = access_control::clock(clock_acc_info)?;
let registrar = access_control::registrar(registrar_acc_info, program_id)?;
let entity = access_control::entity(entity_acc_info, registrar_acc_info, program_id)?;
let member = access_control::member_belongs_to(
@ -100,6 +113,23 @@ fn access_control(req: AccessControlRequest) -> Result<AccessControlResponse, Re
)?;
let vendor =
access_control::locked_reward_vendor(vendor_acc_info, registrar_acc_info, program_id)?;
let is_mega = vendor.pool == registrar.pool_mint_mega;
let spts = spt_acc_infos
.iter()
.enumerate()
.map(|(idx, spt_acc_info)| {
if is_mega {
if &member.balances[idx].spt_mega != spt_acc_info.key {
return Err(RegistryErrorCode::InvalidSpt)?;
}
} else {
if &member.balances[idx].spt != spt_acc_info.key {
return Err(RegistryErrorCode::InvalidSpt)?;
}
}
access_control::token_account(spt_acc_info)
})
.collect::<Result<_, _>>()?;
// ClaimLockedReward specific.
//
@ -120,11 +150,15 @@ fn access_control(req: AccessControlRequest) -> Result<AccessControlResponse, Re
return Err(RegistryErrorCode::EntityNotActivated)?;
}
Ok(AccessControlResponse { registrar, vendor })
Ok(AccessControlResponse {
vendor,
spts,
clock,
})
}
fn state_transition(req: StateTransitionRequest) -> 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,25 +176,31 @@ 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();
// 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
}
};
if amount > 0 {
let ix = {
let instr = LockupInstruction::CreateVesting {
beneficiary: member.beneficiary,
end_ts: vendor.end_ts,
end_ts,
period_count: vendor.period_count,
deposit_amount: amount,
nonce,
@ -203,6 +242,7 @@ fn state_transition(req: StateTransitionRequest) -> Result<(), RegistryError> {
],
&[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<TokenAccount>,
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],
}

View File

@ -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<AccessControlResponse, RegistryError> {
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<AccessControlResponse, Re
member_acc_info,
vendor_acc_info,
token_acc_info,
spt_acc_infos,
} = req;
// Authorization: none required. This operation is purely beneficial for
@ -90,6 +98,23 @@ fn access_control(req: AccessControlRequest) -> Result<AccessControlResponse, Re
let vendor =
access_control::unlocked_reward_vendor(vendor_acc_info, registrar_acc_info, program_id)?;
let _token = access_control::token(token_acc_info, &member.beneficiary)?;
let is_mega = vendor.pool == registrar.pool_mint_mega;
let spts = spt_acc_infos
.iter()
.enumerate()
.map(|(idx, spt_acc_info)| {
if is_mega {
if &member.balances[idx].spt != spt_acc_info.key {
return Err(RegistryErrorCode::InvalidSpt)?;
}
} else {
if &member.balances[idx].spt_mega != spt_acc_info.key {
return Err(RegistryErrorCode::InvalidSpt)?;
}
}
access_control::token_account(spt_acc_info)
})
.collect::<Result<_, _>>()?;
// ClaimLockedReward specific.
//
@ -110,34 +135,28 @@ fn access_control(req: AccessControlRequest) -> Result<AccessControlResponse, Re
return Err(RegistryErrorCode::EntityNotActivated)?;
}
Ok(AccessControlResponse { registrar, vendor })
Ok(AccessControlResponse { vendor, spts })
}
fn state_transition(req: StateTransitionRequest) -> 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<TokenAccount>,
}
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>,

View File

@ -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(&registrar_acc_info, program_id)?;
let registrar = access_control::registrar(registrar_acc_info, program_id)?;
let _ = access_control::entity_check(
entity,
entity_acc_info,

View File

@ -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,
}

View File

@ -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: &registrar,
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<AccessControlResponse, RegistryError> {
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<AccessControlResponse, Re
registrar_acc_info,
registry_signer_acc_info,
program_id,
spt_acc_info,
spt_mega_acc_info,
balances,
} = req;
// Authorization.
@ -94,9 +94,6 @@ fn access_control(req: AccessControlRequest) -> Result<AccessControlResponse, Re
if !rent.is_exempt(member_acc_info.lamports(), member_acc_info.try_data_len()?) {
return Err(RegistryErrorCode::NotRentExempt)?;
}
// Use unpack_unchecked since the data will be zero initialized
// and so won't consume the entire slice (since Member has internal
// state using Vecs).
let mut data: &[u8] = &member_acc_info.try_borrow_data()?;
let member = Member::unpack_unchecked(&mut data)?;
if member_acc_info.owner != program_id {
@ -105,74 +102,78 @@ fn access_control(req: AccessControlRequest) -> Result<AccessControlResponse, Re
if member.initialized {
return Err(RegistryErrorCode::AlreadyInitialized)?;
}
// Pool token owner must be the program derived address.
// Delegate must be None; it will be set in this instruction.
let spt = TokenAccount::unpack(&spt_acc_info.try_borrow_data()?)?;
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)?;
}
let spt_mega = TokenAccount::unpack(&spt_mega_acc_info.try_borrow_data()?)?;
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)?;
// Registry signer.
let vault_authority = Pubkey::create_program_address(
&vault::signer_seeds(registrar_acc_info.key, &registrar.nonce),
program_id,
)
.map_err(|_| RegistryErrorCode::InvalidVaultNonce)?;
if &vault_authority != registry_signer_acc_info.key {
return Err(RegistryErrorCode::InvalidVaultAuthority)?;
}
// All balance accounts.
access_control::balance_sandbox(
balances,
registrar_acc_info,
&registrar,
registry_signer_acc_info,
&rent,
program_id,
)?;
Ok(AccessControlResponse { registrar })
}
fn state_transition(req: StateTransitionRequest) -> 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::<Result<Vec<BalanceSandbox>, 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>],
}

View File

@ -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,
entity_acc_info,
clock_acc_info,
program_id,
};
with_entity(ctx, &mut |entity: &mut Entity,
registrar: &Registrar,
_: &Clock| {
let AccessControlResponse { depositor } = access_control(AccessControlRequest {
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,
member_vault_acc_info,
member_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)
member_vault_acc_info,
})?;
Ok(())
}
fn access_control(req: AccessControlRequest) -> Result<AccessControlResponse, RegistryError> {
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<AccessControlResponse, Re
member_acc_info,
beneficiary_acc_info,
entity_acc_info,
vault_acc_info,
vault_authority_acc_info,
member_vault_acc_info,
member_vault_authority_acc_info,
registrar_acc_info,
registrar,
program_id,
delegate,
} = req;
// Authorization.
@ -105,92 +72,68 @@ fn access_control(req: AccessControlRequest) -> Result<AccessControlResponse, Re
if !depositor_authority_acc_info.is_signer {
return Err(RegistryErrorCode::Unauthorized)?;
}
// Account validation.
let registrar = access_control::registrar(registrar_acc_info, program_id)?;
let _depositor = access_control::token(depositor_acc_info, depositor_authority_acc_info.key)?;
let member = access_control::member_join(
member_acc_info,
entity_acc_info,
beneficiary_acc_info,
program_id,
)?;
let _vault = access_control::vault_authenticated(
vault_acc_info,
vault_authority_acc_info,
let (_member_vault, _is_mega) = access_control::member_vault(
&member,
member_vault_acc_info,
member_vault_authority_acc_info,
registrar_acc_info,
registrar,
&registrar,
program_id,
depositor_authority_acc_info.key,
)?;
// Deposit specific.
//
// Authenticate the delegate boolean.
let depositor = access_control::token(depositor_acc_info, depositor_authority_acc_info.key)?;
if delegate != (depositor.owner == member.balances.delegate.owner) {
return Err(RegistryErrorCode::DepositorOwnerDelegateMismatch)?;
}
Ok(AccessControlResponse { depositor })
Ok(())
}
fn state_transition(req: StateTransitionRequest) -> 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,
}

View File

@ -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<AccessControlResponse, RegistryError> {
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<AccessControlResponse, Re
//
// Registrar.
let registrar = access_control::registrar(registrar_acc_info, program_id)?;
if &registrar.pool_vault != pool_vault_acc_info.key
&& &registrar.pool_vault_mega != pool_vault_acc_info.key
{
return Err(RegistryErrorCode::InvalidPoolAccounts)?;
}
// Pool.
let pool_token_mint = access_control::mint(pool_token_mint_acc_info)?;
if registrar.pool_mint != *pool_token_mint_acc_info.key
&& registrar.pool_mint_mega != *pool_token_mint_acc_info.key
let pool_mint = access_control::mint(pool_mint_acc_info)?;
if registrar.pool_mint != *pool_mint_acc_info.key
&& registrar.pool_mint_mega != *pool_mint_acc_info.key
{
return Err(RegistryErrorCode::InvalidPoolTokenMint)?;
}
let is_mega = &registrar.pool_vault_mega == pool_vault_acc_info.key;
if is_mega {
if &registrar.pool_mint_mega != pool_token_mint_acc_info.key {
return Err(RegistryErrorCode::InvalidPoolTokenMint)?;
}
} else {
if &registrar.pool_mint != pool_token_mint_acc_info.key {
return Err(RegistryErrorCode::InvalidPoolTokenMint)?;
}
}
// Vault + nonce.
let vendor_vault_authority = Pubkey::create_program_address(
&[
@ -154,19 +136,16 @@ fn access_control(req: AccessControlRequest) -> Result<AccessControlResponse, Re
return Err(RegistryErrorCode::InvalidExpiry)?;
}
// Must be dropping enough to give at least one token to everyone in pool.
if total < pool_token_mint.supply {
if total < pool_mint.supply {
return Err(RegistryErrorCode::InsufficientReward)?;
}
Ok(AccessControlResponse {
pool_token_mint,
clock,
})
Ok(AccessControlResponse { pool_mint, clock })
}
#[inline(always)]
fn state_transition(req: StateTransitionRequest) -> 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,
}

View File

@ -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<AccessControlResponse, RegistryError> {
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<AccessControlResponse, Re
//
// Registrar.
let registrar = access_control::registrar(registrar_acc_info, program_id)?;
if &registrar.pool_vault != pool_vault_acc_info.key
&& &registrar.pool_vault_mega != pool_vault_acc_info.key
{
return Err(RegistryErrorCode::InvalidPoolAccounts)?;
}
// Pool.
let pool_token_mint = access_control::mint(pool_token_mint_acc_info)?;
if registrar.pool_mint != *pool_token_mint_acc_info.key
&& registrar.pool_mint_mega != *pool_token_mint_acc_info.key
let pool_token_mint = access_control::mint(pool_mint_acc_info)?;
if registrar.pool_mint != *pool_mint_acc_info.key
&& registrar.pool_mint_mega != *pool_mint_acc_info.key
{
return Err(RegistryErrorCode::InvalidPoolTokenMint)?;
}
let is_mega = &registrar.pool_vault_mega == pool_vault_acc_info.key;
if is_mega {
if &registrar.pool_mint_mega != pool_token_mint_acc_info.key {
return Err(RegistryErrorCode::InvalidPoolTokenMint)?;
}
} else {
if &registrar.pool_mint != pool_token_mint_acc_info.key {
return Err(RegistryErrorCode::InvalidPoolTokenMint)?;
}
}
// Vault + nonce.
let vendor_vault_authority = Pubkey::create_program_address(
&[
@ -157,7 +139,7 @@ fn access_control(req: AccessControlRequest) -> Result<AccessControlResponse, Re
#[inline(always)]
fn state_transition(req: StateTransitionRequest) -> 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>,

View File

@ -1,56 +1,57 @@
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,
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)
},
)
},
)
},
)?;
Ok(())
@ -58,7 +59,7 @@ pub fn handler(program_id: &Pubkey, accounts: &[AccountInfo]) -> Result<(), Regi
#[inline(always)]
fn access_control(req: AccessControlRequest) -> Result<AccessControlResponse, RegistryError> {
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<AccessControlResponse, Re
entity_acc_info,
clock_acc_info,
program_id,
member_vault_acc_info,
member_vault_pw_acc_info,
member_vault_authority_acc_info,
} = req;
// Authorization.
@ -78,7 +82,7 @@ fn access_control(req: AccessControlRequest) -> Result<AccessControlResponse, Re
// Account validation.
let registrar = access_control::registrar(registrar_acc_info, program_id)?;
let _entity = access_control::entity(entity_acc_info, registrar_acc_info, program_id)?;
let _member = access_control::member_join(
let member = access_control::member_join(
member_acc_info,
entity_acc_info,
beneficiary_acc_info,
@ -88,36 +92,78 @@ fn access_control(req: AccessControlRequest) -> Result<AccessControlResponse, Re
access_control::pending_withdrawal(pending_withdrawal_acc_info, program_id)?;
let clock = access_control::clock(clock_acc_info)?;
let b = member
.balances
.iter()
.filter(|b| b.owner == pending_withdrawal.balance_id)
.collect::<Vec<&BalanceSandbox>>();
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,
&registrar,
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,
&registrar,
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,
&registrar.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,
}

View File

@ -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,
}

View File

@ -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)

View File

@ -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<AccessControlResponse, RegistryError> {
info!("access-control: stake");
msg!("access-control: stake");
let AccessControlRequest {
member_acc_info,
@ -92,13 +94,16 @@ fn access_control(req: AccessControlRequest) -> Result<AccessControlResponse, Re
spt_amount,
entity,
program_id,
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,
pool_mint_acc_info,
balance_id,
} = req;
assert!(spt_amount > 0);
// Beneficiary authorization.
if !beneficiary_acc_info.is_signer {
return Err(RegistryErrorCode::Unauthorized)?;
@ -112,45 +117,50 @@ fn access_control(req: AccessControlRequest) -> Result<AccessControlResponse, Re
beneficiary_acc_info,
program_id,
)?;
let _vault = access_control::vault_authenticated(
vault_acc_info,
vault_authority_acc_info,
let (_member_vault, is_mega) = access_control::member_vault(
&member,
member_vault_acc_info,
member_vault_authority_acc_info,
registrar_acc_info,
registrar,
program_id,
balance_id,
)?;
let (_member_vault_stake, is_mega_stake) = access_control::member_vault_stake(
&member,
member_vault_stake_acc_info,
member_vault_authority_acc_info,
registrar_acc_info,
&registrar,
program_id,
balance_id,
)?;
assert!(is_mega == is_mega_stake);
let _pool_token = access_control::member_pool_token(
&member,
spt_acc_info,
pool_mint_acc_info,
balance_id,
is_mega,
)?;
let (_pool_vault, is_mega) = access_control::pool_vault(pool_vault_acc_info, &registrar)?;
let _pool_mint = access_control::pool_mint(pool_mint_acc_info, &registrar, is_mega)?;
let _pool_token =
access_control::pool_token(spt_acc_info, pool_mint_acc_info, &member, is_mega)?;
// Stake specific.
{
if !member.can_afford(spt_amount, is_mega) {
return Err(RegistryErrorCode::InsufficientStakeIntentBalance)?;
}
if !entity.meets_activation_requirements(&registrar) {
// Can only stake to active entities. Staking MSRM will activate.
if !entity.meets_activation_requirements() {
if !is_mega {
return Err(RegistryErrorCode::EntityNotActivated)?;
}
}
// Will this new stake put the entity over the maximum allowable limit?
let spt_worth = {
if is_mega {
spt_amount * 1_000_000
} else {
spt_amount
}
};
if spt_worth + entity.amount_equivalent() > registrar.max_stake_per_entity {
if entity.stake_will_max(spt_amount, is_mega, &registrar) {
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, &registrar.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>,

View File

@ -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,41 +53,37 @@ 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,
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<AccessControlResponse, RegistryError> {
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<AccessControlResponse, Re
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,
} = req;
// Beneficiary authorization.
@ -118,24 +116,40 @@ fn access_control(req: AccessControlRequest) -> Result<AccessControlResponse, Re
}
// Account validation.
let rent = access_control::rent(rent_acc_info)?;
let member = access_control::member_join(
member_acc_info,
entity_acc_info,
beneficiary_acc_info,
program_id,
)?;
let _vault = access_control::vault_authenticated(
vault_acc_info,
vault_authority_acc_info,
let (_member_vault, is_mega) = access_control::member_vault_pending_withdrawal(
&member,
member_vault_pw_acc_info,
member_vault_authority_acc_info,
registrar_acc_info,
registrar,
program_id,
balance_id,
)?;
let (_member_vault_stake, is_mega_stake) = access_control::member_vault_stake(
&member,
member_vault_stake_acc_info,
member_vault_authority_acc_info,
registrar_acc_info,
registrar,
program_id,
balance_id,
)?;
assert!(is_mega == is_mega_stake);
let _pool_token = access_control::member_pool_token(
&member,
spt_acc_info,
pool_mint_acc_info,
balance_id,
is_mega,
)?;
let (_pool_vault, is_mega) = access_control::pool_vault(pool_vault_acc_info, &registrar)?;
let _pool_mint = access_control::pool_mint(pool_mint_acc_info, &registrar, is_mega)?;
let _pool_token =
access_control::pool_token(spt_acc_info, pool_mint_acc_info, &member, is_mega)?;
let rent = access_control::rent(rent_acc_info)?;
// StartStakeWithdrawal specific.
{
@ -158,24 +172,24 @@ fn access_control(req: AccessControlRequest) -> Result<AccessControlResponse, Re
}
fn state_transition(req: StateTransitionRequest) -> 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, &registrar.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,
}

View File

@ -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: &registrar,
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<AccessControlResponse, RegistryError> {
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<AccessControlResponse, Re
curr_entity_acc_info,
new_entity_acc_info,
clock_acc_info,
asset_acc_infos,
vault_authority_acc_info,
} = req;
// Beneficiary authorization.
@ -80,7 +100,7 @@ fn access_control(req: AccessControlRequest) -> Result<AccessControlResponse, Re
// Account validation.
let clock = access_control::clock(clock_acc_info)?;
let registrar = access_control::registrar(registrar_acc_info, program_id)?;
let _member = access_control::member_join(
let member = access_control::member_join(
member_acc_info,
curr_entity_acc_info,
beneficiary_acc_info,
@ -89,13 +109,54 @@ fn access_control(req: AccessControlRequest) -> Result<AccessControlResponse, Re
let _curr_entity =
access_control::entity(curr_entity_acc_info, registrar_acc_info, program_id)?;
let _new_entity = access_control::entity(new_entity_acc_info, registrar_acc_info, program_id)?;
Ok(AccessControlResponse { registrar, clock })
let mut balance_ids: Vec<Pubkey> = 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,
&registrar,
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,
&registrar,
program_id,
a.owner_acc_info.key,
)?;
assert!(is_mega);
assets.push(Assets {
vault_stake,
vault_stake_mega,
})
}
#[inline(always)]
Ok(AccessControlResponse {
assets,
registrar,
clock,
})
}
#[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<AssetAccInfos<'a, 'b>>,
}
struct AccessControlResponse {
registrar: Registrar,
clock: Clock,
assets: Vec<Assets>,
}
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>,
}

View File

@ -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<Pubkey>,
metadata: Option<Pubkey>,
) -> 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,

View File

@ -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<Pubkey>,
metadata: Option<Pubkey>,
) -> 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<Pubkey>,
}
struct StateTransitionRequest<'a> {
member: &'a mut Member,
delegate: Option<Pubkey>,
metadata: Option<Pubkey>,
}

View File

@ -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<u64>,
max_stake_per_entity: Option<u64>,
) -> 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,

View File

@ -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 {
entity_acc_info,
registrar_acc_info,
clock_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,
let AccessControlResponse { ref registrar } = access_control(AccessControlRequest {
member_vault_authority_acc_info,
depositor_acc_info,
member_acc_info,
beneficiary_acc_info,
entity_acc_info,
vault_acc_info,
member_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: &registrar,
registrar,
registrar_acc_info,
vault_acc_info,
vault_authority_acc_info,
member_vault_acc_info,
member_vault_authority_acc_info,
depositor_acc_info,
token_program_acc_info,
depositor,
})
.map_err(Into::into)
},
)
.map_err(Into::into)
})?;
Ok(())
}
fn access_control(req: AccessControlRequest) -> Result<AccessControlResponse, RegistryError> {
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<AccessControlResponse, Re
}
// Account validation.
let registrar = access_control::registrar(registrar_acc_info, program_id)?;
let _depositor = access_control::token(depositor_acc_info, depositor_authority_acc_info.key)?;
let member = access_control::member_join(
member_acc_info,
entity_acc_info,
beneficiary_acc_info,
program_id,
)?;
let _vault = access_control::vault_authenticated(
vault_acc_info,
vault_authority_acc_info,
let (member_vault, _is_mega) = access_control::member_vault(
&member,
member_vault_acc_info,
member_vault_authority_acc_info,
registrar_acc_info,
&registrar,
program_id,
depositor_authority_acc_info.key,
)?;
// Withdraw specific.
//
// Authenticate the delegate boolean.
let depositor = access_control::token(depositor_acc_info, depositor_authority_acc_info.key)?;
if delegate != (depositor.owner == member.balances.delegate.owner) {
return Err(RegistryErrorCode::DepositorOwnerDelegateMismatch)?;
}
// Do we have enough funds for the withdrawal?
let is_mega = registrar.is_mega(*vault_acc_info.key)?;
if !member.can_withdraw(amount, is_mega, depositor.owner)? {
if !member_vault.amount < amount {
return Err(RegistryErrorCode::InsufficientBalance)?;
}
Ok(AccessControlResponse { depositor })
Ok(AccessControlResponse { registrar })
}
fn state_transition(req: StateTransitionRequest) -> 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,
}

View File

@ -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<Registra
Ok(registrar)
}
#[inline(never)]
pub fn entity(
acc_info: &AccountInfo,
registrar_acc_info: &AccountInfo,
@ -71,17 +73,6 @@ pub fn entity_check(
Ok(())
}
pub fn delegate_check(
member: &Member,
delegate_owner_acc_info: Option<&AccountInfo>,
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,
&registrar,
program_id,
)?;
let b = member
.balances
.iter()
.filter(|b| &b.owner == balance_id)
.collect::<Vec<&BalanceSandbox>>();
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,
&registrar,
program_id,
)?;
let b = member
.balances
.iter()
.filter(|b| &b.owner == balance_id)
.collect::<Vec<&BalanceSandbox>>();
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,
&registrar,
program_id,
)?;
let b = member
.balances
.iter()
.filter(|b| &b.owner == balance_id)
.collect::<Vec<&BalanceSandbox>>();
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 != &registrar.pool_vault
&& pool_vault_acc_info.key != &registrar.pool_vault_mega
{
return Err(RegistryErrorCode::InvalidVault)?;
}
let is_mega = pool_vault_acc_info.key == &registrar.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<TokenAccount, RegistryError> {
let b = member
.balances
.iter()
.filter(|b| &b.owner == balance_id)
.collect::<Vec<&BalanceSandbox>>();
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<TokenAccount, RegistryError> {
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<TokenAccount, RegistryError> {
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,
&registrar,
&rent,
program_id,
)?;
// Stake.
vault_pair(
b.vault_stake_acc_info,
b.vault_stake_mega_acc_info,
registrar_acc_info,
&registrar,
&rent,
program_id,
)?;
// Pending withdrawals.
vault_pair(
b.vault_pw_acc_info,
b.vault_pw_mega_acc_info,
registrar_acc_info,
&registrar,
&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<TokenAccount, RegistryError> {
let token = token_account(acc_info)?;
if token.owner != *authority {
@ -413,3 +635,15 @@ pub fn mint(acc_info: &AccountInfo) -> Result<Mint, RegistryError> {
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>,
}

View File

@ -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;
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 {
self.balances.spt_amount -= spt_amount;
spt_amount.checked_mul(registrar.stake_rate).unwrap()
}
}
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
};
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)]

View File

@ -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<BalanceSandbox>,
/// 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<bool, RegistryError> {
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)?;
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,
}
}
}
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;
}
}
}
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
}
}

View File

@ -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};

View File

@ -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);

View File

@ -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<bool, RegistryError> {
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);

View File

@ -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<RefCell<&'a mut [u8]>>,
@ -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<RefCell<&'a mut [u8]>> {
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());
}

View File

@ -76,6 +76,10 @@ pub enum RegistryErrorCode {
InvalidPoolToken = 62,
InvariantViolation = 63,
InsufficientReward = 64,
InvalidBalanceSandbox = 65,
InvalidSpt = 66,
InvalidPendingWithdrawalVault = 67,
InvalidStakeVault = 68,
Unknown = 1000,
}

View File

@ -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<Pubkey>,
metadata: Option<Pubkey>,
},
UpdateMember { metadata: Option<Pubkey> },
/// 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.

View File

@ -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(&registrar).unwrap();
assert_eq!(registrar.initialized, true);
assert_eq!(registrar.authority, registrar_authority.pubkey());
}
let _registrar = client.registrar(&registrar).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(&registrar).unwrap();
let vault = client.current_deposit_vault(&member, false).unwrap();
assert_eq!(current_deposit_amount, vault.amount);
let god_acc = rpc::get_token_account::<TokenAccount>(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(&registrar).unwrap();
let vault = client.current_deposit_vault(&member, false).unwrap();
assert_eq!(0, vault.amount);
let god_acc = rpc::get_token_account::<TokenAccount>(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(&registrar).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(&registrar).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(&registrar).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(&registrar).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(&registrar).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(&registrar).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(&registrar).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(&registrar).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.

View File

@ -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)