usdc-plus-exchange

Crates.iousdc-plus-exchange
lib.rsusdc-plus-exchange
version0.1.4
created_at2025-08-31 23:22:31.896586+00
updated_at2025-09-16 11:55:48.867605+00
descriptionUSDC <-> USDC+ exchange library for the Reflect protocol.
homepage
repository
max_upload_size
id1818951
size142,039
(sausage-dog)

documentation

README

USDC+ Exchange Rate Library

A Rust library for computing real-time exchange rates between USDC and USDC+ tokens in the Reflect Protocol, incorporating live yield from lending.

Overview

This crate provides four core functions for calculating USDC ↔ USDC+ conversions:

  • Deposit (USDC → USDC+)

    • exchange_rate_usdc_input – raw-data version
    • exchange_rate_usdc_accountsAccountInfo validated version
  • Redeem (USDC+ → USDC)

    • exchange_rate_receipt_input – raw-data version
    • exchange_rate_receipt_accountsAccountInfo validated version

All functions automatically incorporate pending yield before computing the exchange rate.


Usage

Deposit Example (USDC → USDC+)

use usdc_plus_exchange::{
    exchange_rate_usdc_input,
    exchange_rate_usdc_accounts,
};

// With raw account bytes:
let tokens = exchange_rate_usdc_input(
    &controller_data,    // USDC controller account bytes
    &spot_market_data,   // Drift spot market account bytes
    &user_account_data,  // Drift user account bytes
    &usdc_plus_mint_data,  // USDC+ mint account bytes
    1_000_000_000        // 1000 USDC (6 decimals)
)?;

// With Anchor AccountInfo (validates account addresses):
let tokens_validated = exchange_rate_usdc_accounts(
    &ctx.accounts.usdc_controller,
    &ctx.accounts.spot_market,
    &ctx.accounts.drift_user,
    &ctx.accounts.usdc_plus_mint,
    1_000_000_000        // 1000 USDC (6 decimals)
)?;

Redeem Example (USDC+ → USDC)

use usdc_plus_exchange::{
    exchange_rate_receipt_input,
    exchange_rate_receipt_accounts,
};

// With raw account bytes:
let usdc = exchange_rate_receipt_input(
    &controller_data,    // USDC controller account bytes
    &spot_market_data,   // Drift spot market account bytes
    &user_account_data,  // Drift user account bytes
    &usdc_plus_mint_data,  // USDC+ mint account bytes
    1_000_000_000        // 1000 USDC+ (6 decimals)
)?;

// With AccountInfo (validates account addresses):
let usdc_validated = exchange_rate_receipt_accounts(
    &ctx.accounts.usdc_controller,
    &ctx.accounts.spot_market,
    &ctx.accounts.drift_user,
    &ctx.accounts.usdc_plus_mint,
    1_000_000_000        // 1000 USDC+ (6 decimals)
)?;

Function Details

1. exchange_rate_usdc_input

Calculates how many USDC+ tokens you receive for a USDC deposit using raw account data.

pub fn exchange_rate_usdc_input(
    data_usdc_controller: &[u8],
    data_spot_market_usdc: &[u8],
    data_user_account: &[u8],
    data_usdc_plus_mint: &[u8],
    usdc_amount: u64,
) -> Result<u64>
  • Raw account data only (faster, no address validation)
  • Incorporate pending yield computing the deposit exchange rate
  • Returns USDC+ amount with 6 decimal places

2. exchange_rate_usdc_accounts

Validates accounts before calling exchange_rate_usdc_input.

pub fn exchange_rate_usdc_accounts(
    usdc_controller_account: &AccountInfo,
    spot_market_usdc_account: &AccountInfo,
    reflect_user_account: &AccountInfo,
    usdc_plus_mint_account: &AccountInfo,
    usdc_amount: u64,
) -> Result<u64>
  • Validates each account matches Reflect Protocol addresses (require!)
  • Prevents account substitution attacks
  • Performs the same calculation as exchange_rate_usdc_input but with account address validation."

3. exchange_rate_receipt_input

Calculates how much USDC you receive for redeeming USDC+ tokens using raw account data.

pub fn exchange_rate_receipt_input(
    data_usdc_controller: &[u8],
    data_spot_market_usdc: &[u8],
    data_user_account: &[u8],
    data_usdc_plus_mint: &[u8],
    receipt_amount: u64,
) -> Result<u64>
  • Raw account data only (no validation)
  • Incorporates pending yield before computing redemption rate
  • Returns USDC amount with 6 decimal places

4. exchange_rate_receipt_accounts

Validates accounts before calling exchange_rate_receipt_input.

pub fn exchange_rate_receipt_accounts(
    usdc_controller_account: &AccountInfo,
    spot_market_usdc_account: &AccountInfo,
    reflect_user_account: &AccountInfo,
    usdc_plus_mint_account: &AccountInfo,
    receipt_amount: u64,
) -> Result<u64>
  • Validates all account addresses
  • Performs the same calculation as exchange_rate_receipt_input but with account address validation."

Equations

Deposit:  USDC+ = USDC × usdc_plus_supply / deposited_vault_value
Redeem:   USDC  = USDC+ × deposited_vault_value / usdc_plus_supply

Where:

  • usdc_plus_supply = total user shares
  • deposited_vault_value = vault’s actual USDC value

Security

  • Use *_accounts variants when running inside an Anchor program for account validation.
  • Raw-data variants are faster but assume you trust the account data source.

Error Handling

All functions return Result<u64> and may fail with:

  • InvalidAccount – if account validation fails
  • MathError – division by zero or overflow
  • DeserializationError – invalid or truncated account data
  • InsufficientData – provided account data is too short
Commit count: 0

cargo fmt