Search Apps Documentation Source Content File Folder Download Copy Actions Download State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

service_market_test.gno

40.90 Kb · 1214 lines
   1package service_market
   2
   3import (
   4	"chain"
   5	"chain/banker"
   6	"strings"
   7	"testing"
   8
   9	"gno.land/p/nt/testutils/v0"
  10	"gno.land/p/nt/uassert/v0"
  11)
  12
  13var (
  14	testAdmin = testutils.TestAddress("smadmin")
  15	prov1     = testutils.TestAddress("smprov1")
  16	prov2     = testutils.TestAddress("smprov2")
  17	cust1     = testutils.TestAddress("smcust1")
  18	cust2     = testutils.TestAddress("smcust2")
  19	mallory   = testutils.TestAddress("smmallory")
  20)
  21
  22// Established harness facts, carried from the sibling realms' suites:
  23// init runs with an empty origin context (the real deploy captures the
  24// origin caller); the banker resets between tests while realm globals
  25// persist, so conservation is asserted in DELTA form after re-seeding
  26// carried liabilities; testing.SetRealm affects only the frame that
  27// calls it; and testing.SkipHeights WIPES the origin/realm context, so
  28// every caller is re-armed after a skip.
  29func init() {
  30	admin = testAdmin
  31	feeRecipient = testAdmin
  32	self = chain.PackageAddress("gno.land/r/g1qp5pt8cdq2f6kfdamn3yuxwg6quqnfpyewzz39/service_market")
  33}
  34
  35type baseline struct{ held, escrow, users, fees int64 }
  36
  37func begin() baseline {
  38	if l := Liabilities(); l > 0 {
  39		testing.IssueCoins(Address(), ugnot(l))
  40	}
  41	return snap()
  42}
  43
  44func snap() baseline {
  45	return baseline{held: Held(), escrow: EscrowTotal(), users: UsersTotal(), fees: FeesAccrued()}
  46}
  47
  48// conserved asserts ΔH == ΔE + ΔU + ΔF + extraSurplus, the realm's
  49// stated monetary invariant in delta form.
  50func (b baseline) conserved(t *testing.T, extraSurplus int64) {
  51	t.Helper()
  52	dH := Held() - b.held
  53	dE := EscrowTotal() - b.escrow
  54	dU := UsersTotal() - b.users
  55	dF := FeesAccrued() - b.fees
  56	if dH != dE+dU+dF+extraSurplus {
  57		t.Fatalf("conservation violated: ΔH=%d ΔE=%d ΔU=%d ΔF=%d ΔS=%d", dH, dE, dU, dF, extraSurplus)
  58	}
  59	if Liabilities() != EscrowTotal()+UsersTotal()+FeesAccrued() {
  60		t.Fatalf("Liabilities() = %d, want E+U+F", Liabilities())
  61	}
  62}
  63
  64// appInvariant re-derives the escrow pool from the orders themselves.
  65// EscrowTotal is a running counter; this proves it still equals Σ amount
  66// over non-terminal orders, which is the claim SweepDenom's reserve
  67// rests on.
  68func appInvariant(t *testing.T) {
  69	t.Helper()
  70	var sum int64
  71	for id := int64(0); id < NumOrders(); id++ {
  72		_, _, _, amount, _, status := OrderInfo(id)
  73		switch status {
  74		case OrderPurchased, OrderDelivered:
  75			sum += amount
  76		case OrderReleased, OrderRefunded:
  77		default:
  78			t.Fatalf("order %d has unknown status %q", id, status)
  79		}
  80	}
  81	if sum != EscrowTotal() {
  82		t.Fatalf("EscrowTotal() = %d, but Σ open orders = %d", EscrowTotal(), sum)
  83	}
  84}
  85
  86func coinsOf(addr address) int64 {
  87	return banker.NewReadonlyBanker().GetCoin(addr, Denom)
  88}
  89
  90func ugnot(n int64) chain.Coins {
  91	return chain.NewCoins(chain.NewCoin(Denom, n))
  92}
  93
  94// NOTE ON THE HARNESS. testing.SetRealm applies to the frame that CALLS
  95// it, so the caller identity must be armed in the SAME frame as the
  96// entrypoint invocation. A nested `as(from)` helper is silently
  97// ineffective: the realm reverts when that helper returns, and the call
  98// lands as the default test caller instead of `from` — which is a test
  99// that quietly stops testing what it names. Hence the three lines
 100// inline at every site, matching the sibling suites.
 101
 102// registerAs publishes a service (non-payable: envelope explicitly cleared).
 103func registerAs(cur realm, from address, title, desc string, price, delivery int64) int64 {
 104	testing.SetRealm(testing.NewUserRealm(from))
 105	testing.SetOriginCaller(from)
 106	testing.SetOriginSend(nil)
 107	return RegisterService(cross(cur), title, desc, price, delivery, MaxFeeBps)
 108}
 109
 110// purchaseAs performs a chain-faithful purchase: envelope staged AND landed.
 111func purchaseAs(cur realm, from address, serviceID, pay int64) int64 {
 112	testing.SetRealm(testing.NewUserRealm(from))
 113	testing.SetOriginCaller(from)
 114	testing.SetOriginSend(ugnot(pay))
 115	testing.IssueCoins(Address(), ugnot(pay))
 116	return PurchaseService(cross(cur), serviceID)
 117}
 118
 119func TestInitialConfig(t *testing.T) {
 120	if Admin() != testAdmin || FeeRecipient() != testAdmin {
 121		t.Fatal("seeded roles mismatch")
 122	}
 123	var zero address
 124	if PendingAdmin() != zero {
 125		t.Fatal("pending admin not zero")
 126	}
 127	if FeeBps() != 0 || NumServices() != 0 || NumOrders() != 0 {
 128		t.Fatal("initial counters not zero")
 129	}
 130	if Held() != 0 || Liabilities() != 0 || EscrowTotal() != 0 {
 131		t.Fatal("initial accounting not zero")
 132	}
 133	if Address() == zero {
 134		t.Fatal("realm address is zero")
 135	}
 136}
 137
 138func TestRegisterService(cur realm, t *testing.T) {
 139	b := begin()
 140	id := registerAs(cur, prov1, "logo design", "two concepts and revisions", 500000, 20000)
 141
 142	provider, title, price, delivery, snapBps, status, orderCount := ServiceInfo(id)
 143	if provider != prov1 || title != "logo design" || price != 500000 ||
 144		delivery != 20000 || snapBps != 0 || status != ServiceActive || orderCount != 0 {
 145		t.Fatalf("fields wrong: %v %q %d %d %d %s %d",
 146			provider, title, price, delivery, snapBps, status, orderCount)
 147	}
 148	if ServiceDescription(id) != "two concepts and revisions" {
 149		t.Fatal("description mismatch")
 150	}
 151	if ServicesOf(prov1) != 1 {
 152		t.Fatalf("ServicesOf = %d, want 1", ServicesOf(prov1))
 153	}
 154	p, fee, toProvider := Quote(id)
 155	if p != 500000 || fee != 0 || toProvider != 500000 {
 156		t.Fatalf("Quote = %d/%d/%d", p, fee, toProvider)
 157	}
 158	appInvariant(t)
 159	b.conserved(t, 0)
 160}
 161
 162func TestRegisterRejects(cur realm, t *testing.T) {
 163	b := begin()
 164
 165	// Non-payable: an attached envelope is refused, not stranded.
 166	testing.SetRealm(testing.NewUserRealm(prov1))
 167	testing.SetOriginCaller(prov1)
 168	testing.SetOriginSend(ugnot(100))
 169	uassert.AbortsWithMessage(t, cur, "this function does not accept coins", func() {
 170		RegisterService(cross(cur), "x", "y", 1, MinDeliveryBlocks, MaxFeeBps)
 171	})
 172	testing.SetRealm(testing.NewUserRealm(prov1))
 173	testing.SetOriginCaller(prov1)
 174	testing.SetOriginSend(nil)
 175
 176	uassert.AbortsContains(t, cur, "title must be", func() {
 177		RegisterService(cross(cur), "", "d", 1, MinDeliveryBlocks, MaxFeeBps)
 178	})
 179	uassert.AbortsContains(t, cur, "title may only contain", func() {
 180		RegisterService(cross(cur), "bad*title", "d", 1, MinDeliveryBlocks, MaxFeeBps)
 181	})
 182	uassert.AbortsContains(t, cur, "description must be", func() {
 183		RegisterService(cross(cur), "ok", strings.Repeat("x", MaxDescLen+1), 1, MinDeliveryBlocks, MaxFeeBps)
 184	})
 185	uassert.AbortsContains(t, cur, "price must be at least", func() {
 186		RegisterService(cross(cur), "ok", "d", 0, MinDeliveryBlocks, MaxFeeBps)
 187	})
 188	uassert.AbortsContains(t, cur, "deliveryBlocks must be", func() {
 189		RegisterService(cross(cur), "ok", "d", 1, MinDeliveryBlocks-1, MaxFeeBps)
 190	})
 191	uassert.AbortsContains(t, cur, "deliveryBlocks must be", func() {
 192		RegisterService(cross(cur), "ok", "d", 1, MaxDeliveryBlocks+1, MaxFeeBps)
 193	})
 194	uassert.AbortsContains(t, cur, "maxFeeBps must be", func() {
 195		RegisterService(cross(cur), "ok", "d", 1, MinDeliveryBlocks, MaxFeeBps+1)
 196	})
 197	appInvariant(t)
 198	b.conserved(t, 0)
 199}
 200
 201// The provider's published terms cannot be devalued by an admin fee
 202// change between registration and purchase: registration itself refuses
 203// a fee above the ceiling the provider signed for. This is the grants Y1
 204// pattern, applied at the offer rather than the grant.
 205func TestFeeCeilingAndSnapshot(cur realm, t *testing.T) {
 206	b := begin()
 207
 208	testing.SetRealm(testing.NewUserRealm(testAdmin))
 209	testing.SetOriginCaller(testAdmin)
 210	testing.SetOriginSend(nil)
 211	SetFeeBps(cross(cur), 500)
 212
 213	testing.SetRealm(testing.NewUserRealm(prov1))
 214	testing.SetOriginCaller(prov1)
 215	testing.SetOriginSend(nil)
 216	uassert.AbortsContains(t, cur, "exceeds your ceiling", func() {
 217		RegisterService(cross(cur), "cheap only", "d", 1000, MinDeliveryBlocks, 100)
 218	})
 219
 220	// Registered at 500 bps.
 221	id := registerAs(cur, prov1, "copywriting", "800 words", 1000000, 20000)
 222	_, _, _, _, snapBps, _, _ := ServiceInfo(id)
 223	if snapBps != 500 {
 224		t.Fatalf("snapshot bps = %d, want 500", snapBps)
 225	}
 226
 227	// Admin raises the fee afterwards; the existing service keeps 500.
 228	testing.SetRealm(testing.NewUserRealm(testAdmin))
 229	testing.SetOriginCaller(testAdmin)
 230	testing.SetOriginSend(nil)
 231	SetFeeBps(cross(cur), MaxFeeBps)
 232	_, _, _, _, snapBps, _, _ = ServiceInfo(id)
 233	if snapBps != 500 {
 234		t.Fatalf("snapshot bps changed to %d", snapBps)
 235	}
 236
 237	// And an order placed now carries the SERVICE's 500, not the live cap.
 238	oid := purchaseAs(cur, cust1, id, 1000000)
 239	_, _, _, _, orderBps, _ := OrderInfo(oid)
 240	if orderBps != 500 {
 241		t.Fatalf("order bps = %d, want 500", orderBps)
 242	}
 243
 244	// Clean up: release so later tests start from a settled pool.
 245	testing.SetRealm(testing.NewUserRealm(prov1))
 246	testing.SetOriginCaller(prov1)
 247	testing.SetOriginSend(nil)
 248	MarkDelivered(cross(cur), oid, "ipfs://copy")
 249	testing.SetRealm(testing.NewUserRealm(cust1))
 250	testing.SetOriginCaller(cust1)
 251	testing.SetOriginSend(nil)
 252	AcceptDelivery(cross(cur), oid)
 253
 254	testing.SetRealm(testing.NewUserRealm(testAdmin))
 255	testing.SetOriginCaller(testAdmin)
 256	testing.SetOriginSend(nil)
 257	SetFeeBps(cross(cur), 0)
 258	appInvariant(t)
 259	b.conserved(t, 0)
 260}
 261
 262func TestPurchaseEscrows(cur realm, t *testing.T) {
 263	b := begin()
 264	p0 := BalanceOf(prov1)
 265	sid := registerAs(cur, prov1, "translation", "en to fr", 300000, 20000)
 266
 267	oid := purchaseAs(cur, cust1, sid, 300000)
 268	serviceID, customer, provider, amount, _, status := OrderInfo(oid)
 269	if serviceID != sid || customer != cust1 || provider != prov1 ||
 270		amount != 300000 || status != OrderPurchased {
 271		t.Fatalf("order wrong: %d %v %v %d %s", serviceID, customer, provider, amount, status)
 272	}
 273	// The money is in escrow, NOT yet in anyone's claimable balance.
 274	if EscrowTotal()-b.escrow != 300000 {
 275		t.Fatalf("ΔE = %d, want 300000", EscrowTotal()-b.escrow)
 276	}
 277	if BalanceOf(prov1) != p0 {
 278		t.Fatalf("provider credited before resolution: %d -> %d", p0, BalanceOf(prov1))
 279	}
 280	deliveryDeadline, acceptanceDeadline := OrderDeadlines(oid)
 281	if deliveryDeadline != Height()+20000 {
 282		t.Fatalf("delivery deadline = %d", deliveryDeadline)
 283	}
 284	if acceptanceDeadline != 0 {
 285		t.Fatalf("acceptance deadline set before delivery: %d", acceptanceDeadline)
 286	}
 287	_, _, _, _, _, _, orderCount := ServiceInfo(sid)
 288	if orderCount != 1 {
 289		t.Fatalf("service order count = %d", orderCount)
 290	}
 291	appInvariant(t)
 292	b.conserved(t, 0)
 293}
 294
 295func TestPurchaseRejects(cur realm, t *testing.T) {
 296	b := begin()
 297	sid := registerAs(cur, prov1, "editing", "line edit", 250000, 20000)
 298
 299	// Wrong amount, in both directions.
 300	testing.SetRealm(testing.NewUserRealm(cust1))
 301	testing.SetOriginCaller(cust1)
 302	testing.SetOriginSend(ugnot(249999))
 303	testing.IssueCoins(Address(), ugnot(249999))
 304	uassert.AbortsContains(t, cur, "send exactly the listed price", func() {
 305		PurchaseService(cross(cur), sid)
 306	})
 307	testing.SetOriginSend(ugnot(250001))
 308	testing.IssueCoins(Address(), ugnot(250001))
 309	uassert.AbortsContains(t, cur, "send exactly the listed price", func() {
 310		PurchaseService(cross(cur), sid)
 311	})
 312
 313	// Self-purchase.
 314	testing.SetRealm(testing.NewUserRealm(prov1))
 315	testing.SetOriginCaller(prov1)
 316	testing.SetOriginSend(ugnot(250000))
 317	testing.IssueCoins(Address(), ugnot(250000))
 318	uassert.AbortsWithMessage(t, cur, "the provider cannot purchase their own service", func() {
 319		PurchaseService(cross(cur), sid)
 320	})
 321
 322	// Unknown service.
 323	testing.SetRealm(testing.NewUserRealm(cust1))
 324	testing.SetOriginCaller(cust1)
 325	testing.SetOriginSend(ugnot(250000))
 326	testing.IssueCoins(Address(), ugnot(250000))
 327	uassert.AbortsWithMessage(t, cur, "unknown service id", func() {
 328		PurchaseService(cross(cur), 9999)
 329	})
 330	testing.SetRealm(testing.NewUserRealm(cust1))
 331	testing.SetOriginCaller(cust1)
 332	testing.SetOriginSend(nil)
 333
 334	// Those aborts each landed coins at the realm that the transaction
 335	// then reverted. In the harness the send is simulated rather than
 336	// rolled back, so the excess shows up as surplus; assert it is
 337	// EXACTLY surplus and has not leaked into escrow or a balance.
 338	appInvariant(t)
 339	if EscrowTotal() != b.escrow {
 340		t.Fatalf("a rejected purchase moved escrow: %d -> %d", b.escrow, EscrowTotal())
 341	}
 342	if UsersTotal() != b.users {
 343		t.Fatalf("a rejected purchase credited a balance")
 344	}
 345}
 346
 347// Retiring stops NEW orders and nothing else. An order already in
 348// flight keeps its own copy of provider, amount and fee.
 349func TestRetireService(cur realm, t *testing.T) {
 350	b := begin()
 351	n0 := ServicesOf(prov1)
 352	p0 := BalanceOf(prov1)
 353	sid := registerAs(cur, prov1, "consulting", "one hour", 400000, 20000)
 354	oid := purchaseAs(cur, cust1, sid, 400000)
 355
 356	testing.SetRealm(testing.NewUserRealm(mallory))
 357	testing.SetOriginCaller(mallory)
 358	testing.SetOriginSend(nil)
 359	uassert.AbortsWithMessage(t, cur, "only the provider may retire this service", func() {
 360		RetireService(cross(cur), sid)
 361	})
 362
 363	testing.SetRealm(testing.NewUserRealm(prov1))
 364	testing.SetOriginCaller(prov1)
 365	testing.SetOriginSend(nil)
 366	RetireService(cross(cur), sid)
 367	_, _, _, _, _, status, _ := ServiceInfo(sid)
 368	if status != ServiceRetired {
 369		t.Fatalf("status = %s", status)
 370	}
 371	if ServicesOf(prov1) != n0 {
 372		t.Fatalf("retire did not free the provider slot: %d -> %d", n0, ServicesOf(prov1))
 373	}
 374
 375	// Terminal: no un-retire, and no second retire.
 376	uassert.AbortsWithMessage(t, cur, "service is not active", func() {
 377		RetireService(cross(cur), sid)
 378	})
 379
 380	// New orders refused...
 381	testing.SetRealm(testing.NewUserRealm(cust2))
 382	testing.SetOriginCaller(cust2)
 383	testing.SetOriginSend(ugnot(400000))
 384	testing.IssueCoins(Address(), ugnot(400000))
 385	uassert.AbortsWithMessage(t, cur, "service is not active", func() {
 386		PurchaseService(cross(cur), sid)
 387	})
 388
 389	// ...but the in-flight order still completes normally.
 390	testing.SetRealm(testing.NewUserRealm(prov1))
 391	testing.SetOriginCaller(prov1)
 392	testing.SetOriginSend(nil)
 393	MarkDelivered(cross(cur), oid, "notes.pdf")
 394	testing.SetRealm(testing.NewUserRealm(cust1))
 395	testing.SetOriginCaller(cust1)
 396	testing.SetOriginSend(nil)
 397	AcceptDelivery(cross(cur), oid)
 398	_, _, _, _, _, ostatus := OrderInfo(oid)
 399	if ostatus != OrderReleased {
 400		t.Fatalf("in-flight order broke on retire: %s", ostatus)
 401	}
 402	if BalanceOf(prov1) != p0+400000 {
 403		t.Fatalf("provider credited %d, want %d", BalanceOf(prov1)-p0, 400000)
 404	}
 405	appInvariant(t)
 406	// The refused cust2 purchase landed its 400000 at the realm; on chain
 407	// the abort reverts that send, but the harness simulates it rather
 408	// than rolling it back, so it surfaces as out-of-band surplus. It is
 409	// asserted as surplus precisely to prove it did NOT reach escrow or a
 410	// balance.
 411	b.conserved(t, 400000)
 412}
 413
 414func TestServiceCapPerProvider(cur realm, t *testing.T) {
 415	b := begin()
 416	ids := make([]int64, 0, MaxServicesPerProvider)
 417	for i := 0; i < MaxServicesPerProvider; i++ {
 418		ids = append(ids, registerAs(cur, prov2, "svc", "d", 1000, MinDeliveryBlocks))
 419	}
 420	if ServicesOf(prov2) != MaxServicesPerProvider {
 421		t.Fatalf("ServicesOf = %d", ServicesOf(prov2))
 422	}
 423	testing.SetRealm(testing.NewUserRealm(prov2))
 424	testing.SetOriginCaller(prov2)
 425	testing.SetOriginSend(nil)
 426	uassert.AbortsContains(t, cur, "services per provider", func() {
 427		RegisterService(cross(cur), "one too many", "d", 1000, MinDeliveryBlocks, MaxFeeBps)
 428	})
 429
 430	// Retiring frees exactly one slot.
 431	RetireService(cross(cur), ids[0])
 432	ids = append(ids, registerAs(cur, prov2, "replacement", "d", 1000, MinDeliveryBlocks))
 433	testing.SetRealm(testing.NewUserRealm(prov2))
 434	testing.SetOriginCaller(prov2)
 435	testing.SetOriginSend(nil)
 436	uassert.AbortsContains(t, cur, "services per provider", func() {
 437		RegisterService(cross(cur), "still too many", "d", 1000, MinDeliveryBlocks, MaxFeeBps)
 438	})
 439
 440	// The cap is per provider, not global.
 441	registerAs(cur, prov1, "unaffected", "d", 1000, MinDeliveryBlocks)
 442
 443	// Teardown: realm globals persist between tests in this harness, so
 444	// leaving prov2 pinned at the cap would silently break every later
 445	// test that registers as prov2. Retire everything this test opened.
 446	testing.SetRealm(testing.NewUserRealm(prov2))
 447	testing.SetOriginCaller(prov2)
 448	testing.SetOriginSend(nil)
 449	for _, id := range ids[1:] {
 450		RetireService(cross(cur), id)
 451	}
 452	if ServicesOf(prov2) != 0 {
 453		t.Fatalf("teardown left %d services on prov2", ServicesOf(prov2))
 454	}
 455	appInvariant(t)
 456	b.conserved(t, 0)
 457}
 458
 459// ---- the three required protections ----
 460
 461// UNAUTHORIZED SETTLEMENT. Nobody but the customer can resolve a
 462// delivered order early — not the provider who did the work, not the
 463// admin, not the fee recipient, not a stranger, not another realm.
 464func TestUnauthorizedSettlement(cur realm, t *testing.T) {
 465	b := begin()
 466	p0 := BalanceOf(prov1)
 467	sid := registerAs(cur, prov1, "audit work", "review the thing", 1000000, 20000)
 468	oid := purchaseAs(cur, cust1, sid, 1000000)
 469
 470	// Only the provider may mark delivered.
 471	for _, bad := range []address{cust1, testAdmin, mallory, prov2} {
 472		testing.SetRealm(testing.NewUserRealm(bad))
 473		testing.SetOriginCaller(bad)
 474		testing.SetOriginSend(nil)
 475		uassert.AbortsWithMessage(t, cur, "only the provider may mark this order delivered", func() {
 476			MarkDelivered(cross(cur), oid, "x")
 477		})
 478	}
 479	// Not even from another code realm.
 480	testing.SetRealm(testing.NewCodeRealm("gno.land/r/demo/attacker"))
 481	testing.SetOriginSend(nil)
 482	uassert.AbortsWithMessage(t, cur, "only the provider may mark this order delivered", func() {
 483		MarkDelivered(cross(cur), oid, "x")
 484	})
 485
 486	testing.SetRealm(testing.NewUserRealm(prov1))
 487	testing.SetOriginCaller(prov1)
 488	testing.SetOriginSend(nil)
 489	MarkDelivered(cross(cur), oid, "ipfs://report")
 490
 491	// Only the customer may accept. THE key authorization.
 492	for _, bad := range []address{prov1, testAdmin, mallory, cust2} {
 493		testing.SetRealm(testing.NewUserRealm(bad))
 494		testing.SetOriginCaller(bad)
 495		testing.SetOriginSend(nil)
 496		uassert.AbortsWithMessage(t, cur, "only the customer may accept this delivery", func() {
 497			AcceptDelivery(cross(cur), oid)
 498		})
 499	}
 500	testing.SetRealm(testing.NewCodeRealm("gno.land/r/demo/attacker"))
 501	testing.SetOriginSend(nil)
 502	uassert.AbortsWithMessage(t, cur, "only the customer may accept this delivery", func() {
 503		AcceptDelivery(cross(cur), oid)
 504	})
 505
 506	// The timeout valve is permissionless but NOT early: even the
 507	// provider cannot pull it before the window lapses.
 508	testing.SetRealm(testing.NewUserRealm(prov1))
 509	testing.SetOriginCaller(prov1)
 510	testing.SetOriginSend(nil)
 511	uassert.AbortsContains(t, cur, "acceptance window has not lapsed", func() {
 512		ReleaseTimeout(cross(cur), oid)
 513	})
 514
 515	// Nothing has moved.
 516	if BalanceOf(prov1) != p0 {
 517		t.Fatalf("provider credited without resolution: %d -> %d", p0, BalanceOf(prov1))
 518	}
 519	if EscrowTotal()-b.escrow != 1000000 {
 520		t.Fatalf("escrow moved: ΔE=%d", EscrowTotal()-b.escrow)
 521	}
 522
 523	// The customer, and only the customer, resolves it.
 524	testing.SetRealm(testing.NewUserRealm(cust1))
 525	testing.SetOriginCaller(cust1)
 526	testing.SetOriginSend(nil)
 527	AcceptDelivery(cross(cur), oid)
 528	if BalanceOf(prov1)-p0 != 1000000 {
 529		t.Fatalf("provider credited %d, want 1000000 at 0 bps", BalanceOf(prov1)-p0)
 530	}
 531	appInvariant(t)
 532	b.conserved(t, 0)
 533}
 534
 535// There is no admin path to escrow at all. The admin's only powers are
 536// the fee for FUTURE services, the fee recipient, and succession.
 537func TestAdminCannotTouchEscrow(cur realm, t *testing.T) {
 538	b := begin()
 539	sid := registerAs(cur, prov1, "held work", "d", 700000, 20000)
 540	oid := purchaseAs(cur, cust1, sid, 700000)
 541
 542	testing.SetRealm(testing.NewUserRealm(testAdmin))
 543	testing.SetOriginCaller(testAdmin)
 544	testing.SetOriginSend(nil)
 545	uassert.AbortsWithMessage(t, cur, "only the provider may mark this order delivered", func() {
 546		MarkDelivered(cross(cur), oid, "x")
 547	})
 548	uassert.AbortsWithMessage(t, cur, "only the provider may decline this order", func() {
 549		DeclineOrder(cross(cur), oid)
 550	})
 551	uassert.AbortsContains(t, cur, "delivery window has not lapsed", func() {
 552		ClaimRefund(cross(cur), oid)
 553	})
 554
 555	// And sweep cannot reach live escrow: the reserve covers E too.
 556	testing.IssueCoins(Address(), ugnot(12345)) // genuine out-of-band surplus
 557	before := coinsOf(testAdmin)
 558	SweepDenom(cross(cur), Denom)
 559	if got := coinsOf(testAdmin) - before; got != 12345 {
 560		t.Fatalf("swept %d, want exactly the 12345 surplus", got)
 561	}
 562	if EscrowTotal() != b.escrow+700000 {
 563		t.Fatalf("sweep reached escrow: %d", EscrowTotal())
 564	}
 565	appInvariant(t)
 566}
 567
 568// DOUBLE PAYMENT. Every terminal transition is reachable at most once,
 569// and the two terminal outcomes are mutually exclusive.
 570func TestNoDoublePayment(cur realm, t *testing.T) {
 571	b := begin()
 572	sid := registerAs(cur, prov1, "double check", "d", 600000, 20000)
 573
 574	// Accept twice.
 575	oid := purchaseAs(cur, cust1, sid, 600000)
 576	testing.SetRealm(testing.NewUserRealm(prov1))
 577	testing.SetOriginCaller(prov1)
 578	testing.SetOriginSend(nil)
 579	MarkDelivered(cross(cur), oid, "v1")
 580	testing.SetRealm(testing.NewUserRealm(cust1))
 581	testing.SetOriginCaller(cust1)
 582	testing.SetOriginSend(nil)
 583	AcceptDelivery(cross(cur), oid)
 584	credited := BalanceOf(prov1)
 585	uassert.AbortsWithMessage(t, cur, "order is not awaiting acceptance", func() {
 586		AcceptDelivery(cross(cur), oid)
 587	})
 588	if BalanceOf(prov1) != credited {
 589		t.Fatalf("second accept paid again: %d -> %d", credited, BalanceOf(prov1))
 590	}
 591
 592	// Released orders cannot then be refunded, timed out, or re-delivered.
 593	uassert.AbortsWithMessage(t, cur, "order is not awaiting acceptance", func() {
 594		ReleaseTimeout(cross(cur), oid)
 595	})
 596	uassert.AbortsWithMessage(t, cur, "order is not awaiting delivery", func() {
 597		ClaimRefund(cross(cur), oid)
 598	})
 599	testing.SetRealm(testing.NewUserRealm(prov1))
 600	testing.SetOriginCaller(prov1)
 601	testing.SetOriginSend(nil)
 602	uassert.AbortsWithMessage(t, cur, "order is not awaiting delivery", func() {
 603		DeclineOrder(cross(cur), oid)
 604	})
 605	uassert.AbortsWithMessage(t, cur, "order is not awaiting delivery", func() {
 606		MarkDelivered(cross(cur), oid, "v2")
 607	})
 608
 609	// Decline twice, and a declined order cannot then be released.
 610	oid2 := purchaseAs(cur, cust2, sid, 600000)
 611	testing.SetRealm(testing.NewUserRealm(prov1))
 612	testing.SetOriginCaller(prov1)
 613	testing.SetOriginSend(nil)
 614	DeclineOrder(cross(cur), oid2)
 615	refunded := BalanceOf(cust2)
 616	uassert.AbortsWithMessage(t, cur, "order is not awaiting delivery", func() {
 617		DeclineOrder(cross(cur), oid2)
 618	})
 619	if BalanceOf(cust2) != refunded {
 620		t.Fatalf("second decline refunded again")
 621	}
 622	testing.SetRealm(testing.NewUserRealm(cust2))
 623	testing.SetOriginCaller(cust2)
 624	testing.SetOriginSend(nil)
 625	uassert.AbortsWithMessage(t, cur, "order is not awaiting acceptance", func() {
 626		AcceptDelivery(cross(cur), oid2)
 627	})
 628	appInvariant(t)
 629	b.conserved(t, 0)
 630}
 631
 632// A claim pays out once; the ledger is debited before coins move.
 633func TestNoDoubleClaim(cur realm, t *testing.T) {
 634	b := begin()
 635	p0 := BalanceOf(prov1) // carried in from earlier tests; ClaimAll drains it too
 636	sid := registerAs(cur, prov1, "claim once", "d", 800000, 20000)
 637	oid := purchaseAs(cur, cust1, sid, 800000)
 638	testing.SetRealm(testing.NewUserRealm(prov1))
 639	testing.SetOriginCaller(prov1)
 640	testing.SetOriginSend(nil)
 641	MarkDelivered(cross(cur), oid, "done")
 642	testing.SetRealm(testing.NewUserRealm(cust1))
 643	testing.SetOriginCaller(cust1)
 644	testing.SetOriginSend(nil)
 645	AcceptDelivery(cross(cur), oid)
 646
 647	testing.SetRealm(testing.NewUserRealm(prov1))
 648	testing.SetOriginCaller(prov1)
 649	testing.SetOriginSend(nil)
 650	before := coinsOf(prov1)
 651	ClaimAll(cross(cur))
 652	if got := coinsOf(prov1) - before; got != p0+800000 {
 653		t.Fatalf("claimed %d, want %d", got, p0+800000)
 654	}
 655	if BalanceOf(prov1) != 0 {
 656		t.Fatal("balance not zeroed")
 657	}
 658	uassert.AbortsWithMessage(t, cur, "nothing to claim", func() {
 659		ClaimAll(cross(cur))
 660	})
 661	uassert.AbortsContains(t, cur, "insufficient", func() {
 662		Claim(cross(cur), 1)
 663	})
 664	if got := coinsOf(prov1) - before; got != p0+800000 {
 665		t.Fatalf("a second claim paid out: total %d", got)
 666	}
 667	appInvariant(t)
 668	b.conserved(t, 0)
 669}
 670
 671// STUCK FUNDS, arm 1: the provider abandons the order. Anyone may
 672// return the escrow to the customer once the delivery window lapses.
 673func TestStuckFundsProviderAbandons(cur realm, t *testing.T) {
 674	b := begin()
 675	sid := registerAs(cur, prov1, "never delivered", "d", 900000, MinDeliveryBlocks)
 676	oid := purchaseAs(cur, cust1, sid, 900000)
 677
 678	// Too early, even for the customer.
 679	testing.SetRealm(testing.NewUserRealm(cust1))
 680	testing.SetOriginCaller(cust1)
 681	testing.SetOriginSend(nil)
 682	uassert.AbortsContains(t, cur, "delivery window has not lapsed", func() {
 683		ClaimRefund(cross(cur), oid)
 684	})
 685
 686	testing.SkipHeights(MinDeliveryBlocks)
 687
 688	// A total stranger pulls the valve; the money goes to the CUSTOMER,
 689	// not to the caller.
 690	testing.SetRealm(testing.NewUserRealm(mallory))
 691	testing.SetOriginCaller(mallory)
 692	testing.SetOriginSend(nil)
 693	mBefore := BalanceOf(mallory)
 694	ClaimRefund(cross(cur), oid)
 695	if BalanceOf(mallory) != mBefore {
 696		t.Fatal("the valve paid its caller")
 697	}
 698	if BalanceOf(cust1) != 900000 {
 699		t.Fatalf("customer refund = %d, want 900000", BalanceOf(cust1))
 700	}
 701	if FeesAccrued() != b.fees {
 702		t.Fatal("a refund accrued a protocol fee")
 703	}
 704	_, _, _, _, _, status := OrderInfo(oid)
 705	if status != OrderRefunded {
 706		t.Fatalf("status = %s", status)
 707	}
 708	// And the customer can actually get the coins out.
 709	testing.SetRealm(testing.NewUserRealm(cust1))
 710	testing.SetOriginCaller(cust1)
 711	testing.SetOriginSend(nil)
 712	before := coinsOf(cust1)
 713	ClaimAll(cross(cur))
 714	if got := coinsOf(cust1) - before; got != 900000 {
 715		t.Fatalf("customer withdrew %d", got)
 716	}
 717	appInvariant(t)
 718	b.conserved(t, 0)
 719}
 720
 721// STUCK FUNDS, arm 2: the customer goes silent after delivery. Anyone
 722// may release the escrow to the provider once acceptance lapses. This
 723// is the valve whose polarity is INVERTED from every sibling realm's,
 724// and getting it wrong would strand completed work.
 725func TestStuckFundsCustomerGoesSilent(cur realm, t *testing.T) {
 726	b := begin()
 727	sid := registerAs(cur, prov1, "delivered ignored", "d", 1000000, MaxDeliveryBlocks)
 728	oid := purchaseAs(cur, cust1, sid, 1000000)
 729	testing.SetRealm(testing.NewUserRealm(prov1))
 730	testing.SetOriginCaller(prov1)
 731	testing.SetOriginSend(nil)
 732	MarkDelivered(cross(cur), oid, "ipfs://final")
 733
 734	_, acceptanceDeadline := OrderDeadlines(oid)
 735	if acceptanceDeadline != Height()+AcceptanceBlocks {
 736		t.Fatalf("acceptance deadline = %d, want height+%d", acceptanceDeadline, AcceptanceBlocks)
 737	}
 738
 739	testing.SkipHeights(AcceptanceBlocks)
 740
 741	testing.SetRealm(testing.NewUserRealm(mallory))
 742	testing.SetOriginCaller(mallory)
 743	testing.SetOriginSend(nil)
 744	mBefore := BalanceOf(mallory)
 745	ReleaseTimeout(cross(cur), oid)
 746	if BalanceOf(mallory) != mBefore {
 747		t.Fatal("the valve paid its caller")
 748	}
 749	if BalanceOf(prov1) != 1000000 {
 750		t.Fatalf("provider = %d, want 1000000", BalanceOf(prov1))
 751	}
 752	_, _, _, _, _, status := OrderInfo(oid)
 753	if status != OrderReleased {
 754		t.Fatalf("status = %s", status)
 755	}
 756	appInvariant(t)
 757	b.conserved(t, 0)
 758}
 759
 760// The delivery deadline protects the customer, so late delivery is
 761// allowed while the refund valve is still un-pulled — but the refund
 762// valve closes the instant delivery lands, and reopening it is not
 763// possible.
 764func TestLateDeliveryRace(cur realm, t *testing.T) {
 765	b := begin()
 766	p0 := BalanceOf(prov1)
 767	sid := registerAs(cur, prov1, "late but wanted", "d", 500000, MinDeliveryBlocks)
 768	oid := purchaseAs(cur, cust1, sid, 500000)
 769
 770	testing.SkipHeights(MinDeliveryBlocks + 10)
 771
 772	// Provider delivers late; permitted.
 773	testing.SetRealm(testing.NewUserRealm(prov1))
 774	testing.SetOriginCaller(prov1)
 775	testing.SetOriginSend(nil)
 776	MarkDelivered(cross(cur), oid, "late.zip")
 777
 778	// The refund valve is now closed: the order is no longer awaiting
 779	// delivery, so the lapsed delivery deadline is irrelevant.
 780	testing.SetRealm(testing.NewUserRealm(mallory))
 781	testing.SetOriginCaller(mallory)
 782	testing.SetOriginSend(nil)
 783	uassert.AbortsWithMessage(t, cur, "order is not awaiting delivery", func() {
 784		ClaimRefund(cross(cur), oid)
 785	})
 786	testing.SetRealm(testing.NewUserRealm(cust1))
 787	testing.SetOriginCaller(cust1)
 788	testing.SetOriginSend(nil)
 789	uassert.AbortsWithMessage(t, cur, "order is not awaiting delivery", func() {
 790		ClaimRefund(cross(cur), oid)
 791	})
 792
 793	// The customer still holds the real lever: accept, or wait out the
 794	// acceptance window.
 795	AcceptDelivery(cross(cur), oid)
 796	if BalanceOf(prov1)-p0 != 500000 {
 797		t.Fatalf("provider credited %d, want 500000", BalanceOf(prov1)-p0)
 798	}
 799	appInvariant(t)
 800	b.conserved(t, 0)
 801}
 802
 803// ---- fees, sweep, administration ----
 804
 805func TestFeeSplitAndWithdraw(cur realm, t *testing.T) {
 806	b := begin()
 807	p0 := BalanceOf(prov1)
 808	testing.SetRealm(testing.NewUserRealm(testAdmin))
 809	testing.SetOriginCaller(testAdmin)
 810	testing.SetOriginSend(nil)
 811	SetFeeBps(cross(cur), 250) // 2.5%
 812
 813	sid := registerAs(cur, prov1, "fee bearing", "d", 1000000, 20000)
 814	p, fee, toProvider := Quote(sid)
 815	if p != 1000000 || fee != 25000 || toProvider != 975000 {
 816		t.Fatalf("Quote = %d/%d/%d", p, fee, toProvider)
 817	}
 818
 819	oid := purchaseAs(cur, cust1, sid, 1000000)
 820	testing.SetRealm(testing.NewUserRealm(prov1))
 821	testing.SetOriginCaller(prov1)
 822	testing.SetOriginSend(nil)
 823	MarkDelivered(cross(cur), oid, "x")
 824	testing.SetRealm(testing.NewUserRealm(cust1))
 825	testing.SetOriginCaller(cust1)
 826	testing.SetOriginSend(nil)
 827	AcceptDelivery(cross(cur), oid)
 828
 829	if BalanceOf(prov1)-p0 != 975000 {
 830		t.Fatalf("provider credited %d, want 975000", BalanceOf(prov1)-p0)
 831	}
 832	if FeesAccrued()-b.fees != 25000 {
 833		t.Fatalf("fee pot ΔF = %d", FeesAccrued()-b.fees)
 834	}
 835
 836	testing.SetRealm(testing.NewUserRealm(mallory))
 837	testing.SetOriginCaller(mallory)
 838	testing.SetOriginSend(nil)
 839	uassert.AbortsWithMessage(t, cur, "only the fee recipient may withdraw fees", func() {
 840		WithdrawFees(cross(cur))
 841	})
 842	testing.SetRealm(testing.NewUserRealm(testAdmin))
 843	testing.SetOriginCaller(testAdmin)
 844	testing.SetOriginSend(nil)
 845	before := coinsOf(testAdmin)
 846	WithdrawFees(cross(cur))
 847	if got := coinsOf(testAdmin) - before; got != b.fees+25000 {
 848		t.Fatalf("withdrew %d", got)
 849	}
 850	uassert.AbortsWithMessage(t, cur, "no fees accrued", func() {
 851		WithdrawFees(cross(cur))
 852	})
 853
 854	testing.SetRealm(testing.NewUserRealm(testAdmin))
 855	testing.SetOriginCaller(testAdmin)
 856	testing.SetOriginSend(nil)
 857	SetFeeBps(cross(cur), 0)
 858	appInvariant(t)
 859	b.conserved(t, 0)
 860}
 861
 862func TestSweepReservesEscrow(cur realm, t *testing.T) {
 863	b := begin()
 864	sid := registerAs(cur, prov1, "sweep guard", "d", 400000, 20000)
 865	purchaseAs(cur, cust1, sid, 400000)
 866
 867	// No surplus yet. coinio.Sweep aborts rather than sending zero, so
 868	// the escrow is unreachable by REVERT, not merely by arithmetic —
 869	// which is the stronger of the two.
 870	testing.SetRealm(testing.NewUserRealm(testAdmin))
 871	testing.SetOriginCaller(testAdmin)
 872	testing.SetOriginSend(nil)
 873	before := coinsOf(testAdmin)
 874	uassert.AbortsContains(t, cur, "no surplus to sweep", func() {
 875		SweepDenom(cross(cur), Denom)
 876	})
 877	if coinsOf(testAdmin) != before {
 878		t.Fatal("swept out of a zero-surplus realm")
 879	}
 880	if EscrowTotal() != b.escrow+400000 {
 881		t.Fatal("sweep reached escrow")
 882	}
 883
 884	// A foreign denom moves wholly.
 885	testing.IssueCoins(Address(), chain.NewCoins(chain.NewCoin("gjunk", 77)))
 886	SweepDenom(cross(cur), "gjunk")
 887	if banker.NewReadonlyBanker().GetCoin(testAdmin, "gjunk") != 77 {
 888		t.Fatal("foreign denom not swept")
 889	}
 890
 891	testing.SetRealm(testing.NewUserRealm(mallory))
 892	testing.SetOriginCaller(mallory)
 893	testing.SetOriginSend(nil)
 894	uassert.AbortsWithMessage(t, cur, "only the fee recipient may sweep surplus", func() {
 895		SweepDenom(cross(cur), Denom)
 896	})
 897	appInvariant(t)
 898}
 899
 900func TestAdminHandover(cur realm, t *testing.T) {
 901	b := begin()
 902	testing.SetRealm(testing.NewUserRealm(mallory))
 903	testing.SetOriginCaller(mallory)
 904	testing.SetOriginSend(nil)
 905	uassert.AbortsWithMessage(t, cur, "admin only", func() {
 906		TransferAdmin(cross(cur), mallory)
 907	})
 908	uassert.AbortsWithMessage(t, cur, "admin only", func() {
 909		SetFeeBps(cross(cur), 10)
 910	})
 911	uassert.AbortsWithMessage(t, cur, "admin only", func() {
 912		SetFeeRecipient(cross(cur), mallory)
 913	})
 914
 915	testing.SetRealm(testing.NewUserRealm(testAdmin))
 916	testing.SetOriginCaller(testAdmin)
 917	testing.SetOriginSend(nil)
 918	// A malformed nominee is rejected where the typo is made, for parity
 919	// with SetFeeRecipient. The zero address keeps its documented meaning
 920	// as the cancel sentinel and must NOT be caught by that check.
 921	uassert.AbortsWithMessage(t, cur, "invalid admin address", func() {
 922		TransferAdmin(cross(cur), address("g1notanaddress"))
 923	})
 924	TransferAdmin(cross(cur), prov2)
 925	if Admin() != testAdmin {
 926		t.Fatal("nomination took effect immediately")
 927	}
 928	if PendingAdmin() != prov2 {
 929		t.Fatalf("pending = %v", PendingAdmin())
 930	}
 931	TransferAdmin(cross(cur), "")
 932	if PendingAdmin() != "" {
 933		t.Fatalf("zero address did not cancel: %v", PendingAdmin())
 934	}
 935	TransferAdmin(cross(cur), prov2)
 936
 937	// Wrong acceptor.
 938	testing.SetRealm(testing.NewUserRealm(mallory))
 939	testing.SetOriginCaller(mallory)
 940	testing.SetOriginSend(nil)
 941	uassert.AbortsWithMessage(t, cur, "only the nominated admin may accept", func() {
 942		AcceptAdmin(cross(cur))
 943	})
 944	testing.SetRealm(testing.NewUserRealm(prov2))
 945	testing.SetOriginCaller(prov2)
 946	testing.SetOriginSend(nil)
 947	AcceptAdmin(cross(cur))
 948	if Admin() != prov2 {
 949		t.Fatalf("admin = %v", Admin())
 950	}
 951	var zero address
 952	if PendingAdmin() != zero {
 953		t.Fatal("pending not cleared")
 954	}
 955
 956	// Authority MOVED: the former admin is now powerless.
 957	testing.SetRealm(testing.NewUserRealm(testAdmin))
 958	testing.SetOriginCaller(testAdmin)
 959	testing.SetOriginSend(nil)
 960	uassert.AbortsWithMessage(t, cur, "admin only", func() {
 961		SetFeeBps(cross(cur), 10)
 962	})
 963
 964	// Hand it back so the rest of the suite keeps its seeded roles.
 965	testing.SetRealm(testing.NewUserRealm(prov2))
 966	testing.SetOriginCaller(prov2)
 967	testing.SetOriginSend(nil)
 968	TransferAdmin(cross(cur), testAdmin)
 969	testing.SetRealm(testing.NewUserRealm(testAdmin))
 970	testing.SetOriginCaller(testAdmin)
 971	testing.SetOriginSend(nil)
 972	AcceptAdmin(cross(cur))
 973	if Admin() != testAdmin {
 974		t.Fatal("handback failed")
 975	}
 976	appInvariant(t)
 977	b.conserved(t, 0)
 978}
 979
 980// ---- render safety ----
 981
 982func TestRenderSanitizesUntrustedText(cur realm, t *testing.T) {
 983	begin()
 984	evil := "[click](https://evil.example) ![x](https://evil.example/x.png)"
 985	sid := registerAs(cur, prov1, "render probe", evil, 100000, 20000)
 986	oid := purchaseAs(cur, cust1, sid, 100000)
 987	testing.SetRealm(testing.NewUserRealm(prov1))
 988	testing.SetOriginCaller(prov1)
 989	testing.SetOriginSend(nil)
 990	MarkDelivered(cross(cur), oid, evil)
 991
 992	sOut := Render("s/" + itoa(sid))
 993	if strings.Contains(sOut, "](https://evil.example)") {
 994		t.Fatal("service description rendered an unescaped markdown link")
 995	}
 996	oOut := Render("o/" + itoa(oid))
 997	if strings.Contains(oOut, "](https://evil.example/x.png)") {
 998		t.Fatal("delivery uri rendered an unescaped markdown image")
 999	}
1000
1001	// Unknown and malformed ids degrade to a warning, never a panic.
1002	for _, p := range []string{"s/abc", "o/abc", "s/999999", "o/999999"} {
1003		if !strings.Contains(Render(p), "[!WARNING]") {
1004			t.Fatalf("Render(%q) did not warn", p)
1005		}
1006	}
1007	if !strings.Contains(Render(""), "Service marketplace") {
1008		t.Fatal("home render broken")
1009	}
1010	appInvariant(t)
1011}
1012
1013// The home page is bounded regardless of catalog size.
1014func TestRenderIsBounded(cur realm, t *testing.T) {
1015	begin()
1016	for i := 0; i < RenderLimit+5; i++ {
1017		registerAs(cur, prov2, "bulk svc", "d", 1000, MinDeliveryBlocks)
1018		testing.SetRealm(testing.NewUserRealm(prov2))
1019		testing.SetOriginCaller(prov2)
1020		testing.SetOriginSend(nil)
1021		// Retire immediately so the per-provider cap is not the thing
1022		// under test here.
1023		RetireService(cross(cur), NumServices()-1)
1024	}
1025	out := Render("")
1026	if got := strings.Count(out, "\n- [#"); got > RenderLimit {
1027		t.Fatalf("home listed %d services, cap is %d", got, RenderLimit)
1028	}
1029	appInvariant(t)
1030}
1031
1032// ---- guards on every non-payable entrypoint ----
1033
1034func TestNonPayableEntrypointsRefuseCoins(cur realm, t *testing.T) {
1035	b := begin()
1036	sid := registerAs(cur, prov1, "send guard", "d", 100000, 20000)
1037	oid := purchaseAs(cur, cust1, sid, 100000)
1038
1039	stage := func(from address) {
1040		testing.SetRealm(testing.NewUserRealm(from))
1041		testing.SetOriginCaller(from)
1042		testing.SetOriginSend(ugnot(1))
1043	}
1044	msg := "this function does not accept coins"
1045
1046	stage(prov1)
1047	uassert.AbortsWithMessage(t, cur, msg, func() { MarkDelivered(cross(cur), oid, "x") })
1048	uassert.AbortsWithMessage(t, cur, msg, func() { DeclineOrder(cross(cur), oid) })
1049	uassert.AbortsWithMessage(t, cur, msg, func() { RetireService(cross(cur), sid) })
1050	uassert.AbortsWithMessage(t, cur, msg, func() { ClaimAll(cross(cur)) })
1051	uassert.AbortsWithMessage(t, cur, msg, func() { Claim(cross(cur), 1) })
1052	stage(cust1)
1053	uassert.AbortsWithMessage(t, cur, msg, func() { AcceptDelivery(cross(cur), oid) })
1054	uassert.AbortsWithMessage(t, cur, msg, func() { ClaimRefund(cross(cur), oid) })
1055	uassert.AbortsWithMessage(t, cur, msg, func() { ReleaseTimeout(cross(cur), oid) })
1056	stage(testAdmin)
1057	uassert.AbortsWithMessage(t, cur, msg, func() { SetFeeBps(cross(cur), 1) })
1058	uassert.AbortsWithMessage(t, cur, msg, func() { SetFeeRecipient(cross(cur), prov1) })
1059	uassert.AbortsWithMessage(t, cur, msg, func() { TransferAdmin(cross(cur), prov1) })
1060	uassert.AbortsWithMessage(t, cur, msg, func() { AcceptAdmin(cross(cur)) })
1061	uassert.AbortsWithMessage(t, cur, msg, func() { WithdrawFees(cross(cur)) })
1062	uassert.AbortsWithMessage(t, cur, msg, func() { SweepDenom(cross(cur), Denom) })
1063
1064	testing.SetRealm(testing.NewUserRealm(prov1))
1065	testing.SetOriginCaller(prov1)
1066	testing.SetOriginSend(nil)
1067	appInvariant(t)
1068	if EscrowTotal() != b.escrow+100000 {
1069		t.Fatal("a refused call moved escrow")
1070	}
1071}
1072
1073func TestUnknownIdsAbort(cur realm, t *testing.T) {
1074	begin()
1075	testing.SetRealm(testing.NewUserRealm(mallory))
1076	testing.SetOriginCaller(mallory)
1077	testing.SetOriginSend(nil)
1078	uassert.AbortsWithMessage(t, cur, "unknown service id", func() {
1079		RetireService(cross(cur), 999999)
1080	})
1081	uassert.AbortsWithMessage(t, cur, "unknown order id", func() {
1082		AcceptDelivery(cross(cur), 999999)
1083	})
1084	uassert.AbortsWithMessage(t, cur, "unknown order id", func() {
1085		ClaimRefund(cross(cur), 999999)
1086	})
1087	uassert.AbortsWithMessage(t, cur, "unknown order id", func() {
1088		ReleaseTimeout(cross(cur), 999999)
1089	})
1090	// A view is not a crossing call, so its failure is a plain panic
1091	// rather than an abort — a different assertion, not a weaker one.
1092	uassert.PanicsWithMessage(t, cur, "unknown service id", func() {
1093		ServiceDescription(999999)
1094	})
1095	uassert.PanicsWithMessage(t, cur, "unknown order id", func() {
1096		OrderInfo(999999)
1097	})
1098}
1099
1100func TestMarkDeliveredBoundsURI(cur realm, t *testing.T) {
1101	begin()
1102	sid := registerAs(cur, prov1, "uri bound", "d", 100000, 20000)
1103	oid := purchaseAs(cur, cust1, sid, 100000)
1104	testing.SetRealm(testing.NewUserRealm(prov1))
1105	testing.SetOriginCaller(prov1)
1106	testing.SetOriginSend(nil)
1107	uassert.AbortsContains(t, cur, "uri must be at most", func() {
1108		MarkDelivered(cross(cur), oid, strings.Repeat("u", MaxURILen+1))
1109	})
1110	MarkDelivered(cross(cur), oid, strings.Repeat("u", MaxURILen))
1111	if len(OrderURI(oid)) != MaxURILen {
1112		t.Fatal("uri not stored at the boundary")
1113	}
1114	appInvariant(t)
1115}
1116
1117func TestCheckedAddOverflow(t *testing.T) {
1118	const maxInt64 int64 = 1<<63 - 1
1119	if _, ok := checkedAdd(maxInt64, 1); ok {
1120		t.Fatal("overflow not detected")
1121	}
1122	if v, ok := checkedAdd(maxInt64-1, 1); !ok || v != maxInt64 {
1123		t.Fatal("boundary add rejected")
1124	}
1125	if v, ok := checkedAdd(5, -3); !ok || v != 2 {
1126		t.Fatal("negative delta broken")
1127	}
1128}
1129
1130// A full multi-party run, asserting conservation at every checkpoint —
1131// the property that all three protections ultimately rest on.
1132func TestFullLifecycleConservation(cur realm, t *testing.T) {
1133	b := begin()
1134	testing.SetRealm(testing.NewUserRealm(testAdmin))
1135	testing.SetOriginCaller(testAdmin)
1136	testing.SetOriginSend(nil)
1137	SetFeeBps(cross(cur), 100) // 1%
1138
1139	s1 := registerAs(cur, prov1, "alpha", "d", 1000000, MinDeliveryBlocks)
1140	s2 := registerAs(cur, prov2, "beta", "d", 2000000, MaxDeliveryBlocks)
1141	b.conserved(t, 0)
1142
1143	// Accepted.
1144	o1 := purchaseAs(cur, cust1, s1, 1000000)
1145	b.conserved(t, 0)
1146	testing.SetRealm(testing.NewUserRealm(prov1))
1147	testing.SetOriginCaller(prov1)
1148	testing.SetOriginSend(nil)
1149	MarkDelivered(cross(cur), o1, "a")
1150	testing.SetRealm(testing.NewUserRealm(cust1))
1151	testing.SetOriginCaller(cust1)
1152	testing.SetOriginSend(nil)
1153	AcceptDelivery(cross(cur), o1)
1154	b.conserved(t, 0)
1155
1156	// Declined.
1157	o2 := purchaseAs(cur, cust2, s2, 2000000)
1158	testing.SetRealm(testing.NewUserRealm(prov2))
1159	testing.SetOriginCaller(prov2)
1160	testing.SetOriginSend(nil)
1161	DeclineOrder(cross(cur), o2)
1162	b.conserved(t, 0)
1163
1164	// Expired to a refund.
1165	o3 := purchaseAs(cur, cust1, s1, 1000000)
1166	testing.SkipHeights(MinDeliveryBlocks)
1167	testing.SetRealm(testing.NewUserRealm(mallory))
1168	testing.SetOriginCaller(mallory)
1169	testing.SetOriginSend(nil)
1170	ClaimRefund(cross(cur), o3)
1171	b.conserved(t, 0)
1172
1173	// Timed out to a release.
1174	o4 := purchaseAs(cur, cust2, s2, 2000000)
1175	testing.SetRealm(testing.NewUserRealm(prov2))
1176	testing.SetOriginCaller(prov2)
1177	testing.SetOriginSend(nil)
1178	MarkDelivered(cross(cur), o4, "b")
1179	testing.SkipHeights(AcceptanceBlocks)
1180	testing.SetRealm(testing.NewUserRealm(mallory))
1181	testing.SetOriginCaller(mallory)
1182	testing.SetOriginSend(nil)
1183	ReleaseTimeout(cross(cur), o4)
1184	b.conserved(t, 0)
1185
1186	if EscrowTotal() != b.escrow {
1187		t.Fatalf("escrow not drained: %d -> %d", b.escrow, EscrowTotal())
1188	}
1189
1190	// Everyone withdraws; the realm ends holding only what it started
1191	// with plus the fee pot it still owes.
1192	for _, who := range []address{prov1, prov2, cust1, cust2, testAdmin, mallory} {
1193		if BalanceOf(who) == 0 {
1194			continue
1195		}
1196		testing.SetRealm(testing.NewUserRealm(who))
1197		testing.SetOriginCaller(who)
1198		testing.SetOriginSend(nil)
1199		ClaimAll(cross(cur))
1200	}
1201	// Every counterparty this suite has ever used is in that list, so
1202	// draining them must take U to exactly zero — not back to the
1203	// baseline, which still carried earlier tests' unclaimed credits.
1204	if UsersTotal() != 0 {
1205		t.Fatalf("claimable residue: %d", UsersTotal())
1206	}
1207	appInvariant(t)
1208	b.conserved(t, 0)
1209
1210	testing.SetRealm(testing.NewUserRealm(testAdmin))
1211	testing.SetOriginCaller(testAdmin)
1212	testing.SetOriginSend(nil)
1213	SetFeeBps(cross(cur), 0)
1214}