Apr 23, 11-12 PM (30)
Apr 23, 12-1 PM (51)
Apr 23, 1-2 PM (69)
Apr 23, 2-3 PM (74)
Apr 23, 3-4 PM (26)
Apr 23, 4-5 PM (22)
Apr 23, 5-6 PM (7)
Apr 23, 6-7 PM (7)
Apr 23, 7-8 PM (11)
Apr 23, 8-9 PM (14)
Apr 23, 9-10 PM (6)
Apr 23, 10-11 PM (28)
Apr 23, 11-12 AM (18)
Apr 24, 12-1 AM (7)
Apr 24, 1-2 AM (4)
Apr 24, 2-3 AM (7)
Apr 24, 3-4 AM (5)
Apr 24, 4-5 AM (8)
Apr 24, 5-6 AM (13)
Apr 24, 6-7 AM (12)
Apr 24, 7-8 AM (33)
Apr 24, 8-9 AM (40)
Apr 24, 9-10 AM (41)
Apr 24, 10-11 AM (72)
Apr 24, 11-12 PM (57)
Apr 24, 12-1 PM (100)
Apr 24, 1-2 PM (57)
Apr 24, 2-3 PM (35)
Apr 24, 3-4 PM (19)
Apr 24, 4-5 PM (16)
Apr 24, 5-6 PM (38)
Apr 24, 6-7 PM (27)
Apr 24, 7-8 PM (12)
Apr 24, 8-9 PM (42)
Apr 24, 9-10 PM (17)
Apr 24, 10-11 PM (30)
Apr 24, 11-12 AM (16)
Apr 25, 12-1 AM (8)
Apr 25, 1-2 AM (1)
Apr 25, 2-3 AM (10)
Apr 25, 3-4 AM (5)
Apr 25, 4-5 AM (3)
Apr 25, 5-6 AM (13)
Apr 25, 6-7 AM (1)
Apr 25, 7-8 AM (4)
Apr 25, 8-9 AM (24)
Apr 25, 9-10 AM (17)
Apr 25, 10-11 AM (4)
Apr 25, 11-12 PM (4)
Apr 25, 12-1 PM (13)
Apr 25, 1-2 PM (3)
Apr 25, 2-3 PM (10)
Apr 25, 3-4 PM (6)
Apr 25, 4-5 PM (10)
Apr 25, 5-6 PM (16)
Apr 25, 6-7 PM (13)
Apr 25, 7-8 PM (30)
Apr 25, 8-9 PM (55)
Apr 25, 9-10 PM (13)
Apr 25, 10-11 PM (21)
Apr 25, 11-12 AM (22)
Apr 26, 12-1 AM (5)
Apr 26, 1-2 AM (0)
Apr 26, 2-3 AM (2)
Apr 26, 3-4 AM (5)
Apr 26, 4-5 AM (2)
Apr 26, 5-6 AM (2)
Apr 26, 6-7 AM (3)
Apr 26, 7-8 AM (8)
Apr 26, 8-9 AM (3)
Apr 26, 9-10 AM (0)
Apr 26, 10-11 AM (2)
Apr 26, 11-12 PM (1)
Apr 26, 12-1 PM (6)
Apr 26, 1-2 PM (4)
Apr 26, 2-3 PM (14)
Apr 26, 3-4 PM (14)
Apr 26, 4-5 PM (0)
Apr 26, 5-6 PM (13)
Apr 26, 6-7 PM (13)
Apr 26, 7-8 PM (7)
Apr 26, 8-9 PM (7)
Apr 26, 9-10 PM (5)
Apr 26, 10-11 PM (27)
Apr 26, 11-12 AM (21)
Apr 27, 12-1 AM (7)
Apr 27, 1-2 AM (7)
Apr 27, 2-3 AM (9)
Apr 27, 3-4 AM (9)
Apr 27, 4-5 AM (5)
Apr 27, 5-6 AM (13)
Apr 27, 6-7 AM (7)
Apr 27, 7-8 AM (82)
Apr 27, 8-9 AM (47)
Apr 27, 9-10 AM (33)
Apr 27, 10-11 AM (62)
Apr 27, 11-12 PM (80)
Apr 27, 12-1 PM (66)
Apr 27, 1-2 PM (44)
Apr 27, 2-3 PM (52)
Apr 27, 3-4 PM (42)
Apr 27, 4-5 PM (36)
Apr 27, 5-6 PM (26)
Apr 27, 6-7 PM (13)
Apr 27, 7-8 PM (26)
Apr 27, 8-9 PM (13)
Apr 27, 9-10 PM (15)
Apr 27, 10-11 PM (42)
Apr 27, 11-12 AM (28)
Apr 28, 12-1 AM (17)
Apr 28, 1-2 AM (8)
Apr 28, 2-3 AM (4)
Apr 28, 3-4 AM (5)
Apr 28, 4-5 AM (5)
Apr 28, 5-6 AM (8)
Apr 28, 6-7 AM (8)
Apr 28, 7-8 AM (37)
Apr 28, 8-9 AM (54)
Apr 28, 9-10 AM (59)
Apr 28, 10-11 AM (53)
Apr 28, 11-12 PM (56)
Apr 28, 12-1 PM (49)
Apr 28, 1-2 PM (54)
Apr 28, 2-3 PM (69)
Apr 28, 3-4 PM (31)
Apr 28, 4-5 PM (14)
Apr 28, 5-6 PM (47)
Apr 28, 6-7 PM (9)
Apr 28, 7-8 PM (9)
Apr 28, 8-9 PM (14)
Apr 28, 9-10 PM (20)
Apr 28, 10-11 PM (34)
Apr 28, 11-12 AM (29)
Apr 29, 12-1 AM (13)
Apr 29, 1-2 AM (1)
Apr 29, 2-3 AM (1)
Apr 29, 3-4 AM (6)
Apr 29, 4-5 AM (1)
Apr 29, 5-6 AM (4)
Apr 29, 6-7 AM (12)
Apr 29, 7-8 AM (45)
Apr 29, 8-9 AM (70)
Apr 29, 9-10 AM (49)
Apr 29, 10-11 AM (27)
Apr 29, 11-12 PM (50)
Apr 29, 12-1 PM (39)
Apr 29, 1-2 PM (21)
Apr 29, 2-3 PM (66)
Apr 29, 3-4 PM (25)
Apr 29, 4-5 PM (36)
Apr 29, 5-6 PM (16)
Apr 29, 6-7 PM (10)
Apr 29, 7-8 PM (14)
Apr 29, 8-9 PM (13)
Apr 29, 9-10 PM (17)
Apr 29, 10-11 PM (25)
Apr 29, 11-12 AM (29)
Apr 30, 12-1 AM (6)
Apr 30, 1-2 AM (8)
Apr 30, 2-3 AM (1)
Apr 30, 3-4 AM (6)
Apr 30, 4-5 AM (2)
Apr 30, 5-6 AM (8)
Apr 30, 6-7 AM (15)
Apr 30, 7-8 AM (17)
Apr 30, 8-9 AM (40)
Apr 30, 9-10 AM (19)
Apr 30, 10-11 AM (45)
Apr 30, 11-12 PM (51)
3,788 commits this week Apr 23, 2026 - Apr 30, 2026
refactor: clean up uplc-fuzz replay and CLI code
Extract parse_plutus_version() to deduplicate the version string parsing that was duplicated between main() and replay(). Replace the debug-specific summarize_top() function, which was hardcoded to Case/Constant patterns left over from investigating a specific divergence, with a generic term_variant_name() that returns the top-level variant name for any term. Import Outcome at the top of replay() to remove six fully-qualified path references. Change &PathBuf parameters to &Path for idiomatic Rust. Exit with code 1 when replay detects a divergence so scripts and CI can detect failures programmatically.

