Compact bitmap storage, Yul mulDiv/safe-transfer libraries, unchecked-loop AST rewriter - #648
Merged
Merged
Conversation
…hecked-loop AST rewriter
- BitmapTracker (contracts/data/): packs 256 boolean flags per storage slot
via mapping(uint256 => uint256) buckets instead of one 32-byte slot per
flag, cutting a fresh-flag SSTORE from ~20,000 gas down to a warm-slot
write once a bucket has been touched once. isSet/set/unset plus three
named namespaces (operational flags, processed nonces, user claims)
sharing the same bit-shift helpers.
- YulMathLib (contracts/math/): mulDivDown(x, y, denominator) entirely in
Yul, re-deriving the standard 512-bit-safe mulDiv technique (CRT-based
exact product via mulmod, exact-remainder subtraction, power-of-two
factoring, Newton-Raphson modular inverse) so x*y can exceed 256 bits
without reverting early, as long as the final quotient fits. Reverts
with custom errors (DivisionByZero, MulDivOverflow) instead of a
generic panic.
- YulSafeTransfer (contracts/tokens/): hand-built ERC20 transfer/
transferFrom calldata via mstore + raw call, branching on returndata to
accept standard (bool-returning), non-standard (USDT-style, no return
value), and reverting tokens correctly, rejecting only a literal
`false` return or an unexpected data length.
- Rule G005 (packages/cli/src/transformers/loop_unchecked.rs): a
comment/string-aware source scanner that rewrites `for` loops whose
counter is declared inline and stepped by a simple `i++`/`++i`/`i += 1`
into the `unchecked { ++i; }` idiom, preserving indentation and leaving
already-unchecked, decrementing, differently-stepped, and externally-
declared counters untouched.
Also fixes apps/api-service/hardhat.config.ts and package.json: the
pinned @nomicfoundation/hardhat-toolbox@^6.1.0 only supports Hardhat 2,
paired here with hardhat@^3.1.9 — a broken combination that made
`npx hardhat compile`/`test` unusable for these first-ever Solidity
contracts in this app. Swapped to the Hardhat-3-native
hardhat-toolbox-mocha-ethers, its peer plugins, and the network `type`
discriminators Hardhat 3 requires. Confirmed this does not regress the
existing NestJS/Jest suite: its `Cannot find module 'jest-util'` failure
reproduces identically on a clean reinstall of the original, untouched
package.json (a pre-existing --legacy-peer-deps dependency-hoisting
issue, unrelated to this change).
Closes MDTechLabs#632
Closes MDTechLabs#638
Closes MDTechLabs#639
Closes MDTechLabs#640
|
@ogazboiz Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits. You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀 |
Collaborator
|
please resolve conflict @ogazboiz |
2 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Changes
contracts/data/BitmapTracker.solpacks 256 boolean flags per storage slot (mapping(uint256 => uint256)buckets,index >> 8selects the slot /index & 0xffselects the bit) instead of one 32-byte slot per flag.isSet/set/unseton a generic bitmap, plus three named namespaces (operational flags, processed nonces, user claims) sharing the same bit-shift helpers so they can't collide on the same index.contracts/math/YulMathLib.sol'smulDivDown(x, y, denominator)is implemented entirely in Yul, re-deriving the standard 512-bit-safemulDivtechnique (exact product viamulmod/CRT reconstruction, exact-remainder subtraction, power-of-two factoring, 6-step Newton-Raphson modular inverse) sox * ycan exceed 256 bits without reverting early, as long as the final quotient still fits. Reverts withDivisionByZero/MulDivOverflowcustom errors instead of a generic Solidity panic.contracts/tokens/YulSafeTransfer.solbuilds ERC20transfer/transferFromcalldata by hand (mstoreinto scratch memory) and executes a rawcall, branching onreturndatasize()to correctly accept standard bool-returning tokens, non-standard tokens that return nothing at all (USDT-style), and to bubble up the original revert reason on failure — rejecting only a literalfalsereturn or an unexpected data length.packages/cli/src/transformers/loop_unchecked.rs(thegasguard-clicrate) scans Solidity source (comment/string-aware, so it never mistakes text inside a////* *//string literal for real code) and rewritesforloops whose counter is declared inline and stepped by a simplei++/++i/i += 1into theunchecked { ++i; }idiom — preserving indentation and comments, and correctly handling nested loops. Deliberately leaves already-unchecked, decrementing, differently-stepped, and externally-declared counters untouched.Also fixed (found while implementing #632/#638/#639)
apps/api-service/hardhat.config.tspinned@nomicfoundation/hardhat-toolbox@^6.1.0, which only supports Hardhat 2, alongsidehardhat@^3.1.9— a broken combination (Cannot find module '@nomicfoundation/hardhat-chai-matchers') that madenpx hardhat compile/testcompletely unusable, blocking these first-ever Solidity contracts and tests in this app. Swapped to the Hardhat-3-nativehardhat-toolbox-mocha-ethers, its peer plugins, and the networktypediscriminators Hardhat 3 requires.Verified this doesn't regress the existing NestJS/Jest suite: its
Cannot find module 'jest-util'failure reproduces identically on a from-scratch reinstall of the original, untouchedpackage.json(a pre-existing--legacy-peer-depsdependency-hoisting issue, unrelated to this change) — confirmed independently, not just via the branch's own state.Test plan
npx hardhat compile(fromapps/api-service/) — clean,solc 0.8.20npx hardhat test test/data/BitmapTracker.test.ts test/math/YulMathLib.test.ts test/tokens/YulSafeTransfer.test.ts— 26/26 passing, including a 250-case fuzz run formulDivDownagainst a BigInt reference implementation and full USDT/reverting/false-returning token coverage forYulSafeTransfercargo test -p gasguard-cli— 12/12 passing, including nested-loop and comment/string-literal edge cases; independently confirmed the rewritten fixture output compiles cleanly viasolccargo clippy -p gasguard-cli --tests/cargo fmt -p gasguard-cli -- --check— cleanFullMath-style 512-bitmulDiv; the standard USDT-tolerant safe-transfer branching)Closes #632
Closes #638
Closes #639
Closes #640