Solidity Treasures
СтатистикаUseful materials and tools for development on Ethereum. News proposals @hirama
- Последний пост
- 15 авг.
- Последнее чтение
- 18:13
- Постов за неделю
- 1
- Всего постов
- 21
- Тип
- открытый
- Язык
- английский
- Категория
- Криптовалюты
- В каталоге с
- 13 авг.
- 1/24сутки в ленте
- 122
- 1/48двое суток
- 139
- 1/72трое суток
- 150
Оценка по просмотрам недавних постов: пост набирает почти всё за первые сутки.
Посты
On-chain penalty enforcement, and the MEV vectors it opens The DMQ framework makes "panic states" programmatically enforceable: penalties execute on-chain rather than living in off-chain policy. The author deployed it to Sepolia and collected real execution data instead of stopping at a model. Why it matters: the moment a penalty is an on-chain state transition, it becomes an MEV surface. Anyone who can order, front-run, or trigger the enforcement tx can extract value or grief the penalized party. Proof-of-execution on testnet is exactly where these vectors show up before mainnet. Takeaway: if your protocol enforces slashing or penalties on-chain, treat the enforcement path as adversarial ordering. Assume the trigger can be MEV'd and design for it (commit-reveal, private submission, or making the penalty ordering-independent). ethresear.ch: DMQ Framework @soliditypedia
Spending policies enforced by a ZK proof, not a trusted signer Most wallet spending limits leak intent: the contract sees the amount, the recipient, the rule. ERC-8366 proposes a composable interface where any fund-holding contract — an escrow, ERC-4337 account, or EIP-7702-delegated EOA — releases funds only against a zero-knowledge proof that a policy was satisfied, without revealing the policy inputs on-chain. The mental model: separate who may spend from under what constraints. A verifier checks a proof that (balance, limits, epoch) hold; the escrow never learns the private thresholds. Because it's a function set, one policy circuit can back many account types. The hard part is nullifier and epoch design: without them a valid proof replays, letting a caller drain repeatedly under a spent limit. Treat the proof like a one-shot capability, bound to state, or the privacy win becomes a double-spend. ERC-8366 draft @soliditypedia
ERC-4337 paymasters that accept ERC-20s, signatures, or NFTs OpenZeppelin Contracts v5.7 ships composable paymaster primitives, so sponsoring gas becomes a policy you write, not a bespoke contract. The hard part in a paymaster is validatePaymasterUserOp: you must decide who to sponsor and how to charge, then reconcile in postOp after the real gas cost is known. The new base contracts split this into pluggable checks: an ERC-20 paymaster pulls token payment at that price, a signature paymaster verifies an off-chain grant, an NFT-gated one checks ownership. Watch the postOp refund path: overcharge on validation, refund the delta after execution, or a reverting token transfer can grief the bundler. Test the postOpReverted branch. OpenZeppelin Contracts v5.7 @soliditypedia
Uniswap v4 hooks move security into your code — and the defaults bite Hooks let pools run custom logic on swaps and liquidity changes: dynamic fees, custom accounting, external calls. That flexibility relocates trust boundaries into hook code, and two real incidents (Cork, Bunni) show where it breaks. The recurring failures Trail of Bits flags: Access control: hook callbacks must reject any caller that isn't the PoolManager, and validate the pool key. Anyone can call your hook directly otherwise. Reentrancy via the unlock pattern: v4's flash-accounting unlock lets external calls re-enter mid-settlement. Never assume balances are final inside a callback. Arithmetic/rounding: custom accounting that rounds in the user's favor leaks value over many swaps — the Bunni-class bug. Treat hooks as untrusted-by-default: authenticate the caller, guard reentrancy, round against the user. Trail of Bits: Building secure Uniswap v4 hooks @soliditypedia
OpenZeppelin 5.7.0 breaks EIP-712 domains that relied on long name/version If your contract passes a name or version longer than 31 bytes to EIP712, upgrading to 5.7.0 will now revert in the constructor with ShortStrings.StringTooLong. Earlier versions kept a storage fallback for values that didn't fit a ShortString. That fallback is gone: the domain is stored exclusively in immutables. Cheaper reads and a simpler _domainSeparatorV4(), but a hard failure mode for anyone who leaned on the fallback. Before bumping: audit every EIP712(name, version) call. Long protocol names or semver strings with build metadata are the usual offenders. If you need a long name, hash it down or shorten before passing. OpenZeppelin Contracts v5.7.0 @soliditypedia
Instant redemption is the wrong default for illiquid RWAs Tokenize an asset that settles T+2 off-chain, then let it redeem instantly on-chain, and you have created a liquidity mismatch: the vault promises what the underlying can't deliver on demand. Two design responses are converging. Async settlement: ERC-7540 splits redemption into request then claim, so the vault can honor real settlement windows instead of pretending everything is T+0. Centrifuge ran this across $1.6B+ in RWA pools before it landed as a reusable building block in OpenZeppelin Community Contracts. Overcollateralization: a parallel ethresear.ch proposal hardcodes 200% collateral to absorb the redemption gap when instant settlement is unavoidable — trading capital efficiency for solvency guarantees. Takeaway: match your redemption semantics to the underlying's settlement latency. If you inherit ERC4626 for an illiquid asset, you probably want ERC-7540's request/claim flow instead. Centrifuge / OpenZeppelin · ethresear.ch @soliditypedia
Pricing a prediction market on-chain with LMSR, no order book A new ERC draft binds each binary (YES/NO) market one-to-one to an ERC-721: question, odds, pool, and resolution all live on-chain and render into the tokenURI. The interesting part is the pricing. Instead of matching buyers and sellers, it uses Hanson's Logarithmic Market Scoring Rule. A single liquidity parameter b sets depth; the cost to move the market is the difference of a cost function: C(q) = b * ln(exp(q_yes/b) + exp(q_no/b)) price_yes = exp(q_yes/b) / (exp(q_yes/b) + exp(q_no/b)) Any trade size gets a deterministic price, so there is always liquidity and no counterparty needed. The hard part on-chain is the exp/ln math: fixed-point implementations (PRBMath, ABDK) are mandatory, and overflow in exp(q/b) is the real footgun — bound q/b or the cost function reverts. ethereum-magicians.org @soliditypedia
Study real exploits by running them, not reading about them Most exploit write-ups leave you guessing about the exact state and call sequence. The evm-hack-registry is a self-contained, offline-runnable archive of DeFi exploit proof-of-concepts spanning the full history of EVM hacks (2017 to 2026). Each entry forks the pre-exploit state and reproduces the drain in a test, so you can step through the actual call trace, tweak balances, and confirm which invariant broke. Far higher signal than a post-mortem paragraph. Practical use: before an audit, grep the registry for the class you're reviewing (reentrancy, price-oracle manipulation, unchecked delegatecall) and re-run the closest match against your own contract's assumptions. github.com/sanbir/evm-hack-registry @soliditypedia
Upgrading an EOA to a smart wallet without losing its address EIP-7702 lets an EOA set code via a signed authorization, but you still need a storage layout that survives implementation swaps. Base's eip-7702-proxy is a minimal ERC-1967 proxy that delegates a plain EOA to CoinbaseSmartWallet, keeping the account's address and history intact. Why it matters: the naive approach points the EOA directly at wallet logic, freezing you on one implementation and exposing you to initialization races. Routing through a 1967 proxy gives a stable upgrade slot and a controlled first-init path — the same discipline you already apply to contract upgrades, now for EOAs. The subtle risk: an unguarded first delegation is front-runnable, so init authorization must be bound to the account. Read the proxy as a reference for that binding. github.com/base/eip-7702-proxy @soliditypedia
An O(1) fully on-chain limit order book, without per-order storage Classic on-chain CLOBs die on gas: matching walks a linked list, so fills and cancels scale with book depth. The Cohort Order Book proposal sidesteps this by making liquidity at each price level fungible. The mental model: instead of tracking individual orders, each price level holds pooled liquidity split into generations (cohorts). A trader's claim is a share in a cohort, not a discrete order. A fill consumes the oldest generation wholesale, so placement, cancel, and match are all O(1) — no traversal, no unbounded loops. The tradeoffs to scrutinize: FIFO fairness within a generation (§6) and the one-sided-add justification (§4). Fungible cohorts approximate price-time priority rather than guaranteeing it per order. Worth studying if you build matching engines or audit order-book AMMs — the generational accounting is where the correctness lives. Ethereum Magicians draft @soliditypedia
Ostium drained ~$18M via a registered oracle forwarder and future-dated reports Per Blockaid, the attacker didn't break the price feed — they abused a trusted path into it. A registered forwarder submitted oracle reports timestamped in the future, letting the attacker book fake trading profits against the vault before honest prices caught up. Root cause is a recurring pattern: perps and margin systems trust any report from a whitelisted forwarder without validating the report's timestamp bounds. If your protocol consumes signed price reports, enforce staleness AND future-time checks: require(report.timestamp <= block.timestamp, "future"); require(block.timestamp - report.timestamp <= MAX_AGE, "stale"); A valid signature from a valid source is not a valid price. Bound the time window explicitly. The Defiant @soliditypedia
This week in Solidity Security and correctness: Yul optimizer miscompile: the optimizer's call-graph analysis sometimes tagged mutually recursive functions as non-recursive, excluding them from memory spilling and risking silent corruption. Recheck builds that lean on the optimizer. details OpenZeppelin's contributor rules: a solid checklist for anyone shipping libraries — API design for safe inheritance, errors/events/NatSpec/assembly conventions, and layered testing from fuzz to formal. source Tooling: Foundry is building symbolic execution: recent work adds hashcons expressions, counterexample minimization, and branch-frontier capture — verification plumbing, not cosmetics. source @soliditypedia
An AI agent that can wipe prod with one command isn't hypothetical — it's Tuesday 😅 A shell alias blocks one command on one machine. HELM is a fail-closed firewall for the whole agent boundary. Every action hits it before it runs: safe goes through, destructive gets blocked, unknown MCP tools get quarantined, anything borderline escalates to you. Every decision comes signed with a receipt you can verify offline. Local, works with Hermes, OpenClaw, Claude Code and Codex. No cloud, no model key, no Docker. Open source, Apache-2.0. brew install helm-ai-kernel helm-ai-kernel setup claude-code --yes ⭐️ github.com/Mindburn-Labs/helm-oss
A Yul optimizer bug could silently miscompile mutually recursive functions On May 11 2026, the Solidity team found the optimizer's call graph analysis sometimes classified mutually recursive functions as non-recursive. Such functions were then wrongly excluded from memory spilling — the mechanism that saves stack slots to memory. Result: a spill that should have happened didn't, so recursive calls could overwrite live stack data. Affects code with mutual recursion compiled via IR (--via-ir) with the optimizer on, since 0.8.0. Miscompilation is possible but data-dependent; check any deeply/mutually recursive Yul-heavy contracts. Fixed in v0.8.36 (also adds Amsterdam EVM support). Recompile and re-audit affected deployments. Bug disclosure · 0.8.36 release @soliditypedia
Native UTXOs on Ethereum: state that can be spent, not just accumulated Every time an address receives ETH for the first time, it gets a permanent account entry. State only grows. The proposal adds a UTXO layer alongside the account model: value lives in discrete, spendable outputs that vanish from state once consumed. Why it matters for contract devs: account balances are mutable shared state — a magnet for reentrancy and race conditions. UTXOs are consume-once, which makes concurrency and privacy schemes far easier to reason about. Think stealth addresses and payment pools that don't bloat the trie forever. The hard part is bridging the two models cleanly: how contracts read, spend, and create outputs without breaking composability. The thread works through the state-growth tradeoffs and a possible EVM interface. ethresear.ch: Native UTXOs on Ethereum @soliditypedia
Nice initiative from a leading audit firm! They review your code and provide patches with suggested fixes 😍 https://trailofbits.com/patch-the-planet @soliditypedia
A singleton wallet you delegate to, not deploy: EIP-7702 in practice Uniswap open-sourced calibur, a non-upgradeable singleton wallet contract designed to be set as the delegation target in an EIP-7702 transaction. Your EOA points its code at one shared implementation instead of deploying a per-user proxy. Why it matters: 7702 lets an EOA temporarily run contract code. The design question is what code. A singleton means one audited implementation for every account, no per-user deploy cost, and no upgrade slot to hijack. Non-upgradeable removes the classic delegate-storage footgun. Things to check when adopting this pattern: replay across chains (bind signatures to chainid), and that the delegate does not assume a fresh storage layout, since it runs in the EOA's own account storage. Uniswap/calibur @soliditypedia
Run a custom-rule static pass before every audit handoff Most Solidity linters ship fixed detectors. radar takes a different angle: you write detection rules in Python against the AST/IR, so project-specific invariants ("this modifier must guard every state-changing fn", "no delegatecall to non-immutable targets") become reusable checks instead of review-time memory. It covers Solidity plus Rust, Anchor, and Stylus — useful if your stack spans EVM and SVM/WASM contracts. Pattern: encode each past finding as a rule so a class of bug can never silently return. Treat it as a complement to Slither, not a replacement — the win is codifying your own threat model. Auditware/radar @soliditypedia
Verify Merkle multiproofs on-chain without rolling your own If you're building a bridge or light client, the proof-verification primitive is where subtle bugs live: wrong leaf ordering, unsorted siblings, second-preimage attacks from unprefixed leaves, or single-proof code abused for batched proofs. solidity-merkle-trees covers more than the usual sorted-pair tree: it implements multiproofs (verify many leaves in one pass) for Merkle Mountain Ranges, Patricia tries, and standard binary trees. Multiproofs share interior nodes, so batching N leaves costs far less than N independent verify calls. Takeaway: prefer an audited multiproof library over a hand-written loop, and always domain-separate leaf vs. node hashing to block second-preimage forgery. polytope-labs/solidity-merkle-trees @soliditypedia
UniswapX moves swap settlement off the AMM and onto signed orders Instead of calling a pool directly, a user signs an off-chain order describing inputs, minimum outputs, and a decay curve. Third-party fillers compete to settle it on-chain and front the gas — so the swapper pays no ETH and signs, not sends. Why it matters for builders: - Settlement is a Dutch auction: the order's acceptable price decays over the order's lifetime, letting fillers fill as soon as it's profitable. This shifts MEV capture into open competition rather than a single sequencer. - Orders are permit2-based, so token approval and transfer authorization live in the signature, not a prior on-chain approve. - Audit surface shifts to signature replay, deadline/nonce handling, and reactor validation logic — not pool math. If you're integrating intent-style flows, study the reactor and the order structs before assuming AMM threat models carry over. github.com/Uniswap/UniswapX @soliditypedia