fix(guild): role/membership gates on unsecured entry points + per-function permission linter (#19) - #63
Conversation
…ction permission linter (Riddlrealm#19)
Note: CI failures here are unrelated to this changeThe Root cause: error[E0277]: the trait bound ChaCha20Rng: ed25519_dalek::rand_core::CryptoRng Because This change is verified locally with
Suggested infra fix (repo-wide, separate from this PR): either commit |
…sions-audit # Conflicts: # .gitignore
Closes #19
Audit result
All 13 pub entry points in
guildalready callrequire_auth(); the gaps wereone layer deeper — the role/membership authorization check. Full per-method
matrix in
docs/audits/admin-permissions-matrix.md.What
assert_memberhelper, extracted from the inline membership checks invote/vote_withdrawalso every membership gate shares one implementationand one panic message.
execute_withdrawalanddepositnow gate on membership (assert_member).disbandnow uses the canonicalassert_activegate.scripts/check-missing-permissions.shnow runs a per-function AST checker(
tools/check-permissions, usingsyn) instead of the per-filegrep, whichpassed an entire contract on a single
require_authmatch anywhere.admin-permissions-matrix.mdwith the real guild audit.Mapimport (unblocksclippy -D warnings).Design decision
execute_withdrawalgates on membership, not officer: the authority alreadylives in the vote quorum; execution is ministerial, and requiring an officer
would strand guilds whose officer is absent.
(
member_can_execute_approved_withdrawal) locanstill execute an approved withdrawal.
Honest severity (not overstated)
execute_withdrawal— a genuine access-control gap, but low severity: funds goto
proposal.officerand a vote quorum is already required. Now members-only.deposit— not an exploit; an intentional,(non-members can no longer deposit), matchid the
membership gates already on voting.
disband— was already once-only via acheck; this switches it to the canonicala"Guild disbanded"message as every other mutator). Consistency/hardening,not a vulnerability fix.
Linter scope
The checker enforces the contracts in its
ENd,the subject of this issue) and returns zero `ne-off
workspace-wide run surfaced ~140 pre-existing candidate functions across ~45
other contracts; triaging those is separate follow-up work. (Clippy warn-levels
for the script are tracked in #46.)
Tests
3 new
#[should_panic](per acceptance criteexisting guild suite green (6/6 total).
Verification (local)
cargo clippy -p guild -- -D warnings— clcargo test -p guild— 6/6 passingbash scripts/check-missing-permissions.shcargo build --target wasm32-unknown-unknown --release -p guild— ok