Skip to content

Commit 862cb7d

Browse files
0xdevcollinsclaude
andauthored
chore: strip explanatory comments from contract source (#81)
* chore: strip explanatory comments from contract source Remove prose, doc, and inline comments across the events and profile contracts (src + tests), keeping only the `// ===` banner section headers that mark functions/groups plus SPDX license lines. Comment-only change: no code, signatures, or logic touched; 232 tests pass and both debug and wasm-release builds are clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * test: remove unnecessary whitespace in cancel_at_boundary_pays_partners_full_no_owner_residual test --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
1 parent e1f1793 commit 862cb7d

43 files changed

Lines changed: 3 additions & 1173 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

contracts/events/src/admin.rs

Lines changed: 0 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,20 @@
1-
// boundless-events: admin operations.
2-
//
3-
// Spec: boundless-platform-contract-prd.md Section 6.1.
4-
51
use soroban_sdk::{panic_with_error, Address, BytesN, Env, String};
62

73
use crate::errors::Error;
84
use crate::events as evt;
95
use crate::storage;
106
use crate::types::{PendingAdmin, PendingUpgrade};
117

12-
// Two-step admin rotation TTL: 7 days at the mainnet 5-second ledger cadence.
13-
// 7 * 24 * 60 * 60 / 5 = 120_960 ledgers.
148
const PENDING_ADMIN_TTL_LEDGERS: u32 = 120_960;
159

16-
// Fee bps cap. 100% = 10_000 bps. L4 (2026-06 audit): tightened from 5_000
17-
// (50%) to 1_000 (10%). 10% covers the full envelope of real Boundless
18-
// pricing tiers; a config typo can no longer push the fee above operating
19-
// range. Per-event overrides still respect this cap.
2010
pub(crate) const MAX_FEE_BPS: u32 = 1_000;
2111

22-
// H6: timelocked upgrade windows.
23-
//
24-
// UPGRADE_TIMELOCK_LEDGERS earliest gap between propose and apply.
25-
// ~1 day so off-chain monitors have a window
26-
// to react before the new wasm lands.
27-
// PENDING_UPGRADE_TTL_LEDGERS hard expiry on the proposal; ~30 days.
28-
// Past this the admin must re-propose.
29-
// Testnet builds (`--features testnet`) zero the upgrade timelock for fast
30-
// iteration; the default build (mainnet + everything else) keeps the full
31-
// ~1-day timelock. Fail-safe: omitting the flag yields the secure value, never 0.
3212
#[cfg(not(feature = "testnet"))]
3313
const UPGRADE_TIMELOCK_LEDGERS: u32 = 17_280;
3414
#[cfg(feature = "testnet")]
3515
const UPGRADE_TIMELOCK_LEDGERS: u32 = 0;
3616
const PENDING_UPGRADE_TTL_LEDGERS: u32 = 518_400;
3717

38-
// Initial contract version. Written by __constructor and bumped on
39-
// apply_upgrade. Bump alongside any storage-layout or public-surface change
40-
// that warrants a migration entrypoint.
4118
pub const INITIAL_VERSION: &str = "1.1.0";
4219

4320
// ============================================================
@@ -50,8 +27,6 @@ pub fn initialize(
5027
fee_bps: u32,
5128
profile_contract: Address,
5229
) {
53-
// Refuse double-init by checking the admin key in instance storage (the
54-
// new home for admin/config per the 2026-06 audit).
5530
if env.storage().instance().has(&crate::types::DataKey::Admin) {
5631
panic_with_error!(env, Error::AlreadyInitialized);
5732
}
@@ -140,12 +115,6 @@ pub fn set_fee_bps(env: &Env, new_bps: u32) -> Result<(), Error> {
140115

141116
pub fn set_fee_account(env: &Env, new_account: Address) -> Result<(), Error> {
142117
require_admin(env)?;
143-
// M2 (2026-06 audit): we do not verify trustline existence at the
144-
// contract layer because Soroban's SAC interface cannot reliably
145-
// distinguish "no trustline" from "zero balance". Admin must verify
146-
// off-chain BEFORE calling this; the FeeAccountUpdated event below is
147-
// the signal off-chain monitors rely on to re-verify. See
148-
// docs/audit-2026-06-stellar-skill.md M2.
149118
storage::set_fee_account(env, &new_account);
150119
storage::touch_instance(env);
151120
evt::FeeAccountUpdated {
@@ -190,33 +159,13 @@ pub fn unpause(env: &Env) -> Result<(), Error> {
190159

191160
// ============================================================
192161
// UPGRADE (timelocked; H6)
193-
//
194-
// Three steps:
195-
// 1. propose_upgrade(wasm_hash, new_version) — admin-only; writes
196-
// PendingUpgrade with proposed_at = now, available_at = now + TIMELOCK,
197-
// expires_at = now + TTL. Off-chain monitors can see exactly which
198-
// version + wasm is queued before it lands.
199-
// 2. apply_upgrade() — admin-only; requires
200-
// now in [available_at, expires_at]; swaps the wasm hash and bumps
201-
// the on-chain version label.
202-
// 3. cancel_pending_upgrade() — admin-only; prunes a stale
203-
// or unwanted proposal so a fresh one can be queued.
204-
//
205-
// migrate(to_version) is a SEPARATE call that runs the one-shot data
206-
// migration matched to the just-applied version. Guard via MigratedToVersion.
207-
//
208-
// Spec: docs/audit-2026-06-stellar-skill.md H6.
209162
// ============================================================
210163
pub fn propose_upgrade(
211164
env: &Env,
212165
new_wasm_hash: BytesN<32>,
213166
new_version: String,
214167
) -> Result<(), Error> {
215168
require_admin(env)?;
216-
// Empty version is rejected; reuse InvalidPillar to stay inside the
217-
// soroban contracterror 50-variant cap (a dedicated InvalidVersion
218-
// would push us over). Off-chain monitors should treat InvalidPillar
219-
// on propose_upgrade as "bad version label."
220169
if new_version.is_empty() {
221170
return Err(Error::InvalidPillar);
222171
}
@@ -262,7 +211,6 @@ pub fn apply_upgrade(env: &Env) -> Result<(), Error> {
262211
new_version: pending.new_version.clone(),
263212
}
264213
.publish(env);
265-
// Keep the legacy Upgraded event for indexers built against the old shape.
266214
evt::Upgraded {
267215
new_wasm_hash: pending.wasm_hash,
268216
}
@@ -286,29 +234,6 @@ pub fn cancel_pending_upgrade(env: &Env) -> Result<(), Error> {
286234

287235
// ============================================================
288236
// MIGRATE (post-upgrade one-shot; H6)
289-
//
290-
// Called once per version after apply_upgrade swaps the wasm. The shape
291-
// is:
292-
//
293-
// 1. Read the current Version label (set by apply_upgrade) and the
294-
// previously-applied migration marker (MigratedToVersion). If the
295-
// marker already equals the current Version, reject as
296-
// MigrationAlreadyApplied — a second invocation is always a
297-
// misconfiguration.
298-
// 2. Dispatch on (prev, current) and run the migration body. Bodies
299-
// run cleanly inside the same tx as the marker write, so a failure
300-
// reverts both — there is no half-migrated state to recover from.
301-
// 3. Stamp MigratedToVersion = current and emit Migrated{}.
302-
//
303-
// Mainnet bootstrap: the first deploy lands the constructor with the
304-
// current storage layout, so no migration body is needed. The first real
305-
// migration body will land with the first storage-layout upgrade after
306-
// mainnet goes live. We keep an empty match arm for the no-op case so the
307-
// shape is stable and future contributors do not have to debate where
308-
// the dispatch goes.
309-
//
310-
// NB: Soroban String only supports equality + length, no `as_str()` /
311-
// pattern matching. The dispatch below uses `String::from_str` + equality.
312237
// ============================================================
313238
pub fn migrate(env: &Env) -> Result<(), Error> {
314239
require_admin(env)?;
@@ -324,31 +249,8 @@ pub fn migrate(env: &Env) -> Result<(), Error> {
324249

325250
// ============================================================
326251
// PER-(from -> to) MIGRATION DISPATCH
327-
//
328-
// Each future upgrade adds an `if` clause here with its migration body.
329-
// Touch only persistent / instance entries that the new layout changes;
330-
// anything the new code reads with backwards-compatible defaults can
331-
// be left alone.
332-
//
333-
// Pattern:
334-
//
335-
// if from_version == String::from_str(env, "0.2.0")
336-
// && current == String::from_str(env, "0.3.0")
337-
// {
338-
// migrate_0_2_0_to_0_3_0(env)?;
339-
// }
340-
//
341-
// The corresponding private fn lives below the match block. Keep it
342-
// small enough to read; if the migration is large, split it into named
343-
// helpers and call from inside the body.
344252
// ============================================================
345253

346-
// No-op for the 1.0.0 -> 1.1.0 credit-removal upgrade: the contracts hold
347-
// no events yet, so there are no EventRecord rows to rewrite. __constructor
348-
// populates storage in the current shape, so admin can call migrate() once
349-
// just to stamp the marker and unlock the audit trail (the Migrated event
350-
// signals off-chain runbooks that the post-upgrade cleanup ran).
351-
352254
storage::set_migrated_to_version(env, &current);
353255
storage::touch_instance(env);
354256
evt::Migrated {
@@ -404,8 +306,6 @@ pub fn require_admin(env: &Env) -> Result<(), Error> {
404306
}
405307

406308
pub fn require_not_paused(env: &Env) -> Result<(), Error> {
407-
// Every operation path runs this first, so this is the single spot to
408-
// bump instance TTL on the hot path. Admin paths bump explicitly.
409309
storage::touch_instance(env);
410310
if storage::is_paused(env) {
411311
return Err(Error::Paused);

contracts/events/src/bounty.rs

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,3 @@
1-
// boundless-events: bounty-specific behavior.
2-
//
3-
// Spec: boundless-platform-contract-prd.md Sections 6.3, 7.
4-
//
5-
// Bounties use ReleaseKind::Single. Credits (apply cost / refunds) are handled
6-
// off-chain; the contract only records applicants and ensures their profile.
7-
81
use soroban_sdk::{Address, BytesN, Env};
92

103
use crate::admin;
@@ -40,11 +33,8 @@ pub fn apply(
4033

4134
applicant.require_auth();
4235

43-
// append_applicant returns Err on duplicate or cap exceeded.
4436
storage::append_applicant(env, bounty_id, &applicant, MAX_APPLICANTS_PER_EVENT)?;
4537

46-
// Cross-contract: ensure the applicant has a profile (idempotent). Credits
47-
// are charged off-chain now, so there is no on-chain spend here.
4838
let profile = profile_client::client(env);
4939
let bootstrap_op = idempotency::derive_child(env, &op_id, tag::BOOTSTRAP);
5040
profile.bootstrap(&applicant, &bootstrap_op);
@@ -76,17 +66,12 @@ pub fn withdraw_application(
7666

7767
applicant.require_auth();
7868

79-
// Reject withdrawal if the applicant already submitted.
8069
if storage::get_submission(env, bounty_id, &applicant).is_some() {
8170
return Err(Error::SubmissionAlreadyExists);
8271
}
8372

84-
// Membership check + swap-remove. Slot lookup is O(1), so this avoids
85-
// the prior O(n) linear scan even at the cap.
8673
storage::remove_applicant(env, bounty_id, &applicant)?;
8774

88-
// Credits (including any withdrawal refund) are handled off-chain.
89-
9075
evt::ApplicationWithdrawn {
9176
event_id: bounty_id,
9277
applicant,

contracts/events/src/crowdfunding.rs

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,3 @@
1-
// boundless-events: crowdfunding-specific behavior.
2-
//
3-
// Spec: boundless-crowdfunding-prd.md.
4-
//
5-
// Crowdfunding is a builder-led, community-funded pillar with these rules:
6-
// - ReleaseKind::Multi(n>0): milestones drive release cadence, like grants.
7-
// - deadline required: defines the funding window. Submitting/contributing
8-
// after the deadline is rejected by the standard event-active checks.
9-
// - Owner is the project builder. There is exactly one recipient, also
10-
// the builder, registered as Winner at position 1 (100% of distribution).
11-
// - No upfront owner deposit: create_event SKIPS escrow::deposit_with_fee
12-
// for Pillar::Crowdfunding. Escrow starts at 0 and grows via add_funds
13-
// from community backers.
14-
// - winner_distribution MUST be a single entry at position 1 with 100%.
15-
// - claim_milestone uses dynamic math:
16-
// amount = remaining_escrow / (total_milestones - claimed_so_far)
17-
// so each release pays a fair share of whatever the campaign actually
18-
// raised. The first milestone takes 1/n of escrow, the next 1/(n-1) of
19-
// what's left, ..., the last takes the entire remainder.
20-
//
21-
// The contract enforces only the on-chain shape. Off-chain layers add admin
22-
// review, community voting, milestone validation, and pause semantics.
231
#![allow(dead_code)]
242

253
use soroban_sdk::{Address, Env};
@@ -28,19 +6,15 @@ use crate::errors::Error;
286
use crate::types::{EventRecord, ReleaseKind};
297

308
pub fn validate_create(_env: &Env, record: &EventRecord, _owner: &Address) -> Result<(), Error> {
31-
// Multi(n) required.
329
match record.release_kind {
3310
ReleaseKind::Multi(n) if n > 0 => {}
3411
_ => return Err(Error::InvalidReleaseKind),
3512
}
3613

37-
// Funding window required.
3814
if record.deadline.is_none() {
3915
return Err(Error::DeadlineRequired);
4016
}
4117

42-
// Distribution must be exactly one entry at position 1 with 100%. The
43-
// builder is the sole recipient; no co-recipient splits are supported.
4418
if record.winner_distribution.len() != 1 {
4519
return Err(Error::InvalidDistribution);
4620
}

contracts/events/src/errors.rs

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,24 @@
1-
// boundless-events: error codes.
2-
//
3-
// Spec: boundless-platform-contract-prd.md Section 14.
4-
51
use soroban_sdk::contracterror;
62

73
#[contracterror]
84
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
95
#[repr(u32)]
106
pub enum Error {
11-
// Init
127
AlreadyInitialized = 1,
138
AdminCannotBeZero = 2,
149
FeeAccountCannotBeZero = 3,
1510
ProfileContractCannotBeZero = 4,
1611
InvalidFeeBps = 5,
1712
NotInitialized = 6,
1813

19-
// Auth
2014
Unauthorized = 10,
2115
NotAdmin = 11,
2216
PendingAdminMismatch = 12,
2317
PendingAdminExpired = 13,
2418

25-
// Token
2619
TokenNotSupported = 20,
2720
FeeAccountMissingTrustline = 21,
2821

29-
// Event lifecycle
3022
EventNotFound = 30,
3123
EventNotActive = 31,
3224
InvalidPillar = 32,
@@ -38,14 +30,11 @@ pub enum Error {
3830
DeadlineMustBeFuture = 38,
3931
TitleTooLong = 39,
4032

41-
// Participation
4233
ApplicantAlreadyApplied = 40,
4334
ApplicantNotApplied = 41,
4435
SubmissionNotFound = 42,
4536
SubmissionAlreadyExists = 43,
46-
// 44 (InsufficientCredits) retired with on-chain credits; left as a gap.
4737

48-
// Winners
4938
NoSubmissions = 50,
5039
InvalidWinnerPosition = 51,
5140
DuplicateWinnerPosition = 52,
@@ -55,20 +44,15 @@ pub enum Error {
5544
InsufficientEscrow = 56,
5645
WinnersAlreadySelected = 90,
5746

58-
// Contributions
5947
BelowMinimumContribution = 57,
6048
InvalidContributionAmount = 58,
6149

62-
// Capacity (per-event list caps; see MAX_*_PER_EVENT in event_ops)
6350
TooManyApplicants = 59,
6451

65-
// Idempotency
6652
OpAlreadySeen = 60,
6753

68-
// Capacity continued
6954
TooManyContributors = 61,
7055

71-
// Paged cancellation flow
7256
CancellationNotStarted = 62,
7357
CancellationAlreadyStarted = 63,
7458
CancellationNotFinished = 64,
@@ -78,9 +62,7 @@ pub enum Error {
7862
UpgradeProposalExpired = 68,
7963
MigrationAlreadyApplied = 69,
8064

81-
// Pause
8265
Paused = 70,
8366

84-
// Cross-contract
8567
ProfileCallFailed = 80,
8668
}

contracts/events/src/escrow.rs

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -46,25 +46,13 @@ pub fn release(env: &Env, token_addr: &Address, recipient: &Address, amount: i12
4646
client.transfer(&contract, recipient, &amount);
4747
}
4848

49-
/// Deposit exactly `amount` into escrow with NO platform fee taken here.
50-
///
51-
/// Used by pillars (crowdfunding) that charge the fee at release instead, so the
52-
/// funder pays exactly `amount` and a cancel refunds it in full. Returns the
53-
/// amount credited to escrow (== `amount`).
5449
pub fn deposit_no_fee(env: &Env, token_addr: &Address, from: &Address, amount: i128) -> i128 {
5550
let contract = env.current_contract_address();
5651
let client = token::Client::new(env, token_addr);
5752
client.transfer(from, &contract, &amount);
5853
amount
5954
}
6055

61-
/// Release `amount` from escrow, taking the platform fee off the top: the
62-
/// recipient receives `amount - fee` and the fee account receives `fee`.
63-
///
64-
/// Used by pillars (crowdfunding) where the RECIPIENT bears the fee. The funder
65-
/// already deposited their full pledge via `deposit_no_fee`. The full `amount`
66-
/// leaves escrow (net to recipient + fee to platform), so callers decrement
67-
/// `remaining_escrow` by `amount`.
6856
pub fn release_with_fee_at(
6957
env: &Env,
7058
token_addr: &Address,

0 commit comments

Comments
 (0)