Spusd Wrapper

Technical overview of the sUSDC to SPUSD wrapper mechanism

SPUSD Wrapper System

The SPUSD wrapper system is a critical innovation that bridges the security of soul-bound tokens with the liquidity needs of DeFi users. This document provides a technical overview of how the wrapper mechanism works.

Architecture Overview

The wrapper system consists of two main components:

1. StUSDCWrapper Contract

The wrapper contract handles all conversions between sUSDC and SPUSD:

  • Holds sUSDC tokens during the wrap period
  • Mints/burns SPUSD based on deposits/withdrawals
  • Manages locked token accounting
  • Enforces role-based access for special operations

2. SPUSD Token Contract

The SPUSD token is a standard ERC20 with additional features:

  • Lock-aware transfers (checks vesting status)
  • Restricted minting (only wrapper can mint)
  • Burn mechanism for unwrapping
  • Standard ERC20 compatibility for DEX trading

Core Mechanisms

Wrapping Process

function wrap(uint256 amount) external nonReentrant {
    require(amount > 0, "Wrapper: Zero amount");
    
    // Transfer sUSDC from user to wrapper
    require(
        sUSDC.transferFrom(msg.sender, address(this), amount),
        "Wrapper: Transfer failed"
    );
    
    // Mint equivalent SPUSD to user
    spusd.mint(msg.sender, amount);
    
    emit Wrapped(msg.sender, amount);
}

Flow:

  1. User approves wrapper for sUSDC
  2. User calls wrap(amount)
  3. sUSDC transferred to wrapper
  4. SPUSD minted to user
  5. User can now trade SPUSD

Unwrapping Process

function unwrap(uint256 amount) external nonReentrant {
    require(amount > 0, "Wrapper: Zero amount");
    
    // Check if user has locked tokens
    LockInfo memory lock = lockedBalances[msg.sender];
    if (lock.amount > 0 && block.timestamp < lock.unlockTime) {
        require(
            spusd.balanceOf(msg.sender) - amount >= lock.amount,
            "Wrapper: Tokens locked"
        );
    }
    
    // Burn SPUSD from user
    spusd.burnFrom(msg.sender, amount);
    
    // Transfer sUSDC back to user
    require(
        sUSDC.transfer(msg.sender, amount),
        "Wrapper: Transfer failed"
    );
    
    emit Unwrapped(msg.sender, amount);
}

Flow:

  1. User holds SPUSD tokens
  2. User calls unwrap(amount)
  3. Lock status checked
  4. SPUSD burned from user
  5. sUSDC returned to user

Lock Management

Investor Distribution

For team members and investors with vesting schedules:

function wrapAndLock(
    address to,
    uint256 amount,
    uint256 unlockTime
) external nonReentrant {
    require(
        owner() == msg.sender || hasRole(OPERATOR_ROLE, msg.sender),
        "Wrapper: Not authorized"
    );
    
    // Transfer sUSDC from sender to wrapper
    require(
        sUSDC.transferFrom(msg.sender, address(this), amount),
        "Wrapper: Transfer failed"
    );
    
    // Update lock info
    if (unlockTime > lockedBalances[to].unlockTime) {
        lockedBalances[to].unlockTime = unlockTime;
    }
    lockedBalances[to].amount += amount;
    
    // Mint SPUSD to recipient
    spusd.mint(to, amount);
    
    emit LockedTokensMinted(to, amount, unlockTime);
}

Lock Checking in SPUSD

The SPUSD token checks locks on every transfer:

function _update(address from, address to, uint256 amount) internal override {
    // Skip check for minting/burning
    if (from == address(0) || to == address(0)) {
        super._update(from, to, amount);
        return;
    }
    
    // Check if sender has locked tokens
    (uint256 locked, uint256 unlockTime) = IStUSDCWrapper(wrapper).getLockInfo(from);
    if (locked > 0 && block.timestamp < unlockTime) {
        // Ensure user maintains minimum locked balance
        uint256 balance = balanceOf(from);
        require(balance - amount >= locked, "SPUSD: Tokens locked");
    }
    
    super._update(from, to, amount);
}

Security Features

Access Control

  • Only wrapper contract can mint SPUSD
  • Only wrapper contract can burn SPUSD
  • Owner/Operator roles for wrapAndLock
  • No admin functions to drain funds

Economic Security

  • Strict 1:1 backing ratio enforced
  • No fractional reserve possible
  • All sUSDC held in wrapper contract
  • Transparent on-chain verification

Technical Security

  • Reentrancy guards on all state-changing functions
  • No external calls except to trusted contracts
  • Comprehensive input validation
  • Event emission for all operations

Integration Points

For DEXs

SPUSD appears as a standard ERC20 token:

  • transfer() and transferFrom() work normally
  • approve() and allowance() standard
  • balanceOf() returns total balance (including locked)
  • Lock checking happens transparently

For Lending Protocols

SPUSD can be used as collateral:

  • Standard ERC20 interface
  • No special integration required
  • Lock status doesn't affect collateral value
  • Liquidations work normally

For Analytics

Key metrics to track:

  • Total SPUSD supply = Total sUSDC locked in wrapper
  • Circulating supply = Total supply - locked amounts
  • Wrapper sUSDC balance = Backing ratio verification
  • Lock statistics = Vesting schedule tracking

Gas Optimization

The wrapper system is optimized for gas efficiency:

  • Single storage slot for lock info
  • Minimal external calls
  • Efficient balance checks
  • Batching not required (already optimal)

Typical gas costs:

  • Wrap: ~120,000 gas
  • Unwrap: ~100,000 gas
  • Transfer: ~65,000 gas (with lock check)

Emergency Procedures

Wrapper Issues

If the wrapper has issues:

  1. No new wrapping/unwrapping possible
  2. Existing SPUSD remains tradeable
  3. sUSDC remains safe in wrapper
  4. Can deploy new wrapper if needed

SPUSD Issues

If SPUSD has issues:

  1. Wrapper holds all backing sUSDC
  2. Can snapshot balances
  3. Deploy new SPUSD token
  4. Migrate via wrapper update

Future Enhancements

Planned Features

  • Batch operations for gas savings
  • Permit support for gasless transactions
  • Cross-chain bridge integration
  • Advanced lock types (linear vesting)

Backward Compatibility

All enhancements maintain:

  • Existing SPUSD remains valid
  • No changes to core wrap/unwrap
  • Additional features are optional
  • Full backward compatibility

Conclusion

The SPUSD wrapper system elegantly solves the liquidity problem of soul-bound tokens while maintaining security and simplicity. By separating concerns between the soul-bound layer (sUSDC) and liquidity layer (SPUSD), users get the best of both worlds: security and flexibility.