The four changes
Every requirement, every candidate.
Highlighted rows are faults the ported upstream tests accept. Each change keeps its own requirement version: a parent revision is graded against the behaviour it promised, so a requested change is not counted as an upstream defect.
Use unsafeAccess in EnumerableSet
Switches the set’s internal array reads and writes to unchecked access. One contract file changes: EnumerableSet.sol.
Parent229fc7682026-09-17 · its own requirement version
Currentdab7110e2026-09-17 · re-run from scratch
Contract files1 changedcode
Requirements8 carriednone inherits a pass
Parent’s passing resultRefused for this revision“Result belongs to different requested inputs”
Current revisionAll checks passapproval still needs review
| Candidate | Label | Ported upstream tests | SCAR checks | Failed requirements |
|---|
| The parent revision, before the changeupstream-parent · 229fc768 | valid | accepted | accepted | — |
| The current revision, as mergedupstream-current · dab7110e | valid | accepted | accepted | — |
| Valid alternative: the current revision with the parent’s checked access restoredchecked-access-alternative · dab7110e | valid | accepted | accepted | — |
| Constructed fault: records the moved value’s position off by onewrong-moved-position · dab7110e | faulty | rejected | rejected | moved-position, sequence-membership, variable-width-reuse |
| Constructed fault: silently refuses to store the zero valuezero-sentinel-assumption · dab7110e | faulty | accepted | rejected | sequence-membership, variable-width-reuse |
| Constructed fault: clearing leaves stale position records behindstale-cleared-position · dab7110e | faulty | rejected | rejected | clear-reuse, sequence-membership, variable-width-reuse |
8 requirements, in plain words
- Legitimate useClearing removes values and position records; previously held values can be reinserted.clear-reuse
- Legitimate useA new collection is empty and removing an absent member returns false.empty-set
- Legitimate useRemoving a non-last member preserves the moved member's position so later removal remains correct.moved-position
- Legitimate useInsertion preserves unique membership and duplicate insertion returns false.set-insertion
- Legitimate usePagination clamps its range and returns the selected current values.set-pagination
- BoundaryEmpty, end and overflowing indices are rejected without changing membership.index-bounds
- BoundaryAcross 32 generated operations over an eight-value domain, membership, cardinality and enumeration agree with an independent Boolean reference model.SCAR-authoredsequence-membership
- BoundaryEmpty and 1/31/32/33/64/65/129-byte values retain correct membership across removal, clearing and reuse.SCAR-authoredvariable-width-reuse
Scope and changed files
The three changed storage implementations: Bytes32Set, StringSet and BytesSet. Generated sequences use eight values and 32 operations; asymptotic gas cost and every wrapper type are not proven. All checks are controlled local unit executions. Full upstream JS/TS suites, deployed state and independent labels are outside this experiment.
contracts/utils/structs/EnumerableSet.sol · code changed
Do not propagate reverts on signatures
Moves contract-signature validation into a new SecuredSignatureValidator, which treats a reverting signer as an invalid signature. Two contract files change (Safe.sol, and the new validator), and two requirement definitions change with them.
Parent09fada862026-05-27 · its own requirement version
Current77901a5a2026-06-05 · re-run from scratch
Contract files2 changedcode, new file; SCAR’s review test updated
Requirements6 carried, 2 changednone inherits a pass
Parent’s passing resultRefused for this revision“Result belongs to different requested inputs”
Current revisionAll checks passapproval still needs review
| Candidate | Label | Ported upstream tests | SCAR checks | Failed requirements |
|---|
| The parent revision, before the changeupstream-parent · 09fada86 | valid | accepted | accepted | — |
| The current revision, as mergedupstream-current · 77901a5a | valid | accepted | accepted | — |
| Valid alternative: reads the returned word in assembly instead of abi.decodeword-load-alternative · 77901a5a | valid | accepted | accepted | — |
| Constructed fault: accepts a signer response longer than 32 bytestrailing-data-accepted · 77901a5a | faulty | accepted | rejected | return-length |
| Constructed fault: accepts any 32-byte response, magic value or notmagic-check-omitted · 77901a5a | faulty | rejected | rejected | invalid-contract-signature, signature-inputs |
| Constructed fault: rejects every contract signatureall-signatures-rejected · 77901a5a | faulty | rejected | rejected | return-length, signature-inputs, valid-contract-signature |
8 requirements, in plain words
- SecurityA reverting signer is reported as the Safe GS024 signature error.changedfailure-contractBefore:
A reverting signer propagates its original failure data under the pre-change call contract. - SecurityA well-formed response with a non-magic value is rejected.invalid-contract-signature
- SecurityAn address with no code cannot satisfy a contract-signature check by returning empty data.SCAR-authoredsigner-code
- SecuritySignature validation cannot commit writes to the signer contract's state.SCAR-authoredstatic-signature-validation
- Legitimate useThe intended hash and signature bytes are passed unchanged to the contract signer.signature-inputs
- Legitimate useA well-formed 32-byte ABI-encoded ERC-1271 magic response is accepted.valid-contract-signature
- BoundaryA signer response is accepted only when its length is exactly 32 bytes and the word is ABI-encoded ERC-1271 magic.changedSCAR-authoredreturn-lengthBefore:
The pre-change ABI call accepts the correctly padded magic word with at least 32 returned bytes, including trailing data. - BoundaryThe signature offset and length are checked before reading signer data, preserving GS022 and GS023 outcomes.signature-bounds
Scope and changed files
Safe.checkContractSignature through an explicit internal-method adapter and controlled ERC-1271 signers. Owner-list, threshold, transaction execution and P-256 precompile correctness are outside this scoped pack. All checks are controlled local unit executions. Full upstream JS/TS suites, deployed state and independent labels are outside this experiment.
contracts/Safe.sol · code changedcontracts/common/SecuredSignatureValidator.sol · new filereview-tests/current/SignatureRequirements.t.sol · SCAR’s review test, updated with the change
Document delegatecall interaction with AccessManaged.setAuthority
Documentation in AccessManaged.sol and AccessManager.sol. No executable code changes; one requirement is added to cover what the new comment describes.
Parent7c856ec22026-09-18 · its own requirement version
Current9a0211902026-09-21 · re-run from scratch
Contract files2 changedcomments only
Requirements5 carried, 1 addednone inherits a pass
Parent’s passing resultRefused for this revision“Result belongs to different requested inputs”
Current revisionAll checks passapproval still needs review
| Candidate | Label | Ported upstream tests | SCAR checks | Failed requirements |
|---|
| The parent revision, before the changeupstream-parent · 7c856ec2 | valid | accepted | accepted | — |
| The current revision, as mergedupstream-current · 9a021190 | valid | accepted | accepted | — |
6 requirements, in plain words
- SecurityA direct authority transfer from a caller other than the current authority is rejected.authority-caller
- SecurityA direct transfer to an address with no code is rejected.authority-code
- SecurityThe setAuthority reservation is checked for the direct entry selector; it does not establish an invariant over delegated entry paths.addedSCAR-authoredselector-scope
- Legitimate useThe current authority can transfer the target to another deployed authority.authority-transfer
- Legitimate useAn authorized manager execution can invoke the target's restricted application function.SCAR-authoredmanaged-call
- SetupThe target is initialized with the configured manager as its authority.initial-authority
Scope and changed files
AccessManaged direct authority transfers and a controlled AccessManager application call. The direct-selector check does not establish safety of self-delegated entry paths. All checks are controlled local unit executions. Full upstream JS/TS suites, deployed state and independent labels are outside this experiment.
contracts/access/manager/AccessManaged.sol · comments changedcontracts/access/manager/AccessManager.sol · comments changed