Skip to content

Fix rental/sale income leaking into business accounts#15

Merged
ParadauxIO merged 1 commit into
mainfrom
fix/rent-routes-to-personal-account
May 29, 2026
Merged

Fix rental/sale income leaking into business accounts#15
ParadauxIO merged 1 commit into
mainfrom
fix/rent-routes-to-personal-account

Conversation

@ParadauxIO
Copy link
Copy Markdown
Contributor

Problem

Rental payments (and sale/auction/refund proceeds) were silently landing in business accounts instead of the landlord's personal balance.

TreasuryEconomyProvider.resolveRecipientAccount resolved every recipient by preferring GOVERNMENT > BUSINESS > PERSONAL among the accounts that UUID owns. A firm's BUSINESS account in the Business plugin is created as createAccount(AccountType.BUSINESS, proprietorUuid, ...) β€” i.e. owned by the proprietor's own player UUID. So any landlord who also runs a firm had getAccountsByOwner(landlordUuid) return both their PERSONAL and their firm's BUSINESS account, and the BUSINESS-over-PERSONAL preference routed their income into the firm.

All economy flows (rent, buy, auction bids, offers, refunds) funnel through this one method, so they were all affected.

Fix

Prefer the recipient's PERSONAL account first, falling back to the prior GOVERNMENT > BUSINESS > first-available ordering only when no personal account exists.

This is correct and minimal given two Treasury invariants:

  • PERSONAL accounts are one-per-real-player.
  • GOVERNMENT/SYSTEM accounts are owned by the virtual UUID (0,0), never a player.

So:

  • Player landlord β†’ always has a PERSONAL account β†’ paid personally βœ“ (leak fixed)
  • Authority/government UUID (e.g. the configured default-*-authority-uuid) β†’ no PERSONAL account β†’ still falls through to GOVERNMENT βœ“ (legitimate path preserved)

Also in this PR

  • Add TreasuryEconomyProviderTest covering all three routing cases.
  • Add treasury-api to the test classpath (it was compileOnly, so tests couldn't reference Treasury types).
  • Fix RealtyPaperApiImplTest, which no longer compiled on main: ExecutorState gained a third component (networkExec) but the test still passed only two args. This was blocking the whole test module from compiling.

Testing

  • ./gradlew :realty-paper:test β€” green (new test + previously-uncompilable suite).
  • ./gradlew :realty-paper:shadowJar β€” builds.

Note: this only fixes routing going forward. Funds already mis-routed into business accounts won't move themselves β€” but since the affected landlords own those firms, they can withdraw/redirect the balances themselves.

πŸ€– Generated with Claude Code

TreasuryEconomyProvider.resolveRecipientAccount resolved every payment
recipient by preferring GOVERNMENT > BUSINESS > PERSONAL among the
accounts that UUID owns. Because a firm's BUSINESS account is owned by
the proprietor's own player UUID, any landlord who also runs a firm had
their rent (and sale/auction/refund proceeds) silently routed into the
business account instead of their personal balance.

Prefer the recipient's PERSONAL account first, falling back to the prior
GOVERNMENT > BUSINESS > first-available ordering only when no personal
account exists. This is safe given Treasury's invariants: PERSONAL
accounts are one-per-real-player, and GOVERNMENT/SYSTEM accounts are
owned by the virtual UUID (0,0), never a player. So player landlords are
paid personally while synthetic authority UUIDs (no personal account)
still route to their government treasury account.

Also:
- Add TreasuryEconomyProviderTest covering the three routing cases.
- Add treasury-api to the test classpath (was compileOnly, so tests
  couldn't reference Treasury types).
- Fix RealtyPaperApiImplTest, which no longer compiled: ExecutorState
  gained a third component (networkExec) but the test passed only two.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@ParadauxIO ParadauxIO merged commit 38e183b into main May 29, 2026
1 check passed
@ParadauxIO ParadauxIO deleted the fix/rent-routes-to-personal-account branch May 31, 2026 00:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant