Skip to content

Adds network finance system#405

Merged
PsyCommando merged 3 commits intoPersistentSS13:devfrom
NataKilar:outreach-money
Mar 1, 2023
Merged

Adds network finance system#405
PsyCommando merged 3 commits intoPersistentSS13:devfrom
NataKilar:outreach-money

Conversation

@NataKilar
Copy link
Collaborator

Description of changes

Adds computer network finance system.

Related Accounts

  • Adds related parent and child accounts. Parent accounts hold all the "real" money in the game, while the child accounts' balance represents a share in the parent accounts money. In the simplest sense, parent accounts represent a bank, child accounts represent a client of that bank.
  • Parent accounts have a fractional reserve which determines to what extent the parent account can be indebted to its child accounts. For example, a fractional reserve of 90% requires the parent account to retain 90% of the total money in each child account.
  • Child accounts can have set withdrawal limits, interest rates and transaction fees on withdrawals/transfers to accounts with a different parent account. Interest rates can be either positive or negative, compounding daily.

Network finance

  • Each computer network can have a single parent account managed by a banking mainframe. Finances are managed remotely with the financial management program.
  • The parent account datum is held on the computer network datum itself. In the event the network goes down, it will be held by the banking mainframe temporarily. In the event the banking mainframe goes down, financial services will be frozen until it is restored. In the event both go down, an escrow panic is triggered (see below).
  • The money stored in the parent account is abstractly stored in cryptographic currency storage devices, or "money cubes". These objects don't actually keep track of the money they store under normal circumstances -- it is assumed that money in the parent account is stored evenly between cubes. If no money cubes exist on the network, funds are temporarily frozen.
  • Each network account may have a child account attached. Interest rates, withdrawal limits, and transaction fees can be set individually per account.
  • The parent account on the network is managed solely through the financial management program. Child accounts can be accessed remotely through a new ATM program.
  • Cash can be deposited and withdrawn as long as a computer has a cryptographic holoprinter installed (brrrrr). This device requires plastic to print money. Otherwise, transfers can be performed digitally, within networks and between networks via PLEXUS.
  • For rapid transactions, a network enabled POS system has been added. These are similar to the old EFTPOS devices, and can read from a network ID card for quick transactions.

Escrow accounts and Money Security

  • In general, the system is designed to prevent the owner of a parent account from stealing all of their client's money, while still leaving them vulnerable to theft.
  • Money cubes can be tampered with by users with sufficient financial or device skill. Upon tampering, the money cube will drop cash.
  • If more than one money cube exists on the network, then the money cube will drop the entirety of its share in cash. However, this will trigger loss prevention measures, which suspends withdrawal limits on all child accounts and notifies them by e-mail. If another theft occurs in a two day period, or if the money cube was the sole storage on the network, an escrow panic will be triggered.
  • If both the network and banking mainframe go down, an escrow panic will be triggered as well.
  • An escrow panic immediately dumps as much cash as available in the parent account into global escrow accounts which are accessible by child account users from any ATM terminal. Users are notified by e-mail, assuming the network still exists.
  • Parent accounts can close child accounts manually as well, but this will also create an escrow account with the child's remaining balance.
  • Withdrawal limits, interest rate, fractional reserves, etc. cannot be changed arbitrarily. Modifications to these are delayed, and will notify users. If the user would be unable to retrieve their money from their accounts within the time period before the modification takes effect, withdrawal limits will be suspended.

There are probably other miscellaneous features which cannot be detailed in full, since this is extremely long already. Happy to answer questions on Discord, though.

Authorship

Myself

@PsyCommando PsyCommando added the 🆕 enhancement New feature or request label Feb 21, 2023
@PsyCommando
Copy link
Collaborator

Let me know when you want this reviewed btw.

@NataKilar
Copy link
Collaborator Author

Let me know when you want this reviewed btw.

Should be good to review whenever, although I wont be able to address anything til the weekend

@PsyCommando
Copy link
Collaborator

After looking at things a bit, I was wondering. Are you planning on porting this upstream? Because it just overwrite a lot of the default economy stuff?

Copy link
Collaborator

@PsyCommando PsyCommando left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's some things I left comments on, but they're mostly minor things. So I'll approve this for now.


var/adjustment = 0

/datum/controller/subsystem/money_accounts/fire(resumed = FALSE)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I gotta admit, I'm not all that fond of holding all account data in-game, and just looping through all of them constantly.
The way I handled them in my rework was via SQL tables and stored procedures. So DM had very little work to do.
But if you really wanna go that way I'm not gonna protest.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can see the benefit of that, but since this is looping relatively rarely and performing very few actions, I'm not that worried about performance. I'm also leery of having features which require a working database to function, and that probably wouldn't pass muster upstream.

var/datum/money_account/max_profit = all_money_accounts[1]
var/datum/money_account/max_loss = all_money_accounts[1]
for(var/datum/money_account/D in all_money_accounts)
if(SSmoney_accounts.all_glob_accounts.len)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally use length() instead of len.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will be fixed, as other instances.

var/account_type = ACCOUNT_TYPE_PERSONAL
var/currency

var/list/pending_modifications = list() // Modifications pending for the account.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be a good idea to make this a lazy list?

source_name = get_source_name()

target = null
source = null
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Won't this cause issues if anything calls valid() on this after perform()?
It seems to me the handling of refs for transactions is making some pretty big assumptions. There's a small timeframe when you essentially make the transaction datum unusable. (Because target and source are nulled out, and everything expects them to be set.)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is correct, and for the most part intentional. Once a transaction is finalized, you should never need to check if its valid again. It only remains for logging purposes. I'd say that calling valid() after perform() is always invalid.

if(prob(50))
if(all_money_accounts.len)
winner_account = pick(all_money_accounts)
if(SSmoney_accounts.all_glob_accounts.len)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

better use length()

@PsyCommando PsyCommando merged commit eded23e into PersistentSS13:dev Mar 1, 2023
@PsyCommando PsyCommando linked an issue Mar 9, 2023 that may be closed by this pull request
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🆕 enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Banking rework

2 participants