# HyperFunToken

## VaultCore (HyperFunToken.sol)

`HyperFunToken.sol` is the core vault contract. It is also the ERC20 vault token and AMM.

### Inheritance

```solidity
contract HyperFunToken is
    Initializable,
    UUPSUpgradeable,
    OwnableUpgradeable,
    ReentrancyGuardUpgradeable,
    ERC20Upgradeable
```

### Key Constants

```solidity
uint256 public constant BPS = 10000;
uint256 public constant PRECISION = 1e18;
uint256 public constant MAX_FEE = 3000; // 30%

address public constant USDC = 0xb88339CB7199b77E23DB6E890353E22632Ba630f;
address public constant CORE_DEPOSIT_WALLET = 0x6B9E773128f453f5c2C60935Ee2DE2CBc5390A24;
ICoreWriter public constant CORE_WRITER = ICoreWriter(0x3333333333333333333333333333333333333333);
address public constant USDC_L1_SYSTEM = 0x2000000000000000000000000000000000000000;
address public constant PRECOMPILE_SPOT = 0x0000000000000000000000000000000000000801;
```

### State Variables

#### Vault Roles

```solidity
address public leader;           // Vault leader (trader)
address public admin;            // Admin (factory owner)
address public tradingModule;    // HyperFunTrading address
address public factory;          // HyperFunFactory address
```

#### Bonding Curve

```solidity
uint256 public virtualBase;      // Virtual USDC reserve
uint256 public virtualTokens;    // Virtual token reserve
uint256 public initialAssets;    // Initial assets baseline for scaling
```

#### Fee Settings

```solidity
uint256 public feeBps;           // Performance fee (max 30%)
uint256 public protocolFee;      // Protocol fee (default 1%)
```

> **Note:** Trading fee, price limits, exit fee tiers, and other settings are now read from Factory global settings via `_getSettings()` and `_getSettingsExt()`.

#### Accounting

```solidity
uint256 public totalDeposits;    // Total USDC deposited (18 decimals)
uint256 public totalVolume;      // Total trading volume (18 decimals)

mapping(address => DepositRecord) public depositRecords;       // Legacy
mapping(address => UserPurchaseInfo) public userPurchaseInfo;  // Exit fee tracking
mapping(address => EntryRecord) public entryRecords;           // Performance fee tracking
```

#### Pending Sells

```solidity
struct PSSell {
    uint256 usdcAmount;    // Net USDC to receive
    uint256 feeAmount;     // Trading fee
    uint256 timestamp;     // Creation time
}

mapping(address => PSSell) public pendingSells;
uint256 public totalPSUsdc;      // Total pending USDC (reserved)
```

#### TWAP NAV (V40)

```solidity
uint256 public twapNav;              // Smoothed NAV value (18 decimals)
uint256 public twapNavTime;          // Last update timestamp
uint256 public twapMaxChangePerMin;  // Half-life in seconds (default 600 = 10 min)
```

#### Metadata

```solidity
string public metadataURI;       // IPFS or URL for vault metadata
```

***

### Core Functions

#### Buy Tokens

```solidity
function buy(uint256 usdcAmount, uint256 minTokensOut) external;
```

Buy vault tokens with USDC. Includes slippage protection via `minTokensOut`.

**Flow:**

1. Validate `usdcAmount >= minDepositUsdc`
2. Get smoothed NAV for price protection
3. Transfer USDC to vault
4. Deduct trading fee (default 1%)
5. Calculate tokens via constant product formula
6. Check slippage: `tokensOut >= minTokensOut`
7. Check max buy limit (90% of virtual tokens)
8. Update bonding curve reserves
9. Mint tokens to buyer
10. Update entry record and purchase info
11. Transfer fee to treasury
12. Trigger auto-rebalance
13. Update TWAP NAV

#### Sell Tokens

```solidity
function sell(uint256 tokens, uint256 minUsdcOut) external;
```

Sell vault tokens for USDC. Includes slippage protection via `minUsdcOut`.

**Flow:**

1. Validate balance and no existing pending sell
2. Get smoothed NAV
3. Calculate performance fee (if profitable)
4. Calculate USDC out via constant product formula
5. Calculate exit fee (time-based)
6. Cap by available liquidity
7. Check slippage: `netUsdcOut >= minUsdcOut`
8. Update bonding curve reserves
9. Burn tokens
10. Mint performance fee tokens to leader
11. Transfer USDC (or create pending sell)
12. Update TWAP NAV

#### Claim Pending Sell

```solidity
function claimSell() external;
```

Claim USDC from a pending sell after L1 funds have arrived.

#### Leader Deposit

```solidity
function deposit(uint256 usdcAmount) external;
```

Leader-only function to deposit USDC at NAV (no bonding curve, no trading fee).

***

### View Functions

#### NAV & Pricing

```solidity
function getNAV() public view returns (uint256);
function getRawNAV() public view returns (uint256);
function getSmoothedNAV() public view returns (uint256);
function getBuyPrice() public view returns (uint256);
function getSellPrice() public view returns (uint256);
function getSellPriceCapped() public view returns (uint256);
```

#### Calculations

```solidity
function calculateTokensOut(uint256 usdcIn) public view returns (
    uint256 tokensOut,
    uint256 newPrice,
    uint256 priceImpactBps
);

function calculateUsdcOut(uint256 tokensIn) public view returns (
    uint256 usdcOut,
    uint256 newPrice,
    uint256 priceImpactBps
);

function calculateExitFee(address user) public view returns (
    uint256 exitFeeBps,
    uint256 daysHeldResult
);
```

#### Assets & Liquidity

