From b931f9451cc9af65c43788ca3734d933a6a5ee7d Mon Sep 17 00:00:00 2001 From: Ahmed Din Date: Wed, 21 Oct 2026 03:35:46 +0500 Subject: [PATCH] chore(ci): add size budget file for each contract (#94) - Add contracts/size-budget.json defining 64KB thresholds for each contract - Enforce size budget verification in .github/workflows/contracts-ci.yml - Update CHANGELOG.md --- .github/workflows/contracts-ci.yml | 21 +++++++++++++++++++++ CHANGELOG.md | 2 ++ contracts/size-budget.json | 7 +++++++ 3 files changed, 30 insertions(+) create mode 100644 contracts/size-budget.json diff --git a/.github/workflows/contracts-ci.yml b/.github/workflows/contracts-ci.yml index 552f5db..789e228 100644 --- a/.github/workflows/contracts-ci.yml +++ b/.github/workflows/contracts-ci.yml @@ -109,6 +109,27 @@ jobs: stellar contract build --manifest-path contracts/governance/Cargo.toml stellar contract build --manifest-path contracts/oracle-adapter/Cargo.toml + - name: Check WASM size budgets + run: | + node -e ' + const fs = require("fs"); + const path = require("path"); + const budgets = JSON.parse(fs.readFileSync("contracts/size-budget.json", "utf8")); + let failed = false; + for (const [name, budget] of Object.entries(budgets)) { + const file = path.join("target/wasm32v1-none/release", `${name}.wasm`); + if (fs.existsSync(file)) { + const size = fs.statSync(file).size; + console.log(`[SIZE] ${name}: ${size} bytes (budget: ${budget} bytes)`); + if (size > budget) { + console.error(`[ERROR] ${name} exceeds budget (${size} > ${budget})`); + failed = true; + } + } + } + if (failed) process.exit(1); + ' + # Published with the artifacts, so the hash of a deployed contract's wasm # can be checked against the commit that built it. - name: Record wasm checksums diff --git a/CHANGELOG.md b/CHANGELOG.md index 097b5dc..a01e504 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +- `ci`: Add `contracts/size-budget.json` establishing tracked byte thresholds for each contract, enforced in `.github/workflows/contracts-ci.yml` (#94). + - `rwa-asset`: holder count tracking (#146). `holder_count()` returns the number of addresses currently holding a strictly positive balance. The counter is incremented when a balance crosses 0 → >0 (first receive) and decremented when a balance hits exactly 0 (full burn or full send). `set_holder_cap(cap)` lets the admin set an optional ceiling on the holder count (Reg D style); any `mint`, `transfer`, `transfer_from` or `forced_transfer` that would add a new holder when the count already equals the cap is rejected with `ExceedsHolderCap` (error 25). `holder_count_cap()` returns the configured ceiling or `None`. The new `HolderCapSet` event is emitted by `set_holder_cap`, including when the cap is removed. A property test (`tests/test_holder_count.rs`) verifies the invariant `holder_count == count(addresses with balance > 0)` after every step in a 50-operation sequence of mints, burns, and transfers, both with and without an active cap. - `rwa-asset`: `set_governance`, `propose_cap_increase`/`approve_cap_increase`/`cancel_cap_increase` and `pending_cap_increase`. `update_metadata` still refuses to loosen a supply cap by itself (IR-02); raising one now requires the admin to propose a value and a separately configured `governance` address to approve it, mirroring `propose_admin`/`accept_admin`'s two-step shape. See [ADR-007](docs/architecture/007-governance-controlled-supply-cap.md) for why this is a second address rather than the `governance` contract itself (#148). diff --git a/contracts/size-budget.json b/contracts/size-budget.json new file mode 100644 index 0000000..13ba851 --- /dev/null +++ b/contracts/size-budget.json @@ -0,0 +1,7 @@ +{ + "rwa_asset": 65536, + "registry": 65536, + "compliance": 65536, + "governance": 65536, + "oracle_adapter": 65536 +}