[N-03] Access Control Audit#337
Conversation
|
Important Review skippedAuto incremental reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## release-v1.2 #337 +/- ##
================================================
+ Coverage 95.88% 95.93% +0.04%
================================================
Files 22 22
Lines 2187 2187
Branches 592 593 +1
================================================
+ Hits 2097 2098 +1
Misses 65 65
+ Partials 25 24 -1
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Pull request overview
This PR remediates access-control audit feedback by tightening role storage typing, adding an explicit initial-admin constructor, and simplifying role renunciation to always apply to the transaction sender.
Changes:
- Replaces untyped
Bagrole storage withTable<TypeName, RoleData>. - Adds
new_with_adminand refactorsnewto delegate to it. - Removes the explicit
accountparameter fromrenounce_roleand updates tests.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
contracts/access/sources/access_control.move |
Updates storage, constructors, renounce API, error constants, and role accessors. |
contracts/access/tests/access_control_tests.move |
Adds constructor tests and updates renounce tests for the new signature. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…into fix/access-control-N-04
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
contracts/access/sources/access_control.move (1)
161-165:⚠️ Potential issue | 🟠 Major | 🏗️ Heavy liftUpgrade safety:
AccessControl.roleslayout change is breaking for publishedkeyobjects
In Sui package upgrades, changing the field type of an existing publickeystruct (hereroles: Bag→roles: Table<TypeName, RoleData>) is not upgrade-safe because struct layouts must remain strictly identical for previously published objects. A release that mutates this struct in place will require a migration/versioning approach instead (e.g., keep the old struct layout, addAccessControlV2with the new field type, and provide an explicit migration/swap entry function, or use a versioned wrapper/dynamic-field migration pattern).🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@contracts/access/sources/access_control.move` around lines 161 - 165, The change to AccessControl<RootRole>::roles from Bag to Table breaks upgrade safety for published key objects; revert the in-place field-type change and instead preserve the original struct layout by keeping the existing AccessControl struct unchanged and introduce a new AccessControlV2 (or similar) that has roles: Table<TypeName, RoleData>; add a migration entry function (e.g., migrate_access_control_to_v2) that accepts the old AccessControl key object, performs a controlled in-contract migration/swap to construct AccessControlV2 (moving data from the old Bag into the new Table), and enforces proper access checks/versions; alternatively add a new field (e.g., new_roles: Table<...>) to the existing struct while keeping the old roles field to preserve layout and provide an explicit migration function to populate and then retire the old field. Ensure all references use the new type names (AccessControl, AccessControlV2, roles, new_roles, migrate_access_control_to_v2) so upgrades are safe.
🧹 Nitpick comments (1)
contracts/access/tests/access_control_tests.move (1)
457-459: ⚡ Quick winUpdate the stale storage wording.
This comment still describes the old Bag-backed layout, but the code under test now stores roles in a
Table<TypeName, RoleData>. Keeping the branch description in sync with the implementation will make these renounce idempotency cases easier to follow.♻️ Proposed wording update
-// Renounce idempotency: role in bag, but the caller is not a member — the -// second early-return path. Distinct from the "role not in bag" path covered +// Renounce idempotency: role exists in the table, but the caller is not a +// member — the second early-return path. Distinct from the "role not in the +// table" path covered🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@contracts/access/tests/access_control_tests.move` around lines 457 - 459, Update the test comment describing the "renounce idempotency" case to reflect the current Table-backed storage: replace references to "bag" with "Table<TypeName, RoleData>" and reword the branch description to say that the role exists in the Table but the caller is not a member (the second early-return path), so the comment matches the implementation under test (roles stored in Table<TypeName, RoleData>).
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@contracts/access/sources/access_control.move`:
- Around line 83-115: The abort-code numbers were shifted when removing
ECannotRenounceForOtherAccount, which breaks callers/tests that depend on
numeric codes; restore the original numeric slot by reintroducing a placeholder
error constant named ECannotRenounceForOtherAccount (or a clearly marked
reserved constant) with the original #[error(code = 4)] annotation and a comment
marking it retired/unused, and keep all subsequent constants (EDelayTooLarge,
ENotOneTimeWitness, EForeignRole, ENotPendingTransfer, ENotPendingRenounce,
ENoPendingDelayChange, EZeroAddress, EDefaultAdminTransferToSelf) using their
existing #[error(code = ...)] values so their numeric codes do not change.
Ensure the placeholder is unused in logic but present in
contracts/access/sources/access_control.move to preserve the API.
---
Outside diff comments:
In `@contracts/access/sources/access_control.move`:
- Around line 161-165: The change to AccessControl<RootRole>::roles from Bag to
Table breaks upgrade safety for published key objects; revert the in-place
field-type change and instead preserve the original struct layout by keeping the
existing AccessControl struct unchanged and introduce a new AccessControlV2 (or
similar) that has roles: Table<TypeName, RoleData>; add a migration entry
function (e.g., migrate_access_control_to_v2) that accepts the old AccessControl
key object, performs a controlled in-contract migration/swap to construct
AccessControlV2 (moving data from the old Bag into the new Table), and enforces
proper access checks/versions; alternatively add a new field (e.g., new_roles:
Table<...>) to the existing struct while keeping the old roles field to preserve
layout and provide an explicit migration function to populate and then retire
the old field. Ensure all references use the new type names (AccessControl,
AccessControlV2, roles, new_roles, migrate_access_control_to_v2) so upgrades are
safe.
---
Nitpick comments:
In `@contracts/access/tests/access_control_tests.move`:
- Around line 457-459: Update the test comment describing the "renounce
idempotency" case to reflect the current Table-backed storage: replace
references to "bag" with "Table<TypeName, RoleData>" and reword the branch
description to say that the role exists in the Table but the caller is not a
member (the second early-return path), so the comment matches the implementation
under test (roles stored in Table<TypeName, RoleData>).
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: d02053ba-2a36-485f-a25b-4cc483386d61
📒 Files selected for processing (2)
contracts/access/sources/access_control.movecontracts/access/tests/access_control_tests.move
* feat: add assertion (#335) * feat: update comments (#336) * [N-03] Access Control Audit (#337) * feat: update comments * feat: apply updates * feat: update bag references * feat: rename param * feat: apply review updates * feat: rollback renmae * [N-05] Access Control Audit (#338) * feat: update delay logic * feat: improve doc comments * feat: improve events * feat: apply review updates * [N-01] Access Control Audit (#339) * feat: update delay logic * feat: improve doc comments * feat: improve events * feat: apply review update * feat: apply review updates * Fix N-04 (Code and Documentation Improvements) (#332) * Fix N-03 (introduce ELogResultUnrepresentable for UD30x9 log functions) (#341) * fix: `N-02` exact powers of 10 for `log10` (#344) * Fix N-02 (exact powers of 10 for log10) * Apply minor suggestion * fix: `N-01` raw_log2 precision comment (#333) * Fix N-01 (Internal Precision Comment Overstates raw_log2 Error Bound) * Fix raw_log2 precision wording * feat: add reports (#351) * feat: update changelog * feat: update changelog (#353) * feat: update comments * feat: update published information --------- Co-authored-by: immrsd <103599616+immrsd@users.noreply.github.com>
* feat: add assertion (#335) * feat: update comments (#336) * [N-03] Access Control Audit (#337) * feat: update comments * feat: apply updates * feat: update bag references * feat: rename param * feat: apply review updates * feat: rollback renmae * [N-05] Access Control Audit (#338) * feat: update delay logic * feat: improve doc comments * feat: improve events * feat: apply review updates * [N-01] Access Control Audit (#339) * feat: update delay logic * feat: improve doc comments * feat: improve events * feat: apply review update * feat: apply review updates * Fix N-04 (Code and Documentation Improvements) (#332) * Fix N-03 (introduce ELogResultUnrepresentable for UD30x9 log functions) (#341) * fix: `N-02` exact powers of 10 for `log10` (#344) * Fix N-02 (exact powers of 10 for log10) * Apply minor suggestion * fix: `N-01` raw_log2 precision comment (#333) * Fix N-01 (Internal Precision Comment Overstates raw_log2 Error Bound) * Fix raw_log2 precision wording * feat: add reports (#351) * feat: update changelog (#353) * feat: update published information (#355) * feat: Implement Rate Limiter module (#315) * feat: add rate limiter implementation * docs: document invariants * fix: enforce missing invariants * test: add more tests * feat: cooldown supports capacity/used * ref: assume monotonic Clock * fix: new_bucket accepts initial tokens (remove new_bucket_with_tokens) * ref: track cooldown_end instead of last_used * fix: cooldown used increases by 1 on consume * ref: use 'available' design instead of 'used' * ref: inline roll_window * test: add cooldown_reconfigure_rearms_when_drained_and_deadline_elapsed * docs: mention operator's responsibility for cooldown_ms * ref: rename q to steps_to_full in bucket_accrue * docs: update invariants * fix: remove capacity + refill_amount assertion in assert_bucket_config * docs: add missing / update docs * feat: add variety of errors * docs: add missing / update docs * test: remove invariant class mentions * ref: apply Code Quality Checklist (openzeppelin_utils) * test: replace cleanup with 'abort EUnreachable' in expected-failure tests * test: use abort 0 instead of error * feat: remove 'Ms' suffix from Error names * docs: error docs don't reference internal variables * docs: rephrase rate_limiter error messages without internal field names Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs: update README * docs: update README * docs: align invariants.md to be sharing-ready * docs: improve wording & clarity for invariants.md * feat: cooldown now decrements available by amount * test: change abort 0 to 100 (avoids confusing with ERateLimited) * test: change all destructor patterns into abortions * docs: invariant rewording * docs: update format for invariants.md * docs: update format for invariants.md and add missing invariants * docs: align invariants format * docs: update outdated invariant references * docs: remove rate limiter temp. artifacts * chore: simplify changelog * ref: convert assert macros into funs * docs: document private funs * test(fix): add proper teardown in happy tests * ci: add contracts/utils to CI test job dir matrix * test: add regression tests for bucket_accrue * fix: bucket_accrue double spend bug * docs: add empty line before enum variant docs Co-authored-by: Daniel Bigos <daniel.bigos96@gmail.com> * Revert "docs: add empty line before enum variant docs" This reverts commit 21a9076. * feat: inline config validation assertions * docs: add more info on rate limiter types in README * docs: add clarifying comments for apparent overflow suspects * docs: mention library being access control-agnostic * docs: reword library to module * feat: add initial_available to all limiter types * ref: put capacity as first cooldown type field * ref: use spread op instead of ignoring cooldown_ms field * docs: show identical API for all types in README * docs: for fixed window update wording that it resets to full capacity * fix: reconfigure sets last_refill to now + forbid 0 initial available for cooldown * docs: remove post-core artifact * test: add bucket_reconfigure_to_faster_rate_discards_old_subinterval * docs: add SAFETY before overflow-related comments * test: verify available always returns up-to-date accrual state * test: add missing zero-config reconfigure tests * test: add try_consume_with_zero_amount for all limiter types * test: add try_consume_of_available_aborts_when_drained * docs: note that try_consume(0) aborts after available() == 0 * docs: note RateLimiter enum is not upgrade-compatible Adding variants or fields to a deployed public enum would break BCS deserialization for integrator objects that already stored the prior shape. Document this constraint at the module level. * test: add edge case test cases * docs: remove llm artifacts * ref: reorder fileds in new_cooldown * test: remove Pub.local.toml * ref: in reconfigure_fixed_window move let now into match * ref: in reconfigure_bucket move let now into match * docs: remove mention of reconfigure_cooldown clamping available to 0 * fix: align cooldown clamp behavior on reconfigure * fix: try_consume updates state only on success * docs: align * ref: fixedwindow now shares bucket's internal logic * ref: update capacity prior to accrual on reconfigure_bucket * docs: add comment * Revert "docs: add comment" This reverts commit ecb0145. * Revert "ref: update capacity prior to accrual on reconfigure_bucket" This reverts commit b545b6d. * ref: Rate Limiter: Reconfiguration via Rich `new_*` Functions (#326) * impl * simplify further * fix: expose last_refill_ms for bucket * tests: add missing * docs: update utils README * docs: fix new_cooldown accepted combos * feat: project bucket-shaped anchor getters `last_refill_ms` and `window_start_ms` now take `&Clock` and return the anchor advanced by every whole interval elapsed since the last commit, so the snapshot `(anchor, available(clock))` is internally coherent. `cooldown_end_ms` stays a plain getter — a cooldown deadline does not evolve with time. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix: error numbering * fix: error messages no longer reference private fields * docs: move EBucketAnchorInFuture comment next to the error * add spec * update spec * tests: add missing invariant tests * feat: add is_type discriminator getters --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Co-authored-by: Eric Nordelo <eric.nordelo39@gmail.com> Co-authored-by: Daniel Bigos <daniel.bigos96@gmail.com> * tests: fix formatting in rate limiter tests (#334) * feat: [N-01]: try_consume now returns false on amount = 0 (#342) * feat: try_consume returns false on amount = 0 * test: update * docs: update readme * docs: [N-02]: warn against preserving bucket anchor across a rate change (#350) * docs: warn against preserving bucket anchor across a rate change Accrual applies the current rate over the entire span since the anchor, so carrying an old last_refill_ms anchor while changing refill_amount or refill_interval_ms re-prices elapsed time at the new rate and mints tokens instantly. Document this constraint in the new_bucket parameter doc and the module-level Reconfiguration section. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs: update readme --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs: clarify rate limiter error, available summary, and window seeding (#347) - EWrongVariant: describe variant-typed getter mismatch instead of the removed in-place reconfigure API - available: correct "available capacity" to available units (headroom) and list all three projections (accrual, window reset, cooldown release) - new_fixed_window: flag that a backdated anchor discards the seeded initial_available once a full window has elapsed Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs: document deliberate absence of events in rate limiter (#348) Add an Observability section to the rate_limiter module doc block explaining that the module emits no events by design (the limiter has no stable identity of its own) and that emitting events for rate-limit hits, cooldown arming, and reconfiguration is the integrator's responsibility at their own entry functions. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * feat: abort with ECooldownDeadlineOverflow on cooldown deadline overflow (#349) * ref: [N-03]: reorder declaration fields for buckets (#343) * ref: reorder declaration fields for buckets * align field ordering * feat: add median implementation (#362) * feat: add median implementation (#135) * add separate quick_sort implementations for each type * remove duplicated qsort implementations * add in-place qsort implementation * add partition function * rewrite qsort without recursion * convert quick_sort to macro * add comprehensive test cases for qsort * update qsort documentation * add review fixes * remove --trace flag from testing pipeline * Revert "remove --trace flag from testing pipeline" This reverts commit 9bf7065. * split macro module * inline partition macro * add median implementation * add more edge case test cases * fix fmt * remove quick_sort duplicate * feat: add median * docs: update PR * Route median through u256 workhorse fun (#325) * fix: fmt * fix: apply CR comments * test: add missing test * fix: macro * feat: use quickselect * feat: improve CHANGELOG * feat: apply review updates * feat: update comment --------- Co-authored-by: Daniel Bigos <daniel.bigos@openzeppelin.com> Co-authored-by: Daniel Bigos <daniel.bigos@icloud.com> Co-authored-by: immrsd <103599616+immrsd@users.noreply.github.com> Co-authored-by: Eric Nordelo <eric.nordelo39@gmail.com> * docs: add ! to macros and update import format Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * chore: update median PR in changelog * chore: add ! to median macro mention * docs: add missing ; after rounding imports in examples --------- Co-authored-by: Alisander Qoshqosh <37006439+qalisander@users.noreply.github.com> Co-authored-by: Daniel Bigos <daniel.bigos@openzeppelin.com> Co-authored-by: Daniel Bigos <daniel.bigos@icloud.com> Co-authored-by: immrsd <103599616+immrsd@users.noreply.github.com> Co-authored-by: Eric Nordelo <eric.nordelo39@gmail.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * [N-01] Core Math Audit (#357) * feat: Implement Rate Limiter module (#315) * feat: add rate limiter implementation * docs: document invariants * fix: enforce missing invariants * test: add more tests * feat: cooldown supports capacity/used * ref: assume monotonic Clock * fix: new_bucket accepts initial tokens (remove new_bucket_with_tokens) * ref: track cooldown_end instead of last_used * fix: cooldown used increases by 1 on consume * ref: use 'available' design instead of 'used' * ref: inline roll_window * test: add cooldown_reconfigure_rearms_when_drained_and_deadline_elapsed * docs: mention operator's responsibility for cooldown_ms * ref: rename q to steps_to_full in bucket_accrue * docs: update invariants * fix: remove capacity + refill_amount assertion in assert_bucket_config * docs: add missing / update docs * feat: add variety of errors * docs: add missing / update docs * test: remove invariant class mentions * ref: apply Code Quality Checklist (openzeppelin_utils) * test: replace cleanup with 'abort EUnreachable' in expected-failure tests * test: use abort 0 instead of error * feat: remove 'Ms' suffix from Error names * docs: error docs don't reference internal variables * docs: rephrase rate_limiter error messages without internal field names Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs: update README * docs: update README * docs: align invariants.md to be sharing-ready * docs: improve wording & clarity for invariants.md * feat: cooldown now decrements available by amount * test: change abort 0 to 100 (avoids confusing with ERateLimited) * test: change all destructor patterns into abortions * docs: invariant rewording * docs: update format for invariants.md * docs: update format for invariants.md and add missing invariants * docs: align invariants format * docs: update outdated invariant references * docs: remove rate limiter temp. artifacts * chore: simplify changelog * ref: convert assert macros into funs * docs: document private funs * test(fix): add proper teardown in happy tests * ci: add contracts/utils to CI test job dir matrix * test: add regression tests for bucket_accrue * fix: bucket_accrue double spend bug * docs: add empty line before enum variant docs Co-authored-by: Daniel Bigos <daniel.bigos96@gmail.com> * Revert "docs: add empty line before enum variant docs" This reverts commit 21a9076. * feat: inline config validation assertions * docs: add more info on rate limiter types in README * docs: add clarifying comments for apparent overflow suspects * docs: mention library being access control-agnostic * docs: reword library to module * feat: add initial_available to all limiter types * ref: put capacity as first cooldown type field * ref: use spread op instead of ignoring cooldown_ms field * docs: show identical API for all types in README * docs: for fixed window update wording that it resets to full capacity * fix: reconfigure sets last_refill to now + forbid 0 initial available for cooldown * docs: remove post-core artifact * test: add bucket_reconfigure_to_faster_rate_discards_old_subinterval * docs: add SAFETY before overflow-related comments * test: verify available always returns up-to-date accrual state * test: add missing zero-config reconfigure tests * test: add try_consume_with_zero_amount for all limiter types * test: add try_consume_of_available_aborts_when_drained * docs: note that try_consume(0) aborts after available() == 0 * docs: note RateLimiter enum is not upgrade-compatible Adding variants or fields to a deployed public enum would break BCS deserialization for integrator objects that already stored the prior shape. Document this constraint at the module level. * test: add edge case test cases * docs: remove llm artifacts * ref: reorder fileds in new_cooldown * test: remove Pub.local.toml * ref: in reconfigure_fixed_window move let now into match * ref: in reconfigure_bucket move let now into match * docs: remove mention of reconfigure_cooldown clamping available to 0 * fix: align cooldown clamp behavior on reconfigure * fix: try_consume updates state only on success * docs: align * ref: fixedwindow now shares bucket's internal logic * ref: update capacity prior to accrual on reconfigure_bucket * docs: add comment * Revert "docs: add comment" This reverts commit ecb0145. * Revert "ref: update capacity prior to accrual on reconfigure_bucket" This reverts commit b545b6d. * ref: Rate Limiter: Reconfiguration via Rich `new_*` Functions (#326) * impl * simplify further * fix: expose last_refill_ms for bucket * tests: add missing * docs: update utils README * docs: fix new_cooldown accepted combos * feat: project bucket-shaped anchor getters `last_refill_ms` and `window_start_ms` now take `&Clock` and return the anchor advanced by every whole interval elapsed since the last commit, so the snapshot `(anchor, available(clock))` is internally coherent. `cooldown_end_ms` stays a plain getter — a cooldown deadline does not evolve with time. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix: error numbering * fix: error messages no longer reference private fields * docs: move EBucketAnchorInFuture comment next to the error * add spec * update spec * tests: add missing invariant tests * feat: add is_type discriminator getters --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Co-authored-by: Eric Nordelo <eric.nordelo39@gmail.com> Co-authored-by: Daniel Bigos <daniel.bigos96@gmail.com> * tests: fix formatting in rate limiter tests (#334) * feat: add median implementation (#135) * add separate quick_sort implementations for each type * remove duplicated qsort implementations * add in-place qsort implementation * add partition function * rewrite qsort without recursion * convert quick_sort to macro * add comprehensive test cases for qsort * update qsort documentation * add review fixes * remove --trace flag from testing pipeline * Revert "remove --trace flag from testing pipeline" This reverts commit 9bf7065. * split macro module * inline partition macro * add median implementation * add more edge case test cases * fix fmt * remove quick_sort duplicate * feat: add median * docs: update PR * Route median through u256 workhorse fun (#325) * fix: fmt * fix: apply CR comments * test: add missing test * fix: macro * feat: use quickselect * feat: improve CHANGELOG * feat: apply review updates * feat: update comment --------- Co-authored-by: Daniel Bigos <daniel.bigos@openzeppelin.com> Co-authored-by: Daniel Bigos <daniel.bigos@icloud.com> Co-authored-by: immrsd <103599616+immrsd@users.noreply.github.com> Co-authored-by: Eric Nordelo <eric.nordelo39@gmail.com> * feat: update check * feat: update version --------- Co-authored-by: Nenad <nenad.misic@openzeppelin.com> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Co-authored-by: Daniel Bigos <daniel.bigos96@gmail.com> Co-authored-by: Alisander Qoshqosh <37006439+qalisander@users.noreply.github.com> Co-authored-by: Daniel Bigos <daniel.bigos@openzeppelin.com> Co-authored-by: Daniel Bigos <daniel.bigos@icloud.com> Co-authored-by: immrsd <103599616+immrsd@users.noreply.github.com> * [N-02] Core Math Audit (#359) * feat: Implement Rate Limiter module (#315) * feat: add rate limiter implementation * docs: document invariants * fix: enforce missing invariants * test: add more tests * feat: cooldown supports capacity/used * ref: assume monotonic Clock * fix: new_bucket accepts initial tokens (remove new_bucket_with_tokens) * ref: track cooldown_end instead of last_used * fix: cooldown used increases by 1 on consume * ref: use 'available' design instead of 'used' * ref: inline roll_window * test: add cooldown_reconfigure_rearms_when_drained_and_deadline_elapsed * docs: mention operator's responsibility for cooldown_ms * ref: rename q to steps_to_full in bucket_accrue * docs: update invariants * fix: remove capacity + refill_amount assertion in assert_bucket_config * docs: add missing / update docs * feat: add variety of errors * docs: add missing / update docs * test: remove invariant class mentions * ref: apply Code Quality Checklist (openzeppelin_utils) * test: replace cleanup with 'abort EUnreachable' in expected-failure tests * test: use abort 0 instead of error * feat: remove 'Ms' suffix from Error names * docs: error docs don't reference internal variables * docs: rephrase rate_limiter error messages without internal field names Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs: update README * docs: update README * docs: align invariants.md to be sharing-ready * docs: improve wording & clarity for invariants.md * feat: cooldown now decrements available by amount * test: change abort 0 to 100 (avoids confusing with ERateLimited) * test: change all destructor patterns into abortions * docs: invariant rewording * docs: update format for invariants.md * docs: update format for invariants.md and add missing invariants * docs: align invariants format * docs: update outdated invariant references * docs: remove rate limiter temp. artifacts * chore: simplify changelog * ref: convert assert macros into funs * docs: document private funs * test(fix): add proper teardown in happy tests * ci: add contracts/utils to CI test job dir matrix * test: add regression tests for bucket_accrue * fix: bucket_accrue double spend bug * docs: add empty line before enum variant docs Co-authored-by: Daniel Bigos <daniel.bigos96@gmail.com> * Revert "docs: add empty line before enum variant docs" This reverts commit 21a9076. * feat: inline config validation assertions * docs: add more info on rate limiter types in README * docs: add clarifying comments for apparent overflow suspects * docs: mention library being access control-agnostic * docs: reword library to module * feat: add initial_available to all limiter types * ref: put capacity as first cooldown type field * ref: use spread op instead of ignoring cooldown_ms field * docs: show identical API for all types in README * docs: for fixed window update wording that it resets to full capacity * fix: reconfigure sets last_refill to now + forbid 0 initial available for cooldown * docs: remove post-core artifact * test: add bucket_reconfigure_to_faster_rate_discards_old_subinterval * docs: add SAFETY before overflow-related comments * test: verify available always returns up-to-date accrual state * test: add missing zero-config reconfigure tests * test: add try_consume_with_zero_amount for all limiter types * test: add try_consume_of_available_aborts_when_drained * docs: note that try_consume(0) aborts after available() == 0 * docs: note RateLimiter enum is not upgrade-compatible Adding variants or fields to a deployed public enum would break BCS deserialization for integrator objects that already stored the prior shape. Document this constraint at the module level. * test: add edge case test cases * docs: remove llm artifacts * ref: reorder fileds in new_cooldown * test: remove Pub.local.toml * ref: in reconfigure_fixed_window move let now into match * ref: in reconfigure_bucket move let now into match * docs: remove mention of reconfigure_cooldown clamping available to 0 * fix: align cooldown clamp behavior on reconfigure * fix: try_consume updates state only on success * docs: align * ref: fixedwindow now shares bucket's internal logic * ref: update capacity prior to accrual on reconfigure_bucket * docs: add comment * Revert "docs: add comment" This reverts commit ecb0145. * Revert "ref: update capacity prior to accrual on reconfigure_bucket" This reverts commit b545b6d. * ref: Rate Limiter: Reconfiguration via Rich `new_*` Functions (#326) * impl * simplify further * fix: expose last_refill_ms for bucket * tests: add missing * docs: update utils README * docs: fix new_cooldown accepted combos * feat: project bucket-shaped anchor getters `last_refill_ms` and `window_start_ms` now take `&Clock` and return the anchor advanced by every whole interval elapsed since the last commit, so the snapshot `(anchor, available(clock))` is internally coherent. `cooldown_end_ms` stays a plain getter — a cooldown deadline does not evolve with time. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix: error numbering * fix: error messages no longer reference private fields * docs: move EBucketAnchorInFuture comment next to the error * add spec * update spec * tests: add missing invariant tests * feat: add is_type discriminator getters --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Co-authored-by: Eric Nordelo <eric.nordelo39@gmail.com> Co-authored-by: Daniel Bigos <daniel.bigos96@gmail.com> * tests: fix formatting in rate limiter tests (#334) * feat: add median implementation (#135) * add separate quick_sort implementations for each type * remove duplicated qsort implementations * add in-place qsort implementation * add partition function * rewrite qsort without recursion * convert quick_sort to macro * add comprehensive test cases for qsort * update qsort documentation * add review fixes * remove --trace flag from testing pipeline * Revert "remove --trace flag from testing pipeline" This reverts commit 9bf7065. * split macro module * inline partition macro * add median implementation * add more edge case test cases * fix fmt * remove quick_sort duplicate * feat: add median * docs: update PR * Route median through u256 workhorse fun (#325) * fix: fmt * fix: apply CR comments * test: add missing test * fix: macro * feat: use quickselect * feat: improve CHANGELOG * feat: apply review updates * feat: update comment --------- Co-authored-by: Daniel Bigos <daniel.bigos@openzeppelin.com> Co-authored-by: Daniel Bigos <daniel.bigos@icloud.com> Co-authored-by: immrsd <103599616+immrsd@users.noreply.github.com> Co-authored-by: Eric Nordelo <eric.nordelo39@gmail.com> * feat: update check * feat: update version * feat: bump version * feat: apply improvements --------- Co-authored-by: Nenad <nenad.misic@openzeppelin.com> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Co-authored-by: Daniel Bigos <daniel.bigos96@gmail.com> Co-authored-by: Alisander Qoshqosh <37006439+qalisander@users.noreply.github.com> Co-authored-by: Daniel Bigos <daniel.bigos@openzeppelin.com> Co-authored-by: Daniel Bigos <daniel.bigos@icloud.com> Co-authored-by: immrsd <103599616+immrsd@users.noreply.github.com> * [N-03] Math Core Audit (#360) * feat: Implement Rate Limiter module (#315) * feat: add rate limiter implementation * docs: document invariants * fix: enforce missing invariants * test: add more tests * feat: cooldown supports capacity/used * ref: assume monotonic Clock * fix: new_bucket accepts initial tokens (remove new_bucket_with_tokens) * ref: track cooldown_end instead of last_used * fix: cooldown used increases by 1 on consume * ref: use 'available' design instead of 'used' * ref: inline roll_window * test: add cooldown_reconfigure_rearms_when_drained_and_deadline_elapsed * docs: mention operator's responsibility for cooldown_ms * ref: rename q to steps_to_full in bucket_accrue * docs: update invariants * fix: remove capacity + refill_amount assertion in assert_bucket_config * docs: add missing / update docs * feat: add variety of errors * docs: add missing / update docs * test: remove invariant class mentions * ref: apply Code Quality Checklist (openzeppelin_utils) * test: replace cleanup with 'abort EUnreachable' in expected-failure tests * test: use abort 0 instead of error * feat: remove 'Ms' suffix from Error names * docs: error docs don't reference internal variables * docs: rephrase rate_limiter error messages without internal field names Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs: update README * docs: update README * docs: align invariants.md to be sharing-ready * docs: improve wording & clarity for invariants.md * feat: cooldown now decrements available by amount * test: change abort 0 to 100 (avoids confusing with ERateLimited) * test: change all destructor patterns into abortions * docs: invariant rewording * docs: update format for invariants.md * docs: update format for invariants.md and add missing invariants * docs: align invariants format * docs: update outdated invariant references * docs: remove rate limiter temp. artifacts * chore: simplify changelog * ref: convert assert macros into funs * docs: document private funs * test(fix): add proper teardown in happy tests * ci: add contracts/utils to CI test job dir matrix * test: add regression tests for bucket_accrue * fix: bucket_accrue double spend bug * docs: add empty line before enum variant docs Co-authored-by: Daniel Bigos <daniel.bigos96@gmail.com> * Revert "docs: add empty line before enum variant docs" This reverts commit 21a9076. * feat: inline config validation assertions * docs: add more info on rate limiter types in README * docs: add clarifying comments for apparent overflow suspects * docs: mention library being access control-agnostic * docs: reword library to module * feat: add initial_available to all limiter types * ref: put capacity as first cooldown type field * ref: use spread op instead of ignoring cooldown_ms field * docs: show identical API for all types in README * docs: for fixed window update wording that it resets to full capacity * fix: reconfigure sets last_refill to now + forbid 0 initial available for cooldown * docs: remove post-core artifact * test: add bucket_reconfigure_to_faster_rate_discards_old_subinterval * docs: add SAFETY before overflow-related comments * test: verify available always returns up-to-date accrual state * test: add missing zero-config reconfigure tests * test: add try_consume_with_zero_amount for all limiter types * test: add try_consume_of_available_aborts_when_drained * docs: note that try_consume(0) aborts after available() == 0 * docs: note RateLimiter enum is not upgrade-compatible Adding variants or fields to a deployed public enum would break BCS deserialization for integrator objects that already stored the prior shape. Document this constraint at the module level. * test: add edge case test cases * docs: remove llm artifacts * ref: reorder fileds in new_cooldown * test: remove Pub.local.toml * ref: in reconfigure_fixed_window move let now into match * ref: in reconfigure_bucket move let now into match * docs: remove mention of reconfigure_cooldown clamping available to 0 * fix: align cooldown clamp behavior on reconfigure * fix: try_consume updates state only on success * docs: align * ref: fixedwindow now shares bucket's internal logic * ref: update capacity prior to accrual on reconfigure_bucket * docs: add comment * Revert "docs: add comment" This reverts commit ecb0145. * Revert "ref: update capacity prior to accrual on reconfigure_bucket" This reverts commit b545b6d. * ref: Rate Limiter: Reconfiguration via Rich `new_*` Functions (#326) * impl * simplify further * fix: expose last_refill_ms for bucket * tests: add missing * docs: update utils README * docs: fix new_cooldown accepted combos * feat: project bucket-shaped anchor getters `last_refill_ms` and `window_start_ms` now take `&Clock` and return the anchor advanced by every whole interval elapsed since the last commit, so the snapshot `(anchor, available(clock))` is internally coherent. `cooldown_end_ms` stays a plain getter — a cooldown deadline does not evolve with time. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix: error numbering * fix: error messages no longer reference private fields * docs: move EBucketAnchorInFuture comment next to the error * add spec * update spec * tests: add missing invariant tests * feat: add is_type discriminator getters --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Co-authored-by: Eric Nordelo <eric.nordelo39@gmail.com> Co-authored-by: Daniel Bigos <daniel.bigos96@gmail.com> * tests: fix formatting in rate limiter tests (#334) * feat: add median implementation (#135) * add separate quick_sort implementations for each type * remove duplicated qsort implementations * add in-place qsort implementation * add partition function * rewrite qsort without recursion * convert quick_sort to macro * add comprehensive test cases for qsort * update qsort documentation * add review fixes * remove --trace flag from testing pipeline * Revert "remove --trace flag from testing pipeline" This reverts commit 9bf7065. * split macro module * inline partition macro * add median implementation * add more edge case test cases * fix fmt * remove quick_sort duplicate * feat: add median * docs: update PR * Route median through u256 workhorse fun (#325) * fix: fmt * fix: apply CR comments * test: add missing test * fix: macro * feat: use quickselect * feat: improve CHANGELOG * feat: apply review updates * feat: update comment --------- Co-authored-by: Daniel Bigos <daniel.bigos@openzeppelin.com> Co-authored-by: Daniel Bigos <daniel.bigos@icloud.com> Co-authored-by: immrsd <103599616+immrsd@users.noreply.github.com> Co-authored-by: Eric Nordelo <eric.nordelo39@gmail.com> * feat: update check * feat: update version * feat: bump version * feat: apply improvements * feat: improvements --------- Co-authored-by: Nenad <nenad.misic@openzeppelin.com> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Co-authored-by: Daniel Bigos <daniel.bigos96@gmail.com> Co-authored-by: Alisander Qoshqosh <37006439+qalisander@users.noreply.github.com> Co-authored-by: Daniel Bigos <daniel.bigos@openzeppelin.com> Co-authored-by: Daniel Bigos <daniel.bigos@icloud.com> Co-authored-by: immrsd <103599616+immrsd@users.noreply.github.com> * docs: add Rate limiter examples (#361) * docs: merge faucet examples into one * docs: add staking_vault example * docs: add base mage_duel example * docs: update mage_duel example * docs: delete metadata_cap in rare_coin * docs: apply move-quality skill * docs: fix mage_duel wrong duel assertion * docs: fix typo in utils/README * docs: remove ENotOpponent error from mage_duel * docs: move example tests to separate modules * docs: increase test coverage * docs: remove traces * docs: add missing test docs for examples * docs: fmt * docs: make unaudited examples warnings visible at top of sections * docs: use full gh URLs to examples * docs: change title 'rate_limiter at a Glance' to 'Rate Limiter at a Glance' * docs: remove operator notes * Update contracts/utils/README.md Co-authored-by: Eric Nordelo <eric.nordelo39@gmail.com> * docs: add exapmles ref in contracts/README * docs: fix mage_duel module docs * docs: remove mention of "compiling" examples Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * docs: remove mentions of "compiling" when mentioning examples Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * test: add test_only attribute to example test modules * test: take shared faucet in the test tx where it's actually needed * test: Add missing comment dots + remove redundant imports * docs: use release-v1.3 as the branch to point example URLs --------- Co-authored-by: Eric Nordelo <eric.nordelo39@gmail.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * chore: add rate limiter audit report (#364) * [N-04] Core Math Audit (#363) * feat: Implement Rate Limiter module (#315) * feat: add rate limiter implementation * docs: document invariants * fix: enforce missing invariants * test: add more tests * feat: cooldown supports capacity/used * ref: assume monotonic Clock * fix: new_bucket accepts initial tokens (remove new_bucket_with_tokens) * ref: track cooldown_end instead of last_used * fix: cooldown used increases by 1 on consume * ref: use 'available' design instead of 'used' * ref: inline roll_window * test: add cooldown_reconfigure_rearms_when_drained_and_deadline_elapsed * docs: mention operator's responsibility for cooldown_ms * ref: rename q to steps_to_full in bucket_accrue * docs: update invariants * fix: remove capacity + refill_amount assertion in assert_bucket_config * docs: add missing / update docs * feat: add variety of errors * docs: add missing / update docs * test: remove invariant class mentions * ref: apply Code Quality Checklist (openzeppelin_utils) * test: replace cleanup with 'abort EUnreachable' in expected-failure tests * test: use abort 0 instead of error * feat: remove 'Ms' suffix from Error names * docs: error docs don't reference internal variables * docs: rephrase rate_limiter error messages without internal field names Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs: update README * docs: update README * docs: align invariants.md to be sharing-ready * docs: improve wording & clarity for invariants.md * feat: cooldown now decrements available by amount * test: change abort 0 to 100 (avoids confusing with ERateLimited) * test: change all destructor patterns into abortions * docs: invariant rewording * docs: update format for invariants.md * docs: update format for invariants.md and add missing invariants * docs: align invariants format * docs: update outdated invariant references * docs: remove rate limiter temp. artifacts * chore: simplify changelog * ref: convert assert macros into funs * docs: document private funs * test(fix): add proper teardown in happy tests * ci: add contracts/utils to CI test job dir matrix * test: add regression tests for bucket_accrue * fix: bucket_accrue double spend bug * docs: add empty line before enum variant docs Co-authored-by: Daniel Bigos <daniel.bigos96@gmail.com> * Revert "docs: add empty line before enum variant docs" This reverts commit 21a9076. * feat: inline config validation assertions * docs: add more info on rate limiter types in README * docs: add clarifying comments for apparent overflow suspects * docs: mention library being access control-agnostic * docs: reword library to module * feat: add initial_available to all limiter types * ref: put capacity as first cooldown type field * ref: use spread op instead of ignoring cooldown_ms field * docs: show identical API for all types in README * docs: for fixed window update wording that it resets to full capacity * fix: reconfigure sets last_refill to now + forbid 0 initial available for cooldown * docs: remove post-core artifact * test: add bucket_reconfigure_to_faster_rate_discards_old_subinterval * docs: add SAFETY before overflow-related comments * test: verify available always returns up-to-date accrual state * test: add missing zero-config reconfigure tests * test: add try_consume_with_zero_amount for all limiter types * test: add try_consume_of_available_aborts_when_drained * docs: note that try_consume(0) aborts after available() == 0 * docs: note RateLimiter enum is not upgrade-compatible Adding variants or fields to a deployed public enum would break BCS deserialization for integrator objects that already stored the prior shape. Document this constraint at the module level. * test: add edge case test cases * docs: remove llm artifacts * ref: reorder fileds in new_cooldown * test: remove Pub.local.toml * ref: in reconfigure_fixed_window move let now into match * ref: in reconfigure_bucket move let now into match * docs: remove mention of reconfigure_cooldown clamping available to 0 * fix: align cooldown clamp behavior on reconfigure * fix: try_consume updates state only on success * docs: align * ref: fixedwindow now shares bucket's internal logic * ref: update capacity prior to accrual on reconfigure_bucket * docs: add comment * Revert "docs: add comment" This reverts commit ecb0145. * Revert "ref: update capacity prior to accrual on reconfigure_bucket" This reverts commit b545b6d. * ref: Rate Limiter: Reconfiguration via Rich `new_*` Functions (#326) * impl * simplify further * fix: expose last_refill_ms for bucket * tests: add missing * docs: update utils README * docs: fix new_cooldown accepted combos * feat: project bucket-shaped anchor getters `last_refill_ms` and `window_start_ms` now take `&Clock` and return the anchor advanced by every whole interval elapsed since the last commit, so the snapshot `(anchor, available(clock))` is internally coherent. `cooldown_end_ms` stays a plain getter — a cooldown deadline does not evolve with time. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix: error numbering * fix: error messages no longer reference private fields * docs: move EBucketAnchorInFuture comment next to the error * add spec * update spec * tests: add missing invariant tests * feat: add is_type discriminator getters --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Co-authored-by: Eric Nordelo <eric.nordelo39@gmail.com> Co-authored-by: Daniel Bigos <daniel.bigos96@gmail.com> * tests: fix formatting in rate limiter tests (#334) * feat: add median implementation (#135) * add separate quick_sort implementations for each type * remove duplicated qsort implementations * add in-place qsort implementation * add partition function * rewrite qsort without recursion * convert quick_sort to macro * add comprehensive test cases for qsort * update qsort documentation * add review fixes * remove --trace flag from testing pipeline * Revert "remove --trace flag from testing pipeline" This reverts commit 9bf7065. * split macro module * inline partition macro * add median implementation * add more edge case test cases * fix fmt * remove quick_sort duplicate * feat: add median * docs: update PR * Route median through u256 workhorse fun (#325) * fix: fmt * fix: apply CR comments * test: add missing test * fix: macro * feat: use quickselect * feat: improve CHANGELOG * feat: apply review updates * feat: update comment --------- Co-authored-by: Daniel Bigos <daniel.bigos@openzeppelin.com> Co-authored-by: Daniel Bigos <daniel.bigos@icloud.com> Co-authored-by: immrsd <103599616+immrsd@users.noreply.github.com> Co-authored-by: Eric Nordelo <eric.nordelo39@gmail.com> * feat: update check * feat: update version * feat: bump version * feat: apply improvements * feat: improvements * feat: improve median impl * docs: math/core doc-quality pass + median wrapper docs and u128 tests (#365) Post-review follow-ups on the N-04 median work plus a doc-quality sweep of math/core (move-quality checklist): - vector: document #### Parameters / #### Returns on the median_u8..median_u256 wrappers (previously only #### Aborts). - median tests: add median_u128_even_length_rounding_modes and extend median_u128_basics with the 0 & MAX overflow boundary (BTT gap fill). - macros: add /// docs to EDivideByZero/EZeroModulus and the TEN_POW_* consts; fix spurious-bullet continuations in several #### Returns/#### Aborts blocks; add #### Generics to inv_mod/mul_mod, #### Aborts to mul_mod/mul_div_inner/ inv_mod_extended_impl, and name EZeroModulus in inv_mod's #### Aborts. - u512: add /// docs to the four error constants, HALF_BITS/HALF_MASK, and the hi/lo struct fields. - decimal_scaling: tag example fences as ```move, promote the "Truncation Behavior" header to ####, and convert scale_amount's #### Examples to a fenced move block. - decimal_scaling tests: rename "Test Helpers" section to "Test-Only Helpers". All 753 tests pass with --lint --warnings-are-errors; prettier clean. --------- Co-authored-by: Nenad <nenad.misic@openzeppelin.com> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Co-authored-by: Daniel Bigos <daniel.bigos96@gmail.com> Co-authored-by: Alisander Qoshqosh <37006439+qalisander@users.noreply.github.com> Co-authored-by: Daniel Bigos <daniel.bigos@openzeppelin.com> Co-authored-by: Daniel Bigos <daniel.bigos@icloud.com> Co-authored-by: immrsd <103599616+immrsd@users.noreply.github.com> * feat: add Published info (#369) * feat: add Published info (#371) * chore: Add core math diff audit report (#372) * chore: add core math diff audit report * chore: update name and commit range * chore: update changelog for release v1.3 (#373) * docs: update docs' URLs (#387) * docs: use relative paths for example links in README * docs: link to specific examples in rate_limiter mod docs * docs: change tree to block in gh urls * remove .skills --------- Co-authored-by: Eric Nordelo <eric.nordelo39@gmail.com> Co-authored-by: immrsd <103599616+immrsd@users.noreply.github.com> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Co-authored-by: Daniel Bigos <daniel.bigos96@gmail.com> Co-authored-by: Alisander Qoshqosh <37006439+qalisander@users.noreply.github.com> Co-authored-by: Daniel Bigos <daniel.bigos@openzeppelin.com> Co-authored-by: Daniel Bigos <daniel.bigos@icloud.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Summary by CodeRabbit
Breaking Changes
renounce_rolesignature: the account parameter has been removed. Callers must now rely on the transaction context instead of specifying an explicit account.New Features
new_with_adminconstructor to properly initialize with the provided initial administrator address and emit corresponding events.