usdc-plus-exchange 0.1.8

USDC <-> USDC+ exchange library for the Reflect protocol.
Documentation
use anchor_lang::prelude::{*, borsh::BorshSchema};
use crate::errors::ReflectErrorCodes;
use std::io::Write;

pub const RECIPIENTS_LIMIT: usize = 10;


// For later
// *********************************************
// This is for later integration when recipients have to be deserialised.
// This is if pool dynamics get updated later.

#[repr(C)]
#[derive(BorshSchema, Default, AnchorSerialize, AnchorDeserialize, Debug, PartialEq, Eq, InitSpace, Clone, Copy)]
/** Cut is in 4 decimal places.
Weight of 10.55% is represented as 1055.
All weights must add up to 10000.
*/
pub struct Recipient {
    pub address: Pubkey,
    pub cut: u16,
}

impl Recipient {
    /** Deserialise a Recipient from a buffer. */
    pub fn deserialize(buf: &mut &[u8]) -> Result<Self> {
        let address = Pubkey::deserialize(buf)?;
        let cut = u16::deserialize(buf)?;
        Ok(Recipient { address, cut })
    }
    
    /** Serialise a Recipient to a writer. */
    pub fn try_serialise<W: Write>(&self, writer: &mut W) -> Result<()> {
        self.address.serialize(writer)?;
        self.cut.serialize(writer)?;
        Ok(())
    }   
}

#[repr(C)]
#[derive(BorshSchema, AnchorDeserialize, AnchorSerialize, Default, Debug, PartialEq, Eq, Clone, InitSpace, Copy)]
pub struct Recipients {
    /** Those that receive strategy yield. */
    pub recipients: [Recipient; RECIPIENTS_LIMIT], 
    /** Counter to track how many recipients are in use. */
    pub recipients_count: u8,
}

impl Recipients {
    pub fn deserialize(buf: &mut &[u8]) -> Result<Self> {
        let mut recipients = [Recipient::default(); RECIPIENTS_LIMIT];
        
        for i in 0..RECIPIENTS_LIMIT {
            recipients[i] = Recipient::deserialize(buf)?;
        }
        
        let recipients_count = u8::deserialize(buf)?;
        
        Ok(Recipients {
            recipients,
            recipients_count,
        })
    }
    
    pub fn try_serialise<W: Write>(&self, writer: &mut W) -> Result<()> {
        for recipient in &self.recipients {
            recipient.try_serialise(writer)?;
        }        
        self.recipients_count.serialize(writer)?;        
        Ok(())
    }    

    pub fn get_recipients_vec(&self) -> Vec<Recipient> {              
        self.recipients[..self.recipients_count as usize]
            .iter()
            .copied()
            .collect()
    }

    /// Returns only the cuts of active recipients
    pub fn get_cuts(&self) -> Vec<u16> {
        self.recipients[..self.recipients_count as usize]
            .iter()
            .map(|recipient| recipient.cut)
            .collect()
    }

    /// Overwrites previous one.
    pub fn set_recipients(&mut self, recipients: &Vec<Recipient>) {
        self.recipients
            .iter_mut()
            .zip(recipients.iter())
            .for_each(|(dest, src)| *dest = *src);
        self.recipients[recipients.len()..].fill(Recipient::default());        
        self.recipients_count = recipients.len() as u8;
    }    

    /// Get the number of recipients
    pub fn recipients_count(&self) -> usize {
        self.recipients_count as usize
    }
}


// Below values are not set.
// They need to be worked out.
// Function unimplemented.
pub const RECIPIENTS_START: usize = 0;
pub const USDC_CONTROLLER_SIZE: usize = 10_000;
pub fn deserialise_recipients(data_usdc_controller: &[u8]) -> Result<Recipients> {
    if data_usdc_controller.len() < RECIPIENTS_START + 40 {
        return Err(ReflectErrorCodes::InsufficientData.into());
    }
    
    let mut slice = &data_usdc_controller[RECIPIENTS_START..];
    Recipients::deserialize(&mut slice)
        .map_err(|_| ReflectErrorCodes::DeserializationError.into())
}