Every payment Remlo broadcasts on Tempo carries a 32-byte memo encoded in the TIP-20 format. The memo binds an on-chain transfer to a specific employer, employee, pay period, cost center, and accounting record. Compliance and indexing pipelines read it without parsing tx logs.Documentation Index
Fetch the complete documentation index at: https://docs.remlo.xyz/llms.txt
Use this file to discover all available pages before exploring further.
32-byte structure
| Bytes | Purpose | Description |
|---|---|---|
| 0–3 | Message type | 4 ASCII chars. paic (0x70616963) for pain.001 payroll, ybnu for yield bonus, etc. |
| 4–11 | Employer ID | First 8 bytes of the employer UUID (hyphens stripped, hex-decoded) |
| 12–19 | Employee ID | First 8 bytes of the employee UUID |
| 20–23 | Pay period | Packed big-endian uint32. Layout: (year << 16) | (month << 8) | day |
| 24–27 | Cost center | Big-endian uint32. Internal accounting code, defaults to 0 |
| 28–31 | Record hash | First 4 bytes of SHA-256 over the off-chain payroll record |
lib/memo.ts. Encoding is pure (no async, no DB). Decoding inverts the same layout. The off-chain DB stores memo_bytes as Postgres bytea so memo bytes round-trip without lossy text encoding.
For a payment in the pain.001 message type:
What the memo is for
Compliance pipelines index payments by(employerId, employeeId, payPeriod) to produce monthly reports without needing to maintain a separate off-chain ledger. The on-chain log is the source of truth.
Treasury reconciliation uses the record hash to confirm that a settled on-chain transfer matches the payroll run row in Supabase. A mismatch means a disagreement between intent and execution; the dashboard surfaces this as a yellow status badge.
Audit trails for jurisdictions that require structured payment metadata get a deterministic, machine-readable artifact attached to every transfer at the protocol level.
Decoding a memo
Agents and indexers can decode memos via the MPP API:TIP-403 compliance policies
Tempo’s TIP-403 standard exposes a precompile-style registry that maps(policyId, wallet) to bool authorized. Remlo’s EmployeeRegistry reads this registry when an employer registers a new employee under a policy ID, and reverts the registration if the wallet isn’t cleared.
Most demo employers default to policyId = 0, which skips the check. Production employers in regulated jurisdictions bind a real policy ID and use the registry as a sanctions filter at registration time, not at every payment.
The policy enforcement runs at the EmployeeRegistry layer (registration), not at the PayrollBatcher layer (payment), because the same wallet shouldn’t have to re-prove sanctions clearance on every payroll run. Policy state can change (a wallet gets sanctioned mid-employment). When that happens, the registry returns false, the dashboard shows the employee as kyc_status = blocked, and PayrollBatcher’s optional H-4 path catches it via EmployeeRegistry.isEmployedBy (which combines active state and employer membership).