# YearnV3 Base Operations

### ERC-4626 Core Requirements

As a reminder, the ERC4626 core requirements are reproduced below:

#### Asset Operations

```solidity
// Deposit/Withdraw Interface
function deposit(uint256 assets, address receiver) returns (uint256 shares)
function mint(uint256 shares, address receiver) returns (uint256 assets) 
function withdraw(uint256 assets, address receiver, address owner) returns (uint256 shares)
function redeem(uint256 shares, address receiver, address owner) returns (uint256 assets)

// Max Limits
function maxDeposit(address) returns (uint256)
function maxMint(address) returns (uint256)
function maxWithdraw(address) returns (uint256)
function maxRedeem(address) returns (uint256)

// Preview Functions
function previewDeposit(uint256 assets) returns (uint256 shares)
function previewMint(uint256 shares) returns (uint256 assets)
function previewWithdraw(uint256 assets) returns (uint256 shares)
function previewRedeem(uint256 shares) returns (uint256 assets)
```

#### Accounting Views

```solidity
// Core Accounting
function totalAssets() returns (uint256)
function convertToShares(uint256 assets) returns (uint256)
function convertToAssets(uint256 shares) returns (uint256)

// ERC20 Interface
function totalSupply() returns (uint256)
function balanceOf(address) returns (uint256)

// Asset Info
function asset() returns (address)
```

### YearnV3 Asset Operation

Yearn V3's implementation of ERC-4626 follows a strict operation pattern to ensure safety and efficiency:

1. **Pre-operation Validation**: Validates limits and state before executing operations.
2. **Asset Transfers and Conversions**: Handles the transfer of assets and conversion to/from shares.
3. **Strategy Hooks**: Calls strategy-specific hooks to deploy or withdraw funds.
4. **State Updates and Event Emission**: Updates internal state and emits relevant events.

Example implementation of `deposit()`:

```solidity
deposit(uint256 assets, address receiver) external returns (uint256 shares) {
    // Check deposit limits
    require(assets <= _maxDeposit(receiver), "ERC4626: deposit more than max");
    // Calculate shares, revert if zero
    require((shares = _convertToShares(assets, Math.Rounding.Down)) != 0, "ZERO_SHARES");
    
    // Safe transfer assets in first (ERC777 reentrancy protection)
    asset.safeTransferFrom(msg.sender, address(this), assets);
    
    // Deploy funds via strategy hook
    IBaseStrategy(address(this)).deployFunds(asset.balanceOf(address(this)));
    
    // Update total assets
    totalAssets += assets;
    
    // Mint shares 
    _mint(receiver, shares);
    
    emit Deposit(msg.sender, receiver, assets, shares);
}
```

### Share Accounting

Yearn V3 tracks ownership and vault holdings using a **dynamic price-per-share (PPS)** ratio. This system ensures accurate ownership representation while protecting against manipulation.

**Primary State**

| **Field**                              | **Description**                         |
| -------------------------------------- | --------------------------------------- |
| `mapping(address => uint256) balances` | Tracks share balances for each address. |
| `uint256 totalSupply`                  | Total shares issued by the vault.       |
| `uint256 totalAssets`                  | Total assets managed by the vault.      |

**Conversion Functions**

| **Function**                                               | **Description**                                        |
| ---------------------------------------------------------- | ------------------------------------------------------ |
| `_convertToShares(uint256 assets, Math.Rounding rounding)` | Converts assets to shares, considering rounding modes. |
| `_convertToAssets(uint256 shares, Math.Rounding rounding)` | Converts shares to assets, considering rounding modes. |

**Key Features**

* Dynamic PPS calculations based on total assets and supply.
* Configurable rounding modes for flexible operations.
* First depositor protection.
* Share transfer restrictions for security.
* Balance and allowance management.

### Profit Mechanics

Yearn employs a **gradual profit realization system** to prevent PPS manipulation. When a keeper calls `report()`, profits are calculated and locked, with fees distributed and profits unlocked linearly.

```solidity
struct StrategyData {
    uint256 profitUnlockingRate;      // Per-second rate
    uint96 fullProfitUnlockDate;      // Unlock completion time
    uint32 profitMaxUnlockTime;       // Default 3 days
    uint16 performanceFee;            // Default 10%
    uint96 lastReport;                // Last report timestamp
}

function report() external returns (uint256 profit, uint256 loss) {
    // Calculate profit/loss
    uint256 newTotalAssets = _harvestAndReport();
    uint256 oldTotalAssets = totalAssets;
    
    if (newTotalAssets > oldTotalAssets) {
        // Lock profits
        profit = newTotalAssets - oldTotalAssets;
        sharesToLock = _convertToShares(profit);
        
        // Calculate and distribute fees
        totalFees = (profit * performanceFee) / MAX_BPS;
        _mint(feeRecipient, feeShares);
        
        // Setup linear unlocking
        profitUnlockingRate = sharesToLock / profitMaxUnlockTime;
        fullProfitUnlockDate = block.timestamp + profitMaxUnlockTime;
    }
    
    totalAssets = newTotalAssets;
    lastReport = block.timestamp;
}
```

**Key Features**

* **Linear Unlocking**: Term Strategy Vaults default to a `profitMaxUnlockTime` of 3 days, during which profits are unlocked gradually in a linear fashion to ensure smooth realization and prevent manipulation.

### **Performance Fee Structure**

Yearn implements gradual profit realization and transparent fee distribution mechanisms to align incentives and prevent PPS manipulation.

**Profit Realization**:

* Profits are calculated and locked when `report()` is called.
* Unlocks linearly over a configurable window (default: 3 days for Term Strategy vaults), ensuring smooth price appreciation for depositors.&#x20;

For example:

```solidity
performanceFee = 1000                  // 10% default
profitMaxUnlockTime = 3 days          // Unlock window
managerAddress = 0x0E14e7...          // Strategy control
keeperAddress = 0x54Eef1...           // Report caller
performanceFeeRecipient = 0x0E14e7... // Fee receiver
```

**Performance Fee Structure**:

* **Fee Parameters**:
  * Default: 10% of realized profits.
  * 80/20 split between vault curator and Yearn protocol.
* **Fee Distribution**:
  * Charged during the `report()` call.
  * Distributed immediately to `performanceFeeRecipient`.

**Profit Unlocking**:

* Profits locked at report time.
* Linear unlocking over the chosen window to ensure fairness and smooth price-per-share increases.

{% hint style="info" %}
**Keeper Responsibility**: `report()` should be called at regular intervals, typically every 3 days, to maintain consistent profit unlocking. The frequency can be adjusted to match the unlocking window.
{% endhint %}


---

# 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://developers.term.finance/periphery-contracts/curated-vaults/core-functionality/yearnv3-base-operations.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.
