diff --git a/IMPLEMENTATION_SUMMARY.md b/IMPLEMENTATION_SUMMARY.md deleted file mode 100644 index ce2de565..00000000 --- a/IMPLEMENTATION_SUMMARY.md +++ /dev/null @@ -1,64 +0,0 @@ -# Implementation Summary - -This document summarizes the implementation of the four GitHub issues: - -## Issue #179 - Reentrancy Guards - -**Changes Made:** -- Created `contracts/token/src/reentrancy_guard.rs` module with comprehensive reentrancy protection -- Added reentrancy guard checks to 20+ state-modifying functions in token contract -- Implemented `enter()` and `exit()` methods with proper storage management -- Added `require_not_entered()` macro for easy integration - -**Files Modified:** -- `contracts/token/src/lib.rs` (added module import and function guards) -- `contracts/token/src/reentrancy_guard.rs` (new file) - -## Issue #180 - Rate Limiting - -**Changes Made:** -- Created `contracts/rate-limit/` directory with complete rate limiting contract -- Implemented both global and per-address rate limits with configurable time windows -- Integrated rate limiting into mint, transfer, transfer_from, burn, and burn_from operations -- Added configuration functions for setting rate limits - -**Files Modified:** -- `contracts/rate-limit/Cargo.toml` (new file) -- `contracts/rate-limit/src/lib.rs` (new file) -- `contracts/token/Cargo.toml` (added dependency) -- `contracts/token/src/lib.rs` (added module import and function guards) -- `contracts/token/src/rate_limit.rs` (new file) - -## Issue #181 - Fuzz Testing - -**Changes Made:** -- Enhanced `contracts/token/src/proptest.rs` with additional tests for reentrancy protection and rate limiting -- Added comprehensive core invariant testing -- Improved test coverage for edge cases and failure scenarios - -**Files Modified:** -- `contracts/token/src/proptest.rs` (updated) - -## Issue #182 - E2E Tests - -**Changes Made:** -- Created `e2e/` directory with end-to-end integration tests -- Implemented complete lifecycle testing (deploy → init → mint → transfer → verify) -- Added parallel execution testing -- Created CI documentation and setup instructions - -**Files Modified:** -- `e2e/Cargo.toml` (new file) -- `e2e/integration_test.rs` (new file) -- `e2e/README.md` (new file) -- `README.md` (updated with new features and structure) - -## Branch Strategy - -Four separate branches will be created: -- `feature/179-reentrancy-guards` -- `feature/180-rate-limiting` -- `feature/181-fuzz-testing` -- `feature/182-e2e-tests` - -Each branch contains only the changes relevant to its respective issue. \ No newline at end of file diff --git a/PR_BODY.md b/PR_BODY.md deleted file mode 100644 index db433663..00000000 --- a/PR_BODY.md +++ /dev/null @@ -1,172 +0,0 @@ -# docs(admin): Add NatSpec documentation for has_role view function - -Adds comprehensive NatSpec documentation to the `has_role` function in the admin access-control module, completing the documentation effort tracked in #493. -# bc-forge: Full RBAC, Fee Management, Lifecycle, Rate Limiting, and Token Wrapper Implementation - -## Overview - -This PR consolidates the complete implementation of bc-forge's smart contract ecosystem across six Soroban contracts: **Admin (RBAC)**, **Token (SEP-41)**, **Lifecycle (Pause/Unpause)**, **Rate Limit**, **Wrapper**, and **Vesting**. All contracts are now integrated with role-based access control, fee management, pause guards, rate limiting, and comprehensive test coverage. - ---- - -## Contracts & Features - -### 1. Admin — Role-Based Access Control (`contracts/admin/src/lib.rs`) - -**Role Enum:** `Admin`, `Minter`, `SuperAdmin`, `Pauser` — with `Admin` implicitly inheriting all roles. - -**Core Functions:** -- `set_admin` / `get_admin` / `has_admin` — Admin lifecycle management -- `grant_role` / `revoke_role` — Role assignment (gated to SuperAdmin/Admin) -- `has_role` — Role lookup with zero-address guard and event emission -- `require_role` / `require_role_guard` — Access control guards that panic with `UnauthorizedRole` / `RoleNotHeld` / `InvalidRole` -- Named guards: `require_admin`, `require_minter`, `require_super_admin`, `require_fee_admin`, `require_pauser` -- `SUPER_ADMIN_ROLE` constant — Canonical reference for the SuperAdmin variant - -**Multi-sig / Proposals:** -- `set_admin_pool` / `get_admin_pool` / `get_threshold` — Multi-admin pool with threshold validation -- `create_proposal` / `approve_proposal` / `is_proposal_ready` / `mark_executed` — On-chain proposal workflow - -**Storage:** Instance-level singleton storage for admin, pool, and proposals; persistent storage per role/address with TTL extension. Unique `AdminKey` enum discriminants prevent slot collisions. - -### 2. Token — SEP-41 with Fee Management (`contracts/token/src/lib.rs`) - -**Fee Management:** -- `FeeConfig` (`base_fee`, `complexity_multiplier`, `max_fee`, `enabled`) with admin-only `set_fee_config` -- `set_treasury` / `get_treasury` — Fee collection address -- `set_fee_exemption` / `remove_fee_exemption` — Per-address fee exemptions - -**Mint & Supply:** -- `mint` — Minter-gated, checks pause state, rate limits, and `max_supply` -- `batch_mint` — Iterates recipients with per-address rate limiting -- `set_max_supply` / `get_max_supply` — Configurable supply cap (Minter-gated) - -**Other Entry Points:** -- `batch_transfer` — Single auth with total balance check -- `transfer_ownership` — Delegates to `admin::set_admin` -- `pause` / `unpause` / `pause_as` / `unpause_as` — Via `bc_forge_lifecycle` -- `upgrade` — WASM contract upgrade (SuperAdmin-gated) - -**Guards:** Pause check on all mutating operations; rate limits on mint/transfer/burn; reentrancy guard on mint, batch_mint, batch_transfer, approve. - -### 3. Lifecycle — Pause/Unpause (`contracts/lifecycle/src/lib.rs`) - -- `pause(env, caller)` — Pauser-gated; panics if already paused -- `unpause(env, caller)` — Pauser-gated; panics if not paused -- `is_paused(env)` — Returns paused state with TTL extension -- `require_not_paused(env)` — Panics with `"contract is paused"` - -### 4. Rate Limit (`contracts/rate-limit/src/lib.rs`) - -- Global and per-address rate limits keyed by operation type (e.g. `"mint"`, `"transfer"`) -- `set_global_rate_limit` / `set_address_rate_limit` — Admin-gated configuration -- `check_rate_limit` — Core logic with time-window auto-reset -- `internal_check_rate_limit` — Reusable core for cross-contract calls - -### 5. Wrapper — Token Wrapping (`contracts/wrapper/src/lib.rs`) - -- `initialize` — Sets admin, underlying token, decimals, name, symbol -- `wrap` — Pulls underlying tokens, mints scaled wrapper tokens (reentrancy-guarded) -- `unwrap` — Burns wrapper, transfers underlying back (reentrancy-guarded) -- Decimal scaling via `scale_to_wrapper` / `scale_to_underlying` -- Full SEP-41 `TokenInterface` impl (allowance, approve, balance, transfer, transfer_from, burn, burn_from) -- Pause/unpause via `bc_forge_lifecycle` - -### 6. Vesting — Vesting Schedules (`contracts/vesting/src/lib.rs`) - -- `initialize` — Sets token and admin -- `create_vesting` — Admin-only; mints tokens into vault -- `release` — Beneficiary-authorized; claims vested tokens -- `revoke` — Admin-only (revocable schedules only) -- `get_vesting_info` — Public query returning `Vec` with claimable amounts and revocation status -- Linear vesting with cliff support; cross-contract auth via `authorize_current_contract_call` - ---- - -## Cross-Cutting Concerns - -- **Reentrancy Guard:** Applied to all sensitive entry points via `reentrancy_guard!` macro -- **Storage TTL Extension:** All state mutations extend instance/storage TTL -- **Event Emission:** `role_grnt` and `role_rvk` events emitted on role changes -- **Zero-Address Guards:** Admin, role holders, and fee recipients validated against zero address -- **Fuzz Testing:** Added 8 proptest fuzz tests (100 iterations each) in `contracts/admin/src/tests/proptest.rs` that randomly generate all 4 `Role` variants and verify: - - | Test | Property Verified | - |------|-------------------| - | `fuzz_grant_role_every_variant` | Granting succeeds for every valid `Role` variant | - | `fuzz_grant_role_idempotent` | Granting the same role N times is idempotent | - | `fuzz_grant_role_multiple_roles` | Any subset of roles can be granted to the same address | - | `fuzz_grant_role_via_super_admin` | A SuperAdmin can delegate any role | - | `fuzz_grant_role_many_holders` | Granting to many distinct addresses — all hold the role | - | `fuzz_grant_role_emits_event` | `grant_role` emits a `role_grnt` event with correct data | - | `fuzz_grant_role_self_grant` | Self-grant works for SuperAdmin | - | `fuzz_admin_implicitly_has_all_roles` | Admin role implicitly grants all other roles | - ---- - -## Files Changed - -| File | Lines | -|------|-------| -| `contracts/admin/src/lib.rs` | +174 | -| `contracts/admin/src/tests/proptest.rs` | +161 (new) | -| `contracts/token/src/lib.rs` | +132 | -| `contracts/token/src/events.rs` | +39 (new) | -| `contracts/token/src/test.rs` | +92 | -| `contracts/lifecycle/src/lib.rs` | +69/- | -| `contracts/rate-limit/src/lib.rs` | +176 (new) | -| `contracts/wrapper/src/lib.rs` | +16 | -| `contracts/vesting/src/lib.rs` | +4 | -| `contracts/admin/Cargo.toml` | +1 | -| `contracts/lifecycle/Cargo.toml` | +1 | -| `contracts/rate-limit/Cargo.toml` | +1 | -| `sdk/src/client.ts` | +4 | -| Test snapshots (various) | +3,884 | -| `Cargo.lock` | +3 | -| `PR_BODY.md` | Updated | - ---- - -## Validation - -- [x] `cargo build` compiles all contracts -- [x] `cargo test` passes across workspace -- [x] `cargo fmt --all -- --check` passes -- [x] 8 proptest fuzz tests (100 iterations each) pass in `contracts/admin/src/tests/proptest.rs` -- [x] Test snapshots updated for all contract changes -- [x] No breaking changes to existing public APIs -# feat(admin): apply require_super_admin to revoke_role guard (#449) - -Closes #493 - -## Changes - -### `contracts/admin/src/lib.rs` -- **`has_role`**: Added a 40-line NatSpec doc comment block (`///`) covering: - - **Summary**: Read-only query returning `true` when an address holds a role - - **Authorization note**: Clarifies this is a non-enforcing query — use `require_role` / `require_role_guard` when authentication is needed - - **Admin Role Superset**: Documents that `Admin` role holders implicitly inherit all other roles, with a concrete code example - - **Zero Address**: Documents the `GAAAA…WHF` zero-address sentinel short-circuit - - **Events**: Documents the `role_chk` event emission with `(address, role, result)` data, enabling off-chain auditability - - **TTL**: Documents that persistent storage TTL is extended on access, but instance TTL is not bumped (pure read) - - **Panics**: Explicitly documents the non-panicking guarantee, including the uninitialized-contract case where all roles return `false` - -## Why - -The `has_role` view is the most frequently called query in the access-control layer — used by `require_role`, `require_role_guard`, and every role-specific guard (`require_admin`, `require_minter`, `require_super_admin`, `require_pauser`). Despite being central to the authorization model, it had no doc comments. This documentation makes the function's behavior (admin superset, zero-address handling, event emission, TTL behavior) discoverable via `cargo doc` and IDE hover. - -## Type of change -- [x] Docs - -## Checklist -- [x] I ran `cargo fmt` locally and verified formatting -- [x] I updated relevant docs / comments -- [x] No secrets or credentials are included -- [x] No breaking changes to public APIs -- [x] Follows existing NatSpec conventions in the file (see `get_admin`, `revoke_role`, `init_storage` for precedent) - -## Breaking changes? -No — documentation-only change. Zero code modifications. - -## Related issues -Closes #493 diff --git a/clippy.log b/clippy.log deleted file mode 100644 index ea3639f1..00000000 Binary files a/clippy.log and /dev/null differ diff --git a/e2e/test.rs b/e2e/test.rs deleted file mode 100644 index a26a585d..00000000 Binary files a/e2e/test.rs and /dev/null differ diff --git a/fix_tests.py b/fix_tests.py deleted file mode 100644 index 824776f5..00000000 --- a/fix_tests.py +++ /dev/null @@ -1,58 +0,0 @@ -import re - -with open("contracts/token/src/test.rs", "r") as f: - lines = f.readlines() - -out = [] -skip = False -for i, line in enumerate(lines): - if line.strip() == "fn test_accept_ownership_without_proposal_fails() {": - # we will rewrite this function to actually be valid - out.append(line) - out.append(" let env = Env::default();\n") - out.append(" env.mock_all_auths();\n") - out.append(" let (client, _) = setup_contract(&env);\n") - out.append(" let _admin = init_default(&env, &client);\n") - out.append(" client.accept_ownership();\n") - out.append("}\n") - skip = True - continue - - if skip: - if line.startswith("}"): - skip = False - continue - - if line.strip() == "// Set expiration to ledger 1000 (future)" and "let current_ledger = env.ledger().sequence();" in lines[i+1]: - if lines[i-1].strip() == "}": - # This is the dangling block at 155 - skip = True - continue - - if line.strip() == "fn test_two_step_ownership_transfer_happy_path() {}": - out.append("fn test_two_step_ownership_transfer_happy_path() {\n") - continue - - if line.strip() == "fn test_cancel_transfer() {": - out.append(line) - out.append(" let env = Env::default();\n") - out.append(" env.mock_all_auths();\n") - out.append(" let (client, _) = setup_contract(&env);\n") - out.append(" let admin = init_default(&env, &client);\n") - out.append(" let new_admin = Address::generate(&env);\n") - out.append(" client.propose_owner(&new_admin);\n") - out.append(" client.cancel_transfer();\n") - out.append(" assert!(client.pending_owner().is_none());\n") - out.append("}\n") - skip = True - continue - - if line.strip() == "fn test_transfer_ownership_updates_admin() {": - # there's a dangling 'fn test_transfer_ownership_updates_admin() {' inside a test? - # wait, let's look at it. - pass - - out.append(line) - -with open("contracts/token/src/test.rs", "w") as f: - f.writelines(out) diff --git a/src/errors/sorobanParser.ts b/src/errors/sorobanParser.ts deleted file mode 100644 index 6c6e0edd..00000000 --- a/src/errors/sorobanParser.ts +++ /dev/null @@ -1,2 +0,0 @@ -// Paste your full TypeScript code block here - \ No newline at end of file