Ecosystem metrics
- New Repos
- 1,897
- New
- Commits
- 69
- up 64.3%
- Releases
- 10
- up 66.7%
- Contributors
- 28
- up 21.7%
- Merges
- 2
- up 100.0%
Activity Overview
Commits and releases over time
- Commits
- Releases
- Authors
Repository Explorer
No repositories match that filter.
600 commits in all time
May 20, 2026 09:40 – Aug 18, 2026 09:40 UTC
Merge 0d42a5f7258852c30958e5d9644ab7962d2f24d3 into c1e451f3864d614d28a54c6e5beacd19cdb71592
fa5e8421
undefined
5/657 ++ 349 --
Merge 4b3bd37c1f13d8a1d5b98f57b1ccb3c9fb9c703e into c1e451f3864d614d28a54c6e5beacd19cdb71592
3ec779c2
pull/38/merge
2/144 ++ 1 --
feat: contracts: instances self-fund MBR from the registry on vote
- The registry becomes an MBR vault. `vote()` ends with `checkNeedMBR()` subroutine: if the instance app account is at or below its minimum balance, it inner-calls the registry's new `requestMBR`, which pays it `mbrTopUp` (new global, 5 A, settable via `setMBRTopUp`). Users never pay vote-record MBR, and instances no longer need hand-funding. - Post-condition, not a threshold. The AVM updates `min_balance` the instant a box is allocated but enforces the requirement only after each (outer) transaction, so the account may sit underwater mid-execution as long as the top-up lands first. However, MBR do is enforced between intermediate states of a group transaction, so a sibling payment later in the same group would be too late. Nits: `checkNeedMBR()` could sit in more than one place: - periodVoteCache is always an overwrite, so the call could go before it - on a re-vote the record write is an overwrite too, so the call could be skipped Left plain at the end for clarity; the saving would be a handful of opcodes. What is not flexible is that it must stay after the vote record write - that write is the allocation it repairs.
4cdbf76f
feat/frac-pipeline
14/7,307 ++ 5,018 --
Also verify the typed client, the artifact the tests actually run against
There are TWO arrows out of the committed artifact, not one, and neither was
checked:
contracts/out/TrelyanInscription.*
| algod compile | algokit generate client
v v
bytecode ==? chain contracts/trelyan_client.py
The client branch matters more than it looks. contracts/trelyan_client.py is an
89 KB generated file stamped "DO NOT MODIFY IT BY HAND", and the LocalNet suite
deploys the committed TEAL and drives it THROUGH that client. CI only ever
consumes it; nothing regenerated it and compared. A contract whose ABI moved
without the client being regenerated would be exercised by a suite talking to
the old interface -- and the suite would pass.
CHECKED WITHOUT RUNNING THE GENERATOR, DELIBERATELY
`algokit generate client` needs algokitgen-py, which would pin this check to a
generator version whose formatting churn is not a finding. It is also, on the
machine this was written on, blocked outright by a Windows Application Control
policy (os error 4551) -- the same policy that currently blocks cargo-deny.
No generator is needed: the client EMBEDS the full spec it was generated from,
in _APP_SPEC_JSON. Comparing that to the committed arc56.json needs nothing but
the two committed files, runs anywhere, and is stable across generator versions.
The comparison is on PARSED JSON rather than bytes, because the client embeds
the spec minified while arc56.json is pretty-printed -- a byte comparison would
fail always and therefore mean nothing.
Failure reporting distinguishes an ABI-method change (names differ; the suite is
testing a different interface) from a signature/struct/metadata change (names
agree), because those read very differently to a reviewer.
VERIFIED
- clean tree: all five artifacts plus the client in step, exit 0
- rename a method inside the client's embedded spec: CLIENT DRIFT, exit 1,
naming both method lists
- a missing _APP_SPEC_JSON block is reported as "repair the check", not
silently passed -- if the generator's output shape changes, this check stops
reading what it thinks it reads, and that is a finding about the check
ee6e17aa
ci/verify-teal-matches-source
1/87 ++ 4 --
Merge 592af0c9820f634b59989ab3e81f02fc53acf965 into c1e451f3864d614d28a54c6e5beacd19cdb71592
dfaee88b
pull/29/merge
3/82 ++ 1 --
Reject a mis-sized pubkey in verify() — it was a reachable OOB read
HIGH. `falcon_det1024_verify_compressed` takes NO pubkey length parameter:
deterministic.c calls falcon_verify(..., pubkey, FALCON_DET1024_PUBKEY_SIZE,
...), so it reads exactly 1793 bytes from that pointer regardless of what the
caller allocated. `sig` and `message` are length-delimited and bounded; pubkey
alone was not.
FalconDet1024.verify() passed pubkey straight through as a bare c_char_p with
no check, so a shorter buffer read up to 1729 bytes past the end. Reachable
from the shipped public API -- trelyan_pq.verify is exported from __init__ --
so a verifier reading a pubkey from an arbitrary box or file could crash, or
compute a verdict partly from unrelated adjacent heap memory.
Proved with a guard page (two pages, only the first committed, payload flush
against the boundary):
full 1793-byte pubkey -> returns cleanly, reads exactly 1793
1792-byte pubkey -> ACCESS VIOLATION at the first byte past the buffer
64-byte pubkey -> ACCESS VIOLATION
The one-byte-short case is the one that matters: it is the realistic
truncation. Reaching it needs no valid signature -- junk bytes with the right
two header values get there.
The asymmetry is what marks it an oversight rather than a decision: sign() has
always checked len(privkey) != PRIVKEY_SIZE. verify() checked nothing.
WHY NOTHING CAUGHT IT, which is the part worth keeping:
* tests/fuzz/fuzz_falcon_verify.cc (C/ASan, 13.8M execs) DOCUMENTS this exact
invariant and honours it -- it always hands the function a fixed 1793-byte
buffer, and its comment calls a smaller one "a caller-side over-read -- a
harness bug, not a finding". Correct, and it means that harness could never
surface this by construction.
* tests/fuzz/fuzz_encoding_atheris.py DID feed short pubkeys and asserted
verify() "must return False, not raise" -- an assertion the code could not
satisfy, because it crashed instead. That file is referenced by no
workflow, so it has never run.
* No test varied pubkey length; the KAT and fuzz suites vary the signature
only, always with a full-size key.
The invariant was written down in one file, violated in another, and the
harness that would have caught it was never wired up.
Fixed in BOTH copies. contracts/falcon_det1024.py is the one deploy_testnet.py
signs real TestNet inscriptions with, and fixing only the SDK is exactly how
TCE-03's cwd hijack survived its first fix.
Raises rather than returning False, matching sign(): a mis-sized key is a
caller error, not a failed verification, and returning False would let a
truncated key read as "signature invalid". The Atheris harness's contract is
corrected to expect that, with the reason recorded inline.
9 regression tests, none needing the C library so they run everywhere.
Mutation-proved: removing either guard fails all 9. SDK suite 50 -> 59 passed,
19 skipped.
Security impact: closes a memory-safety defect reachable from the public API of
an audit-bound crypto SDK. No protocol, wire-format or on-chain change; the
contract's own ABI already pins committed_pubkey to 1793 bytes, so on-chain
state was never the exposure -- the off-chain verifier path was.
906715ca
fix/verify-pubkey-length-oob
4/171 ++ 3 --
Merge 0f0d14b1c9320f12d582efbed76476a2e838ea20 into b27decbb670d4d5e481699358da41e34ddfc26a4
8ac1dfbb
pull/592/merge
11/516 ++ 213 --
Merge 4cee93a5d9aa96a99d25a6d1288d01e6f0fdfac8 into 9bc334a8819e21a61e5717e04c07dec184a7c579
5523d1ef
pull/73/merge
2/205 ++ 329 --
Merge b60d7a6bbad5c6756581271bd035e01034cbb4cc into 0b42a140b8b4e7209c648f9c8dd5f9f0043e42ac
028df353
pull/637/merge
1/0 ++ 1 --
Merge 59fd5c909fce3e0c675b8ca6b090f58157105095 into fd2b3698ab3576338916b442e7dc1078c851955e
de33fd5e
pull/632/merge
3/57 ++ 11 --
Merge b175262b6f5bbfd406604d978d217ec991cbf566 into 8602e0430cdc499f3bc1cecc5abe4aa31f4aee44
13f0968a
pull/172/merge
85/9,658 ++ 8,186 --