Signed-off-by: Jonathan Lim <[email protected]>
test: add case-on-list conformance tests
Tests for case expressions on list constants:
- case-list-empty-valid: empty list with 2 branches takes nil branch
- case-list-nonempty-valid: non-empty list takes cons branch with head/tail
- case-list-empty-too-many-branches: empty list with 4 branches errors

These tests currently fail due to incorrect branch count validation
in the case-on-constants implementation.

Signed-off-by: Jonathan Lim <[email protected]>
fix: use saturating arithmetic in cost model and budget spending
Prevents integer overflow panics when cost model inputs are very large
(e.g. dropList with a huge index). All arithmetic in costing functions,
budget subtraction, and ExBudget::Sub now uses saturating operations
so overflow produces clamped values instead of panics, letting the
out-of-budget check fire normally.

Signed-off-by: Jonathan Lim <[email protected]>
feat: bytecode VM support for new builtins, case-on-constants, and VarBig
- Expand builtin pre-wrap range from 0..92 to 0..101 for 9 new builtins
  (Value ops, MultiScalarMul)
- Add case_on_constant handler: Bool (with branch count validation),
  Unit, Integer, List (head/tail field pushing), Pair (fst/snd)
- Add VarBig opcode (0x16) with u32 index for De Bruijn indices > 255,
  fixing silent truncation that caused wrong variable lookups in large
  scripts (e.g. stablecoin contracts)
- Compiler emits Var (u8) for indices <= 255, VarBig (u32) otherwise;
  ApplyVar/ForceVar superinstructions restricted to u8 range

Signed-off-by: Jonathan Lim <[email protected]>
perf: step countdown + inner return drain loop + boxed CasesFrame
Three optimizations to the VM dispatch loop:

1. Replace unbudgeted_steps[9] total counter with a countdown that
   decrements to zero. Saves one array increment per step and turns
   the >= comparison into a free zero-check after decrement.

2. Restructure the run loop to drain return chains without going back
   through the outer compute loop. Eliminates Phase construction and
   matching on the hot Compute→Return transition.

3. Box the CasesFrame (rare, 0.3% of opcodes) to shrink Frame from
   32 to 16 bytes, halving memory bandwidth for every frame push/pop.

Signed-off-by: Jonathan Lim <[email protected]>
perf: box ConstrFrame to shrink Frame enum size
The Constr variant contained 6 fields including a BumpVec, making the
Frame enum ~72 bytes. Boxing it puts only an 8-byte pointer in the
enum, reducing Frame to ~24 bytes. This halves the per-push/pop copy
cost for the common frame variants (AwaitArg, AwaitFunTerm, Force).

Small improvement on diverse workloads (escrow: 231→221µs, uniswap:
852→832µs). 818/818 conformance tests passing.

Signed-off-by: Jonathan Lim <[email protected]>