diff --git a/Cargo.toml b/Cargo.toml index b86783bb..7cc8e957 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,7 @@ resolver = "2" [workspace.package] authors = ["The Aha Company"] edition = "2024" -license = "Apache-2.0" +license = "MIT" repository = "https://github.com/theahaco/scaffold-stellar" version = "0.0.1" description = "PayD — Decentralized payroll and payment platform on Stellar/Soroban" diff --git a/LICENSE b/LICENSE index 261eeb9e..6efb918e 100644 --- a/LICENSE +++ b/LICENSE @@ -1,201 +1,21 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. +MIT License + +Copyright (c) 2026 The Aha Company + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/contracts/bulk_payment/src/lib.rs b/contracts/bulk_payment/src/lib.rs index d638a7f7..a0cfc562 100644 --- a/contracts/bulk_payment/src/lib.rs +++ b/contracts/bulk_payment/src/lib.rs @@ -91,6 +91,21 @@ pub struct ContractStatusChangedEvent { pub admin: Address, } +/// Emitted when an all-or-nothing batch completes successfully. +#[contractevent] +pub struct BatchExecutedEvent { + pub batch_id: u64, + pub total_sent: i128, +} + +/// Emitted when a partial batch completes (some payments may have been skipped). +#[contractevent] +pub struct BatchPartialEvent { + pub batch_id: u64, + pub success_count: u32, + pub fail_count: u32, +} + // ── Storage types ───────────────────────────────────────────────────────────── #[contracttype] @@ -395,14 +410,15 @@ impl BulkPaymentContract { // Single transfer of total amount to escrow token_client.transfer(&sender, ¤t_contract, &total); - // Distribute from escrow to recipients + let batch_id = Self::next_batch_id(&env); + + // Distribute from escrow to recipients and emit per-payment events for op in payments.iter() { token_client.transfer(¤t_contract, &op.recipient, &op.amount); + PaymentSentEvent { recipient: op.recipient.clone(), amount: op.amount }.publish(&env); } Self::record_usage(&env, &sender, total); - - let batch_id = Self::next_batch_id(&env); let record = BatchRecord { sender, token, diff --git a/contracts/vesting_escrow/src/lib.rs b/contracts/vesting_escrow/src/lib.rs index 8bf3a21c..3d4ade44 100644 --- a/contracts/vesting_escrow/src/lib.rs +++ b/contracts/vesting_escrow/src/lib.rs @@ -1,5 +1,5 @@ #![no_std] -use soroban_sdk::{contract, contractimpl, contracttype, token, Address, Env, String}; +use soroban_sdk::{contract, contractimpl, contracttype, contractevent, token, Address, Env, String}; #[contracttype] #[derive(Clone)] @@ -24,6 +24,35 @@ pub enum DataKey { LastClawbackLedger, } +// ── Events ──────────────────────────────────────────────────────────────────── + +/// Emitted when the vesting escrow is successfully funded and configured. +#[contractevent] +pub struct VestingInitializedEvent { + pub beneficiary: Address, + pub token: Address, + pub total_amount: i128, + pub cliff_seconds: u64, + pub duration_seconds: u64, + pub start_time: u64, +} + +/// Emitted when the beneficiary successfully claims vested tokens. +#[contractevent] +pub struct TokensClaimedEvent { + pub beneficiary: Address, + pub amount: i128, + pub total_claimed: i128, +} + +/// Emitted when the clawback admin terminates the grant early. +#[contractevent] +pub struct ClawbackExecutedEvent { + pub clawback_admin: Address, + pub unvested_returned: i128, + pub vested_remaining: i128, +} + const PERSISTENT_TTL_THRESHOLD: u32 = 20_000; const PERSISTENT_TTL_EXTEND_TO: u32 = 120_000; @@ -88,10 +117,19 @@ impl VestingContract { e.storage().persistent().set(&DataKey::Config, &config); Self::bump_config_ttl(&e); - + // Transfer tokens from funder to contract let client = token::Client::new(&e, &token); client.transfer(&funder, &e.current_contract_address(), &amount); + + VestingInitializedEvent { + beneficiary, + token, + total_amount: amount, + cliff_seconds, + duration_seconds, + start_time, + }.publish(&e); } pub fn claim(e: Env) { @@ -118,6 +156,12 @@ impl VestingContract { // Transfer tokens let client = token::Client::new(&e, &config.token); client.transfer(&e.current_contract_address(), &config.beneficiary, &claimable); + + TokensClaimedEvent { + beneficiary: config.beneficiary, + amount: claimable, + total_claimed: config.claimed_amount, + }.publish(&e); } pub fn clawback(e: Env) { @@ -150,6 +194,14 @@ impl VestingContract { let client = token::Client::new(&e, &config.token); client.transfer(&e.current_contract_address(), &config.clawback_admin, &unvested); } + + // vested_remaining = vested - already_claimed (still held in contract for beneficiary) + let vested_remaining = vested - config.claimed_amount; + ClawbackExecutedEvent { + clawback_admin: config.clawback_admin, + unvested_returned: unvested, + vested_remaining, + }.publish(&e); } pub fn get_vested_amount(e: Env) -> i128 { diff --git a/docs/whitepaper.md b/docs/whitepaper.md new file mode 100644 index 00000000..7e653af4 --- /dev/null +++ b/docs/whitepaper.md @@ -0,0 +1,276 @@ +# PayD Protocol — Technical Whitepaper + +**Version:** 1.0.0 +**Date:** 2026 +**License:** MIT + +--- + +## Abstract + +PayD is a decentralized cross-border payroll protocol built on the Stellar network and Soroban smart contract platform. It replaces legacy correspondent-banking rails with on-chain settlement, reducing international payment latency from 2–5 business days to sub-5 seconds while cutting transfer fees from 5–15% to a fraction of a cent. This document describes the protocol architecture, smart contract design, token model, and security properties. + +--- + +## 1. Problem Statement + +Traditional international payroll suffers from four structural deficiencies: + +| Problem | Impact | +|---|---| +| Correspondent-bank chains | 2–5 day settlement windows | +| SWIFT + intermediary fees | 5–15% per transfer | +| Opaque FX conversion | Unpredictable effective rates | +| No cryptographic proof | Disputes require manual reconciliation | + +These costs are disproportionately borne by workers in emerging markets who rely on cross-border employment. PayD eliminates each category through on-chain settlement and programmable disbursement logic. + +--- + +## 2. Network Layer — Stellar + +PayD is deployed on Stellar because it provides: + +- **~3–5 second finality** — deterministic, single-round consensus (SCP) +- **~$0.00001 per operation** — negligible transaction cost at scale +- **Native multi-asset support** — custom asset issuance without ERC-20 overhead +- **Anchor ecosystem** — SEP-006/SEP-024 compliant on/off ramps for 100+ fiat corridors +- **Soroban** — a WASM smart contract VM for programmable payment logic + +### 2.1 Stellar Consensus Protocol (SCP) + +SCP is a federated Byzantine agreement protocol. Each node defines a *quorum slice* — a subset of peers it trusts. Safety is guaranteed when quorum slices overlap sufficiently; liveness depends on quorum intersection properties across the network. PayD relies on Stellar's public network with Tier-1 validators (SDF, Lobstr, Blockdaemon, etc.) for finality guarantees. + +--- + +## 3. Asset Model + +Each organization deploying PayD issues an **organization-scoped stable asset** (e.g. `ORGXUSD`) backed 1:1 with a reference currency held in a regulated custodian account. + +``` +Employer (funder) + │ + │ fund(amount) + ▼ +Distribution Account ──── trustline ──── Employee Wallet + │ + │ bulk_payment / vesting_escrow + ▼ +Stellar Network ──── anchor ──── Local Bank / Mobile Money +``` + +### 3.1 Trustlines + +Employees must establish a Stellar *trustline* to the organization asset before receiving payments. PayD's onboarding flow automates this step via a wallet deep-link. + +### 3.2 Anchors (SEP-006 / SEP-024) + +Anchors are regulated entities that convert Stellar assets to local fiat. PayD integrates anchor APIs at the employee portal layer; the smart contracts are anchor-agnostic — they only deal with on-chain asset transfers. + +--- + +## 4. Smart Contract Architecture + +All PayD contracts are written in Rust targeting the Soroban WASM VM. They share common patterns: + +- **Persistent storage** for long-lived state (configurations, balances) +- **Temporary storage** for short-lived batch records +- **`require_auth()`** guards on every state-mutating entry point +- **TTL extension** to prevent ledger archival of active contract state +- **Ledger-sequence replay protection** to prevent duplicate execution + +### 4.1 BulkPayment Contract + +Handles payroll disbursement to up to 100 employees per transaction envelope. + +**Entry points:** + +| Function | Description | +|---|---| +| `initialize(admin)` | Sets contract admin; callable once | +| `execute_batch(sender, token, payments, seq)` | All-or-nothing batch; reverts on any invalid amount | +| `execute_batch_partial(sender, token, payments, seq)` | Best-effort batch; skips invalid entries | +| `execute_batch_v2(…, all_or_nothing)` | Unified entry with per-payment `PaymentEntry` records | +| `refund_failed_payment(batch_id, idx)` | Returns held funds for a `Failed` entry to the sender | +| `set_account_limits(account, daily, weekly, monthly)` | Admin-configurable spend limits per account | +| `set_paused(paused)` | Circuit breaker — suspends all batch operations | + +**Event log (issue #161):** + +| Event topic | Payload | Emitted when | +|---|---|---| +| `batch_executed` | `batch_id, total_sent` | All-or-nothing batch succeeds | +| `batch_partial` | `batch_id, success_count, fail_count` | Partial batch completes | +| `payment` | `recipient, amount` | Individual payment is sent | +| `skipped` | `recipient, amount` | Individual payment is skipped | +| `bonus` | `category, recipient, amount` | Bonus-category payment is sent | +| `refund` | `batch_id, idx, sender, amount` | Failed payment is refunded | +| `paused` | `paused, admin` | Contract is paused or unpaused | +| `limits` | `account, daily, weekly, monthly` | Account limits are updated | + +**Sequence number management:** +Every batch call takes an `expected_sequence` parameter. The contract stores a monotonically incrementing counter and rejects calls where `expected_sequence ≠ current`. This prevents concurrent submissions from racing on the same nonce. + +**Rate limiting:** +Per-account daily/weekly/monthly caps are enforced using ledger-count windows (1 day ≈ 17,280 ledgers at 5s close time). A cap of `0` means unlimited. + +### 4.2 VestingEscrow Contract + +Holds salary in on-chain escrow and releases it according to a programmable vesting schedule. Designed for contractor grants, executive salary, and team token distributions. + +**Vesting model:** + +``` +Amount + │ ┌──────────── total_amount + │ ╱ + │ ╱ + │ ╱ + │ ╱ + │ ╱ + │ 0 vested ╱ linear vesting after cliff + │ │ + ├───────────┼───────────────────────────────── time + cliff_seconds start + duration_seconds +``` + +- **Cliff:** No tokens vest before `start_time + cliff_seconds`. At the cliff, `cliff_seconds / duration_seconds * total_amount` immediately becomes claimable. +- **Linear vesting:** After the cliff, tokens vest proportionally to time elapsed. +- **Clawback:** The `clawback_admin` can terminate the grant at any time. Vested tokens remain claimable by the beneficiary; unvested tokens are returned to the admin. + +**Entry points:** + +| Function | Description | +|---|---| +| `initialize(funder, beneficiary, token, start_time, cliff_seconds, duration_seconds, amount, clawback_admin)` | Fund and configure the escrow; callable once | +| `claim()` | Beneficiary withdraws all currently claimable tokens | +| `clawback()` | Admin terminates grant; returns unvested portion | +| `get_vested_amount()` | Query total vested (including already-claimed) | +| `get_claimable_amount()` | Query unclaimed vested balance | +| `get_config()` | Read full `VestingConfig` | + +**Events emitted:** + +| Event | Key fields | Emitted on | +|---|---|---| +| `vesting_initialized` | `beneficiary, token, total_amount, cliff_seconds, duration_seconds, start_time` | Successful `initialize` | +| `tokens_claimed` | `beneficiary, amount, total_claimed` | Successful `claim` with `claimable > 0` | +| `clawback_executed` | `clawback_admin, unvested_returned, vested_remaining` | Successful `clawback` | + +**Replay protection:** +`claim` and `clawback` record the last processed ledger sequence. A second call in the same ledger sequence panics, preventing transaction-resubmission exploits. + +### 4.3 CrossAssetPayment Contract + +Performs path-payment swaps (Stellar's built-in DEX routing) before disbursement. Useful when the employer holds USDC but employees need local stable assets. + +### 4.4 RevenueSplit Contract + +Distributes incoming payments to a fixed list of recipients at predefined percentage shares. Used for contractor pools and DAO treasury splits. + +--- + +## 5. Security Model + +### 5.1 Authorization + +Every externally-callable entry point that mutates state calls `address.require_auth()`. Soroban enforces that the authorization is provided in the transaction's auth envelope — there is no implicit `msg.sender` as in EVM. + +### 5.2 Overflow Protection + +All arithmetic uses checked operations (`checked_add`, `checked_mul`, `checked_div`) and returns an error on overflow rather than wrapping. + +### 5.3 Replay / Double-Execution Protection + +- **Batch contracts:** Global sequence counter + per-sender last-ledger tracking +- **Vesting contract:** Per-operation last-ledger tracking (`LastClaimLedger`, `LastClawbackLedger`) + +### 5.4 Circuit Breaker + +`BulkPayment` includes an admin-controlled pause flag. When paused, all `execute_batch*` calls return `ContractPaused`. Administrative functions remain accessible so the admin can investigate and resume. + +### 5.5 TTL / Archival Risk + +Soroban ledger entries expire. PayD contracts extend TTL on every write and expose a `bump_ttl()` admin function for proactive renewal of idle contracts. + +--- + +## 6. Off-Chain Components + +### 6.1 Backend API + +A Node.js/TypeScript REST service that: +- Manages employee records and wallet mappings +- Schedules recurring payroll runs +- Submits signed transactions to Horizon +- Indexes emitted contract events into a PostgreSQL ledger + +### 6.2 Frontend Dashboard + +A React/TypeScript SPA that provides: +- Employer payroll management (add/remove employees, CSV upload) +- Real-time batch status tracking via WebSocket +- Employee payment history and anchor withdrawal flows +- Gamification layer (XP, levels) to incentivize on-time repayment in lending scenarios + +### 6.3 Event Indexer + +Polls Horizon `/transactions` and `/effects` endpoints, decodes Soroban `contractEvents`, and writes structured records to the database. Drives analytics dashboards and webhook notifications. + +--- + +## 7. Protocol Flow + +### 7.1 Standard Monthly Payroll + +``` +1. Employer approves ORGXUSD allowance to BulkPayment contract +2. Backend builds Vec from employee database +3. Backend signs and submits execute_batch_v2(all_or_nothing=true) +4. Soroban: validates all amounts, transfers sender → each recipient +5. Contract emits PaymentSentEvent per recipient + BatchExecutedEvent +6. Indexer picks up events; dashboard updates in real time +7. Employees receive ORGXUSD; optionally withdraw via anchor to local bank +``` + +### 7.2 Contractor Vesting Grant + +``` +1. HR initializes VestingEscrow with 12-month duration, 3-month cliff +2. Contractor's address set as beneficiary; HR org as clawback_admin +3. On cliff date: contractor calls claim(); receives 3/12 of grant +4. Monthly thereafter: contractor calls claim(); receives proportional slice +5. If contractor leaves early: HR calls clawback(); unvested returned to org +``` + +--- + +## 8. Compliance Considerations + +- All on-chain transfers are publicly auditable on Stellar's ledger +- Organizations are responsible for KYC/AML on the employer side +- Anchor partners handle KYC/AML for the employee fiat off-ramp +- PayD contracts do not custody fiat; they only move on-chain assets +- The MIT license permits commercial use without restriction + +--- + +## 9. Roadmap + +| Milestone | Description | +|---|---| +| v1.0 | BulkPayment + VestingEscrow + REST API + React dashboard | +| v1.1 | Multi-currency path payments via CrossAssetPayment | +| v1.2 | Revenue split contract + DAO treasury integration | +| v2.0 | Multi-tenant organizations, RBAC, audit log export | + +--- + +## 10. References + +- [Stellar Developer Docs](https://developers.stellar.org) +- [Soroban Smart Contracts](https://soroban.stellar.org) +- [SEP-006: Deposit and Withdrawal API](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0006.md) +- [SEP-024: Hosted Deposit and Withdrawal](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0024.md) +- [SEP-034: Contract Metadata](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0034.md) +- [Stellar Consensus Protocol (SCP)](https://www.stellar.org/papers/stellar-consensus-protocol)