Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
113 changes: 113 additions & 0 deletions ARCs/arc-1594.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
---
arc: 1594
title: Core Security Token Operations
description: Issuance, redemption, and validation primitives for Algorand security tokens
author: Ludovit Scholtz (@scholtz)
discussions-to: https://github.com/algorandfoundation/ARCs/discussions
status: Draft
type: Standards Track
category: Interface
sub-category: Application
created: 2025-09-03
requires: 88, 200
replaces:
---

# ARC-1594: Core Security Token Operations

## Abstract

ARC-1594 specifies core issuance, redemption, and transfer validation semantics for security tokens on Algorand. It provides deterministic pre-transfer checks and standardized status / error codes enabling wallets, exchanges, and compliance services to integrate with regulated token flows.

## Motivation

Security tokens require pre-trade eligibility checks (KYC/AML, jurisdiction, lock-up expirations) that are not expressible purely via permissionless transfers. ERC-1594 defines these on Ethereum; this ARC maps them to Algorand leveraging atomic transaction groups and AVM logic for predictable, low-latency enforcement.

## Specification

### Interfaces (ABI Recommendations)

(All method identifiers in snake*case with ARC-4 type signatures. ARC-1594 methods are namespaced with `arc1594*`. Simplification: this core profile drops explicit partition parameters; partition-aware functionality is delegated to ARC-1410.)

- `arc1594_issue(to: address, amount: uint256, data: bytes)`
- `arc1594_redeem(amount: uint256, data: bytes)` (caller/self redemption)
- `arc1594_redeemFrom(from: address, amount: uint256, data: bytes)` (owner/governance or holder-authorized redemption)
- `arc1594_set_issuable(flag: bool)` (owner toggles global issuance enable switch)
- `arc1594_is_issuable() -> (flag: bool)` (readonly global issuance enable flag)
- `arc1594_transfer_with_data(to: address, amount: uint256, data: bytes)` (standard transfer emitting/accepting opaque metadata)
- `arc1594_transfer_from_with_data(from: address, to: address, amount: uint256, data: bytes)` (allowance/operator transfer with metadata)

Partitioned behavior (if needed) MUST be layered by simultaneously implementing ARC-1410; ARC-1594 then operates on the default/unrestricted partition implicitly.

Note: Per-account KYC / lockup admin setter methods have been removed from the core; such compliance layers MAY be specified by an extension ARC to keep ARC-1594 minimal.

### Codes

Return codes:

- `0` Success
- `10` SenderNotEligible
- `11` RecipientNotEligible
- `12` PartitionRestricted
- `13` AmountExceedsPartitionBalance
- `14` GlobalTransferHalted
- `15` LockupActive
- `16` DocumentDisclosureRequired
(Code 20 removed in partitionless core profile; unknown partition is handled by ARC-1410 layer.)
- `30` InvalidSignatureOrAuth
- `40` InternalError

Codes MUST be logged as the first 8 bytes of a log entry or written to a well-known box/state key `last-val-code` keyed by sender address. Reason strings are optional and SHOULD be UTF-8.

### State Model

Minimum required state keys / boxes:

- Global: `halt` (uint64; 1 = transfers disabled except controller)
- Local (per investor): `kyc` (uint64; 1 = eligible), `lockup-until` (uint64; round or timestamp), optional jurisdiction code `jur` (uint64)
- Boxes (optional extended): `elig-<addr>` for arbitrary packed compliance flags.

### Authorization

Issuance / Redemption MUST be restricted to governance authority (Issuer) or delegated operators (multi-sig, logic signature) recorded in global state keys (`issuer`, `operator-<n>`). Validation is permissionless but enforces rules.

### Events (Logging Conventions)

Implementations SHOULD log compact structured events (CBOR or msgpack) for indexing:

- arc1594_issue: tag 0x01 | addr | amount | partition (partition omitted in core partitionless profile)
- arc1594_redeem: tag 0x02 | addr | amount | partition (partition omitted in core partitionless profile)

### Failure Semantics

If validation fails, the subsequent ARC-200 transfer MUST fail or be omitted. No partial state changes should misrepresent balances.

## Security Considerations

- Ensure replay protection: include group ID or txn ID in validation ephemeral state so old approvals can't be reused.
- Prevent redemption of locked or escrowed partitions unless explicitly allowed.
- Use constant-time comparisons for signature attestations if verifying off-chain oracle attestations.

## Reference Types

Suggested canonical encoding for address lists in boxes: msgpack array of raw 32-byte addresses.

## Compliance Oracle Pattern (Optional)

An oracle signs `(from, to, amount, partition, round, expiryRound)`; contract verifies signature against authorized oracle key, bypassing on-chain local flags where policy allows.

## Backwards Compatibility

Can coexist with a plain ARC-200 token; if wallet ignores validation flow, controller enforcement can still reverse unauthorized transfers (with ARC-1644) though this is discouraged for UX predictability.

## Reference Implementation

[arc1594.algo.ts](https://github.com/scholtz/arc-1400/blob/main/projects/arc-1400/smart_contracts/security_token/arc1594.algo.ts)

## Rationale

Partition-independent core keeps minimal surface, delegating complexity to optional ARCs (1410, 1643, 1644) for modular adoption.

## Copyright

CC0 1.0 Universal.
Loading