Fungible Asset vs Primary Fungible Store Details

1. Fungible Asset

Key Characteristics

module aptos_framework::fungible_asset {
    struct FungibleAsset {
        metadata: Object<Metadata>,
        amount: u64,
    }

    struct FungibleStore has key {
        metadata: Object<Metadata>,
        balance: u64,
        frozen: bool,
    }
}

Functionality

  1. Low-level Operations
    • Direct token manipulation
    • Custom store creation
    • Flexible store management
  2. Direct Control
    • Manual store creation
    • Explicit store handling
    • Fine-grained control
  3. Advanced Features
    • Custom store implementations
    • Complex token behaviors
    • Specialized token logic

Use Cases

  1. DeFi Protocols

    // Example: Custom liquidity pool store
    struct LiquidityPoolStore has key {
        store: FungibleStore,
        pool_info: PoolInfo,
        // Additional DeFi-specific fields
    }
    
  2. Complex Token Systems

    // Example: Multi-tier token system
    struct TieredStore has key {
        base_store: FungibleStore,
        tier_level: u8,
        rewards_multiplier: u64,
    }
    
  3. Protocol-Specific Implementations

    // Example: Staking contract
    struct StakingStore has key {
        tokens: FungibleStore,
        lock_period: u64,
        rewards_rate: u64,
    }
    

2. Primary Fungible Store

Functionality

  1. High-level Operations
    • Automatic store management
    • Simplified transfers
    • Standard token operations
  2. User-Focused
    • Automatic store creation
    • Intuitive interfaces
    • Standard workflows
  3. Standard Features
    • Basic transfer operations
    • Standard balance management
    • Common token functionalities

Use Cases

  1. Standard Tokens

    // Example: Simple token transfer
    public fun transfer(
        from: &signer,
        to: address,
        amount: u64
    ) {
        primary_fungible_store::transfer(from, get_metadata(), to, amount);
    }
    
  2. User Wallets

    // Example: Check balance
    public fun get_balance(account: address): u64 {
        primary_fungible_store::balance(account, get_metadata())
    }
    
  3. Simple Token Systems

    // Example: Basic token implementation
    public fun mint_to(recipient: address, amount: u64) {
        primary_fungible_store::mint(&mint_ref, recipient, amount);
    }
    

3. When to Use

Use Fungible Asset When:

  1. Custom Store Logic is Needed

    // Example: Custom store with special logic
    struct CustomStore has key {
        base_store: FungibleStore,
        custom_data: vector<u8>,
        special_rules: Rules,
    }
    
  2. Implementing Complex Protocols

    // Example: AMM implementation
    struct AMMStore has key {
        token_a: FungibleStore,
        token_b: FungibleStore,
        lp_tokens: FungibleStore,
        curve_parameters: CurveParams,
    }
    
  3. Detailed Control is Required

    // Example: Custom transfer logic
    public fun custom_transfer(
        store: &mut FungibleStore,
        amount: u64,
        rules: &TransferRules
    ) {
        // Custom validation
        validate_transfer(store, amount, rules);
        // Custom transfer logic
        perform_transfer(store, amount);
    }
    

Use Primary Fungible Store When:

  1. Implementing Simple Tokens

    // Example: Basic token operations
    public entry fun simple_transfer(
        from: &signer,
        to: address,
        amount: u64
    ) {
        transfer(from, get_metadata(), to, amount);
    }
    
  2. Focusing on User Experience

    // Example: User-friendly interface
    public entry fun send_tokens(
        user: &signer,
        recipient: address,
        amount: u64
    ) {
        // No need to create store - handled automatically
        transfer(user, get_metadata(), recipient, amount);
    }
    
  3. Implementing Standard Token Functionality

    // Example: Standard token implementation
    public entry fun initialize_token(
        admin: &signer,
        name: String,
        symbol: String,
        decimals: u8
    ) {
        // Standard initialization with automatic store support
        create_primary_store_enabled_fungible_asset(
            admin,
            name,
            symbol,
            decimals
        );
    }
    

4. Best Practices

Fungible Asset Framework

  1. Custom Store Design

    • Clearly define store structure
    • Implement specific rules
    • Handle edge cases
  2. Security Considerations

    // Example: Secure custom store
    struct SecureStore has key {
        store: FungibleStore,
        access_control: AccessControl,
        audit_trail: AuditLog,
    }
    

Primary Fungible Store Framework

  1. Simplicity First

    • Use standard operations
    • Leverage automatic store creation
    • Focus on user experience
  2. Standard Patterns

    // Example: Standard token pattern
    public fun initialize_standard_token(
        admin: &signer,
        config: TokenConfig
    ) {
        // Use standard initialization
        create_standard_token(admin, config);
    }
    

5. Decision Matrix

| Criteria | Fungible Asset | Primary Fungible Store | | --- | --- | --- | | Complexity | High | Low | | Flexibility | High | Moderate | | User Experience | Custom | Standardized | | Use Case | Complex DeFi/Custom Logic | Standard Tokens | | Development Effort | High | Low | | Maintenance | Complex | Simple | | Integration | Custom | Standardized |