***Slack Channel** - #pfi*
***Status** – WIP*
***Author** – plew*
# **Overview**
A core functionality of our PFI is moving money. Initially, we will support transacting with USD, USDC, and MXN. For a financial institution, considerations around money movements can be divided into two broad areas:
1. Payment rails which facilitate the movement itself
2. Supporting infrastructure to satisfy requirements from accounting, treasury, and audit
This doc outlines the main components required to launch our [production PFI](https://docs.google.com/document/d/1PNQWNqPzHIYihM7NAuxFbQXnbJUHMEXR_hOyktZZ16c/edit) in Q4.
An overarching principle is to optimize our design for satisfying our short term requirements while remaining extensible enough to iterate on in the future.
# **Goals**
- FTL module architecture specificity
- domain modeling
- identify data required for accounting and audit requirements
- overview of ledger interactions
# **Non-Goals**
TODO refine
- Detailed data modeling
- Automate treasury operations
- Post-processing of audit data
# Components
- Exchange state machine
- Payment rail integrations
- Ledgering + fees
## Adjacent Functions
- Pricing engine
- Treasury management
# Requirements
- **Support institutional, retail, and self custody customers**
- **Global extensibility**
- The architecture should not assume that the system will always be limited to USD, USDC, and MXN, i.e no hard coded currencies, lock-in to regions, etc.
- Multi-currency exchanges are a first class citizen
- **Minimally viable design**
- **We have a mechanism for maintaining data for historic audit purposes**
# Design
## PFI Payment Platform

## Component Modules
### Payment state machine
All exchanges consist of two sides - a payin and a payout. Each of the sides can succeed/fail in different ways depending on the payment/currency rail. The exchange state machine keeps track of what state of processing the exchange is in, and triggers the necessary next transitions.
#### Domain Models
- exchanges
- payin
- payout
Note: payin/payout could be collapsed into one table like "movements" or something
### Ledger
Ledger is the source of truth for all money movements.
It can have more than one layer of abstraction, since a software ledger is inherently already abstracted from the underlying physical bank accounts or wallets which hold the assets. We may choose to have an instance of a ledger which contains all customer exchange related entries, and another which models the underlying internal accounts and treasury settlements between them.
Account balance checks for custodied funds (either on behalf of a retail or institutional customer) happen against ledger data. Customers who have insufficient funds to cover a transaction should not be allowed to proceed with the exchange.
TODO where are we tracking OUR float balances with partners?
The ledger will be used for rudimentary reconciliation processes, which will simply be SQL queries run against the DB or the ledgering data replicated to a data warehouse for now. At a high level, they will consist of totalling transaction volume by currency and payment method (e.g, MXN via Bitso, MXN via Bankaya, USDC via Circle). This report can be manually reconciled against transaction data pulled directly from partners.
#### Fees
TODO write this section
#### Domain Models
- ledger entries/transactions
Consumers of ledger data:
- risk (ML and limits)
- treasury
### Payment rails
Each payment processor has its own module for the integration. It abstracts the partner API and handles incoming notifications/webhooks. It may make sense to have a "routing" layer as the number of partners and currencies increases. For example, if there are two providers for MXN, we can dynamically modify what % of remittance traffic gets sent to which provider.
#### Domain Models
- internal representation of external transaction, OR none and these modules call ledger to add the external id
## Mapping Funds Flows
1. **USDC on chain -> MXN retail**
- customer transfers USDC to tbd's circle wallet address
- monitor circle wallet for incoming txn
- once landed, send MXN to recipient
2. **USDC stored balance -> MXN retail/instutional**
- deduct USDC from customer stored balance
- send MXN to recipient
3. **USDC -> MXN self custody**
- customer transfers USDC to tbd's circle wallet address
- monitor circle wallet for incoming txn
- once landed, send MXN to recipient
4. **MXN -> USDC on chain retail**
- pull from debit card or bank account
- funds settle into TBD bitso balance
- USDC pay out to customer address
5. **MXN -> USDC stored balance retail/institutional**
- pull from debit card or bank account
- funds settle into TBD bitso balance
- USDC book transfer into customer stored balance
6. **USD -> USDC self custody**
- pull from debit card or bank account
- funds settle into TBD square merchant account
- USDC on chain transfer to self custody wallet address
TODO will we allow a custodied retail customer to execute an exchange when their stored balance is insufficient? this would pull directly from a debit card/bank account. We can either do a ledger entry to credit their stored balance and immediately deduct, or we can have it bypass their stored balance entirely.
Note: for a custodial retail customer topping up their stored balance, we should not store card/bank details as it creates more DSG complexity. (Possibly a separate question for didpay in case we don't want customer to reenter card/bank details every time.)
## Pricing
## Data warehousing strategy
Two primary data sinks for the Q4 system:
1. risk and trust
2. snowflake/other data warehouse (to satisfy auditing requirements)
We will use [FTL pubsub](https://hackmd.io/@ftl/HyDTmzMdp) to publish PFI data to topics, which can then be directed to Risk ML's preferred data storage.
TODO find out if easiest to use an existing data warehouse at Block (i.e snowflake) or if we want to do something else
# Security Considerations
TODO fill out
*What sensitive data does this feature collect or use that is pre-existing?*
| Sensitive Data | http://go/dsl | External Access? | Sensitivity | Why? |
| ----------------------- | ------------- | ---------------- | ------------- | ----------------------------- |
| customer/balance tokens | 2/3 | personal data | transactions tied to balances |
| | | | | |
# Tasks
- [DRI] link this document on Slack Channel
- *This is intended to provide a high level view of tasks.*
- *Should give the reader a sense of scope.*
- *Should this be two separate one-pagers? Maybe a design doc? The size and number of tasks might help guide this decision.*
# **Open Questions**
*What else is being considered?*
*Over time, these should become resolved or answered.*