Stage 7.2: manipulation detection (player price push, prediction/perp forfeits)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
ZHU MINCHAOandClaude Sonnet 5.5 committed 2026-11-04 08:03:44 +08:00
1 parent 002606056d
commit 786de325da
11 files changed
+99 -8

No files matched your search

+9 -1
View File
@@ -183,7 +183,7 @@ namespace Decentralized.Domain
/// 夜间:先登记今晚的观测,再结算 ToDay 到了的盘口(赢的钱回到下注的钱包,wallet 按地址找)。outcome 由接入层给出(事件 / 派系读观测,纯度和行情读游戏数值),null 表示拿不到数据。
/// 赢家每份兑付 1 信用点;内幕持仓达到份额上限的 <see cref="Tuning.PredictInsiderShare"/> 后,有概率被查:只退本金,收益的一半记罪证。
/// </summary>
public List<PredictEvent> Night(int day, IEnumerable<string> activeNow, Func<PredictMarket, bool?> outcome, Func<string, Wallet> wallet, Rng rng)
public List<PredictEvent> Night(int day, IEnumerable<string> activeNow, Func<PredictMarket, bool?> outcome, Func<string, Wallet> wallet, Rng rng, double push = 0)
{
var now = activeNow.Distinct().ToList();
if (Prev != null) Started[day] = now.Where(x => !Prev.Contains(x)).ToList();
@@ -206,6 +206,14 @@ namespace Decentralized.Domain
}
m.Outcome = res.Value ? 1 : 0;
var winners = all.Where(x => x.Yes == res.Value).ToList();
// 操纵:行情盘上,赢家的方向和玩家推价的方向一致时按推价幅度被查——本金和收益都没收,收益的一半记罪证
if (m.Kind == PredictKind.Price && winners.Count > 0 && winners.Any(x => x.Yes ? push > 0 : push < 0) && rng.Chance(Market.ManipChance(push)))
{
double profitM = winners.Sum(x => x.Shares) - cost;
evs.Add(new PredictEvent { Kind = "manip", Title = m.Title, Market = m, Amount = cost, Fraud = Math.Min(Tuning.PredictFraudCap, Math.Max(0, profitM) * Tuning.PredictFraudShare) });
Record(day, m, m.Outcome, -cost, true);
continue;
}
if (all.Count > 0 && winners.Count == 0)
{
evs.Add(new PredictEvent { Kind = "lose", Title = m.Title, Market = m, Amount = cost });