Skip to content

Add Soroban test-stablecoin with OpenZeppelin freeze support#55

Closed
alex-predicate wants to merge 7 commits intomainfrom
feat/soroban-test-stablecoin
Closed

Add Soroban test-stablecoin with OpenZeppelin freeze support#55
alex-predicate wants to merge 7 commits intomainfrom
feat/soroban-test-stablecoin

Conversation

@alex-predicate
Copy link
Copy Markdown
Contributor

Summary

  • Soroban token contract for validating the asset compliance flow (Track 1)
  • Built on OpenZeppelin Stellar Contracts 0.6.0 — audited FungibleToken, BlockList, FungibleBurnable, and AccessControl traits
  • SAC-compatible with 6 decimals, admin-controlled minting, and manager-role blocklist enforcement

Contract interface

Function Access Description
transfer, approve, allowance, balance, etc. Public Standard SEP-41 token ops (auto-provided by OZ)
mint(to, amount) Admin Create new tokens
block_user(user, operator) Manager Block account from all token operations
unblock_user(user, operator) Manager Restore account access
blocked(account) Public Check if account is blocked
burn(from, amount) Token holder Destroy tokens (blocked users cannot burn)

How to test

cd soroban && cargo test

13 tests covering constructor, mint, transfer, block/unblock, blocked-transfer, blocked-approve, transfer_from, burn, and burn-from-blocked scenarios.

What's next

Track 2 (application compliance) — predicate-registry and predicate-client contracts — will come in a follow-up PR on the feat/soroban-contracts branch.

🤖 Generated with Claude Code

alex-predicate and others added 3 commits March 24, 2026 18:46
Design document for adding Soroban (Stellar) smart contracts:
predicate-registry, test-stablecoin, and predicate-client library.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
7-task plan covering workspace scaffolding, predicate-client types,
predicate-registry contract, test-stablecoin, integration tests,
CI/CD updates, and final verification.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
SAC-compatible Soroban token built on OpenZeppelin Stellar Contracts 0.6.0:
- FungibleToken with BlockList extension (blocks transfers, approvals, burns)
- FungibleBurnable for token destruction
- AccessControl with "manager" role for compliance admin
- 6 decimals, admin-controlled minting
- 13 tests covering all token operations and block enforcement

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown

@claude claude bot left a comment

Choose a reason for hiding this comment

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

⚠️ Code review skipped — your organization's overage spend limit has been reached.

Code review is billed via overage credits. To resume reviews, an organization admin can raise the monthly limit in Settings → Usage.

Once credits are available, reopen this pull request to trigger a review.

alex-predicate and others added 3 commits March 24, 2026 23:21
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor Author

@alex-predicate alex-predicate left a comment

Choose a reason for hiding this comment

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

Good work overall — clean contract, well-composed OZ building blocks, solid test coverage. A few items to address, mostly around test gaps and housekeeping. See inline comments.

#![no_std]

use soroban_sdk::{
contract, contracterror, contractimpl, symbol_short, Address, Env, MuxedAddress, String,
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Unused imports: MuxedAddress, Symbol, and Vec are imported but unused. These will likely trigger compiler warnings.

Suggested change
contract, contracterror, contractimpl, symbol_short, Address, Env, MuxedAddress, String,
contract, contracterror, contractimpl, symbol_short, Address, Env, String,

soroban-sdk = "23.5.3"
stellar-tokens = "0.6.0"
stellar-access = "0.6.0"
stellar-macros = "0.6.0"
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

stellar-macros does not appear to be used directly in the source. If the OZ traits pull it in transitively, this explicit dependency is unnecessary.

doctest = false

[dependencies]
soroban-sdk = "23.5.3"
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

SDK version mismatch with spec: The design spec references soroban-sdk 25.3.0, but this pins 23.5.3. If 23.5.3 is the correct version for OZ 0.6.0 compatibility, that's fine — but the spec should be updated to reflect the actual version used.

#[test]
fn test_constructor() {
let e = Env::default();
e.mock_all_auths();
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

All tests use mock_all_auths(), which bypasses all auth checks at the SDK level. This means enforce_admin_auth, require_auth, and ensure_role are never truly exercised.

Consider adding at least 1-2 tests that use e.mock_auths() with specific authorizations instead, to verify the auth requirements are wired correctly.

// Transfer works after unblock
client.transfer(&admin, &user, &100i128);
assert_eq!(client.balance(&user), 100i128);
}
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Missing negative test: non-manager cannot block. This is the most security-critical access control boundary in the contract. Add a test that asserts a non-manager address calling block_user panics.

Similarly, there's no test that a non-admin calling mint is rejected. These two negative auth tests would significantly strengthen coverage.


- name: Cache cargo
uses: actions/cache@v3
with:
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

actions/cache@v3 is deprecated — GitHub recommends v4. The existing Foundry jobs don't use cache actions at all, so this would be the only v3 reference in the workflow.

Suggested change
with:
uses: actions/cache@v4

- Remove unused stellar-macros dependency
- Add comment explaining why MuxedAddress/Symbol/Vec imports are needed
  (OZ macro expansions require them)
- Add comment explaining soroban-sdk 23.5.3 pin (OZ 0.6.0 compatibility)
- Upgrade actions/cache@v3 to v4
- Add auth tests: non-admin cannot mint, non-manager cannot block

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@alex-predicate alex-predicate deleted the feat/soroban-test-stablecoin branch March 24, 2026 21:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant