Multiple hardware wallets: per-wallet devices, wallets page, Poinbase custodial account, PLEDGER item with supply-chain poisoning

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
ZHU MINCHAOandClaude Opus 5.5 committed 2026-11-03 22:58:24 +08:00
1 parent add61a6b5e
commit 783f73989d
19 files changed
+557 -199

No files matched your search

+16 -4
View File
@@ -90,7 +90,7 @@ namespace Decentralized
// 镇压开始:黑市为换取放行,按声望出卖一批 CRT 地址
if (ev == MarketEvent.Crackdown && Stablecoins.CrtFrozenByCrackdown(StoreReputation.GetBMReputation(), d.Rng))
{
double frozen = d.Hot.Freeze(Assets.CRT, Tuning.CrtFreezeShare, day + Tuning.CrtUnfreezeAfter);
double frozen = d.Wallets.Sum(w => w.Freeze(Assets.CRT, Tuning.CrtFreezeShare, day + Tuning.CrtUnfreezeAfter));
if (frozen > 0)
{
PlayerStore.Instance.AddNightLog(L.T("nightlog.crt_freeze", Fmt.Num(frozen), day + Tuning.CrtUnfreezeAfter), "cc7755");
@@ -98,7 +98,8 @@ namespace Decentralized
}
}
}
foreach (var t in d.Hot.Thaw(day)) PlayerStore.Instance.AddNightLog(L.T("nightlog.thaw", Fmt.Num(t.Value), t.Key));
foreach (var w in d.Wallets)
foreach (var t in w.Thaw(day)) PlayerStore.Instance.AddNightLog(L.T("nightlog.thaw", Fmt.Num(t.Value), t.Key));
if (!wasSanctioned && d.Mixer.Sanctioned(day) && Unlock.MixerUnlocked) News.Show("pd_news_sanction_" + day, L.T("news.sanction.title"), L.T("news.sanction.desc"), 3);
d.ActiveEvents = events;
if (Unlock.BlackUnlocked) BlackDelivery.Night(d, day, events.Contains(MarketEvent.Crackdown));
@@ -126,7 +127,9 @@ namespace Decentralized
if (d.Network.Reward < rewardBefore) d.Market.OnHalving(d.Rng);
if (d.Network.Reward < rewardBefore) News.Show("pd_news_halving_" + day, L.T("news.halving.title"), L.T("news.halving.desc"), 2);
double crcFactor = d.Stable.Night(day, d.Rng, 0);
if (crcFactor < 1) d.Hot.Balances[Assets.CRC] = d.Hot.Get(Assets.CRC) * crcFactor;
if (crcFactor < 1)
foreach (var w in d.Wallets.Append(d.Poinbase))
if (w.Get(Assets.CRC) > 0) w.Balances[Assets.CRC] = w.Get(Assets.CRC) * crcFactor;
d.Market.UpdateSupply(day);
if (Tuning.HalvingDays - day % Tuning.HalvingDays == 3) News.Show("pd_news_prehalving_" + day, L.T("news.prehalving.title"), L.T("news.prehalving.desc"), 3);
d.Market.Night(events, d.Rng, day, Session.Price);
@@ -136,7 +139,7 @@ namespace Decentralized
var ps = PlayerStore.Instance;
if (mined > 0) ps.AddNightLog(L.T("nightlog.mined", Fmt.Num(mined)));
foreach (var m in d.Mixer.Night(d.Hot, day, Session.Price, d.Rng))
foreach (var m in d.Mixer.Night(d.WalletAt, day, Session.Price, d.Rng))
{
Log.Info($"混币器:{(m.Rugged ? "跑路" : "提回")} {m.Amount:0.##} {m.Asset},污点 {m.TaintBefore:0} → {m.TaintAfter:0},标记 {m.Flagged}");
if (m.Rugged) ps.AddNightLog(L.T("nightlog.mixer_rug", Fmt.Num(m.Amount), m.Asset), "cc7755");
@@ -146,6 +149,15 @@ namespace Decentralized
if (m.Flagged) ps.AddNightLog(line, "cc7755"); else ps.AddNightLog(line);
}
}
// 被投毒的硬件钱包:钱够多以后,别人用手里的助记词把它转空
foreach (var w in d.Wallets.Where(x => x.Poisoned))
{
double v = w.Value(Session.Price);
if (!d.Rng.Chance(Wallet.DrainChance(v))) continue;
w.Drain(Session.Price);
Log.Info($"投毒钱包 {w.Address} 被转空:{v:0}");
ps.AddNightLog(L.T("nightlog.drained", WalletWindow.NameOf(w), Fmt.Credits(v)), "cc7755");
}
foreach (var name in report.Burnt) ps.AddNightLog(L.T("nightlog.burnt", name), "cc7755");
int unpowered = report.Rigs - report.PoweredRigs;
if (unpowered > 0 && units.Count + unpowered > 0) ps.AddNightLog(L.T("nightlog.unpowered", unpowered), "cc7755");