Phase 2: mixer (Web3 tab in the network, terminal page, sanctions, night return), unlock registration per upgrade
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
133367b58d
commit
09a5cae69c
11 files changed
+290
-16
No files matched your search
@@ -0,0 +1,98 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Decentralized.Domain
|
||||
{
|
||||
/// <summary>混币器里一笔在途的存入。</summary>
|
||||
public sealed class MixDeposit
|
||||
{
|
||||
public string Asset;
|
||||
public double Amount;
|
||||
/// <summary>存入时一并带走的污点与成本(信用点)。</summary>
|
||||
public double Taint, Basis;
|
||||
public int Rounds;
|
||||
public int ReadyDay;
|
||||
}
|
||||
|
||||
/// <summary>一笔混币结束时的结果,供夜间日志使用。</summary>
|
||||
public sealed class MixResult
|
||||
{
|
||||
public bool Rugged;
|
||||
public string Asset;
|
||||
public double Amount, TaintBefore, TaintAfter;
|
||||
public bool Flagged;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 混币器:把币存进去,每轮扣手续费、降低污点,轮数 = 等待天数,到期提回同一个地址。
|
||||
/// 匿名集 = NPC 背景量 + 玩家存入量,玩家占比越大清洗效果越差。镇压事件开始时可能被制裁:
|
||||
/// 制裁期间提出的币视为被标记(出金审查按"来自混币器或被标记地址"加重,且地址被标记)。每晚有极小概率跑路。
|
||||
/// </summary>
|
||||
public sealed class Mixer
|
||||
{
|
||||
public List<MixDeposit> Pending = new List<MixDeposit>();
|
||||
public int SanctionedUntil = -1;
|
||||
/// <summary>提回的币最近一次从混币器出来的天数,用来给出金审查加重。</summary>
|
||||
public int LastReturnDay = -999;
|
||||
|
||||
public bool Sanctioned(int day) => day <= SanctionedUntil;
|
||||
|
||||
/// <summary>资金来自混币器:最近 AML 窗口内提回过币,或者被标记。</summary>
|
||||
public bool RecentlyMixed(int day) => day - LastReturnDay <= Tuning.AmlWindowDays;
|
||||
|
||||
/// <summary>一轮的清洗率:基准 × 匿名集系数。</summary>
|
||||
public static double RoundRate(double depositValue) => Tuning.MixerCleanRate * Tuning.MixerNpcVolume / (Tuning.MixerNpcVolume + Math.Max(0, depositValue));
|
||||
|
||||
/// <summary>存入:从钱包按价值比例带走污点与成本。轮数超出范围或余额不足返回 null。</summary>
|
||||
public MixDeposit Deposit(Wallet w, string asset, double amount, int rounds, int day, Func<string, double> price)
|
||||
{
|
||||
if (rounds < 1 || rounds > Tuning.MixerMaxRounds || amount <= 0 || w.Get(asset) + 1e-9 < amount) return null;
|
||||
double value = amount * price(asset);
|
||||
if (value < Tuning.MixerMin) return null;
|
||||
double total = w.Value(price);
|
||||
double share = total > 0 ? Math.Min(1, value / total) : 0;
|
||||
double taint = w.Taint * share, basis = w.Basis * share;
|
||||
w.Add(asset, -amount);
|
||||
w.Taint -= taint;
|
||||
w.Basis -= basis;
|
||||
var d = new MixDeposit { Asset = asset, Amount = amount, Taint = taint, Basis = basis, Rounds = rounds, ReadyDay = day + rounds };
|
||||
Pending.Add(d);
|
||||
return d;
|
||||
}
|
||||
|
||||
/// <summary>镇压事件开始:有一定概率被制裁,持续若干天。</summary>
|
||||
public void OnEvent(MarketEvent ev, int day, Rng rng)
|
||||
{
|
||||
if (ev == MarketEvent.Crackdown && rng.Chance(Tuning.MixerSanctionChance)) SanctionedUntil = day + Tuning.MixerSanctionDays;
|
||||
}
|
||||
|
||||
/// <summary>每晚:到期的存入提回钱包(污点按轮数降低),在途的各有小概率跑路。</summary>
|
||||
public List<MixResult> Night(Wallet w, int day, Func<string, double> price, Rng rng)
|
||||
{
|
||||
var results = new List<MixResult>();
|
||||
foreach (var d in Pending.ToList())
|
||||
{
|
||||
if (rng.Chance(Tuning.MixerRugChance))
|
||||
{
|
||||
Pending.Remove(d);
|
||||
results.Add(new MixResult { Rugged = true, Asset = d.Asset, Amount = d.Amount });
|
||||
continue;
|
||||
}
|
||||
if (day < d.ReadyDay) continue;
|
||||
Pending.Remove(d);
|
||||
double rate = RoundRate(d.Amount * price(d.Asset));
|
||||
double taint = d.Taint * Math.Pow(1 - rate, d.Rounds);
|
||||
double amount = d.Amount * Math.Pow(1 - Tuning.MixerFee, d.Rounds);
|
||||
bool flagged = Sanctioned(day);
|
||||
w.Add(d.Asset, amount);
|
||||
w.Taint += taint;
|
||||
w.Basis += d.Basis;
|
||||
if (flagged) w.Flagged = true;
|
||||
LastReturnDay = day;
|
||||
results.Add(new MixResult { Asset = d.Asset, Amount = amount, TaintBefore = d.Taint, TaintAfter = taint, Flagged = flagged });
|
||||
}
|
||||
return results;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -57,6 +57,9 @@ namespace Decentralized.Domain
|
||||
public const int AmlWindowDays = 7;
|
||||
public const double AmlTaintRatio = 0.10, AmlHeavyRatio = 0.30, AmlMixerBonus = 0.30, AmlMaxChance = 0.9;
|
||||
public const double TaxRate = 0.08;
|
||||
/// <summary>混币器:每轮手续费、基准清洗率、NPC 背景量(信用点)、最大轮数、最小存入、制裁概率与天数、每晚跑路概率。</summary>
|
||||
public const double MixerFee = 0.02, MixerCleanRate = 0.35, MixerNpcVolume = 20000, MixerMin = 100, MixerSanctionChance = 0.5, MixerRugChance = 0.004;
|
||||
public const int MixerMaxRounds = 5, MixerSanctionDays = 5;
|
||||
/// <summary>各派系顾客用币付款的概率。</summary>
|
||||
public const double CoinPayCrc = 0.12, CoinPayCrt = 0.25, CoinPayCra = 0.25, CoinPayPsc = 0.10;
|
||||
/// <summary>单个金融违规事件记入的罪证上限。</summary>
|
||||
|
||||
Reference in new issue
Block a user