```solidity
function getTotalAssets() public view returns (uint256);
function getAvailableLiquidity() public view returns (uint256);
function getL1AccountValue() public view returns (uint256);
function getL1SpotBalance() public view returns (uint256);
function getMaxBuyUsdc() public view returns (uint256);
function getMaxBuyTokens() public view returns (uint256);
```

#### Bonding Curve

```solidity
function getEffectiveVirtualBase() public view returns (uint256);
function getEffectiveVirtualTokens() public view returns (uint256);
```

***

### Admin Functions

#### Factory Owner Only

```solidity
function setPaused(bool _paused) external;
function setAdmin(address _admin) external;
function setTradingModule(address _tradingModule) external;
function approveBuilderFee(address builder, uint64 maxFeeRate) external;
```

#### Trading Module Only

```solidity
function triggerRebalance() external;
function depositToL1(uint256 amount) external;
function executeL1Action(bytes calldata action) external;
```

#### Leader Only

```solidity
function setMetadataURI(string calldata _metadataURI) external;
```

#### Emergency (Factory Owner)

```solidity
function emergencyWithdrawL1SpotToEVM(uint256 amount6) external;
function emergencyWithdrawEVM(uint256 amount6) external;
```

***

### Events

```solidity
event TokenBought(address indexed user, uint256 usdcIn, uint256 tokensOut, uint256 price);
event TokenSold(address indexed user, uint256 tokensIn, uint256 usdcOut, uint256 price);
event SellPS(address indexed user, uint256 usdcAmount, uint256 feeAmount);
event SellClaimed(address indexed user, uint256 usdcAmount);
event ExitFeeCharged(address indexed user, uint256 feeAmount, uint256 feeBps, uint256 daysHeld);
event PerformanceFeeMinted(address indexed user, address indexed leader, uint256 feeTokens, uint256 nav);
event Deposited(address indexed user, uint256 usdcAmount, uint256 shares);
event DepositedToL1(uint256 amount);
event WithdrawnFromL1(uint256 amount);
event Rebalanced(bool toL1, uint256 amount, uint256 newRatioBps);
event AdminChanged(address indexed oldAdmin, address indexed newAdmin);
event TradingModuleChanged(address indexed oldModule, address indexed newModule);
event MetadataUpdated(string newUri);
event BuilderFeeApproved(address indexed builder, uint64 maxFeeRate);
```

***

### Access Control

```solidity
modifier onlyAdmin() {
    require(msg.sender == admin, "!Admin");
    _;
}

modifier onlyLeader() {
    require(msg.sender == leader, "!Leader");
    _;
}

modifier onlyTradingModule() {
    require(msg.sender == tradingModule, "!TM");
    _;
}

modifier onlyFactoryOwner() {
    require(
        factory != address(0) &&
        (msg.sender == factory || msg.sender == IHyperFunFactory(factory).owner()),
        "!FO"
    );
    _;
}

modifier whenNotPaused() {
    require(!paused, "Paused");
    _;
}
```

***

### Upgrade Authority

```solidity
function _authorizeUpgrade(address) internal override {
    require(factory != address(0), "No factory");
    require(msg.sender == IHyperFunFactory(factory).owner(), "Only factory owner");
}
```

> **Security:** Only factory owner can upgrade. Leaders cannot upgrade, protecting investors from malicious upgrades.

***

### Internal Mechanisms

#### NAV Calculation (Tiered Mode)

NAV uses graduation tiers from Factory for dynamic virtual assets:

```solidity
function getNAV() public view returns (uint256) {
    uint256 supply = totalSupply();
    uint256 total = getTotalAssets();

    uint256 effectiveNavVirtual = _calcTieredNavVirtual(total, supply);

    uint256 totalWithVirtual = total + effectiveNavVirtual;
    uint256 supplyWithVirtual = supply + effectiveNavVirtual;

    if (supplyWithVirtual == 0) return PRECISION;
    return (totalWithVirtual * PRECISION) / supplyWithVirtual;
}
```

#### TWAP NAV (V40)

Smoothed NAV protects against sudden price spikes during liquidations:

```solidity
function getSmoothedNAV() public view returns (uint256) {
    uint256 instantNav = getNAV();

    // Allow immediate increase (no upside protection needed)
    if (instantNav >= twapNav) {
        return instantNav;
    }

    // Half-life decay for decreases
    // After 10 minutes, smoothed NAV moves halfway to instant NAV
    ...
}
```

#### Performance Fee

Calculated on profit using weighted average entry NAV:

```solidity
function _calculatePerformanceFee(
    address user,
    uint256 tokens,
    uint256 currentNav
) internal view returns (uint256 feeTokens) {
    EntryRecord storage record = entryRecords[user];

    if (currentNav <= record.weightedEntryNav) {
        return 0;  // No profit, no fee
    }

    uint256 profitPerToken = currentNav - record.weightedEntryNav;
    uint256 totalProfit18 = (tokens * profitPerToken) / PRECISION;
    uint256 fee18 = (totalProfit18 * feeBps) / BPS;
    feeTokens = (fee18 * PRECISION) / currentNav;
}
```

#### Entry NAV Inheritance

Prevents performance fee gaming via token transfers:

```solidity
function _update(address from, address to, uint256 amount) internal override {
    super._update(from, to, amount);

    // On transfers, recipient inherits sender's weighted entry NAV
    if (from != address(0) && to != address(0) && from != to) {
        // Weighted average calculation...
    }
}
```

***

### Related Contracts

| Contract          | Role                            |
| ----------------- | ------------------------------- |
| `HyperFunFactory` | Global settings, vault creation |
| `HyperFunTrading` | L1 trading execution            |


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://hyper-fun.gitbook.io/hypers.fun/smart-contracts/hyperfuntoken.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
