Last year, our engineers submitted over 375 pull requests that were merged into non–Trail of Bits repositories, touching more than 90 projects from cryptography libraries to the Rust compiler.
This work reflects one of our driving values: “share what others can use.” The measure isn’t whether you share something, but whether it’s actually useful to someone else. This principle is why we publish handbooks, write blog posts, and release tools like Claude skills, Slither, Buttercup, and Anamorpher.
But this value isn’t limited to our own projects; we also share our efforts with the wider open-source community. When we hit limitations in tools we depend on, we fix them upstream. When we find ways to make the software ecosystem more secure, we contribute those improvements.
Most of these contributions came out of client work—we hit a bug we were able to fix or wanted a feature that didn’t exist. The lazy option would have been forking these projects for our needs or patching them locally. Contributing upstream instead takes longer, but it means the next person doesn’t have to solve the same problem. Some of our work is also funded directly by organizations like the OpenSSF and Alpha-Omega, who we collaborate with to make things better for everyone.
implicit_clone lint to handle to_string() calls, which let us deprecate the redundant string_to_string lint. We added replacement suggestions to disallowed_methods so that teams can suggest alternatives when flagging forbidden API usage, and we added path validation for disallowed_* configurations so that typos don’t silently disable lint rules. We also extended the QueryStability lint to handle IntoIterator implementations in rustc, which catches nondeterminism bugs in the compiler. The motivation came from a real issue we spotted: iteration order over hash maps was leaking into rustdoc’s JSON output.toString to improve hevm’s compatibility with Foundry.A merged pull request is the easy part. The hard part is everything maintainers do before and after: writing extensive documentation, keeping CI green, fielding bug reports, explaining the same thing to the fifth person who asks. We get to submit a fix and move on. They’re still there a year later, making sure it all holds together.
Thanks to everyone who shaped these contributions with us, from first draft to merge. See you next year.
pyproject.toml according to PEP 639PrintableStringUtcTime and GeneralizedTimeOPTIONALtype_to_tagDEFAULTIMPLICIT and EXPLICITSEQUENCE OFSIZE to SEQUENCE OFBIT STRINGIA5StringPyStringMethods::to_cowSIZE support to BIT STRINGSIZE support to OCTET STRINGSIZE support to UTF8StringSIZE support to PrintableStringSIZE support to IA5Stringelided_named_lifetimes warningsExpression::GetRefbinary to binabi.encode() with empty argsNamespace reference in Binarymismatched_lifetime_syntaxes lint__builtin_ia32_pshufd__builtin_ia32_pslldqi_byteshiftpslldqi construct__builtin_ia32_psrldqi_byteshiftformat_push_string and format_collect to pedanticdisallowed_*unnecessary_debug_formatting lintignore_without_reason lintinconsistent_struct_constructor configuration; don’t suggest deprecated configurationsvisit_map happy path more evidentdisallowed_* configurationsderive_deserialize_allowing_unknownimplicit_clone to handle to_string callsneedless_borrow_for_generic_args doc commentexplicit_write in testsmap-unwrap-orevm on its own directorymaybeLit{Byte,Word,Addr}Simp and maybeConcStoreSimpStorable vectors for memoryword256Bytes, word160BytestoString cheatcodepypi-attestations verify pypi CLI subcommand*.slsa.attestation attestation filesverify pypi commandverify pypi subcommandmake reformatpypi-attestations repositorypypi-attestations to v0.0.28int64 for index types