Skip to main content

Smart Contract Architecture

Overview

Karpous smart contracts are deployed on Base (Ethereum L2) and implement a security-first design pattern inspired by BoringVault and Maple Finance.


Contract Descriptions

Core Layer

KarpousVault

The vault is the central entry point for all deposits. It implements a passthrough-only design.

PropertyValue
PatternBoringVault (modified)
Fund StorageNEVER - immediate forwarding
Ledger AddressImmutable at deployment
AuthorizationPortal-based access control

Key Functions:

// Forward deposit to Ledger (NO STORAGE)
function passthrough(
address from,
address token,
uint256 amount,
bytes32 depositId,
ProductType product
) external;

// Admin: authorize/revoke portals
function setPortal(address portal, bool authorized) external;

KarpousAccountant

Central configuration management for all platform parameters.

Manages:

  • Lock period configurations (1/3/6/12 months)
  • Boost multipliers (1.25x - 2x)
  • Asset configurations (price, yield, supply caps)
  • Fee settings (deposit, withdrawal, claim)
  • Supported token whitelist

Key Data:

struct LockConfig {
uint40 lockSeconds; // Lock duration
uint40 boostSeconds; // Boost period
uint16 boostMultiplierBps; // Multiplier (basis points)
}

struct AssetConfig {
bool active;
uint16 baseYieldBps; // APY in basis points
uint256 currentPrice;
uint256 minDeposit;
uint256 maxSupply;
}

Portal Layer

FTokenPortalV2

Manages fractional asset token deposits and mints ERC20 fTokens.

FeatureDescription
Token TypeERC20 (real tokens)
Fee1% deposit fee
Supply CapPer-asset maximum
Sale PeriodConfigurable start/end times

Deposit Flow:

EarnPortal

Time-locked staking with yield boost multipliers.

FeatureDescription
Lock Periods1, 3, 6, 12 months
Boost Multiplier1.25x - 2x (early deposit)
Auto-RenewalOptional with yield compounding
Grace Period24 hours (configurable)

Lock Configuration:

DurationLock DaysBoost PeriodBoost Multiplier
1 month307 days1.25x
3 months907 days1.25x
6 months18015 days1.5x
12 months36530 days2x

Position Structure:

struct EarnPosition {
address user;
uint128 amount;
address token;
uint8 lockDuration; // 0=1mo, 1=3mo, 2=6mo, 3=12mo
uint40 depositTime;
uint40 lockExpiry;
uint40 boostExpiry;
uint16 boostMultiplierBps;
bool withdrawn;
bool autoRenew;
uint24 gracePeriodHours;
}

DirectPurchasePortal

Whole-unit asset purchases (not fractional).

FeatureDescription
Unit TypeWhole units (1, 2, 3...)
Per-User LimitOptional maximum
Supply CapTotal units available
FeeVariable per asset

Withdrawal Layer

EarnWithdrawalQueue

Manages withdrawal requests with admin approval workflow.

Status Lifecycle:

Roles:

RolePermissions
OPERATORApprove/reject requests
SOLVERFulfill matured requests
UserRequest/cancel own withdrawals

ProductYieldQueue

Manages yield distribution and claim processing.

FeatureDescription
Update FrequencyWeekly batch
Claim Fee1%
Maturity Period1 hour
Per-ProductSeparate tracking per asset/lock type

Yield Flow:


Token Contracts

FToken (ERC20)

Each real-world asset has its own FToken contract.

PropertyValue
StandardERC20
Decimals18
Transfer LockEnabled by default
MintingOnly FTokenPortalV2
BurningNot supported (one-way)

Access Control:

MINTER_ROLE  → FTokenPortalV2 (can mint)
ADMIN_ROLE → Multisig (can toggle transfers)

Contract Interactions

Deposit Interaction

Withdrawal Interaction


Event System

All contracts emit events for backend synchronization:

Vault Events

event Passthrough(
address indexed from,
address indexed token,
uint256 amount,
bytes32 indexed depositId,
ProductType product,
uint256 timestamp
);

Portal Events

event FTokenDeposit(bytes32 indexed depositId, address indexed user, ...);
event EarnPositionCreated(bytes32 indexed positionId, address indexed user, ...);
event DirectPurchaseCompleted(bytes32 indexed purchaseId, address indexed user, ...);

Withdrawal Events

event WithdrawalRequested(bytes32 indexed requestId, ...);
event WithdrawalApproved(bytes32 indexed requestId, ...);
event WithdrawalFulfilled(bytes32 indexed requestId, ...);

Deployment Architecture

Contract Deployment Order

Configuration Steps:

1. vault.setPortal(ftokenPortal, true)
2. vault.setPortal(earnPortal, true)
3. vault.setPortal(directPurchasePortal, true)
4. Grant OPERATOR_ROLE to operators
5. Grant SOLVER_ROLE to solvers
6. Grant MINTER_ROLE to FTokenPortalV2

Network Configuration

NetworkChain IDUse Case
Base Mainnet8453Production
Base Sepolia84532Testnet

Gas Optimization

Techniques Used

TechniqueImplementation
Packed Structsuint40, uint128 for timestamps and amounts
EnumerableSetEfficient iteration for active requests
Batch OperationsArrays for approvals/fulfillments
Custom ErrorsGas-efficient error handling
ImmutablesLedger address, portal address

Gas Estimates

OperationGas Cost
Deposit (FToken)~150,000
Deposit (Earn)~180,000
Request Withdrawal~120,000
Fulfill Withdrawal~80,000 per request
Claim Yield~100,000