myco-bonding-curve/docs/06-reserve-tranching.md

63 lines
2.5 KiB
Markdown

# 06: Reserve Tranching
## Source
- **Protocol**: Gyroscope GYD
- **Files**: `ReserveManager.sol`, `VaultRegistry.sol`, `ReserveSafetyManager.sol`, `DataTypes.sol`
- **Repo**: `gyrostable/gyd-core`
## Rationale for MYCO
A multi-asset bonding curve needs risk separation. Not all reserve assets carry the same risk — stablecoins differ from ETH, which differs from governance tokens. Tranching provides:
1. **Risk isolation**: If one vault's assets crash, other tranches are unaffected
2. **Governance control**: Target weights can be adjusted to shift risk profile
3. **Dynamic rebalancing**: Weights drift with asset performance (price-weighted)
4. **Safety invariants**: Operations that worsen imbalance are blocked
5. **Flow limits**: Short-term capital movement between tranches is bounded
For MYCO specifically: commitment-based minting (labor, subscriptions, staking) creates "non-financial tranches" — the tranching system provides a unified framework for managing both financial and commitment-backed reserves.
## Architecture
Each tranche is a vault holding one type of collateral (or a pool of correlated collateral). The reserve system tracks:
- **Target weights**: Governance-set, time-interpolated between old and new values
- **Current weights**: Actual USD value / total USD value
- **Price drift**: Target weights adjust for asset performance since calibration
- **Safety checks**: Every mint/redeem must either keep weights within epsilon of targets, or move weights closer to targets
## Key Formulas
**Target weight with time interpolation:**
```
scheduled_weight = prev_weight + (current_weight - prev_weight) * min(elapsed / duration, 1)
```
**Price-adjusted target:**
```
weighted_return[i] = (current_price[i] / calibration_price[i]) * scheduled_weight[i]
target_weight[i] = weighted_return[i] / sum(weighted_returns)
```
**Safety check:**
```
For each vault outside epsilon band:
new_deviation = |new_weight - target|
old_deviation = |old_weight - target|
REQUIRE: new_deviation <= old_deviation (must be rebalancing)
```
## Parameters
| Parameter | Effect |
|-----------|--------|
| `target_weight` | Fraction of total reserve value |
| `max_deviation` | How far current weight can deviate before blocking |
| `transition_duration` | How long to interpolate between old/new target |
| `short_flow_memory` | Decay rate for flow tracking per vault |
| `short_flow_threshold` | Max flow as fraction of vault value |
## Implementation
See `src/primitives/reserve_tranching.py`