# Buy & Sell

## Buy & Sell

Followers enter and exit vault positions via [hypers.fun](https://www.hypers.fun) or directly through `HyperFunToken.sol`.

***

### For Users (UI)

####

<figure><img src="/files/qFS4uCobNbcBZWAF0n8m" alt=""><figcaption></figcaption></figure>

#### Buying Vault Tokens

1. Go to vault page (e.g., `hypers.fun/vault/0x...`)
2. Connect wallet
3. Enter USDC amount to invest
4. Review:
   * Tokens you'll receive
   * Price per token
   * Price impact
   * Trading fee (1%)
5. Click "Buy" and confirm transaction
6. Receive vault tokens in your wallet

<figure><img src="/files/oTJ8W76sRhQOWbE8fEmg" alt=""><figcaption></figcaption></figure>

#### Selling Vault Tokens

1. Go to vault page
2. Connect wallet
3. Enter token amount to sell (or click "Max")
4. Review:
   * USDC you'll receive
   * Exit fee (based on holding time)
   * Performance fee (if profitable)
   * Price impact
5. Click "Sell" and confirm transaction
6. Receive USDC (or pending sell if low liquidity)

#### Understanding Fees

| Fee                 | When                   | Rate                       |
| ------------------- | ---------------------- | -------------------------- |
| **Trading Fee**     | Every buy/sell         | 1%                         |
| **Exit Fee**        | When selling           | 0-15% (based on hold time) |
| **Performance Fee** | When selling at profit | 0-30% (set by leader)      |

#### Exit Fee Tiers

| Hold Duration | Exit Fee |
| ------------- | -------- |
| < 7 days      | 15%      |
| 7-30 days     | 8%       |
| 30-90 days    | 3%       |
| > 90 days     | 0%       |

> **Tip:** Hold longer to reduce exit fees!

#### Pending Sells

If the vault doesn't have enough liquid USDC, your sell becomes "pending":

1. Your tokens are burned immediately
2. USDC is reserved for you
3. Wait for leader to close positions or funds to return
4. Click "Claim" when available
5. Receive your USDC

***

### Pricing Mechanism

#### Bonding Curve (Constant Product AMM)

Price is determined by the **x\*y=k** formula (like Pump.fun / Uniswap):

```
Price = NAV × (virtualBase / virtualTokens)
```

#### Price Impact

Large trades move the price:

* **Buying** pushes price UP
* **Selling** pushes price DOWN

```
Price Impact ≈ TradeSize / VirtualReserve
```

#### Price Bounds

| Limit          | Value                         |
| -------------- | ----------------------------- |
| Max Premium    | +100% (price up to 2x NAV)    |
| Max Discount   | -50% (price down to 0.5x NAV) |
| Max Single Buy | 1% of vault                   |

***

### For Developers

#### Buy Function

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

| Parameter      | Description                                   |
| -------------- | --------------------------------------------- |
| `usdcAmount`   | USDC to spend (6 decimals)                    |
| `minTokensOut` | Minimum tokens expected (slippage protection) |

**Buy Flow:**

1. Validate `usdcAmount >= minDepositUsdc` (default 5 USDC)
2. Get smoothed NAV for price protection
3. Transfer USDC from buyer to vault
4. Deduct trading fee (1%)
5. Calculate tokens via constant product:

   ```
   tokensOut = effVirtualTokens × netAmount / (virtualBaseUsdc + netAmount)
   ```
6. Check slippage: `tokensOut >= minTokensOut`
7. Check max buy limit (90% of virtual tokens)
8. Update bonding curve reserves
9. Mint vault tokens to buyer
10. Update entry record (for performance fee)
11. Transfer fee to treasury
12. Trigger auto-rebalance
13. Update TWAP NAV

#### Sell Function

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

| Parameter    | Description                                 |
| ------------ | ------------------------------------------- |
| `tokens`     | Vault tokens to sell (18 decimals)          |
| `minUsdcOut` | Minimum USDC expected (slippage protection) |

**Sell Flow:**

1. Validate balance and no existing pending sell
2. Get smoothed NAV
3. Calculate performance fee (if profitable)
4. Calculate USDC via constant product:

   ```
   usdcOut = virtualBaseUsdc × tokens / (effVirtualTokens + tokens)
   ```
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 to leader (if any)
11. Transfer USDC or create pending sell
12. Update TWAP NAV
13. Trigger auto-rebalance

#### Claim Pending Sell

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

**Claim Flow:**

1. Check pending sell exists
2. Verify EVM balance covers amount
3. Transfer USDC to user
4. Clear pending sell record

***

### View Functions

#### Get Prices

```solidity
// Current prices
function getBuyPrice() public view returns (uint256);
function getSellPrice() public view returns (uint256);
function getSellPriceCapped() public view returns (uint256);

// NAV
function getNAV() public view returns (uint256);
function getSmoothedNAV() public view returns (uint256);
```

#### Calculate Trade

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

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

// Get exit fee for user
function calculateExitFee(address user) public view returns (
    uint256 exitFeeBps,
    uint256 daysHeld
);
```

#### Check Liquidity

```solidity
function getAvailableLiquidity() public view returns (uint256);  // EVM + L1 Spot
function getTotalAssets() public view returns (uint256);         // Total vault value
function getMaxBuyUsdc() public view returns (uint256);          // Max per transaction
```

***

### Example: Buy via ethers.js

```javascript
const { ethers } = require('ethers');

const VAULT = '0x606B0B98d13C35d44726e491f428BE90eAb5eDB9';
const USDC = '0xb88339CB7199b77E23DB6E890353E22632Ba630f';

const vaultAbi = [
  'function buy(uint256 usdcAmount, uint256 minTokensOut) external',
  'function calculateTokensOut(uint256 usdcIn) view returns (uint256,uint256,uint256)',
  'function getBuyPrice() view returns (uint256)'
];
const erc20Abi = [
  'function approve(address,uint256) external returns (bool)',
  'function balanceOf(address) view returns (uint256)'
];

async function buyTokens(signer, usdcAmount) {
  const vault = new ethers.Contract(VAULT, vaultAbi, signer);
  const usdc = new ethers.Contract(USDC, erc20Abi, signer);

  // Preview trade
  const [tokensOut, newPrice, impactBps] = await vault.calculateTokensOut(usdcAmount);
  console.log(`Tokens out: ${ethers.formatEther(tokensOut)}`);
  console.log(`Price impact: ${impactBps / 100}%`);

  // Set slippage (1%)
  const minTokens = tokensOut * 99n / 100n;

  // Approve USDC
  await usdc.approve(VAULT, usdcAmount);

  // Buy
  const tx = await vault.buy(usdcAmount, minTokens);
  await tx.wait();

  console.log('Buy successful!');
}

// Buy 100 USDC worth
buyTokens(signer, 100_000_000n);  // 100 USDC (6 decimals)
```

### Example: Sell via ethers.js

```javascript
async function sellTokens(signer, tokenAmount) {
  const vault = new ethers.Contract(VAULT, vaultAbi, signer);

  const sellAbi = [
    'function sell(uint256 tokens, uint256 minUsdcOut) external',
    'function calculateUsdcOut(uint256 tokensIn) view returns (uint256,uint256,uint256)',
    'function calculateExitFee(address) view returns (uint256,uint256)'
  ];
  const vaultSell = new ethers.Contract(VAULT, sellAbi, signer);

  // Check exit fee
  const [exitFeeBps, daysHeld] = await vaultSell.calculateExitFee(signer.address);
  console.log(`Exit fee: ${exitFeeBps / 100}% (held ${daysHeld} days)`);

  // Preview trade
  const [usdcOut, newPrice, impactBps] = await vaultSell.calculateUsdcOut(tokenAmount);
  console.log(`USDC out: ${usdcOut / 1_000_000}`);

  // Set slippage (1%)
  const minUsdc = usdcOut * 99n / 100n;

  // Sell
  const tx = await vaultSell.sell(tokenAmount, minUsdc);
  await tx.wait();

  console.log('Sell successful!');
}
```

***

### 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);
```

***

### Data Structures

#### Pending Sell

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

#### Entry Record (Performance Fee)

```solidity
struct EntryRecord {
    uint256 weightedEntryNav;  // Weighted average entry NAV
    uint256 totalTokens;       // Total tokens held
}
```

#### Purchase Info (Exit Fee)

```solidity
struct UserPurchaseInfo {
    uint256 totalTokens;           // Total tokens bought
    uint256 weightedTimestamp;     // Weighted average purchase time
    uint256 lastPurchaseTime;      // Last purchase timestamp
}
```

***

### Related Pages

* VaultCore - Full token contract reference
* Pricing Mechanism - Detailed pricing math
* Fund Creation - Create your own vault
* Contract Addresses - Deployed contracts


---

# 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/how-it-works/buy-and-sell.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.
