Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ the release policy in `docs/release-policy.md`.
- Added metadata golden-fixture safety checks for JSON/data-URI decoding,
current URI scheme policy, and generated animation HTML script-boundary
validation in local and CI gates.
- Added renderer URI policy helpers and production token image URI validation
for required metadata image inputs.

### Release Impact

Expand All @@ -44,6 +46,8 @@ the release policy in `docs/release-policy.md`.
metadata size-limit custom errors and public limit constants.
- Gate D now runs metadata fixture safety checks in `make check`, CI, and the
platform check wrappers.
- Gate D/G release artifacts now include the ABI and bytecode deltas from the
metadata URI policy helper functions and `UnsafeMetadataURI()` custom error.
- Detached checksum signatures, signed release tags, production address books,
and verified live deployment addresses remain future release-ceremony work.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"generated_by": "scripts/generate_address_books.py:1",
"source": {
"deployment_manifest": "deployments/examples/anvil-6529stream-v0.1.0-001-broadcast.json",
"deployment_manifest_sha256": "sha256:79a0530da77ce6653198a15ccccf2a2deb023765f7a6d14b5a3f28300e19785e",
"deployment_manifest_sha256": "sha256:38bdd644fe53b71a2b3b9afb6cc4de258f28e43b48428cda4646075ea5e34ed1",
"release_artifacts": "release-artifacts/latest",
"abi_checksums": "release-artifacts/latest/abi-checksums.json",
"event_topic_catalog": "release-artifacts/latest/event-topic-catalog.json"
Expand Down Expand Up @@ -65,8 +65,8 @@
"address": "0x1000000000000000000000000000000000000003",
"source": "smart-contracts/StreamCore.sol",
"artifact_path": "out/StreamCore.sol/StreamCore.json",
"abi_hash": "sha256:820f6962c8e27c7e73ac51e18fdfddd81c517f58101a3b28335fcdbba5f7d4b3",
"runtime_bytecode_hash": "sha256:db8cc579c656c43f09acc0fb6ee3d74ad2bc1b0877fc71f0c0737116556e7977",
"abi_hash": "sha256:3738c2bf120feb5bb300a05cb19553829c65b76b2526a70e880e181027d49627",
"runtime_bytecode_hash": "sha256:5a16fdc2550ebfd91c705e6fe790836c86d1b5600f07d46f21db5603fccaa156",
"verification_status": "not_applicable"
},
"StreamCuratorsPool": {
Expand Down
6 changes: 3 additions & 3 deletions deployments/address-books/anvil-6529stream-v0.1.0-001.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"generated_by": "scripts/generate_address_books.py:1",
"source": {
"deployment_manifest": "deployments/examples/anvil-6529stream-v0.1.0-001.json",
"deployment_manifest_sha256": "sha256:926ef2be2b0c7b68f860cb678d545bb35fb3e4507867085d5aff56ec8f70f721",
"deployment_manifest_sha256": "sha256:c1b7b64b7fc2f528260788e206dd3270341be9810230c9914ae350084667fa82",
"release_artifacts": "release-artifacts/latest",
"abi_checksums": "release-artifacts/latest/abi-checksums.json",
"event_topic_catalog": "release-artifacts/latest/event-topic-catalog.json"
Expand Down Expand Up @@ -65,8 +65,8 @@
"address": "0x0000000000000000000000000000000000000003",
"source": "smart-contracts/StreamCore.sol",
"artifact_path": "out/StreamCore.sol/StreamCore.json",
"abi_hash": "sha256:820f6962c8e27c7e73ac51e18fdfddd81c517f58101a3b28335fcdbba5f7d4b3",
"runtime_bytecode_hash": "sha256:db8cc579c656c43f09acc0fb6ee3d74ad2bc1b0877fc71f0c0737116556e7977",
"abi_hash": "sha256:3738c2bf120feb5bb300a05cb19553829c65b76b2526a70e880e181027d49627",
"runtime_bytecode_hash": "sha256:5a16fdc2550ebfd91c705e6fe790836c86d1b5600f07d46f21db5603fccaa156",
"verification_status": "not_applicable"
},
"StreamCuratorsPool": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@
"0x0000000000000000000000000000000000000001",
"0x0000000000000000000000000000000000000002"
],
"abi_hash": "sha256:820f6962c8e27c7e73ac51e18fdfddd81c517f58101a3b28335fcdbba5f7d4b3",
"bytecode_hash": "sha256:db8cc579c656c43f09acc0fb6ee3d74ad2bc1b0877fc71f0c0737116556e7977",
"abi_hash": "sha256:3738c2bf120feb5bb300a05cb19553829c65b76b2526a70e880e181027d49627",
"bytecode_hash": "sha256:5a16fdc2550ebfd91c705e6fe790836c86d1b5600f07d46f21db5603fccaa156",
"verification_status": "not_applicable"
},
"StreamCuratorsPool": {
Expand Down Expand Up @@ -166,11 +166,11 @@
]
},
"release_artifacts": {
"manifest_sha256": "sha256:79a0530da77ce6653198a15ccccf2a2deb023765f7a6d14b5a3f28300e19785e",
"manifest_sha256": "sha256:38bdd644fe53b71a2b3b9afb6cc4de258f28e43b48428cda4646075ea5e34ed1",
"abi_hashes": {
"StreamAdmins": "sha256:0dec302776ef6fe8038a96a716c7300d697c52c9b8d79559ab86c2b5c6599dd5",
"DependencyRegistry": "sha256:8600876198d591fdae934b20c5d370490939504890944dbd8249d85ef17a6795",
"StreamCore": "sha256:820f6962c8e27c7e73ac51e18fdfddd81c517f58101a3b28335fcdbba5f7d4b3",
"StreamCore": "sha256:3738c2bf120feb5bb300a05cb19553829c65b76b2526a70e880e181027d49627",
"StreamCuratorsPool": "sha256:f5d65fb2b17cf0caae7c8c75c6736c5828c869502f55634279556ba8483e6daf",
"StreamMinter": "sha256:5464ee3c1b5c40867aba4565d11fe6b708ea2b2e93aba4f7e3a52ebbe4296c3e",
"StreamDrops": "sha256:2314f89858673138e8b9c2e421dd7a727c7e7746d5eb069e58a61699f2f4de6a",
Expand Down
8 changes: 4 additions & 4 deletions deployments/examples/anvil-6529stream-v0.1.0-001.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@
"0x0000000000000000000000000000000000000001",
"0x0000000000000000000000000000000000000002"
],
"abi_hash": "sha256:820f6962c8e27c7e73ac51e18fdfddd81c517f58101a3b28335fcdbba5f7d4b3",
"bytecode_hash": "sha256:db8cc579c656c43f09acc0fb6ee3d74ad2bc1b0877fc71f0c0737116556e7977",
"abi_hash": "sha256:3738c2bf120feb5bb300a05cb19553829c65b76b2526a70e880e181027d49627",
"bytecode_hash": "sha256:5a16fdc2550ebfd91c705e6fe790836c86d1b5600f07d46f21db5603fccaa156",
"verification_status": "not_applicable"
},
"StreamCuratorsPool": {
Expand Down Expand Up @@ -166,11 +166,11 @@
]
},
"release_artifacts": {
"manifest_sha256": "sha256:926ef2be2b0c7b68f860cb678d545bb35fb3e4507867085d5aff56ec8f70f721",
"manifest_sha256": "sha256:c1b7b64b7fc2f528260788e206dd3270341be9810230c9914ae350084667fa82",
"abi_hashes": {
"StreamAdmins": "sha256:0dec302776ef6fe8038a96a716c7300d697c52c9b8d79559ab86c2b5c6599dd5",
"DependencyRegistry": "sha256:8600876198d591fdae934b20c5d370490939504890944dbd8249d85ef17a6795",
"StreamCore": "sha256:820f6962c8e27c7e73ac51e18fdfddd81c517f58101a3b28335fcdbba5f7d4b3",
"StreamCore": "sha256:3738c2bf120feb5bb300a05cb19553829c65b76b2526a70e880e181027d49627",
"StreamCuratorsPool": "sha256:f5d65fb2b17cf0caae7c8c75c6736c5828c869502f55634279556ba8483e6daf",
"StreamMinter": "sha256:5464ee3c1b5c40867aba4565d11fe6b708ea2b2e93aba4f7e3a52ebbe4296c3e",
"StreamDrops": "sha256:2314f89858673138e8b9c2e421dd7a727c7e7746d5eb069e58a61699f2f4de6a",
Expand Down
12 changes: 8 additions & 4 deletions docs/adr/0006-metadata-freeze.md
Original file line number Diff line number Diff line change
Expand Up @@ -231,10 +231,14 @@ strings. The second slice hardens generated animation wrapper boundaries by
escaping the external library attribute, embedding `tokenData` and dependency
scripts through escaped JavaScript strings, and neutralizing closing-script
sequences. The third slice defines numeric byte limits for stored metadata
inputs and generated `tokenURI` output. The remaining public-beta work is still
to define semantic attribute schema validation or structured attributes,
browser render-sandbox proofing for generated animation code, URI policy checks,
and invalid UTF-8 policy.
inputs and generated `tokenURI` output. The fourth slice validates committed
metadata fixtures outside Foundry for JSON/data-URI/HTML boundaries and the
current URI scheme policy. The fifth slice exposes renderer URI policy helpers
and enforces the required content URI policy for token image writes. The
remaining public-beta work is still to define semantic attribute schema
validation or structured attributes, browser render-sandbox proofing for
generated animation code, collection base URI and external library URL
production URI checks, and invalid UTF-8 policy.

The implementation must define maximum sizes for:

Expand Down
13 changes: 8 additions & 5 deletions docs/known-blockers.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,18 +81,21 @@ contributors who start from the README.
`tokenData` from an escaped string, and neutralizes closing-script sequences
in generated HTML. Numeric byte limits now cover collection display fields,
collection scripts, token data, token images, token attributes, generated
`tokenURI` output, dependency scripts, and dependency provenance. Remaining
metadata blockers include dependency artifact packaging and deployment
`tokenURI` output, dependency scripts, and dependency provenance. Token image
writes now reject unsafe content URI inputs, and renderer helpers define the
current content/script URI scheme policy for tests and fixture checks.
Remaining metadata blockers include dependency artifact packaging and deployment
migration runbooks beyond registry provenance strings, full browser execution
sandbox automation, semantic attribute schema validation, production URI
enforcement, and invalid UTF-8 policy. Committed metadata fixtures now have
sandbox automation, semantic attribute schema validation, collection base URI
and external library URL production enforcement, and invalid UTF-8 policy.
Committed metadata fixtures now have
Python checks for JSON/data-URI decoding, current URI scheme policy, and final
animation HTML wrapper/script boundaries.
- `StreamCore` now uses a linked metadata renderer library, removes optional
ERC-721 Enumerable support, preserves a live `totalSupply()`
view, and has a production-only size gate:
`forge build --sizes --via-ir --skip test --skip script --force`. That gate currently shows
`StreamCore` under EIP-170 with deployment headroom, but deployment scripts,
`StreamCore` under EIP-170 with narrow deployment headroom, but deployment scripts,
manifests, and rehearsals still need to use this production profile.
- Dead public/allowlist mint-count mappings and retrieval APIs were removed
from `StreamCore`; the retained airdrop counter now has explicit regression
Expand Down
34 changes: 28 additions & 6 deletions docs/metadata.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,10 @@ base64-encoded HTML animation URL.
fields emitted by on-chain metadata and rejects raw attribute fragments that
contain literal control characters, unterminated strings, unbalanced
object/array delimiters, or unquoted `]`/`}` breakout attempts. It does not yet
solve semantic attribute schema validation, URI policy, invalid UTF-8 policy,
browser render-sandbox checks, dependency artifact packaging beyond registry
provenance strings, stale randomness display, or deployment release manifests.
solve semantic attribute schema validation, collection base URI or external
library URL production enforcement, invalid UTF-8 policy, browser
render-sandbox checks, dependency artifact packaging beyond registry provenance
strings, stale randomness display, or deployment release manifests.

## Escaping And Attribute Fragments

Expand Down Expand Up @@ -83,9 +84,30 @@ script. This protects wrapper structure, but it does not sandbox artist
`collectionScript` code or certify dependency code as safe. Release tooling
now validates the committed golden fixtures for JSON/data-URI structure,
current URI scheme policy, and generated HTML wrapper/script boundaries.
Full browser execution sandboxing, production URI enforcement, semantic
attribute validation, and invalid UTF-8 policy remain required before public
beta.
Full browser execution sandboxing, collection base URI and external library URL
production enforcement, semantic attribute validation, and invalid UTF-8 policy
remain required before public beta.

## URI Policy

`StreamMetadataRenderer` exposes the current URI policy used by metadata tests
and fixture checks:

- Content URIs allow `https://`, `ipfs://`, and `ar://` values.
- Required content URIs must be nonempty.
- Optional content URIs may be empty when the caller explicitly allows it.
- Script URIs allow only nonempty `https://` values.
- `https://` URIs must include a host byte after the scheme.
- URI values containing ASCII whitespace, other ASCII control characters, or
DEL are rejected.

`StreamCore.updateImagesAndAttributes` now enforces the required content URI
policy for token image inputs before storing them, reverting with
`UnsafeMetadataURI()` on failure. Collection base URI and external library URL
production enforcement remain open because `StreamCore` is close to the
EIP-170 bytecode limit; those surfaces are still covered only by size limits,
fixture checks, docs, and release review until a later implementation slice
adds deployable enforcement.

## Size Limits

Expand Down
13 changes: 9 additions & 4 deletions docs/status.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ The current Gate A smoke baseline proves:
- Foundry is configured to compile `smart-contracts`.
- `forge build` runs against Solidity `0.8.19`.
- `forge build --sizes --via-ir --skip test --skip script --force` runs as the production
size gate. Current `StreamCore` production runtime size is 24,461 bytes,
leaving 115 bytes of EIP-170 headroom under the IR-optimized deployment
size gate. Current `StreamCore` production runtime size is 24,508 bytes,
leaving 68 bytes of EIP-170 headroom under the IR-optimized deployment
profile.
- `forge test -vvv` executes real tests for admin guards, target-scoped
function-admin permission regressions, domain-scoped pause controls,
Expand Down Expand Up @@ -72,6 +72,10 @@ The current Gate A smoke baseline proves:
for collection display fields, collection script chunks and counts, token
data, token images, token raw attributes, generated `tokenURI` output,
dependency script chunks and counts, and dependency provenance strings.
`StreamMetadataUriPolicy.t.sol` proves the renderer content/script URI
policy helpers and the production token image URI guard for allowed
`https://`, `ipfs://`, and `ar://` content URIs plus rejected empty,
JavaScript, hostless HTTPS, and whitespace-bearing token image inputs.
`scripts/test_metadata_fixtures.py` and
`scripts/check_metadata_fixtures.py` validate the committed metadata golden
fixtures outside Foundry by strictly decoding JSON and HTML data URIs,
Expand Down Expand Up @@ -144,8 +148,9 @@ release tags, production address books, verified live
deployment hashes and explorer submissions, remaining generated
HTML/JavaScript render-sandbox hardening, dependency
artifact packaging and migration runbooks beyond registry provenance strings,
semantic attribute schema validation, production URI enforcement, invalid UTF-8
policy, full browser execution sandbox automation, deployment discipline, and
semantic attribute schema validation, collection base URI and external library
URL production enforcement, invalid UTF-8 policy, full browser execution
sandbox automation, deployment discipline, and
the broader P0/P1 test suite.

Contributor and security intake files exist so future work can be packaged and
Expand Down
Loading
Loading