From d74999f8449c3924c6e4f2e67028c588a1d92b59 Mon Sep 17 00:00:00 2001 From: Promise Raji Date: Tue, 4 Aug 2026 14:36:15 +0100 Subject: [PATCH] chore: remove temporary and unneeded project files --- IMPLEMENTATION_SUMMARY.md | 64 -------------- PR_BODY.md | 172 ------------------------------------ clippy.log | Bin 169738 -> 0 bytes e2e/test.rs | Bin 178 -> 0 bytes fix_tests.py | 58 ------------ src/errors/sorobanParser.ts | 2 - 6 files changed, 296 deletions(-) delete mode 100644 IMPLEMENTATION_SUMMARY.md delete mode 100644 PR_BODY.md delete mode 100644 clippy.log delete mode 100644 e2e/test.rs delete mode 100644 fix_tests.py delete mode 100644 src/errors/sorobanParser.ts 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 ea3639f1c8c7f194d92293ceb50b530ca3c593a3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 169738 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 z znt)1IKW6E5wndtRM-_3a>%lqv8ud~-sKy8Dw)##h<)lDTu?t`b!sNPzcIb%D(TEEr~ zcIlUP)k|%h~zUR4LfCv{E4XBenSV7*Bov%lOPVp(0~N39dq5?mB(iB#E3@m}M9 zU>Rfj(G&e|c)}z9A)Sb~c|S$M++u01UvG~*Et-?L=pNA*vndMj8u0HpL7}Da6I>PM zo$&3JoNa6vUYeiX($DX`Ij{4QyWFmyI&$C9uD{er))_~yfvQ-0nVchTcAQE}2Zy`) z%l~nA>Q&KOi`(>fU<;!=qUMPR@0Jr0Kkw^&T-E1B`fU2Uyow!uc<}7Hr0A8-89E<3 zfIh=Fs_{6=1GOZE^^F1 zOh{r#WGI50pums=w50@SPCO9X0&yD9e25L!Kpw~jh|Re`eVITvAnfL4;9>v(Ah{h5 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