Poinbase 只收 PSC、CRC、SPARK,新增 SPARK/CRC;DEX 稳定币对改为 StableSwap

- 钱包拦下往 Poinbase 充值地址转 CRT、CRA;资金页按上架币种列出
- 现货交易对跟着行情图选中的币(PSC/CRC、SPARK/CRC)
- CRT/CRC、CRA/CRC 用 StableSwap:手续费 0.04%、A=200;脱锚 A=20,崩盘 A=1 且深度四分之一
- 旧存档读档时补 SPARK/CRC、升级稳定币池

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
ZHU MINCHAOandClaude Opus 5.5 committed 2026-11-07 23:03:59 +08:00
1 parent 6d8b05215c
commit fe82395d32
19 files changed
+192 -26

No files matched your search

+62 -1
View File
@@ -8,6 +8,8 @@ namespace Decentralized.Domain
/// 一个交易对。DEX 是恒定乘积池(x·y = k):Base 是被交易的币,Quote 是计价币,价格 = Quote 储备 / Base 储备。
/// Poinbase 主池是订单簿(<see cref="Book"/>):价格只取决于当天的累计净买入量,冲击随单子变大而增长得比线性慢
/// (价格 = 参考价 × exp(κ · sign(x) · |x|^α),x = 净买入的名义价值 / 深度),拆单不占便宜,同量买进再卖出回到原价。
/// 稳定币对(<see cref="Stable"/>)是 StableSwap 池(Curve 的曲线,放大系数 A):挂钩附近几乎没有滑点,偏离越大越接近恒定乘积;
/// 储备按"价值单位"记(Base 数量 × 挂钩价),挂钩价夜里随参考价重设。
/// 每个交易对各有深度;夜间由 NPC 套利者把价格按比例拉向目标价,订单簿的累计量清零。
/// </summary>
public sealed class Pool
@@ -19,10 +21,53 @@ namespace Decentralized.Domain
/// <summary>订单簿模式:参考价、当天累计净买入的 Base 数量、深度(Quote)。</summary>
public bool Book;
public double Ref, Net, Depth;
/// <summary>StableSwap 模式:放大系数、挂钩价(储备里 Base 一侧按 数量 × 挂钩价 记)。</summary>
public bool Stable;
public double Amp, Peg;
public string Id => $"{Venue}:{Base}/{Quote}";
public double Price => Book ? PriceAt(Net) : QuoteReserve / BaseReserve;
public double Price => Book ? PriceAt(Net) : Stable ? Peg * StableSlope(BaseReserve, QuoteReserve) : QuoteReserve / BaseReserve;
public static Pool CreateStable(Venue venue, string baseAsset, string quote, double price, double depth, double fee, double amp) =>
new Pool { Venue = venue, Base = baseAsset, Quote = quote, Stable = true, Amp = amp, Peg = price, BaseReserve = depth, QuoteReserve = depth, Fee = fee };
// ——— StableSwap(两个币):Ann(x + y) + D = Ann·D + D³ / (4xy),Ann = 4A ———
private double Ann => 4 * Amp;
private double StableD(double x, double y)
{
double s = x + y, d = s;
if (s <= 0) return 0;
for (int i = 0; i < 255; i++)
{
double dp = d * d * d / (4 * x * y), prev = d;
d = (Ann * s + 2 * dp) * d / ((Ann - 1) * d + 3 * dp);
if (Math.Abs(d - prev) <= 1e-12 * d) break;
}
return d;
}
/// <summary>已知一侧储备 x 和不变量 D,求另一侧。</summary>
private double StableOther(double x, double d)
{
double c = d * d / (2 * x) * d / (2 * Ann), b = x + d / Ann, y = d;
for (int i = 0; i < 255; i++)
{
double prev = y;
y = (y * y + c) / (2 * y + b - d);
if (Math.Abs(y - prev) <= 1e-12 * y) break;
}
return y;
}
/// <summary>边际价格(每个价值单位的 Base 换多少 Quote):不变量对两侧偏导之比。平衡时为 1。</summary>
private double StableSlope(double x, double y)
{
double d = StableD(x, y), d3 = d * d * d;
return (Ann + d3 / (4 * x * x * y)) / (Ann + d3 / (4 * x * y * y));
}
public static Pool CreateBook(Venue venue, string baseAsset, string quote, double price, double depth, double fee) =>
new Pool { Venue = venue, Base = baseAsset, Quote = quote, Book = true, Ref = price, Depth = depth, Fee = fee };
@@ -62,6 +107,7 @@ namespace Decentralized.Domain
public double QuoteOut(double baseIn)
{
if (Book) return baseIn > 0 ? Cost(Net - baseIn, Net) * (1 - Fee) : 0;
if (Stable) return baseIn > 0 ? QuoteReserve - StableOther(BaseReserve + baseIn * Peg * (1 - Fee), StableD(BaseReserve, QuoteReserve)) : 0;
double x = BaseReserve + baseIn * (1 - Fee);
return QuoteReserve - BaseReserve * QuoteReserve / x;
}
@@ -70,6 +116,7 @@ namespace Decentralized.Domain
public double BaseOut(double quoteIn)
{
if (Book) return quoteIn > 0 ? BookBaseFor(quoteIn * (1 - Fee)) : 0;
if (Stable) return quoteIn > 0 ? (BaseReserve - StableOther(QuoteReserve + quoteIn * (1 - Fee), StableD(BaseReserve, QuoteReserve))) / Peg : 0;
double y = QuoteReserve + quoteIn * (1 - Fee);
return BaseReserve - BaseReserve * QuoteReserve / y;
}
@@ -79,6 +126,11 @@ namespace Decentralized.Domain
{
if (baseOut <= 0) return 0;
if (Book) return Cost(Net, Net + baseOut) / (1 - Fee);
if (Stable)
{
double x = BaseReserve - baseOut * Peg;
return x <= 0 ? double.PositiveInfinity : (StableOther(x, StableD(BaseReserve, QuoteReserve)) - QuoteReserve) / (1 - Fee);
}
if (baseOut >= BaseReserve) return double.PositiveInfinity;
return (BaseReserve * QuoteReserve / (BaseReserve - baseOut) - QuoteReserve) / (1 - Fee);
}
@@ -89,6 +141,7 @@ namespace Decentralized.Domain
if (baseIn <= 0) return 0;
double out_ = QuoteOut(baseIn);
if (Book) { Net -= baseIn; return out_; }
if (Stable) { BaseReserve += baseIn * Peg; QuoteReserve -= out_; return out_; }
BaseReserve += baseIn;
QuoteReserve -= out_;
return out_;
@@ -100,6 +153,7 @@ namespace Decentralized.Domain
if (quoteIn <= 0) return 0;
double out_ = BaseOut(quoteIn);
if (Book) { Net += out_; return out_; }
if (Stable) { QuoteReserve += quoteIn; BaseReserve -= out_ * Peg; return out_; }
QuoteReserve += quoteIn;
BaseReserve -= out_;
return out_;
@@ -110,6 +164,12 @@ namespace Decentralized.Domain
{
double before = Price;
if (Book) return PriceAt(Net + BaseOut(quoteIn)) / before - 1;
if (Stable)
{
var copy = (Pool)MemberwiseClone();
copy.BuyBase(quoteIn);
return copy.Price / before - 1;
}
double y = QuoteReserve + quoteIn * (1 - Fee);
double x = BaseReserve * QuoteReserve / y;
return (y / x) / before - 1;
@@ -128,6 +188,7 @@ namespace Decentralized.Domain
public void SetPrice(double price, double quoteDepth)
{
if (Book) { Ref = price; Net = 0; Depth = quoteDepth; return; }
if (Stable) { Peg = price; BaseReserve = quoteDepth; QuoteReserve = quoteDepth; return; }
QuoteReserve = quoteDepth;
BaseReserve = quoteDepth / price;
}