核心概念
价格预言机
MCC 价格预言机定义
权威定义文档 - 价格预言机系统的唯一权威来源
最后更新: 2026-02-04 状态: 运行中
2026-02-04 重大更新:
- 价格源从 Pyth 切换到 Raydium (DexScreener API)
- 采集频率从 4 小时改为 1 小时
- 数据点从 180 个改为 720 个
- 默认价格从 $10 改为 $1
1. 概述
MCC 价格预言机负责为 Reincarnation 合约提供 MCC 的基础价格 (base_price),用于计算回购价格 (buyback_price)。
buyback_price = base_price × 1.05 (+5% 溢价)
2. 两条独立的价格线
价格线 1: admin_price (管理员设定价格)
| 属性 | 说明 |
|---|---|
| 来源 | 管理员通过 API 设定 |
| 存储 | 数据库 mcc_price_config.base_price |
| 状态 | 由 is_active 字段控制 |
| 激活时 | Oracle 直接使用此价格更新链上 |
价格线 2: market_price (市场价格)
| 属性 | 说明 |
|---|---|
| 来源 | Raydium 流动性池真实交易价格 |
| 获取 | DexScreener API / 链上池子计算 |
| 计算 | 30天均价 (180个数据点) |
| 未激活时 | Oracle 使用此均价更新链上 |
| 独立性 | 始终独立更新,不受 admin_price 影响 |
3. 价格源优先级
| 优先级 | 价格源 | 条件 | 说明 |
|---|---|---|---|
| 1 | admin_price | is_active = true | 管理员定价,用于特殊情况干预 |
| 2 | Raydium 池价格 | 池子有流动性 | 真实市场价格 |
| 3 | 默认价格 | 兜底 | $1.00 USDC |
4. 市场价格获取方式
4.1 Raydium 流动性池
| 配置 | 值 |
|---|---|
| Pool 地址 | HgK6MkCSiuEk7kpDLhdfpKm8i7STuxxwQVBxAo4oshLa |
| 交易对 | MCC / USDT |
| DEX | Raydium CPMM |
4.2 价格获取方法
方法 1: DexScreener API (推荐)
python
async def get_raydium_price() -> float:
"""从 DexScreener 获取 MCC 市场价格"""
url = "https://api.dexscreener.com/latest/dex/pairs/solana/HgK6MkCSiuEk7kpDLhdfpKm8i7STuxxwQVBxAo4oshLa"
response = await http.get(url)
return float(response["pair"]["priceUsd"])
方法 2: 链上直接计算
python
async def get_price_from_pool() -> float:
"""从 Raydium Pool 账户直接计算价格"""
# 读取池子的 MCC 和 USDT 储备量
pool_data = await rpc.get_account_info(POOL_ADDRESS)
mcc_reserve = parse_mcc_reserve(pool_data)
usdt_reserve = parse_usdt_reserve(pool_data)
# 价格 = USDT 储备 / MCC 储备
return usdt_reserve / mcc_reserve
5. 30天均价计算
5.1 数据采集
| 参数 | 值 |
|---|---|
| 采集频率 | 每 1 小时 |
| 数据点数 | 720 个 (30天 × 24次/天) |
| 存储位置 | mcc_price_history 表 |
5.2 均价计算公式
python
def calculate_30day_average(prices: List[float]) -> float:
"""计算 30 天均价"""
if len(prices) < 180:
# 数据不足时使用已有数据
pass
return sum(prices) / len(prices)
5.3 数据库表
sql
-- 价格历史记录表
CREATE TABLE mcc_price_history (
id SERIAL PRIMARY KEY,
date DATE NOT NULL,
hour_slot INTEGER NOT NULL, -- 0-23 (每小时)
close_price DECIMAL(20, 8) NOT NULL,
source VARCHAR(50) NOT NULL, -- 'raydium', 'admin', 'default'
created_at TIMESTAMP DEFAULT NOW(),
UNIQUE (date, hour_slot, source)
);
6. Oracle 更新流程
每 1 小时执行 (CronJob):
- 检查 admin_price 激活状态: 若 is_active = true,则使用 admin_price
- 获取 Raydium 市场价格: 调用 DexScreener API
- 记录价格到历史表: INSERT INTO mcc_price_history
- 计算 30 天均价: AVG(close_price) WHERE 30 days
- 更新链上合约: Reincarnation.update_price(base_price)
7. 链上合约配置
| 配置 | 值 |
|---|---|
| Program ID | REn8oKyydvjRsistZ2cVi6tksPubvR3bEuLdVTyGknb |
| Pool PDA | H3azAs4vdPKa1zVJ74dkGyUtNzpobE8fDKAn4BmZ26it |
| update_price 指令 | 更新 base_price 字段 |
| 价格精度 | 6 decimals (USDC) |
| 溢价 | 5% (500 bps) |
8. API 端点
| 端点 | 方法 | 说明 |
|---|---|---|
/v1/mcc/price | GET | 获取当前价格信息 |
/v1/mcc/price | POST | 设定管理员价格 (仅保存) |
/v1/mcc/price/activate | POST | 激活管理员价格 |
/v1/mcc/price/deactivate | POST | 停用管理员价格 |
/v1/mcc/price/market | GET | 获取实时市场价格 |
/v1/mcc/price/history | GET | 获取价格历史 |
9. 服务配置
9.1 oracle-service
| 配置项 | 值 |
|---|---|
| 镜像 | microcosm-oracle-service:v1.0.x |
| 执行频率 | 每 4 小时 (CronJob) |
| 命名空间 | microcosm |
9.2 CronJob 时间
yaml
schedule: "0 * * * *" # UTC 每小时整点
10. 安全限制
| 限制 | 值 | 说明 |
|---|---|---|
| 价格下限 | $0.01 | 防止价格过低 |
| 价格上限 | $1000 | 防止价格过高 |
| 单次变动上限 | ±20% | 防止价格剧烈波动 |
11. 监控告警
| 指标 | 阈值 | 级别 |
|---|---|---|
| 价格更新失败 | 连续 2 次 | 警告 |
| 价格更新失败 | 连续 3 次 | 严重 |
| 价格偏离均价 | >20% | 警告 |
| CronJob 未执行 | >5 小时 | 严重 |
12. 术语定义
| 术语 | 定义 |
|---|---|
| base_price | 基础价格,用于计算回购价格 |
| buyback_price | 回购价格 = base_price × 1.05 |
| admin_price | 管理员设定的价格 |
| market_price | 市场真实交易价格 |
| 30天均价 | 180个数据点的平均值 |
文档维护: Claude 创建日期: 2026-02-04
询问 AI