registry: Member balance isolation
This commit is contained in:
parent
f7651516fd
commit
08acb76d3d
16
.travis.yml
16
.travis.yml
|
@ -36,16 +36,12 @@ jobs:
|
|||
name: Lockup tests
|
||||
<<: *localnet
|
||||
script:
|
||||
- docker exec dev make -C lockup init-test features=strict
|
||||
|
||||
# Disabled because these tests require the shared memory program in the validator genesis,
|
||||
# which currently requires a custom local setup.
|
||||
#
|
||||
# - <<: *defaults
|
||||
# name: Registry tests
|
||||
# <<: *localnet
|
||||
# script:
|
||||
# - docker exec dev make -C registry init-test
|
||||
- docker exec dev make -C lockup init-test features=strict#
|
||||
- <<: *defaults
|
||||
name: Registry tests
|
||||
<<: *localnet
|
||||
script:
|
||||
- docker exec dev make -C registry init-test
|
||||
- <<: *defaults
|
||||
name: Fmt and Common Tests
|
||||
script:
|
||||
|
|
|
@ -1,45 +1,53 @@
|
|||
// Use a macro to define the trait with a generic MESSAGE_SIZE, since
|
||||
// Rust doesn't support arrays with generic lengths.
|
||||
// Macro to generate an append only Ring buffer trait. Clients should use this
|
||||
// to create ring buffer accounts, defining a fixed ITEM_SIZE, the maximum
|
||||
// size for each entry in the ring.
|
||||
//
|
||||
// Remove macro (and just use the trait ) once the following issue is addressed:
|
||||
// Uses a macro to define the trait since Rust doesn't (yet) support arrays
|
||||
// with generic lengths.
|
||||
//
|
||||
// Remove macro (and just use the trait) once the following issue is addressed:
|
||||
// https://github.com/rust-lang/rust/issues/43408
|
||||
#[macro_export]
|
||||
macro_rules! ring {
|
||||
($message_size:expr) => {
|
||||
//
|
||||
use arrayref::array_mut_ref;
|
||||
|
||||
const AUTHORITY_START: usize = 0;
|
||||
// TODO: bump head + tail to be u64 instead of u32.
|
||||
const HEAD_START: usize = 32;
|
||||
const TAIL_START: usize = 36;
|
||||
const MESSAGE_START: u32 = 40;
|
||||
const ITEM_START: u32 = 40;
|
||||
|
||||
pub trait Ring<'a, T: BorshSerialize + BorshDeserialize> {
|
||||
const MESSAGE_SIZE: u32 = $message_size;
|
||||
pub trait Ring<'a> {
|
||||
type Item: BorshSerialize + BorshDeserialize;
|
||||
|
||||
const ITEM_SIZE: u32 = $message_size;
|
||||
|
||||
fn buffer(&self) -> Rc<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(),
|
||||
};
|
|
@ -4,6 +4,7 @@
|
|||
pub mod client;
|
||||
#[macro_use]
|
||||
pub mod pack;
|
||||
pub mod accounts;
|
||||
#[cfg(feature = "program")]
|
||||
pub mod program;
|
||||
|
||||
|
|
|
@ -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>,
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use anyhow::{anyhow, Result};
|
||||
use anyhow::Result;
|
||||
use clap::Clap;
|
||||
use serum_lockup::accounts::WhitelistEntry;
|
||||
use serum_lockup_client::*;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -263,7 +263,6 @@ impl Client {
|
|||
stake_beneficiary,
|
||||
vesting,
|
||||
safe,
|
||||
is_mega, // TODO: remove.
|
||||
} = req;
|
||||
let relay_data = {
|
||||
let instr = RegistryInstruction::Deposit { amount };
|
||||
|
@ -284,16 +283,14 @@ impl Client {
|
|||
®istry_pid,
|
||||
)
|
||||
.map_err(|_| anyhow!("unable to create vault authority"))?;
|
||||
let whitelist_program_vault = match is_mega {
|
||||
false => r.vault,
|
||||
true => r.mega_vault,
|
||||
};
|
||||
let v = self.vesting(&vesting)?;
|
||||
let whitelist_program_vault = r_client.vault_for(&member, &v.vault, true)?;
|
||||
|
||||
let relay_accounts = vec![
|
||||
AccountMeta::new(member, false),
|
||||
AccountMeta::new_readonly(stake_beneficiary.pubkey(), true),
|
||||
AccountMeta::new(entity, false),
|
||||
AccountMeta::new_readonly(registrar, false),
|
||||
AccountMeta::new_readonly(solana_sdk::sysvar::clock::ID, false),
|
||||
];
|
||||
|
||||
let resp = self.whitelist_withdraw(WhitelistWithdrawRequest {
|
||||
|
@ -317,7 +314,6 @@ impl Client {
|
|||
) -> Result<RegistryWithdrawResponse, ClientError> {
|
||||
let RegistryWithdrawRequest {
|
||||
amount,
|
||||
is_mega, // TODO: remove.
|
||||
registry_pid,
|
||||
registrar,
|
||||
member,
|
||||
|
@ -346,16 +342,14 @@ impl Client {
|
|||
®istry_pid,
|
||||
)
|
||||
.map_err(|_| anyhow!("unable to create vault authority"))?;
|
||||
let whitelist_program_vault = match is_mega {
|
||||
false => r.vault,
|
||||
true => r.mega_vault,
|
||||
};
|
||||
let v = self.vesting(&vesting)?;
|
||||
let whitelist_program_vault = r_client.vault_for(&member, &v.vault, true)?;
|
||||
|
||||
let relay_accounts = vec![
|
||||
AccountMeta::new(member, false),
|
||||
AccountMeta::new_readonly(stake_beneficiary.pubkey(), true),
|
||||
AccountMeta::new(entity, false),
|
||||
AccountMeta::new_readonly(registrar, false),
|
||||
AccountMeta::new_readonly(solana_sdk::sysvar::clock::ID, false),
|
||||
];
|
||||
|
||||
let resp = self.whitelist_deposit(WhitelistDepositRequest {
|
||||
|
@ -582,7 +576,6 @@ pub struct RegistryDepositRequest<'a> {
|
|||
pub safe: Pubkey,
|
||||
pub beneficiary: &'a Keypair,
|
||||
pub stake_beneficiary: &'a Keypair,
|
||||
pub is_mega: bool,
|
||||
}
|
||||
|
||||
pub struct RegistryDepositResponse {
|
||||
|
@ -591,7 +584,6 @@ pub struct RegistryDepositResponse {
|
|||
|
||||
pub struct RegistryWithdrawRequest<'a> {
|
||||
pub amount: u64,
|
||||
pub is_mega: bool,
|
||||
pub registry_pid: Pubkey,
|
||||
pub registrar: Pubkey,
|
||||
pub member: Pubkey,
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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])
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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!(
|
||||
|
|
|
@ -1,315 +0,0 @@
|
|||
use serum_common::client::rpc;
|
||||
use serum_common::pack::Pack;
|
||||
use serum_registry::accounts;
|
||||
use serum_registry::accounts::reward_queue::{RewardEventQueue, Ring};
|
||||
use serum_registry::client::{Client as InnerClient, ClientError as InnerClientError};
|
||||
use solana_client_gen::prelude::*;
|
||||
use solana_client_gen::solana_sdk;
|
||||
use solana_client_gen::solana_sdk::instruction::{AccountMeta, Instruction};
|
||||
use solana_client_gen::solana_sdk::pubkey::Pubkey;
|
||||
use solana_client_gen::solana_sdk::system_instruction;
|
||||
|
||||
pub fn initialize(
|
||||
client: &InnerClient,
|
||||
mint: &Pubkey,
|
||||
mega_mint: &Pubkey,
|
||||
registrar_authority: &Pubkey,
|
||||
withdrawal_timelock: i64,
|
||||
deactivation_timelock_premium: i64,
|
||||
reward_activation_threshold: u64,
|
||||
max_stake_per_entity: u64,
|
||||
) -> Result<(Signature, Pubkey, Pubkey, u8, Pubkey, Pubkey), InnerClientError> {
|
||||
let reward_event_q = Keypair::generate(&mut OsRng);
|
||||
let registrar_kp = Keypair::generate(&mut OsRng);
|
||||
let (registrar_vault_authority, nonce) =
|
||||
Pubkey::find_program_address(&[registrar_kp.pubkey().as_ref()], client.program());
|
||||
|
||||
// Create and initialize the vaults, both owned by the program-derived-address.
|
||||
let srm_vault = rpc::create_token_account(
|
||||
client.rpc(),
|
||||
mint,
|
||||
®istrar_vault_authority,
|
||||
client.payer(),
|
||||
)
|
||||
.map_err(|e| InnerClientError::RawError(e.to_string()))?;
|
||||
let msrm_vault = rpc::create_token_account(
|
||||
client.rpc(),
|
||||
mega_mint,
|
||||
®istrar_vault_authority,
|
||||
client.payer(),
|
||||
)
|
||||
.map_err(|e| InnerClientError::RawError(e.to_string()))?;
|
||||
|
||||
let pool_vault = rpc::create_token_account(
|
||||
client.rpc(),
|
||||
mint,
|
||||
®istrar_vault_authority,
|
||||
client.payer(),
|
||||
)
|
||||
.map_err(|e| InnerClientError::RawError(e.to_string()))?
|
||||
.pubkey();
|
||||
let mega_pool_vault = rpc::create_token_account(
|
||||
client.rpc(),
|
||||
mega_mint,
|
||||
®istrar_vault_authority,
|
||||
client.payer(),
|
||||
)
|
||||
.map_err(|e| InnerClientError::RawError(e.to_string()))?
|
||||
.pubkey();
|
||||
let decimals = 6; // TODO: decide on this.
|
||||
let pool_mint = rpc::new_mint(
|
||||
client.rpc(),
|
||||
client.payer(),
|
||||
®istrar_vault_authority,
|
||||
decimals,
|
||||
)
|
||||
.map_err(|e| InnerClientError::RawError(e.to_string()))?
|
||||
.0
|
||||
.pubkey();
|
||||
|
||||
let mega_pool_mint = rpc::new_mint(
|
||||
client.rpc(),
|
||||
client.payer(),
|
||||
®istrar_vault_authority,
|
||||
decimals,
|
||||
)
|
||||
.map_err(|e| InnerClientError::RawError(e.to_string()))?
|
||||
.0
|
||||
.pubkey();
|
||||
|
||||
// Build the instructions.
|
||||
let ixs = {
|
||||
let create_registrar_acc_instr = {
|
||||
let lamports = client
|
||||
.rpc()
|
||||
.get_minimum_balance_for_rent_exemption(*accounts::registrar::SIZE as usize)
|
||||
.map_err(InnerClientError::RpcError)?;
|
||||
system_instruction::create_account(
|
||||
&client.payer().pubkey(),
|
||||
®istrar_kp.pubkey(),
|
||||
lamports,
|
||||
*accounts::registrar::SIZE,
|
||||
client.program(),
|
||||
)
|
||||
};
|
||||
let create_reward_event_q_instr = {
|
||||
let data_size = RewardEventQueue::buffer_size(RewardEventQueue::RING_CAPACITY);
|
||||
let lamports = client
|
||||
.rpc()
|
||||
.get_minimum_balance_for_rent_exemption(data_size)?;
|
||||
solana_sdk::system_instruction::create_account(
|
||||
&client.payer().pubkey(),
|
||||
&reward_event_q.pubkey(),
|
||||
lamports,
|
||||
data_size as u64,
|
||||
client.program(),
|
||||
)
|
||||
};
|
||||
|
||||
let initialize_registrar_instr = {
|
||||
let accounts = [
|
||||
AccountMeta::new(registrar_kp.pubkey(), false),
|
||||
// Deposit vaults.
|
||||
AccountMeta::new_readonly(srm_vault.pubkey(), false),
|
||||
AccountMeta::new_readonly(msrm_vault.pubkey(), false),
|
||||
// Pool vaults.
|
||||
AccountMeta::new_readonly(pool_vault, false),
|
||||
AccountMeta::new_readonly(mega_pool_vault, false),
|
||||
// Pool mints.
|
||||
AccountMeta::new_readonly(pool_mint, false),
|
||||
AccountMeta::new_readonly(mega_pool_mint, false),
|
||||
AccountMeta::new(reward_event_q.pubkey(), false),
|
||||
AccountMeta::new_readonly(solana_sdk::sysvar::rent::id(), false),
|
||||
];
|
||||
serum_registry::instruction::initialize(
|
||||
*client.program(),
|
||||
&accounts,
|
||||
*registrar_authority,
|
||||
nonce,
|
||||
withdrawal_timelock,
|
||||
deactivation_timelock_premium,
|
||||
reward_activation_threshold,
|
||||
max_stake_per_entity,
|
||||
)
|
||||
};
|
||||
|
||||
vec![
|
||||
create_reward_event_q_instr,
|
||||
create_registrar_acc_instr,
|
||||
initialize_registrar_instr,
|
||||
]
|
||||
};
|
||||
|
||||
let (recent_hash, _fee_calc) = client
|
||||
.rpc()
|
||||
.get_recent_blockhash()
|
||||
.map_err(|e| InnerClientError::RawError(e.to_string()))?;
|
||||
let tx = Transaction::new_signed_with_payer(
|
||||
&ixs,
|
||||
Some(&client.payer().pubkey()),
|
||||
&vec![client.payer(), &reward_event_q, ®istrar_kp],
|
||||
recent_hash,
|
||||
);
|
||||
let sig = client
|
||||
.rpc()
|
||||
.send_and_confirm_transaction_with_spinner_and_config(
|
||||
&tx,
|
||||
client.options().commitment,
|
||||
client.options().tx,
|
||||
)
|
||||
.map_err(InnerClientError::RpcError)?;
|
||||
Ok((
|
||||
sig,
|
||||
registrar_kp.pubkey(),
|
||||
reward_event_q.pubkey(),
|
||||
nonce,
|
||||
pool_vault,
|
||||
mega_pool_vault,
|
||||
))
|
||||
}
|
||||
|
||||
pub fn create_entity(
|
||||
client: &InnerClient,
|
||||
registrar: Pubkey,
|
||||
leader_kp: &Keypair,
|
||||
name: String,
|
||||
about: String,
|
||||
image_url: String,
|
||||
meta_entity_program_id: Pubkey,
|
||||
) -> Result<(Signature, Pubkey), InnerClientError> {
|
||||
let entity_kp = Keypair::generate(&mut OsRng);
|
||||
let create_acc_instr = {
|
||||
let lamports = client
|
||||
.rpc()
|
||||
.get_minimum_balance_for_rent_exemption(*accounts::entity::SIZE as usize)
|
||||
.map_err(InnerClientError::RpcError)?;
|
||||
system_instruction::create_account(
|
||||
&client.payer().pubkey(),
|
||||
&entity_kp.pubkey(),
|
||||
lamports,
|
||||
*accounts::entity::SIZE,
|
||||
client.program(),
|
||||
)
|
||||
};
|
||||
|
||||
let accounts = [
|
||||
AccountMeta::new(entity_kp.pubkey(), false),
|
||||
AccountMeta::new_readonly(leader_kp.pubkey(), true),
|
||||
AccountMeta::new_readonly(registrar, false),
|
||||
AccountMeta::new_readonly(solana_sdk::sysvar::rent::ID, false),
|
||||
];
|
||||
|
||||
let metadata = Keypair::generate(&mut OsRng);
|
||||
let mqueue = Keypair::generate(&mut OsRng);
|
||||
let create_entity_instr =
|
||||
serum_registry::instruction::create_entity(*client.program(), &accounts, metadata.pubkey());
|
||||
|
||||
let create_md_instrs = create_metadata_instructions(
|
||||
client.rpc(),
|
||||
&client.payer().pubkey(),
|
||||
&metadata,
|
||||
&mqueue,
|
||||
&meta_entity_program_id,
|
||||
&entity_kp.pubkey(),
|
||||
name,
|
||||
about,
|
||||
image_url,
|
||||
);
|
||||
let mut instructions = create_md_instrs;
|
||||
instructions.extend_from_slice(&[create_acc_instr, create_entity_instr]);
|
||||
|
||||
let signers = vec![leader_kp, &metadata, &mqueue, &entity_kp, client.payer()];
|
||||
let (recent_hash, _fee_calc) = client.rpc().get_recent_blockhash()?;
|
||||
|
||||
let tx = Transaction::new_signed_with_payer(
|
||||
&instructions,
|
||||
Some(&client.payer().pubkey()),
|
||||
&signers,
|
||||
recent_hash,
|
||||
);
|
||||
|
||||
client
|
||||
.rpc()
|
||||
.send_and_confirm_transaction_with_spinner_and_config(
|
||||
&tx,
|
||||
client.options().commitment,
|
||||
client.options().tx,
|
||||
)
|
||||
.map_err(InnerClientError::RpcError)
|
||||
.map(|sig| (sig, entity_kp.pubkey()))
|
||||
}
|
||||
|
||||
// todo: remove
|
||||
pub fn member_seed() -> &'static str {
|
||||
"srm:registry:member"
|
||||
}
|
||||
|
||||
fn create_metadata_instructions(
|
||||
client: &RpcClient,
|
||||
payer: &Pubkey,
|
||||
metadata: &Keypair,
|
||||
mqueue: &Keypair,
|
||||
program_id: &Pubkey,
|
||||
entity: &Pubkey,
|
||||
name: String,
|
||||
about: String,
|
||||
image_url: String,
|
||||
) -> Vec<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
|
@ -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"
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -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(())
|
||||
}
|
||||
|
|
|
@ -2,4 +2,4 @@ pub mod metadata;
|
|||
pub mod mqueue;
|
||||
|
||||
pub use metadata::Metadata;
|
||||
pub use mqueue::MQueue;
|
||||
pub use mqueue::{MQueue, Message};
|
||||
|
|
|
@ -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()?;
|
||||
impl<'a> Ring<'a> for MQueue<'a> {
|
||||
type Item = Message;
|
||||
|
||||
// Scope into a block so that the refcell is dropped.
|
||||
{
|
||||
let head_idx = (head * MQueue::MESSAGE_SIZE + MQueue::MESSAGE_START) as usize;
|
||||
let mut acc_data = self.storage.borrow_mut();
|
||||
let dst = array_mut_ref![acc_data, head_idx, MQueue::MESSAGE_SIZE as usize];
|
||||
data.resize(MQueue::MESSAGE_SIZE as usize, 0);
|
||||
dst.copy_from_slice(&data);
|
||||
}
|
||||
// If full, then move the tail as well.
|
||||
if (head + 1) % MQueue::MAX_MESSAGES == tail {
|
||||
self.increment_tail();
|
||||
}
|
||||
self.increment_head();
|
||||
|
||||
Ok(())
|
||||
fn buffer(&self) -> Rc<RefCell<&'a mut [u8]>> {
|
||||
self.storage.clone()
|
||||
}
|
||||
|
||||
pub fn messages_rev(&self) -> Result<Vec<Message>, MetaEntityError> {
|
||||
let data = self.storage.borrow();
|
||||
let head = self.head()?;
|
||||
let tail = self.tail()?;
|
||||
|
||||
// Empty.
|
||||
if head == tail {
|
||||
return Ok(vec![]);
|
||||
}
|
||||
|
||||
let mut msgs = vec![];
|
||||
let mut last = head;
|
||||
while tail != last {
|
||||
if last == 0 {
|
||||
last = MQueue::MAX_MESSAGES - 1;
|
||||
} else {
|
||||
last -= 1;
|
||||
}
|
||||
|
||||
let start = (last * MQueue::MESSAGE_SIZE + MQueue::MESSAGE_START) as usize;
|
||||
let end = start + MQueue::MESSAGE_SIZE as usize;
|
||||
|
||||
let m = Message::unpack_unchecked(&mut &data[start..end])?;
|
||||
msgs.push(m);
|
||||
}
|
||||
|
||||
Ok(msgs)
|
||||
}
|
||||
|
||||
pub fn message_at(&self, cursor: u32) -> Result<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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ pub mod instruction {
|
|||
chat: Option<Pubkey>,
|
||||
},
|
||||
SendMessage {
|
||||
data: Vec<u8>,
|
||||
msg: accounts::Message,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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,66 +176,73 @@ fn state_transition(req: StateTransitionRequest) -> Result<(), RegistryError> {
|
|||
rent_acc_info,
|
||||
clock_acc_info,
|
||||
nonce,
|
||||
spts,
|
||||
clock,
|
||||
} = req;
|
||||
|
||||
// Create vesting account with proportion of the reward.
|
||||
let spt = {
|
||||
if vendor.pool == registrar.pool_vault {
|
||||
member.balances.spt_amount
|
||||
} else {
|
||||
member.balances.spt_mega_amount
|
||||
}
|
||||
};
|
||||
let amount = spt
|
||||
let spt_total = spts.iter().map(|a| a.amount).fold(0, |a, b| a + b);
|
||||
let amount = spt_total
|
||||
.checked_div(vendor.pool_token_supply)
|
||||
.unwrap()
|
||||
.checked_mul(vendor.total)
|
||||
.unwrap();
|
||||
let ix = {
|
||||
let instr = LockupInstruction::CreateVesting {
|
||||
beneficiary: member.beneficiary,
|
||||
end_ts: vendor.end_ts,
|
||||
period_count: vendor.period_count,
|
||||
deposit_amount: amount,
|
||||
nonce,
|
||||
};
|
||||
let mut data = vec![0u8; instr.size()? as usize];
|
||||
LockupInstruction::pack(instr, &mut data)?;
|
||||
Instruction {
|
||||
program_id: *lockup_program_acc_info.key,
|
||||
accounts: vec![
|
||||
AccountMeta::new(*vesting_acc_info.key, false),
|
||||
AccountMeta::new(vendor.vault, false),
|
||||
AccountMeta::new_readonly(*vendor_vault_authority_acc_info.key, true),
|
||||
AccountMeta::new(*vesting_vault_acc_info.key, false),
|
||||
AccountMeta::new_readonly(*safe_acc_info.key, false),
|
||||
AccountMeta::new_readonly(spl_token::ID, false),
|
||||
AccountMeta::new_readonly(sysvar::rent::ID, false),
|
||||
AccountMeta::new_readonly(sysvar::clock::ID, false),
|
||||
],
|
||||
data,
|
||||
// Lockup program requires the timestamp to be <= clock's timestamp.
|
||||
// So update if the time has already passed.
|
||||
let end_ts = {
|
||||
if vendor.end_ts <= clock.unix_timestamp + 60 {
|
||||
clock.unix_timestamp + 60
|
||||
} else {
|
||||
vendor.end_ts
|
||||
}
|
||||
};
|
||||
let signer_seeds = &[
|
||||
registrar_acc_info.key.as_ref(),
|
||||
vendor_acc_info.key.as_ref(),
|
||||
&[vendor.nonce],
|
||||
];
|
||||
solana_sdk::program::invoke_signed(
|
||||
&ix,
|
||||
&[
|
||||
vesting_acc_info.clone(),
|
||||
vendor_vault_acc_info.clone(),
|
||||
vendor_vault_authority_acc_info.clone(),
|
||||
vesting_vault_acc_info.clone(),
|
||||
safe_acc_info.clone(),
|
||||
token_program_acc_info.clone(),
|
||||
rent_acc_info.clone(),
|
||||
clock_acc_info.clone(),
|
||||
lockup_program_acc_info.clone(),
|
||||
],
|
||||
&[signer_seeds],
|
||||
)?;
|
||||
if amount > 0 {
|
||||
let ix = {
|
||||
let instr = LockupInstruction::CreateVesting {
|
||||
beneficiary: member.beneficiary,
|
||||
end_ts,
|
||||
period_count: vendor.period_count,
|
||||
deposit_amount: amount,
|
||||
nonce,
|
||||
};
|
||||
let mut data = vec![0u8; instr.size()? as usize];
|
||||
LockupInstruction::pack(instr, &mut data)?;
|
||||
Instruction {
|
||||
program_id: *lockup_program_acc_info.key,
|
||||
accounts: vec![
|
||||
AccountMeta::new(*vesting_acc_info.key, false),
|
||||
AccountMeta::new(vendor.vault, false),
|
||||
AccountMeta::new_readonly(*vendor_vault_authority_acc_info.key, true),
|
||||
AccountMeta::new(*vesting_vault_acc_info.key, false),
|
||||
AccountMeta::new_readonly(*safe_acc_info.key, false),
|
||||
AccountMeta::new_readonly(spl_token::ID, false),
|
||||
AccountMeta::new_readonly(sysvar::rent::ID, false),
|
||||
AccountMeta::new_readonly(sysvar::clock::ID, false),
|
||||
],
|
||||
data,
|
||||
}
|
||||
};
|
||||
let signer_seeds = &[
|
||||
registrar_acc_info.key.as_ref(),
|
||||
vendor_acc_info.key.as_ref(),
|
||||
&[vendor.nonce],
|
||||
];
|
||||
solana_sdk::program::invoke_signed(
|
||||
&ix,
|
||||
&[
|
||||
vesting_acc_info.clone(),
|
||||
vendor_vault_acc_info.clone(),
|
||||
vendor_vault_authority_acc_info.clone(),
|
||||
vesting_vault_acc_info.clone(),
|
||||
safe_acc_info.clone(),
|
||||
token_program_acc_info.clone(),
|
||||
rent_acc_info.clone(),
|
||||
clock_acc_info.clone(),
|
||||
lockup_program_acc_info.clone(),
|
||||
],
|
||||
&[signer_seeds],
|
||||
)?;
|
||||
}
|
||||
|
||||
// Move member rewards cursor.
|
||||
member.rewards_cursor = cursor + 1;
|
||||
|
@ -217,19 +257,22 @@ struct AccessControlRequest<'a, 'b> {
|
|||
member_acc_info: &'a AccountInfo<'b>,
|
||||
registrar_acc_info: &'a AccountInfo<'b>,
|
||||
vendor_acc_info: &'a AccountInfo<'b>,
|
||||
spt_acc_infos: Vec<&'a AccountInfo<'b>>,
|
||||
clock_acc_info: &'a AccountInfo<'b>,
|
||||
}
|
||||
|
||||
struct AccessControlResponse {
|
||||
registrar: Registrar,
|
||||
vendor: LockedRewardVendor,
|
||||
spts: Vec<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],
|
||||
}
|
||||
|
|
|
@ -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>,
|
||||
|
|
|
@ -31,7 +31,7 @@ where
|
|||
&mut entity_acc_info.try_borrow_mut_data()?,
|
||||
&mut |entity: &mut Entity| {
|
||||
let clock = access_control::clock(&clock_acc_info)?;
|
||||
let registrar = access_control::registrar(®istrar_acc_info, program_id)?;
|
||||
let registrar = access_control::registrar(registrar_acc_info, program_id)?;
|
||||
let _ = access_control::entity_check(
|
||||
entity,
|
||||
entity_acc_info,
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
|
|
|
@ -1,22 +1,15 @@
|
|||
use serum_common::pack::Pack;
|
||||
use serum_registry::access_control;
|
||||
use serum_registry::accounts::{vault, Member, MemberBalances, Registrar};
|
||||
use serum_registry::access_control::{self, BalanceSandboxAccInfo};
|
||||
use serum_registry::accounts::{vault, BalanceSandbox, Member, Registrar};
|
||||
use serum_registry::error::{RegistryError, RegistryErrorCode};
|
||||
use solana_program::info;
|
||||
use solana_program::msg;
|
||||
use solana_sdk::account_info::{next_account_info, AccountInfo};
|
||||
use solana_sdk::program_option::COption;
|
||||
use solana_sdk::program_pack::Pack as TokenPack;
|
||||
use solana_sdk::pubkey::Pubkey;
|
||||
use spl_token::instruction as token_instruction;
|
||||
use spl_token::state::Account as TokenAccount;
|
||||
|
||||
#[inline(never)]
|
||||
pub fn handler(
|
||||
program_id: &Pubkey,
|
||||
accounts: &[AccountInfo],
|
||||
delegate: Pubkey,
|
||||
) -> Result<(), RegistryError> {
|
||||
info!("handler: create_member");
|
||||
pub fn handler(program_id: &Pubkey, accounts: &[AccountInfo]) -> Result<(), RegistryError> {
|
||||
msg!("handler: create_member");
|
||||
|
||||
let acc_infos = &mut accounts.iter();
|
||||
|
||||
|
@ -25,12 +18,24 @@ pub fn handler(
|
|||
let entity_acc_info = next_account_info(acc_infos)?;
|
||||
let registrar_acc_info = next_account_info(acc_infos)?;
|
||||
let registry_signer_acc_info = next_account_info(acc_infos)?;
|
||||
let spt_acc_info = next_account_info(acc_infos)?;
|
||||
let spt_mega_acc_info = next_account_info(acc_infos)?;
|
||||
let token_program_acc_info = next_account_info(acc_infos)?;
|
||||
let rent_acc_info = next_account_info(acc_infos)?;
|
||||
let mut balances = vec![];
|
||||
while acc_infos.len() > 0 {
|
||||
balances.push(BalanceSandboxAccInfo {
|
||||
owner_acc_info: next_account_info(acc_infos)?,
|
||||
spt_acc_info: next_account_info(acc_infos)?,
|
||||
spt_mega_acc_info: next_account_info(acc_infos)?,
|
||||
vault_acc_info: next_account_info(acc_infos)?,
|
||||
vault_mega_acc_info: next_account_info(acc_infos)?,
|
||||
vault_stake_acc_info: next_account_info(acc_infos)?,
|
||||
vault_stake_mega_acc_info: next_account_info(acc_infos)?,
|
||||
vault_pw_acc_info: next_account_info(acc_infos)?,
|
||||
vault_pw_mega_acc_info: next_account_info(acc_infos)?,
|
||||
})
|
||||
}
|
||||
|
||||
let AccessControlResponse { registrar } = access_control(AccessControlRequest {
|
||||
let AccessControlResponse { ref registrar } = access_control(AccessControlRequest {
|
||||
beneficiary_acc_info,
|
||||
member_acc_info,
|
||||
entity_acc_info,
|
||||
|
@ -38,24 +43,20 @@ pub fn handler(
|
|||
registry_signer_acc_info,
|
||||
rent_acc_info,
|
||||
program_id,
|
||||
spt_acc_info,
|
||||
spt_mega_acc_info,
|
||||
balances: &balances,
|
||||
})?;
|
||||
|
||||
Member::unpack_unchecked_mut(
|
||||
&mut member_acc_info.try_borrow_mut_data()?,
|
||||
&mut |member: &mut Member| {
|
||||
state_transition(StateTransitionRequest {
|
||||
beneficiary_acc_info,
|
||||
member,
|
||||
delegate,
|
||||
entity_acc_info,
|
||||
registrar_acc_info,
|
||||
registrar: ®istrar,
|
||||
registrar,
|
||||
registry_signer_acc_info,
|
||||
spt_acc_info,
|
||||
spt_mega_acc_info,
|
||||
token_program_acc_info,
|
||||
balances: &balances,
|
||||
})
|
||||
.map_err(Into::into)
|
||||
},
|
||||
|
@ -66,7 +67,7 @@ pub fn handler(
|
|||
|
||||
#[inline(never)]
|
||||
fn access_control(req: AccessControlRequest) -> Result<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, ®istrar.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,
|
||||
®istrar,
|
||||
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>],
|
||||
}
|
||||
|
|
|
@ -1,23 +1,17 @@
|
|||
use crate::common::entity::{with_entity, EntityContext};
|
||||
use serum_common::pack::Pack;
|
||||
use serum_common::program::invoke_token_transfer;
|
||||
use serum_registry::access_control;
|
||||
use serum_registry::accounts::{Entity, Member, Registrar};
|
||||
use serum_registry::error::{RegistryError, RegistryErrorCode};
|
||||
use solana_program::info;
|
||||
use solana_program::msg;
|
||||
use solana_sdk::account_info::{next_account_info, AccountInfo};
|
||||
use solana_sdk::pubkey::Pubkey;
|
||||
use solana_sdk::sysvar::clock::Clock;
|
||||
use spl_token::state::Account as TokenAccount;
|
||||
|
||||
#[inline(never)]
|
||||
pub fn handler(
|
||||
program_id: &Pubkey,
|
||||
accounts: &[AccountInfo],
|
||||
amount: u64,
|
||||
delegate: bool,
|
||||
) -> Result<(), RegistryError> {
|
||||
info!("handler: deposit");
|
||||
msg!("handler: deposit");
|
||||
|
||||
let acc_infos = &mut accounts.iter();
|
||||
|
||||
|
@ -25,64 +19,39 @@ pub fn handler(
|
|||
let depositor_acc_info = next_account_info(acc_infos)?;
|
||||
let depositor_authority_acc_info = next_account_info(acc_infos)?;
|
||||
let token_program_acc_info = next_account_info(acc_infos)?;
|
||||
let vault_acc_info = next_account_info(acc_infos)?;
|
||||
let vault_authority_acc_info = next_account_info(acc_infos)?;
|
||||
let member_vault_acc_info = next_account_info(acc_infos)?;
|
||||
let member_vault_authority_acc_info = next_account_info(acc_infos)?;
|
||||
|
||||
// Program specfic.
|
||||
let member_acc_info = next_account_info(acc_infos)?;
|
||||
let beneficiary_acc_info = next_account_info(acc_infos)?;
|
||||
let entity_acc_info = next_account_info(acc_infos)?;
|
||||
let registrar_acc_info = next_account_info(acc_infos)?;
|
||||
let clock_acc_info = next_account_info(acc_infos)?;
|
||||
|
||||
let ctx = EntityContext {
|
||||
registrar_acc_info,
|
||||
access_control(AccessControlRequest {
|
||||
depositor_authority_acc_info,
|
||||
depositor_acc_info,
|
||||
member_acc_info,
|
||||
beneficiary_acc_info,
|
||||
entity_acc_info,
|
||||
clock_acc_info,
|
||||
member_vault_acc_info,
|
||||
member_vault_authority_acc_info,
|
||||
program_id,
|
||||
};
|
||||
with_entity(ctx, &mut |entity: &mut Entity,
|
||||
registrar: &Registrar,
|
||||
_: &Clock| {
|
||||
let AccessControlResponse { depositor } = access_control(AccessControlRequest {
|
||||
depositor_authority_acc_info,
|
||||
depositor_acc_info,
|
||||
member_acc_info,
|
||||
beneficiary_acc_info,
|
||||
entity_acc_info,
|
||||
vault_acc_info,
|
||||
vault_authority_acc_info,
|
||||
program_id,
|
||||
registrar_acc_info,
|
||||
registrar,
|
||||
delegate,
|
||||
})?;
|
||||
|
||||
Member::unpack_mut(
|
||||
&mut member_acc_info.try_borrow_mut_data()?,
|
||||
&mut |member: &mut Member| {
|
||||
state_transition(StateTransitionRequest {
|
||||
entity,
|
||||
member,
|
||||
amount,
|
||||
depositor_authority_acc_info,
|
||||
depositor_acc_info,
|
||||
depositor,
|
||||
token_program_acc_info,
|
||||
registrar,
|
||||
vault_acc_info,
|
||||
})
|
||||
.map_err(Into::into)
|
||||
},
|
||||
)
|
||||
.map_err(Into::into)
|
||||
registrar_acc_info,
|
||||
})?;
|
||||
state_transition(StateTransitionRequest {
|
||||
amount,
|
||||
depositor_authority_acc_info,
|
||||
depositor_acc_info,
|
||||
token_program_acc_info,
|
||||
member_vault_acc_info,
|
||||
})?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn access_control(req: AccessControlRequest) -> Result<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,
|
||||
®istrar,
|
||||
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,
|
||||
}
|
||||
|
|
|
@ -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 ®istrar.pool_vault != pool_vault_acc_info.key
|
||||
&& ®istrar.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 = ®istrar.pool_vault_mega == pool_vault_acc_info.key;
|
||||
if is_mega {
|
||||
if ®istrar.pool_mint_mega != pool_token_mint_acc_info.key {
|
||||
return Err(RegistryErrorCode::InvalidPoolTokenMint)?;
|
||||
}
|
||||
} else {
|
||||
if ®istrar.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,
|
||||
}
|
||||
|
|
|
@ -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 ®istrar.pool_vault != pool_vault_acc_info.key
|
||||
&& ®istrar.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 = ®istrar.pool_vault_mega == pool_vault_acc_info.key;
|
||||
if is_mega {
|
||||
if ®istrar.pool_mint_mega != pool_token_mint_acc_info.key {
|
||||
return Err(RegistryErrorCode::InvalidPoolTokenMint)?;
|
||||
}
|
||||
} else {
|
||||
if ®istrar.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>,
|
||||
|
|
|
@ -1,55 +1,56 @@
|
|||
use serum_common::pack::Pack;
|
||||
use serum_common::program::invoke_token_transfer;
|
||||
use serum_registry::access_control;
|
||||
use serum_registry::accounts::{Entity, Member, PendingWithdrawal};
|
||||
use serum_registry::accounts::{vault, BalanceSandbox, PendingWithdrawal, Registrar};
|
||||
use serum_registry::error::{RegistryError, RegistryErrorCode};
|
||||
use solana_program::info;
|
||||
use solana_program::msg;
|
||||
use solana_sdk::account_info::{next_account_info, AccountInfo};
|
||||
use solana_sdk::pubkey::Pubkey;
|
||||
use std::convert::Into;
|
||||
|
||||
#[inline(never)]
|
||||
pub fn handler(program_id: &Pubkey, accounts: &[AccountInfo]) -> Result<(), RegistryError> {
|
||||
info!("handler: end_stake_withdrawl");
|
||||
msg!("handler: end_stake_withdrawl");
|
||||
|
||||
let acc_infos = &mut accounts.iter();
|
||||
|
||||
let pending_withdrawal_acc_info = next_account_info(acc_infos)?;
|
||||
let member_acc_info = next_account_info(acc_infos)?;
|
||||
let member_vault_acc_info = next_account_info(acc_infos)?;
|
||||
let member_vault_pw_acc_info = next_account_info(acc_infos)?;
|
||||
let member_vault_authority_acc_info = next_account_info(acc_infos)?;
|
||||
let beneficiary_acc_info = next_account_info(acc_infos)?;
|
||||
let entity_acc_info = next_account_info(acc_infos)?;
|
||||
let token_program_acc_info = next_account_info(acc_infos)?;
|
||||
let registrar_acc_info = next_account_info(acc_infos)?;
|
||||
let clock_acc_info = next_account_info(acc_infos)?;
|
||||
|
||||
let AccessControlResponse { is_mega } = access_control(AccessControlRequest {
|
||||
let AccessControlResponse { ref registrar } = access_control(AccessControlRequest {
|
||||
registrar_acc_info,
|
||||
pending_withdrawal_acc_info,
|
||||
beneficiary_acc_info,
|
||||
member_acc_info,
|
||||
member_vault_acc_info,
|
||||
member_vault_pw_acc_info,
|
||||
entity_acc_info,
|
||||
clock_acc_info,
|
||||
program_id,
|
||||
member_vault_authority_acc_info,
|
||||
})?;
|
||||
|
||||
Entity::unpack_unchecked_mut(
|
||||
&mut entity_acc_info.try_borrow_mut_data()?,
|
||||
&mut |entity: &mut Entity| {
|
||||
Member::unpack_mut(
|
||||
&mut member_acc_info.try_borrow_mut_data()?,
|
||||
&mut |member: &mut Member| {
|
||||
PendingWithdrawal::unpack_mut(
|
||||
&mut pending_withdrawal_acc_info.try_borrow_mut_data()?,
|
||||
&mut |pending_withdrawal: &mut PendingWithdrawal| {
|
||||
state_transition(StateTransitionRequest {
|
||||
pending_withdrawal,
|
||||
entity,
|
||||
member,
|
||||
is_mega,
|
||||
})
|
||||
.map_err(Into::into)
|
||||
},
|
||||
)
|
||||
},
|
||||
)
|
||||
PendingWithdrawal::unpack_mut(
|
||||
&mut pending_withdrawal_acc_info.try_borrow_mut_data()?,
|
||||
&mut |pending_withdrawal: &mut PendingWithdrawal| {
|
||||
state_transition(StateTransitionRequest {
|
||||
pending_withdrawal,
|
||||
registrar,
|
||||
registrar_acc_info,
|
||||
member_vault_acc_info,
|
||||
member_vault_pw_acc_info,
|
||||
member_vault_authority_acc_info,
|
||||
token_program_acc_info,
|
||||
})
|
||||
.map_err(Into::into)
|
||||
},
|
||||
)?;
|
||||
|
||||
|
@ -58,7 +59,7 @@ pub fn handler(program_id: &Pubkey, accounts: &[AccountInfo]) -> Result<(), Regi
|
|||
|
||||
#[inline(always)]
|
||||
fn access_control(req: AccessControlRequest) -> Result<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,
|
||||
®istrar,
|
||||
program_id,
|
||||
&balances.owner,
|
||||
)?;
|
||||
let (_, is_mega_vault_pw) = access_control::member_vault_pending_withdrawal(
|
||||
&member,
|
||||
member_vault_pw_acc_info,
|
||||
member_vault_authority_acc_info,
|
||||
registrar_acc_info,
|
||||
®istrar,
|
||||
program_id,
|
||||
&balances.owner,
|
||||
)?;
|
||||
|
||||
let is_mega = {
|
||||
if pending_withdrawal.pool == registrar.pool_vault {
|
||||
if pending_withdrawal.pool == registrar.pool_mint {
|
||||
false
|
||||
} else if pending_withdrawal.pool == registrar.pool_vault_mega {
|
||||
} else if pending_withdrawal.pool == registrar.pool_mint_mega {
|
||||
true
|
||||
} else {
|
||||
return Err(RegistryErrorCode::InvariantViolation)?;
|
||||
}
|
||||
};
|
||||
if is_mega != is_mega_vault || is_mega != is_mega_vault_pw {
|
||||
return Err(RegistryErrorCode::InvalidVault)?;
|
||||
}
|
||||
|
||||
// EndStakeWithdrawal specific.
|
||||
if clock.unix_timestamp < pending_withdrawal.end_ts {
|
||||
return Err(RegistryErrorCode::WithdrawalTimelockNotPassed)?;
|
||||
}
|
||||
|
||||
Ok(AccessControlResponse { is_mega })
|
||||
Ok(AccessControlResponse { registrar })
|
||||
}
|
||||
|
||||
fn state_transition(req: StateTransitionRequest) -> Result<(), RegistryError> {
|
||||
info!("state-transition: end_stake_withdrawal");
|
||||
msg!("state-transition: end_stake_withdrawal");
|
||||
|
||||
let StateTransitionRequest {
|
||||
pending_withdrawal,
|
||||
entity,
|
||||
member,
|
||||
is_mega,
|
||||
registrar,
|
||||
registrar_acc_info,
|
||||
member_vault_acc_info,
|
||||
member_vault_pw_acc_info,
|
||||
member_vault_authority_acc_info,
|
||||
token_program_acc_info,
|
||||
} = req;
|
||||
|
||||
member.spt_did_unstake_end(pending_withdrawal.spt_amount, is_mega);
|
||||
entity.spt_did_unstake_end(pending_withdrawal.spt_amount, is_mega);
|
||||
invoke_token_transfer(
|
||||
member_vault_pw_acc_info,
|
||||
member_vault_acc_info,
|
||||
member_vault_authority_acc_info,
|
||||
token_program_acc_info,
|
||||
&[&vault::signer_seeds(
|
||||
registrar_acc_info.key,
|
||||
®istrar.nonce,
|
||||
)],
|
||||
pending_withdrawal.amount,
|
||||
)?;
|
||||
|
||||
pending_withdrawal.burned = true;
|
||||
|
||||
Ok(())
|
||||
|
@ -128,18 +174,24 @@ struct AccessControlRequest<'a, 'b> {
|
|||
pending_withdrawal_acc_info: &'a AccountInfo<'b>,
|
||||
beneficiary_acc_info: &'a AccountInfo<'b>,
|
||||
member_acc_info: &'a AccountInfo<'b>,
|
||||
member_vault_acc_info: &'a AccountInfo<'b>,
|
||||
member_vault_pw_acc_info: &'a AccountInfo<'b>,
|
||||
member_vault_authority_acc_info: &'a AccountInfo<'b>,
|
||||
entity_acc_info: &'a AccountInfo<'b>,
|
||||
clock_acc_info: &'a AccountInfo<'b>,
|
||||
program_id: &'a Pubkey,
|
||||
}
|
||||
|
||||
struct AccessControlResponse {
|
||||
is_mega: bool,
|
||||
registrar: Registrar,
|
||||
}
|
||||
|
||||
struct StateTransitionRequest<'a> {
|
||||
pending_withdrawal: &'a mut PendingWithdrawal,
|
||||
entity: &'a mut Entity,
|
||||
member: &'a mut Member,
|
||||
is_mega: bool,
|
||||
struct StateTransitionRequest<'a, 'b, 'c> {
|
||||
registrar_acc_info: &'a AccountInfo<'b>,
|
||||
member_vault_acc_info: &'a AccountInfo<'b>,
|
||||
member_vault_pw_acc_info: &'a AccountInfo<'b>,
|
||||
member_vault_authority_acc_info: &'a AccountInfo<'b>,
|
||||
token_program_acc_info: &'a AccountInfo<'b>,
|
||||
pending_withdrawal: &'c mut PendingWithdrawal,
|
||||
registrar: &'c Registrar,
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
®istrar,
|
||||
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, ®istrar)?;
|
||||
let _pool_mint = access_control::pool_mint(pool_mint_acc_info, ®istrar, 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(®istrar) {
|
||||
// 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 {
|
||||
return Err(RegistryErrorCode::EntityMaxStake)?;
|
||||
}
|
||||
}
|
||||
// Will this new stake put the entity over the maximum allowable limit?
|
||||
if entity.stake_will_max(spt_amount, is_mega, ®istrar) {
|
||||
return Err(RegistryErrorCode::EntityMaxStake)?;
|
||||
}
|
||||
|
||||
Ok(AccessControlResponse { is_mega })
|
||||
}
|
||||
|
||||
fn state_transition(req: StateTransitionRequest) -> Result<(), RegistryError> {
|
||||
info!("state-transition: stake");
|
||||
msg!("state-transition: stake");
|
||||
|
||||
let StateTransitionRequest {
|
||||
entity,
|
||||
|
@ -159,9 +169,9 @@ fn state_transition(req: StateTransitionRequest) -> Result<(), RegistryError> {
|
|||
is_mega,
|
||||
registrar_acc_info,
|
||||
registrar,
|
||||
vault_acc_info,
|
||||
vault_authority_acc_info,
|
||||
pool_vault_acc_info,
|
||||
member_vault_acc_info,
|
||||
member_vault_authority_acc_info,
|
||||
member_vault_stake_acc_info,
|
||||
spt_acc_info,
|
||||
token_program_acc_info,
|
||||
pool_mint_acc_info,
|
||||
|
@ -170,29 +180,37 @@ fn state_transition(req: StateTransitionRequest) -> Result<(), RegistryError> {
|
|||
|
||||
let signer_seeds = vault::signer_seeds(registrar_acc_info.key, ®istrar.nonce);
|
||||
|
||||
// Mint pool tokens.
|
||||
// Mint pool tokens to member.
|
||||
invoke_mint_tokens(
|
||||
pool_mint_acc_info,
|
||||
spt_acc_info,
|
||||
vault_authority_acc_info,
|
||||
member_vault_authority_acc_info,
|
||||
token_program_acc_info,
|
||||
&[&signer_seeds],
|
||||
spt_amount,
|
||||
)?;
|
||||
|
||||
// Transfer from the deposit vault to pool vault.
|
||||
// Convert from stake token units to srm/msrm units.
|
||||
let token_amount = {
|
||||
let rate = match is_mega {
|
||||
false => registrar.stake_rate,
|
||||
true => registrar.stake_rate_mega,
|
||||
};
|
||||
spt_amount.checked_mul(rate).unwrap()
|
||||
};
|
||||
|
||||
// Transfer from deposit vault to stake vault.
|
||||
invoke_token_transfer(
|
||||
vault_acc_info,
|
||||
pool_vault_acc_info,
|
||||
vault_authority_acc_info,
|
||||
member_vault_acc_info,
|
||||
member_vault_stake_acc_info,
|
||||
member_vault_authority_acc_info,
|
||||
token_program_acc_info,
|
||||
&[&signer_seeds],
|
||||
spt_amount,
|
||||
token_amount,
|
||||
)?;
|
||||
|
||||
// Bookeeping.
|
||||
member.last_stake_ts = clock.unix_timestamp;
|
||||
member.spt_did_stake(spt_amount, is_mega)?;
|
||||
entity.spt_did_stake(spt_amount, is_mega)?;
|
||||
|
||||
Ok(())
|
||||
|
@ -203,15 +221,16 @@ struct AccessControlRequest<'a, 'b, 'c> {
|
|||
beneficiary_acc_info: &'a AccountInfo<'b>,
|
||||
entity_acc_info: &'a AccountInfo<'b>,
|
||||
registrar_acc_info: &'a AccountInfo<'b>,
|
||||
vault_acc_info: &'a AccountInfo<'b>,
|
||||
vault_authority_acc_info: &'a AccountInfo<'b>,
|
||||
pool_vault_acc_info: &'a AccountInfo<'b>,
|
||||
member_vault_acc_info: &'a AccountInfo<'b>,
|
||||
member_vault_authority_acc_info: &'a AccountInfo<'b>,
|
||||
member_vault_stake_acc_info: &'a AccountInfo<'b>,
|
||||
spt_acc_info: &'a AccountInfo<'b>,
|
||||
pool_mint_acc_info: &'a AccountInfo<'b>,
|
||||
program_id: &'a Pubkey,
|
||||
registrar: &'c Registrar,
|
||||
entity: &'c Entity,
|
||||
spt_amount: u64,
|
||||
balance_id: &'c Pubkey,
|
||||
}
|
||||
|
||||
struct AccessControlResponse {
|
||||
|
@ -226,9 +245,9 @@ struct StateTransitionRequest<'a, 'b, 'c> {
|
|||
is_mega: bool,
|
||||
registrar: &'c Registrar,
|
||||
registrar_acc_info: &'a AccountInfo<'b>,
|
||||
vault_acc_info: &'a AccountInfo<'b>,
|
||||
vault_authority_acc_info: &'a AccountInfo<'b>,
|
||||
pool_vault_acc_info: &'a AccountInfo<'b>,
|
||||
member_vault_acc_info: &'a AccountInfo<'b>,
|
||||
member_vault_authority_acc_info: &'a AccountInfo<'b>,
|
||||
member_vault_stake_acc_info: &'a AccountInfo<'b>,
|
||||
spt_acc_info: &'a AccountInfo<'b>,
|
||||
token_program_acc_info: &'a AccountInfo<'b>,
|
||||
pool_mint_acc_info: &'a AccountInfo<'b>,
|
||||
|
|
|
@ -3,9 +3,9 @@ use serum_common::pack::Pack;
|
|||
use serum_common::program::{invoke_burn_tokens, invoke_token_transfer};
|
||||
use serum_registry::access_control;
|
||||
use serum_registry::accounts::vault;
|
||||
use serum_registry::accounts::{Entity, Member, PendingWithdrawal, Registrar};
|
||||
use serum_registry::accounts::{Entity, PendingWithdrawal, Registrar};
|
||||
use serum_registry::error::{RegistryError, RegistryErrorCode};
|
||||
use solana_program::info;
|
||||
use solana_program::msg;
|
||||
use solana_sdk::account_info::{next_account_info, AccountInfo};
|
||||
use solana_sdk::pubkey::Pubkey;
|
||||
use solana_sdk::sysvar::clock::Clock;
|
||||
|
@ -15,8 +15,9 @@ pub fn handler(
|
|||
program_id: &Pubkey,
|
||||
accounts: &[AccountInfo],
|
||||
spt_amount: u64,
|
||||
ref balance_id: Pubkey,
|
||||
) -> Result<(), RegistryError> {
|
||||
info!("handler: start_stake_withdrawal");
|
||||
msg!("handler: start_stake_withdrawal");
|
||||
|
||||
let acc_infos = &mut accounts.iter();
|
||||
|
||||
|
@ -26,9 +27,9 @@ pub fn handler(
|
|||
let beneficiary_acc_info = next_account_info(acc_infos)?;
|
||||
let entity_acc_info = next_account_info(acc_infos)?;
|
||||
let registrar_acc_info = next_account_info(acc_infos)?;
|
||||
let vault_acc_info = next_account_info(acc_infos)?;
|
||||
let vault_authority_acc_info = next_account_info(acc_infos)?;
|
||||
let pool_vault_acc_info = next_account_info(acc_infos)?;
|
||||
let member_vault_pw_acc_info = next_account_info(acc_infos)?;
|
||||
let member_vault_authority_acc_info = next_account_info(acc_infos)?;
|
||||
let member_vault_stake_acc_info = next_account_info(acc_infos)?;
|
||||
let pool_mint_acc_info = next_account_info(acc_infos)?;
|
||||
let spt_acc_info = next_account_info(acc_infos)?;
|
||||
let clock_acc_info = next_account_info(acc_infos)?;
|
||||
|
@ -52,39 +53,35 @@ pub fn handler(
|
|||
entity_acc_info,
|
||||
rent_acc_info,
|
||||
program_id,
|
||||
vault_acc_info,
|
||||
vault_authority_acc_info,
|
||||
pool_vault_acc_info,
|
||||
member_vault_pw_acc_info,
|
||||
member_vault_authority_acc_info,
|
||||
member_vault_stake_acc_info,
|
||||
pool_mint_acc_info,
|
||||
spt_acc_info,
|
||||
registrar,
|
||||
balance_id,
|
||||
})?;
|
||||
PendingWithdrawal::unpack_mut(
|
||||
&mut pending_withdrawal_acc_info.try_borrow_mut_data()?,
|
||||
&mut |pending_withdrawal: &mut PendingWithdrawal| {
|
||||
Member::unpack_mut(
|
||||
&mut member_acc_info.try_borrow_mut_data()?,
|
||||
&mut |member: &mut Member| {
|
||||
state_transition(StateTransitionRequest {
|
||||
pending_withdrawal,
|
||||
registrar,
|
||||
member,
|
||||
entity,
|
||||
member_acc_info,
|
||||
clock,
|
||||
spt_amount,
|
||||
tok_program_acc_info,
|
||||
registrar_acc_info,
|
||||
vault_acc_info,
|
||||
vault_authority_acc_info,
|
||||
pool_vault_acc_info,
|
||||
pool_mint_acc_info,
|
||||
spt_acc_info,
|
||||
is_mega,
|
||||
})
|
||||
.map_err(Into::into)
|
||||
},
|
||||
)
|
||||
state_transition(StateTransitionRequest {
|
||||
pending_withdrawal,
|
||||
registrar,
|
||||
entity,
|
||||
member_acc_info,
|
||||
clock,
|
||||
spt_amount,
|
||||
tok_program_acc_info,
|
||||
registrar_acc_info,
|
||||
member_vault_pw_acc_info,
|
||||
member_vault_authority_acc_info,
|
||||
member_vault_stake_acc_info,
|
||||
pool_mint_acc_info,
|
||||
spt_acc_info,
|
||||
is_mega,
|
||||
balance_id,
|
||||
})
|
||||
.map_err(Into::into)
|
||||
},
|
||||
)
|
||||
.map_err(Into::into)
|
||||
|
@ -94,7 +91,7 @@ pub fn handler(
|
|||
}
|
||||
|
||||
fn access_control(req: AccessControlRequest) -> Result<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, ®istrar)?;
|
||||
let _pool_mint = access_control::pool_mint(pool_mint_acc_info, ®istrar, 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, ®istrar.nonce);
|
||||
|
@ -184,24 +198,32 @@ fn state_transition(req: StateTransitionRequest) -> Result<(), RegistryError> {
|
|||
invoke_burn_tokens(
|
||||
spt_acc_info,
|
||||
pool_mint_acc_info,
|
||||
vault_authority_acc_info,
|
||||
member_vault_authority_acc_info,
|
||||
tok_program_acc_info,
|
||||
&[&signer_seeds],
|
||||
spt_amount,
|
||||
)?;
|
||||
|
||||
// Transfer from pool vault to deposit vault.
|
||||
// Convert from stake token units to srm/msrm units.
|
||||
let token_amount = {
|
||||
let rate = match is_mega {
|
||||
false => registrar.stake_rate,
|
||||
true => registrar.stake_rate_mega,
|
||||
};
|
||||
spt_amount.checked_mul(rate).unwrap()
|
||||
};
|
||||
|
||||
// Transfer from stake vault to pending vault.
|
||||
invoke_token_transfer(
|
||||
pool_vault_acc_info,
|
||||
vault_acc_info,
|
||||
vault_authority_acc_info,
|
||||
member_vault_stake_acc_info,
|
||||
member_vault_pw_acc_info,
|
||||
member_vault_authority_acc_info,
|
||||
tok_program_acc_info,
|
||||
&[&signer_seeds],
|
||||
spt_amount,
|
||||
token_amount,
|
||||
)?;
|
||||
|
||||
// Bookeeping.
|
||||
member.spt_did_unstake_start(spt_amount, is_mega);
|
||||
entity.spt_did_unstake_start(spt_amount, is_mega);
|
||||
|
||||
// Print pending withdrawal receipt.
|
||||
|
@ -210,8 +232,9 @@ fn state_transition(req: StateTransitionRequest) -> Result<(), RegistryError> {
|
|||
pending_withdrawal.member = *member_acc_info.key;
|
||||
pending_withdrawal.start_ts = clock.unix_timestamp;
|
||||
pending_withdrawal.end_ts = clock.unix_timestamp + registrar.deactivation_timelock;
|
||||
pending_withdrawal.spt_amount = spt_amount;
|
||||
pending_withdrawal.pool = *pool_vault_acc_info.key;
|
||||
pending_withdrawal.amount = token_amount;
|
||||
pending_withdrawal.pool = *pool_mint_acc_info.key;
|
||||
pending_withdrawal.balance_id = *balance_id;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -223,13 +246,14 @@ struct AccessControlRequest<'a, 'b, 'c> {
|
|||
member_acc_info: &'a AccountInfo<'b>,
|
||||
entity_acc_info: &'a AccountInfo<'b>,
|
||||
rent_acc_info: &'a AccountInfo<'b>,
|
||||
vault_acc_info: &'a AccountInfo<'b>,
|
||||
vault_authority_acc_info: &'a AccountInfo<'b>,
|
||||
pool_vault_acc_info: &'a AccountInfo<'b>,
|
||||
member_vault_pw_acc_info: &'a AccountInfo<'b>,
|
||||
member_vault_authority_acc_info: &'a AccountInfo<'b>,
|
||||
member_vault_stake_acc_info: &'a AccountInfo<'b>,
|
||||
pool_mint_acc_info: &'a AccountInfo<'b>,
|
||||
spt_acc_info: &'a AccountInfo<'b>,
|
||||
program_id: &'a Pubkey,
|
||||
registrar: &'c Registrar,
|
||||
balance_id: &'c Pubkey,
|
||||
}
|
||||
|
||||
struct AccessControlResponse {
|
||||
|
@ -239,17 +263,17 @@ struct AccessControlResponse {
|
|||
struct StateTransitionRequest<'a, 'b, 'c> {
|
||||
member_acc_info: &'a AccountInfo<'b>,
|
||||
registrar_acc_info: &'a AccountInfo<'b>,
|
||||
vault_acc_info: &'a AccountInfo<'b>,
|
||||
vault_authority_acc_info: &'a AccountInfo<'b>,
|
||||
member_vault_pw_acc_info: &'a AccountInfo<'b>,
|
||||
member_vault_authority_acc_info: &'a AccountInfo<'b>,
|
||||
tok_program_acc_info: &'a AccountInfo<'b>,
|
||||
pool_vault_acc_info: &'a AccountInfo<'b>,
|
||||
member_vault_stake_acc_info: &'a AccountInfo<'b>,
|
||||
pool_mint_acc_info: &'a AccountInfo<'b>,
|
||||
spt_acc_info: &'a AccountInfo<'b>,
|
||||
pending_withdrawal: &'c mut PendingWithdrawal,
|
||||
entity: &'c mut Entity,
|
||||
member: &'c mut Member,
|
||||
registrar: &'c Registrar,
|
||||
clock: &'c Clock,
|
||||
spt_amount: u64,
|
||||
is_mega: bool,
|
||||
balance_id: &'c Pubkey,
|
||||
}
|
||||
|
|
|
@ -1,16 +1,17 @@
|
|||
use serum_common::pack::*;
|
||||
use serum_registry::access_control;
|
||||
use serum_registry::accounts::{Entity, Member, Registrar};
|
||||
use serum_registry::accounts::{Entity, EntityState, Member, Registrar};
|
||||
use serum_registry::error::{RegistryError, RegistryErrorCode};
|
||||
use solana_program::info;
|
||||
use solana_program::msg;
|
||||
use solana_sdk::account_info::{next_account_info, AccountInfo};
|
||||
use solana_sdk::pubkey::Pubkey;
|
||||
use solana_sdk::sysvar::clock::Clock;
|
||||
use spl_token::state::Account as TokenAccount;
|
||||
use std::convert::Into;
|
||||
|
||||
#[inline(never)]
|
||||
pub fn handler(program_id: &Pubkey, accounts: &[AccountInfo]) -> Result<(), RegistryError> {
|
||||
info!("handler: switch_entity");
|
||||
msg!("handler: switch_entity");
|
||||
|
||||
let acc_infos = &mut accounts.iter();
|
||||
|
||||
|
@ -20,8 +21,21 @@ pub fn handler(program_id: &Pubkey, accounts: &[AccountInfo]) -> Result<(), Regi
|
|||
let curr_entity_acc_info = next_account_info(acc_infos)?;
|
||||
let new_entity_acc_info = next_account_info(acc_infos)?;
|
||||
let clock_acc_info = next_account_info(acc_infos)?;
|
||||
let vault_authority_acc_info = next_account_info(acc_infos)?;
|
||||
let mut asset_acc_infos = vec![];
|
||||
while acc_infos.len() > 0 {
|
||||
asset_acc_infos.push(AssetAccInfos {
|
||||
owner_acc_info: next_account_info(acc_infos)?,
|
||||
vault_stake_acc_info: next_account_info(acc_infos)?,
|
||||
vault_stake_mega_acc_info: next_account_info(acc_infos)?,
|
||||
})
|
||||
}
|
||||
|
||||
let AccessControlResponse { registrar, clock } = access_control(AccessControlRequest {
|
||||
let AccessControlResponse {
|
||||
ref assets,
|
||||
ref registrar,
|
||||
ref clock,
|
||||
} = access_control(AccessControlRequest {
|
||||
member_acc_info,
|
||||
beneficiary_acc_info,
|
||||
program_id,
|
||||
|
@ -29,6 +43,8 @@ pub fn handler(program_id: &Pubkey, accounts: &[AccountInfo]) -> Result<(), Regi
|
|||
curr_entity_acc_info,
|
||||
new_entity_acc_info,
|
||||
clock_acc_info,
|
||||
asset_acc_infos,
|
||||
vault_authority_acc_info,
|
||||
})?;
|
||||
|
||||
Member::unpack_mut(
|
||||
|
@ -45,8 +61,9 @@ pub fn handler(program_id: &Pubkey, accounts: &[AccountInfo]) -> Result<(), Regi
|
|||
curr_entity,
|
||||
new_entity,
|
||||
member,
|
||||
registrar: ®istrar,
|
||||
clock: &clock,
|
||||
registrar,
|
||||
clock,
|
||||
assets,
|
||||
})
|
||||
.map_err(Into::into)
|
||||
},
|
||||
|
@ -59,8 +76,9 @@ pub fn handler(program_id: &Pubkey, accounts: &[AccountInfo]) -> Result<(), Regi
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
fn access_control(req: AccessControlRequest) -> Result<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)?;
|
||||
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,
|
||||
®istrar,
|
||||
program_id,
|
||||
a.owner_acc_info.key,
|
||||
)?;
|
||||
assert!(!is_mega);
|
||||
let (vault_stake_mega, is_mega) = access_control::member_vault_stake(
|
||||
&member,
|
||||
a.vault_stake_mega_acc_info,
|
||||
vault_authority_acc_info,
|
||||
registrar_acc_info,
|
||||
®istrar,
|
||||
program_id,
|
||||
a.owner_acc_info.key,
|
||||
)?;
|
||||
assert!(is_mega);
|
||||
assets.push(Assets {
|
||||
vault_stake,
|
||||
vault_stake_mega,
|
||||
})
|
||||
}
|
||||
|
||||
Ok(AccessControlResponse { registrar, clock })
|
||||
Ok(AccessControlResponse {
|
||||
assets,
|
||||
registrar,
|
||||
clock,
|
||||
})
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
#[inline(never)]
|
||||
fn state_transition(req: StateTransitionRequest) -> Result<(), RegistryError> {
|
||||
info!("state-transition: switch_entity");
|
||||
msg!("state-transition: switch_entity");
|
||||
|
||||
let StateTransitionRequest {
|
||||
new_entity_acc_info,
|
||||
|
@ -104,16 +165,35 @@ fn state_transition(req: StateTransitionRequest) -> Result<(), RegistryError> {
|
|||
new_entity,
|
||||
registrar,
|
||||
clock,
|
||||
assets,
|
||||
} = req;
|
||||
|
||||
curr_entity.remove(member);
|
||||
new_entity.add(member);
|
||||
// Bump the last stake timestamp to prevent people from switching from
|
||||
// inactive to active entities to retrieve a reward when they shouldn't.
|
||||
if curr_entity.state == EntityState::Inactive {
|
||||
member.last_stake_ts = clock.unix_timestamp;
|
||||
}
|
||||
|
||||
curr_entity.transition_activation_if_needed(registrar, clock);
|
||||
new_entity.transition_activation_if_needed(registrar, clock);
|
||||
// Bookepping.
|
||||
//
|
||||
// Move all the assets to the new entity.
|
||||
//
|
||||
// Note that the assets don't actually move, as the member vaults are
|
||||
// untouched.
|
||||
for a in assets {
|
||||
// Remove.
|
||||
curr_entity.balances.spt_amount -= a.vault_stake.amount;
|
||||
curr_entity.balances.spt_mega_amount -= a.vault_stake_mega.amount;
|
||||
// Add.
|
||||
new_entity.balances.spt_amount += a.vault_stake.amount;
|
||||
new_entity.balances.spt_mega_amount += a.vault_stake_mega.amount;
|
||||
}
|
||||
|
||||
member.entity = *new_entity_acc_info.key;
|
||||
member.last_stake_ts = clock.unix_timestamp;
|
||||
|
||||
// Trigger activation FSM.
|
||||
curr_entity.transition_activation_if_needed(registrar, clock);
|
||||
new_entity.transition_activation_if_needed(registrar, clock);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -125,12 +205,15 @@ struct AccessControlRequest<'a, 'b> {
|
|||
curr_entity_acc_info: &'a AccountInfo<'b>,
|
||||
new_entity_acc_info: &'a AccountInfo<'b>,
|
||||
clock_acc_info: &'a AccountInfo<'b>,
|
||||
vault_authority_acc_info: &'a AccountInfo<'b>,
|
||||
program_id: &'a Pubkey,
|
||||
asset_acc_infos: Vec<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>,
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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>,
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -1,23 +1,18 @@
|
|||
use crate::common::entity::{with_entity, EntityContext};
|
||||
use serum_common::pack::Pack;
|
||||
use serum_common::program::invoke_token_transfer;
|
||||
use serum_registry::access_control;
|
||||
use serum_registry::accounts::{vault, Entity, Member, Registrar};
|
||||
use serum_registry::accounts::{vault, Registrar};
|
||||
use serum_registry::error::{RegistryError, RegistryErrorCode};
|
||||
use solana_program::info;
|
||||
use solana_program::msg;
|
||||
use solana_sdk::account_info::{next_account_info, AccountInfo};
|
||||
use solana_sdk::pubkey::Pubkey;
|
||||
use solana_sdk::sysvar::clock::Clock;
|
||||
use spl_token::state::Account as TokenAccount;
|
||||
|
||||
#[inline(never)]
|
||||
pub fn handler(
|
||||
program_id: &Pubkey,
|
||||
accounts: &[AccountInfo],
|
||||
amount: u64,
|
||||
delegate: bool,
|
||||
) -> Result<(), RegistryError> {
|
||||
info!("handler: withdraw");
|
||||
msg!("handler: withdraw");
|
||||
|
||||
let acc_infos = &mut accounts.iter();
|
||||
|
||||
|
@ -25,79 +20,54 @@ pub fn handler(
|
|||
let depositor_acc_info = next_account_info(acc_infos)?;
|
||||
let depositor_authority_acc_info = next_account_info(acc_infos)?;
|
||||
let token_program_acc_info = next_account_info(acc_infos)?;
|
||||
let vault_acc_info = next_account_info(acc_infos)?;
|
||||
let vault_authority_acc_info = next_account_info(acc_infos)?;
|
||||
let member_vault_acc_info = next_account_info(acc_infos)?;
|
||||
let member_vault_authority_acc_info = next_account_info(acc_infos)?;
|
||||
|
||||
// Program specfic.
|
||||
let member_acc_info = next_account_info(acc_infos)?;
|
||||
let beneficiary_acc_info = next_account_info(acc_infos)?;
|
||||
let entity_acc_info = next_account_info(acc_infos)?;
|
||||
let registrar_acc_info = next_account_info(acc_infos)?;
|
||||
let clock_acc_info = next_account_info(acc_infos)?;
|
||||
|
||||
let ctx = EntityContext {
|
||||
let AccessControlResponse { ref registrar } = access_control(AccessControlRequest {
|
||||
member_vault_authority_acc_info,
|
||||
depositor_acc_info,
|
||||
member_acc_info,
|
||||
beneficiary_acc_info,
|
||||
entity_acc_info,
|
||||
registrar_acc_info,
|
||||
clock_acc_info,
|
||||
member_vault_acc_info,
|
||||
program_id,
|
||||
};
|
||||
with_entity(ctx, &mut |entity: &mut Entity,
|
||||
registrar: &Registrar,
|
||||
_: &Clock| {
|
||||
let AccessControlResponse { ref depositor } = access_control(AccessControlRequest {
|
||||
vault_authority_acc_info,
|
||||
depositor_acc_info,
|
||||
member_acc_info,
|
||||
beneficiary_acc_info,
|
||||
entity_acc_info,
|
||||
vault_acc_info,
|
||||
program_id,
|
||||
registrar_acc_info,
|
||||
registrar,
|
||||
depositor_authority_acc_info,
|
||||
amount,
|
||||
delegate,
|
||||
})?;
|
||||
Member::unpack_mut(
|
||||
&mut member_acc_info.try_borrow_mut_data()?,
|
||||
&mut |member: &mut Member| {
|
||||
state_transition(StateTransitionRequest {
|
||||
entity,
|
||||
member,
|
||||
amount,
|
||||
registrar: ®istrar,
|
||||
registrar_acc_info,
|
||||
vault_acc_info,
|
||||
vault_authority_acc_info,
|
||||
depositor_acc_info,
|
||||
token_program_acc_info,
|
||||
depositor,
|
||||
})
|
||||
.map_err(Into::into)
|
||||
},
|
||||
)
|
||||
.map_err(Into::into)
|
||||
registrar_acc_info,
|
||||
depositor_authority_acc_info,
|
||||
amount,
|
||||
})?;
|
||||
state_transition(StateTransitionRequest {
|
||||
amount,
|
||||
registrar,
|
||||
registrar_acc_info,
|
||||
member_vault_acc_info,
|
||||
member_vault_authority_acc_info,
|
||||
depositor_acc_info,
|
||||
token_program_acc_info,
|
||||
})?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn access_control(req: AccessControlRequest) -> Result<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,
|
||||
®istrar,
|
||||
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,
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
®istrar,
|
||||
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,
|
||||
®istrar,
|
||||
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,
|
||||
®istrar,
|
||||
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 != ®istrar.pool_vault
|
||||
&& pool_vault_acc_info.key != ®istrar.pool_vault_mega
|
||||
{
|
||||
return Err(RegistryErrorCode::InvalidVault)?;
|
||||
}
|
||||
|
||||
let is_mega = pool_vault_acc_info.key == ®istrar.pool_vault_mega;
|
||||
|
||||
Ok((v, is_mega))
|
||||
}
|
||||
|
||||
pub fn pool_mint(
|
||||
pool_mint_acc_info: &AccountInfo,
|
||||
registrar: &Registrar,
|
||||
|
@ -234,25 +317,33 @@ pub fn pool_mint(
|
|||
Ok(mint)
|
||||
}
|
||||
|
||||
pub fn pool_token(
|
||||
pub fn member_pool_token(
|
||||
member: &Member,
|
||||
pool_token_acc_info: &AccountInfo,
|
||||
pool_mint_acc_info: &AccountInfo,
|
||||
member: &Member,
|
||||
balance_id: &Pubkey,
|
||||
is_mega: bool,
|
||||
) -> Result<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,
|
||||
®istrar,
|
||||
&rent,
|
||||
program_id,
|
||||
)?;
|
||||
// Stake.
|
||||
vault_pair(
|
||||
b.vault_stake_acc_info,
|
||||
b.vault_stake_mega_acc_info,
|
||||
registrar_acc_info,
|
||||
®istrar,
|
||||
&rent,
|
||||
program_id,
|
||||
)?;
|
||||
// Pending withdrawals.
|
||||
vault_pair(
|
||||
b.vault_pw_acc_info,
|
||||
b.vault_pw_mega_acc_info,
|
||||
registrar_acc_info,
|
||||
®istrar,
|
||||
&rent,
|
||||
program_id,
|
||||
)?;
|
||||
|
||||
all_accounts.extend_from_slice(&[
|
||||
b.owner_acc_info.key,
|
||||
b.spt_acc_info.key,
|
||||
b.spt_mega_acc_info.key,
|
||||
b.vault_acc_info.key,
|
||||
b.vault_mega_acc_info.key,
|
||||
b.vault_stake_acc_info.key,
|
||||
b.vault_stake_mega_acc_info.key,
|
||||
b.vault_pw_acc_info.key,
|
||||
b.vault_pw_mega_acc_info.key,
|
||||
]);
|
||||
}
|
||||
let given_len = all_accounts.len();
|
||||
all_accounts.sort();
|
||||
all_accounts.dedup();
|
||||
if given_len != all_accounts.len() {
|
||||
return Err(RegistryErrorCode::InvalidAssetsLen)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn token(acc_info: &AccountInfo, authority: &Pubkey) -> Result<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>,
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::accounts::{Member, Registrar};
|
||||
use crate::accounts::Registrar;
|
||||
use crate::error::RegistryError;
|
||||
use borsh::{BorshDeserialize, BorshSchema, BorshSerialize};
|
||||
use serum_common::pack::*;
|
||||
|
@ -12,6 +12,12 @@ lazy_static::lazy_static! {
|
|||
.expect("Entity has a fixed size");
|
||||
}
|
||||
|
||||
// Conversion from base unit of SRM to base unit of MSRM.
|
||||
//
|
||||
// SRM has 6 decimals. MSRM ~ 1_000_000 SRM => 1 unit of
|
||||
// the MSRM mint == 10**6 * 1_000_000 units of the SRM mint.
|
||||
const MSRM_SRM_RATE: u64 = 1_000_000_000_000;
|
||||
|
||||
#[derive(Clone, Debug, BorshSerialize, BorshDeserialize, BorshSchema)]
|
||||
pub struct Entity {
|
||||
/// Set when this entity is registered.
|
||||
|
@ -45,47 +51,11 @@ impl Default for Entity {
|
|||
}
|
||||
|
||||
impl Entity {
|
||||
pub fn remove(&mut self, member: &mut Member) {
|
||||
self.balances.current_deposit -= member.balances.current_deposit;
|
||||
self.balances.current_mega_deposit -= member.balances.current_mega_deposit;
|
||||
self.balances.spt_amount -= member.balances.spt_amount;
|
||||
self.balances.spt_mega_amount -= member.balances.spt_mega_amount;
|
||||
}
|
||||
|
||||
pub fn add(&mut self, member: &mut Member) {
|
||||
self.balances.current_deposit += member.balances.current_deposit;
|
||||
self.balances.current_mega_deposit += member.balances.current_mega_deposit;
|
||||
self.balances.spt_amount += member.balances.spt_amount;
|
||||
self.balances.spt_mega_amount += member.balances.spt_mega_amount;
|
||||
}
|
||||
|
||||
pub fn activation_amount(&self) -> u64 {
|
||||
self.amount_equivalent() + self.current_deposit_equivalent()
|
||||
}
|
||||
|
||||
pub fn did_deposit(&mut self, amount: u64, mega: bool) {
|
||||
if mega {
|
||||
self.balances.current_mega_deposit += amount;
|
||||
} else {
|
||||
self.balances.current_deposit += amount;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn did_withdraw(&mut self, amount: u64, mega: bool) {
|
||||
if mega {
|
||||
self.balances.current_mega_deposit -= amount;
|
||||
} else {
|
||||
self.balances.current_deposit -= amount;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn spt_did_stake(&mut self, amount: u64, is_mega: bool) -> Result<(), RegistryError> {
|
||||
if is_mega {
|
||||
self.balances.spt_mega_amount += amount;
|
||||
self.balances.current_mega_deposit -= amount;
|
||||
} else {
|
||||
self.balances.spt_amount += amount;
|
||||
self.balances.current_deposit -= amount;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
@ -99,19 +69,11 @@ impl Entity {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn spt_did_unstake_end(&mut self, amount: u64, is_mega: bool) {
|
||||
if is_mega {
|
||||
self.balances.current_mega_deposit += amount;
|
||||
} else {
|
||||
self.balances.current_deposit += amount;
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
pub fn transition_activation_if_needed(&mut self, registrar: &Registrar, clock: &Clock) {
|
||||
match self.state {
|
||||
EntityState::Inactive => {
|
||||
if self.meets_activation_requirements(registrar) {
|
||||
if self.meets_activation_requirements() {
|
||||
self.state = EntityState::Active;
|
||||
}
|
||||
}
|
||||
|
@ -122,12 +84,12 @@ impl Entity {
|
|||
if clock.unix_timestamp > deactivation_start_ts + timelock {
|
||||
self.state = EntityState::Inactive;
|
||||
}
|
||||
if self.meets_activation_requirements(registrar) {
|
||||
if self.meets_activation_requirements() {
|
||||
self.state = EntityState::Active;
|
||||
}
|
||||
}
|
||||
EntityState::Active => {
|
||||
if !self.meets_activation_requirements(registrar) {
|
||||
if !self.meets_activation_requirements() {
|
||||
self.state = EntityState::PendingDeactivation {
|
||||
deactivation_start_ts: clock.unix_timestamp,
|
||||
timelock: registrar.deactivation_timelock,
|
||||
|
@ -137,27 +99,40 @@ impl Entity {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns true if this Entity is capable of being "activated", i.e., can
|
||||
/// enter the staking pool.
|
||||
pub fn meets_activation_requirements(&self, registrar: &Registrar) -> bool {
|
||||
self.activation_amount() >= registrar.reward_activation_threshold
|
||||
&& (self.balances.spt_mega_amount >= 1 || self.balances.current_mega_deposit >= 1)
|
||||
pub fn meets_activation_requirements(&self) -> bool {
|
||||
self.balances.spt_mega_amount >= 1
|
||||
}
|
||||
|
||||
pub fn slash(&mut self, spt_amount: u64, mega: bool) {
|
||||
if mega {
|
||||
self.balances.spt_mega_amount -= spt_amount;
|
||||
} else {
|
||||
self.balances.spt_amount -= spt_amount;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn amount_equivalent(&self) -> u64 {
|
||||
self.balances.spt_amount + self.balances.spt_mega_amount * 1_000_000
|
||||
}
|
||||
|
||||
fn current_deposit_equivalent(&self) -> u64 {
|
||||
self.balances.current_deposit + self.balances.current_mega_deposit * 1_000_000
|
||||
pub fn stake_will_max(&self, spt_amount: u64, is_mega: bool, registrar: &Registrar) -> bool {
|
||||
let spt_value = {
|
||||
if is_mega {
|
||||
spt_amount
|
||||
.checked_mul(registrar.stake_rate_mega)
|
||||
.unwrap()
|
||||
.checked_mul(MSRM_SRM_RATE)
|
||||
.unwrap()
|
||||
} else {
|
||||
spt_amount.checked_mul(registrar.stake_rate).unwrap()
|
||||
}
|
||||
};
|
||||
let amount_equivalent = spt_value
|
||||
.checked_add(
|
||||
self.balances
|
||||
.spt_amount
|
||||
.checked_mul(registrar.stake_rate)
|
||||
.unwrap(),
|
||||
)
|
||||
.unwrap()
|
||||
.checked_add(
|
||||
self.balances
|
||||
.spt_mega_amount
|
||||
.checked_mul(registrar.stake_rate_mega)
|
||||
.unwrap()
|
||||
.checked_mul(MSRM_SRM_RATE)
|
||||
.unwrap(),
|
||||
)
|
||||
.unwrap();
|
||||
amount_equivalent > registrar.max_stake_per_entity
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -168,9 +143,6 @@ pub struct Balances {
|
|||
// Denominated in staking pool tokens.
|
||||
pub spt_amount: u64,
|
||||
pub spt_mega_amount: u64,
|
||||
// Denominated in SRM/MSRM.
|
||||
pub current_deposit: u64,
|
||||
pub current_mega_deposit: u64,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, BorshSerialize, BorshDeserialize, BorshSchema, PartialEq)]
|
||||
|
|
|
@ -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)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(true)
|
||||
}
|
||||
|
||||
pub fn stake_is_empty(&self) -> bool {
|
||||
self.balances.spt_amount == 0 && self.balances.spt_mega_amount == 0
|
||||
}
|
||||
|
||||
pub fn set_delegate(&mut self, delegate: Pubkey) {
|
||||
assert!(self.balances.delegate.deposit == 0);
|
||||
assert!(self.balances.delegate.mega_deposit == 0);
|
||||
self.balances.delegate = OriginalDeposit::new(delegate);
|
||||
}
|
||||
|
||||
pub fn did_deposit(&mut self, amount: u64, mega: bool, owner: Pubkey) {
|
||||
if mega {
|
||||
self.balances.current_mega_deposit += amount;
|
||||
} else {
|
||||
self.balances.current_deposit += amount;
|
||||
}
|
||||
|
||||
let delegate = owner == self.balances.delegate.owner;
|
||||
if delegate {
|
||||
if mega {
|
||||
self.balances.delegate.mega_deposit += amount;
|
||||
} else {
|
||||
self.balances.delegate.deposit += amount;
|
||||
}
|
||||
} else {
|
||||
if mega {
|
||||
self.balances.main.mega_deposit += amount;
|
||||
} else {
|
||||
self.balances.main.deposit += amount;
|
||||
}
|
||||
impl Default for Member {
|
||||
fn default() -> Member {
|
||||
Member {
|
||||
initialized: false,
|
||||
registrar: Pubkey::new_from_array([0; 32]),
|
||||
beneficiary: Pubkey::new_from_array([0; 32]),
|
||||
entity: Pubkey::new_from_array([0; 32]),
|
||||
metadata: Pubkey::new_from_array([0; 32]),
|
||||
balances: vec![BalanceSandbox::default(), BalanceSandbox::default()],
|
||||
rewards_cursor: 0,
|
||||
last_stake_ts: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn did_withdraw(&mut self, amount: u64, mega: bool, owner: Pubkey) {
|
||||
if mega {
|
||||
self.balances.current_mega_deposit -= amount;
|
||||
} else {
|
||||
self.balances.current_deposit -= amount;
|
||||
}
|
||||
|
||||
let delegate = owner == self.balances.delegate.owner;
|
||||
if delegate {
|
||||
if mega {
|
||||
self.balances.delegate.mega_deposit -= amount;
|
||||
} else {
|
||||
self.balances.delegate.deposit -= amount;
|
||||
}
|
||||
} else {
|
||||
if mega {
|
||||
self.balances.main.mega_deposit -= amount;
|
||||
} else {
|
||||
self.balances.main.deposit -= amount;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn spt_did_stake(&mut self, amount: u64, mega: bool) -> Result<(), RegistryError> {
|
||||
if mega {
|
||||
self.balances.spt_mega_amount =
|
||||
self.balances.spt_mega_amount.checked_add(amount).unwrap();
|
||||
self.balances.current_mega_deposit = self
|
||||
.balances
|
||||
.current_mega_deposit
|
||||
.checked_sub(amount)
|
||||
.unwrap();
|
||||
} else {
|
||||
self.balances.spt_amount = self.balances.spt_amount.checked_add(amount).unwrap();
|
||||
self.balances.current_deposit =
|
||||
self.balances.current_deposit.checked_sub(amount).unwrap();
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn spt_did_unstake_start(&mut self, spt_amount: u64, mega: bool) {
|
||||
if mega {
|
||||
self.balances.spt_mega_amount = self
|
||||
.balances
|
||||
.spt_mega_amount
|
||||
.checked_sub(spt_amount)
|
||||
.unwrap();
|
||||
} else {
|
||||
self.balances.spt_amount = self.balances.spt_amount.checked_sub(spt_amount).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn spt_did_unstake_end(&mut self, amount: u64, is_mega: bool) {
|
||||
if is_mega {
|
||||
self.balances.current_mega_deposit += amount;
|
||||
} else {
|
||||
self.balances.current_deposit += amount;
|
||||
}
|
||||
}
|
||||
// BalanceSandbox defines isolated funds that can only be deposited/withdrawn
|
||||
// into the program if the `owner` signs off on the transaction.
|
||||
//
|
||||
// Once controlled by the program, the associated `Member` account's beneficiary
|
||||
// can send funds to/from any of the accounts within the sandbox, e.g., to
|
||||
// stake.
|
||||
#[derive(Default, Debug, BorshSerialize, BorshDeserialize)]
|
||||
pub struct BalanceSandbox {
|
||||
pub owner: Pubkey,
|
||||
// Staking pool token.
|
||||
pub spt: Pubkey,
|
||||
pub spt_mega: Pubkey,
|
||||
// Free balance (deposit) vaults.
|
||||
pub vault: Pubkey,
|
||||
pub vault_mega: Pubkey,
|
||||
// Stake vaults.
|
||||
pub vault_stake: Pubkey,
|
||||
pub vault_stake_mega: Pubkey,
|
||||
// Pending withdrawal vaults.
|
||||
pub vault_pending_withdrawal: Pubkey,
|
||||
pub vault_pending_withdrawal_mega: Pubkey,
|
||||
}
|
||||
|
||||
serum_common::packable!(Member);
|
||||
|
||||
#[derive(Default, Debug, BorshSerialize, BorshDeserialize, BorshSchema)]
|
||||
pub struct MemberBalances {
|
||||
// The amount of SPT tokens in the SRM pool.
|
||||
pub spt_amount: u64,
|
||||
// The amount of SPT tokens in the MSRM pool.
|
||||
pub spt_mega_amount: u64,
|
||||
// SRM in the current_deposit vault.
|
||||
pub current_deposit: u64,
|
||||
// MSRM in the current_deposit vault.
|
||||
pub current_mega_deposit: u64,
|
||||
// Original deposit.
|
||||
pub main: OriginalDeposit,
|
||||
// Original deposit from delegate.
|
||||
pub delegate: OriginalDeposit,
|
||||
}
|
||||
|
||||
impl MemberBalances {
|
||||
pub fn new(beneficiary: Pubkey, delegate: Pubkey) -> Self {
|
||||
Self {
|
||||
spt_amount: 0,
|
||||
spt_mega_amount: 0,
|
||||
current_deposit: 0,
|
||||
current_mega_deposit: 0,
|
||||
main: OriginalDeposit::new(beneficiary),
|
||||
delegate: OriginalDeposit::new(delegate),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn stake_is_empty(&self) -> bool {
|
||||
self.spt_amount + self.spt_mega_amount == 0
|
||||
}
|
||||
}
|
||||
|
||||
// OriginalDeposit tracks the amount of tokens originally deposited into a Member
|
||||
// account. These funds might be in either the deposit vault or the pool.
|
||||
//
|
||||
// It is used to track the amount of funds that must be returned to delegate
|
||||
// programs, e.g., the lockup program.
|
||||
#[derive(Default, Debug, BorshSerialize, BorshDeserialize, BorshSchema)]
|
||||
pub struct OriginalDeposit {
|
||||
pub owner: Pubkey,
|
||||
pub deposit: u64,
|
||||
pub mega_deposit: u64,
|
||||
}
|
||||
|
||||
impl OriginalDeposit {
|
||||
pub fn new(owner: Pubkey) -> Self {
|
||||
Self {
|
||||
owner,
|
||||
deposit: 0,
|
||||
mega_deposit: 0,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.deposit + self.mega_deposit == 0
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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};
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -76,6 +76,10 @@ pub enum RegistryErrorCode {
|
|||
InvalidPoolToken = 62,
|
||||
InvariantViolation = 63,
|
||||
InsufficientReward = 64,
|
||||
InvalidBalanceSandbox = 65,
|
||||
InvalidSpt = 66,
|
||||
InvalidPendingWithdrawalVault = 67,
|
||||
InvalidStakeVault = 68,
|
||||
Unknown = 1000,
|
||||
}
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -42,10 +42,7 @@ fn lifecycle() {
|
|||
let registrar_authority = Keypair::generate(&mut OsRng);
|
||||
|
||||
let InitializeResponse {
|
||||
registrar,
|
||||
nonce,
|
||||
pool_vault,
|
||||
..
|
||||
registrar, nonce, ..
|
||||
} = client
|
||||
.initialize(InitializeRequest {
|
||||
registrar_authority: registrar_authority.pubkey(),
|
||||
|
@ -55,17 +52,18 @@ fn lifecycle() {
|
|||
mega_mint: msrm_mint.pubkey(),
|
||||
reward_activation_threshold,
|
||||
max_stake_per_entity,
|
||||
stake_rate: 1,
|
||||
stake_rate_mega: 1,
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
// Verify initialization.
|
||||
{
|
||||
let registrar = client.registrar(®istrar).unwrap();
|
||||
assert_eq!(registrar.initialized, true);
|
||||
assert_eq!(registrar.authority, registrar_authority.pubkey());
|
||||
}
|
||||
let _registrar = client.registrar(®istrar).unwrap();
|
||||
assert_eq!(_registrar.initialized, true);
|
||||
assert_eq!(_registrar.authority, registrar_authority.pubkey());
|
||||
|
||||
// Initialize the lockup program, vesting account, and whitelist the
|
||||
// registrar so that we can stake locked srm.
|
||||
// registrar so that we can stake lockedacc srm.
|
||||
let (l_client, safe, vesting, vesting_beneficiary) = {
|
||||
let l_pid: Pubkey = std::env::var("TEST_LOCKUP_PROGRAM_ID")
|
||||
.unwrap()
|
||||
|
@ -135,7 +133,7 @@ fn lifecycle() {
|
|||
|
||||
// Update entity.
|
||||
{
|
||||
let new_leader = Pubkey::new_rand();
|
||||
let new_leader = Pubkey::new_unique();
|
||||
let _ = client
|
||||
.update_entity(UpdateEntityRequest {
|
||||
entity,
|
||||
|
@ -169,12 +167,6 @@ fn lifecycle() {
|
|||
assert_eq!(member_account.initialized, true);
|
||||
assert_eq!(member_account.entity, entity);
|
||||
assert_eq!(member_account.beneficiary, beneficiary.pubkey());
|
||||
assert_eq!(
|
||||
member_account.balances.delegate.owner,
|
||||
vesting_vault_authority,
|
||||
);
|
||||
assert_eq!(member_account.balances.spt_amount, 0);
|
||||
assert_eq!(member_account.balances.spt_mega_amount, 0);
|
||||
member
|
||||
};
|
||||
|
||||
|
@ -194,7 +186,7 @@ fn lifecycle() {
|
|||
amount: current_deposit_amount,
|
||||
})
|
||||
.unwrap();
|
||||
let vault = client.current_deposit_vault(®istrar).unwrap();
|
||||
let vault = client.current_deposit_vault(&member, false).unwrap();
|
||||
assert_eq!(current_deposit_amount, vault.amount);
|
||||
let god_acc = rpc::get_token_account::<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(®istrar).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(®istrar).unwrap();
|
||||
let vault = client.current_deposit_vault(&member, true).unwrap();
|
||||
assert_eq!(current_deposit_amount, vault.amount);
|
||||
let l_vault = l_client.vault_for(&vesting).unwrap();
|
||||
assert_eq!(l_vault_amount - current_deposit_amount, l_vault.amount);
|
||||
|
@ -246,7 +237,6 @@ fn lifecycle() {
|
|||
l_client
|
||||
.registry_withdraw(RegistryWithdrawRequest {
|
||||
amount: current_deposit_amount,
|
||||
is_mega: false,
|
||||
registry_pid: *client.program(),
|
||||
registrar,
|
||||
member,
|
||||
|
@ -257,7 +247,7 @@ fn lifecycle() {
|
|||
safe,
|
||||
})
|
||||
.unwrap();
|
||||
let vault = client.current_deposit_vault(®istrar).unwrap();
|
||||
let vault = client.current_deposit_vault(&member, true).unwrap();
|
||||
assert_eq!(0, vault.amount);
|
||||
let l_vault = l_client.vault_for(&vesting).unwrap();
|
||||
assert_eq!(l_vault_amount, l_vault.amount);
|
||||
|
@ -288,9 +278,10 @@ fn lifecycle() {
|
|||
beneficiary,
|
||||
pool_token_amount: 1,
|
||||
mega: true,
|
||||
balance_id: client.payer().pubkey(),
|
||||
})
|
||||
.unwrap();
|
||||
let user_pool_token_acc = client.mega_pool_token(&member).unwrap().account;
|
||||
let user_pool_token_acc = client.mega_pool_token(&member, false).unwrap().account;
|
||||
assert_eq!(user_pool_token_acc.amount, 1);
|
||||
assert_eq!(
|
||||
user_pool_token_acc.owner,
|
||||
|
@ -300,7 +291,7 @@ fn lifecycle() {
|
|||
user_pool_token_acc.delegate,
|
||||
COption::Some(beneficiary.pubkey()),
|
||||
);
|
||||
let msrm_vault = client.stake_mega_pool_asset_vaults(®istrar).unwrap();
|
||||
let msrm_vault = client.stake_mega_pool_asset_vault(&member, false).unwrap();
|
||||
assert_eq!(msrm_vault.amount, 1);
|
||||
}
|
||||
|
||||
|
@ -328,9 +319,10 @@ fn lifecycle() {
|
|||
beneficiary,
|
||||
pool_token_amount: current_deposit_amount,
|
||||
mega: false,
|
||||
balance_id: client.payer().pubkey(),
|
||||
})
|
||||
.unwrap();
|
||||
let user_pool_token_acc = client.pool_token(&member).unwrap().account;
|
||||
let user_pool_token_acc = client.pool_token(&member, false).unwrap().account;
|
||||
assert_eq!(user_pool_token_acc.amount, current_deposit_amount);
|
||||
assert_eq!(
|
||||
user_pool_token_acc.owner,
|
||||
|
@ -341,10 +333,10 @@ fn lifecycle() {
|
|||
COption::Some(beneficiary.pubkey()),
|
||||
);
|
||||
|
||||
let pool_vault_acc = client.stake_pool_asset_vault(®istrar).unwrap();
|
||||
let pool_vault_acc = client.stake_pool_asset_vault(&member, false).unwrap();
|
||||
assert_eq!(pool_vault_acc.amount, current_deposit_amount);
|
||||
|
||||
let vault = client.current_deposit_vault(®istrar).unwrap();
|
||||
let vault = client.current_deposit_vault(&member, false).unwrap();
|
||||
assert_eq!(vault.amount, 0);
|
||||
|
||||
// Stake withdrawal start.
|
||||
|
@ -360,22 +352,22 @@ fn lifecycle() {
|
|||
beneficiary,
|
||||
spt_amount: current_deposit_amount,
|
||||
mega: false,
|
||||
balance_id: client.payer().pubkey(),
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
let member_acc = client.member(&member).unwrap();
|
||||
assert_eq!(member_acc.balances.spt_amount, 0);
|
||||
assert_eq!(member_acc.balances.current_deposit, 0);
|
||||
let vault = client.current_deposit_vault(&member, false).unwrap();
|
||||
assert_eq!(vault.amount, 0);
|
||||
|
||||
let vault = client.current_deposit_vault(®istrar).unwrap();
|
||||
assert_eq!(vault.amount, current_deposit_amount);
|
||||
|
||||
let user_pool_token = client.pool_token(&member).unwrap().account;
|
||||
let user_pool_token = client.pool_token(&member, false).unwrap().account;
|
||||
assert_eq!(user_pool_token.amount, 0);
|
||||
|
||||
let pool_vault_acc = client.stake_pool_asset_vault(®istrar).unwrap();
|
||||
let pool_vault_acc = client.stake_pool_asset_vault(&member, false).unwrap();
|
||||
assert_eq!(pool_vault_acc.amount, 0);
|
||||
|
||||
let pending_withdrawal_vault = client.pending_withdrawal_vault(&member, false).unwrap();
|
||||
assert_eq!(pending_withdrawal_vault.amount, current_deposit_amount);
|
||||
|
||||
// PendingWithdrawal.
|
||||
let pending_withdrawal_acc = client.pending_withdrawal(&pending_withdrawal).unwrap();
|
||||
assert_eq!(pending_withdrawal_acc.initialized, true);
|
||||
|
@ -384,8 +376,8 @@ fn lifecycle() {
|
|||
pending_withdrawal_acc.end_ts,
|
||||
pending_withdrawal_acc.start_ts + deactivation_timelock
|
||||
);
|
||||
assert_eq!(pending_withdrawal_acc.spt_amount, current_deposit_amount);
|
||||
assert_eq!(pending_withdrawal_acc.pool, pool_vault);
|
||||
assert_eq!(pending_withdrawal_acc.amount, current_deposit_amount);
|
||||
assert_eq!(pending_withdrawal_acc.pool, _registrar.pool_mint);
|
||||
pending_withdrawal
|
||||
};
|
||||
|
||||
|
@ -402,12 +394,9 @@ fn lifecycle() {
|
|||
pending_withdrawal,
|
||||
})
|
||||
.unwrap();
|
||||
let vault = client.current_deposit_vault(®istrar).unwrap();
|
||||
let vault = client.current_deposit_vault(&member, false).unwrap();
|
||||
assert_eq!(vault.amount, current_deposit_amount);
|
||||
|
||||
let member = client.member(&member).unwrap();
|
||||
assert_eq!(member.balances.spt_amount, 0);
|
||||
assert_eq!(member.balances.current_deposit, current_deposit_amount);
|
||||
assert_eq!(client.pool_token(&member, false).unwrap().account.amount, 0);
|
||||
}
|
||||
|
||||
// Withdraw MSRM.
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue