Repository navigation
fix: OZ 2.3.0 audit part 2 (L-03, L-04, N-04, N-09, N-10, N-11) - #524
Merged
Merged
Conversation
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…Z N-10) Declare the transient slots as file-level constants, which inline assembly can reference when imported, and drop the per-library literal copies and the tests that pinned them to the table. Bytecode is unchanged. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…r (OZ L-03) PERMIT2_TRANSFER_FROM and each PERMIT2_TRANSFER_FROM_BATCH detail now accept the USE_RESOLVED_AMOUNT sentinel, so a route can pull exactly an amount a prior RESOLVE produced. The batch transfers one detail at a time through Permit2's single transferFrom, which runs the same per-detail transfer as its batch call and avoids copying the details to memory. Document exactly which amount fields read the sentinel. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…L-04) The register is intentionally shared by a plan and its sub-plans: a RESOLVE in a sub-plan that succeeds replaces the parent's value, and a sub-plan that reverts has its writes undone, its RESOLVE included. Document this and correct the _resolve comment, which implied a cleared value can never come back. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Map the USE_RESOLVED_AMOUNT sentinel in WRAP_ETH, UNWRAP_WETH_EXACT, the ACROSS_V4_DEPOSIT_V3 inputAmount, and the v4 SETTLE and TAKE amounts, so the RESOLVE register covers every exact amount alongside the swap, TRANSFER and Permit2 transfer amounts. Minimums, caps, thresholds, portions and signed permit amounts keep their literal meaning. The TAKE override needs _mapTakeAmount to be virtual, so point v4-periphery at fix/oz-ur-2.3.0-audit-part2-findings (a4558a6) and update foundry.lock to match. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…s (OZ N-04) V2 exact-output measures delivery at the recipient, so a token that hands over less than the amount transferred anywhere on the path reverts the route. Add share-based rounding such as stETH, which typically delivers 1-2 wei less, to the documented causes, and point such tokens to exact-input swaps. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
#612 was squash-merged into dev-ur-2.3.0 and its branch deleted, which left the previous pin (a4558a6) on no branch. 7ed8439 is the squash; its tree equals #612's tip. The only difference from a4558a6 is the V4Quoter empty-path guard, which is not part of the router, so the router bytecode is unchanged. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
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.
AI-Generated Description
What
Seven commits addressing the remaining findings from the OpenZeppelin 2.3.0 audit, continuing from #523 (L-01, N-02 through N-07):
Commands.sol— command types are 7 bits (COMMAND_TYPE_MASK), and0x40–0x5fis the highest assigned range. Also fix duplicated-word typo ("the the" → "the") inMaxInputAmount.solprotocolFeeController()onpoolManagerdirectly instead of casting throughIProtocolFees, removing the now-unused importTransientSlotsthe single source of truth for slot constants — convert library constants to file-level constants so consumers import them directly instead of duplicating the literal and asserting equality in testsPERMIT2_TRANSFER_FROMand eachPERMIT2_TRANSFER_FROM_BATCHdetail amount through the resolved-amount register, so a route can pull exactly the amount a priorRESOLVEproduced instead of an offchain upper bound. Also wireWRAP_ETHandUNWRAP_WETH_EXACTthroughResolvedAmount.mapSETTLE,TAKE, andACROSS_V4_DEPOSIT_V3throughResolvedAmount.map; expand README andConstants.solwith the full sentinel-aware and sentinel-excluded field listsV2_SWAP_EXACT_INinsteadChanges
contracts/base/Dispatcher.sol: Drop theIProtocolFeesimport and callpoolManager.protocolFeeController()directly (N-11); mapPERMIT2_TRANSFER_FROMamount throughResolvedAmount.mapandSafeCast160(L-03); mapWRAP_ETHandUNWRAP_WETH_EXACTamounts throughResolvedAmount.map; add sub-plan revert note to_resolveNatSpec (L-04)contracts/modules/Permit2Payments.sol: Rewritepermit2TransferFrom(batch)to transfer one detail at a time so each amount passes throughResolvedAmount.map, replacing the singlePERMIT2.transferFrom(batchDetails)call (L-03)contracts/modules/uniswap/v4/V4SwapRouter.sol: MapSETTLEandTAKEamounts throughResolvedAmount.mapby overriding_mapSettleAmountand_mapTakeAmountcontracts/modules/ChainedActions.sol: MapACROSS_V4_DEPOSIT_V3inputAmountthroughResolvedAmount.mapcontracts/libraries/TransientSlots.sol: Convert from a library withinternal constantmembers to file-levelconstantdeclarations so inline assembly in consumer libraries can reference them directly without duplication (N-10)contracts/libraries/Locker.sol,NestedUnlock.sol,ResolvedAmount.sol,MaxInputAmount.sol: Remove duplicated slot constants, import fromTransientSlots(N-10)contracts/base/RouteSigner.sol: Remove three duplicated slot constants, import fromTransientSlots(N-10)contracts/libraries/Commands.sol: Update the command-type range comment to reflect the actual 7-bit layout (N-09)contracts/libraries/MaxInputAmount.sol: Remove duplicate "the" in the slot documentation comment (N-09)contracts/libraries/Constants.sol: Expand theUSE_RESOLVED_AMOUNTdoc comment to list which amount fields consume the sentinel and which do not (L-03)contracts/modules/uniswap/v2/V2SwapRouter.sol: Expand delivery-check comment to mention share-based rounding (N-04)README.md: UpdateRESOLVEsection with the full list of sentinel-aware and sentinel-excluded amount fields; document sub-plan register sharing (L-04); addV2_SWAP_EXACT_OUTrounding-token note (N-04)test/foundry-tests/Resolve.t.sol: AddResolvePermit2TransferTest— exercises resolved-amount mapping forPERMIT2_TRANSFER_FROMandPERMIT2_TRANSFER_FROM_BATCH, plus robustness tests (truncated details, overstated length, dirty fields, foreign owner)test/foundry-tests/ResolveV4.t.sol: Tests for resolved-amount mapping throughSETTLEandTAKEv4 actionstest/foundry-tests/TransientSlots.t.sol: Removetest_librariesUseTableSlots(redundant now that there is only one copy of each constant); update imports to file-level constantstest/foundry-tests/Locker.t.sol,MaxInputAmount.t.sol,ResolvedAmount.t.sol: Remove slot-equality assertions that are no longer neededBytecode
dev-2.3.0beforePermit2Paymentsand theIProtocolFeesimport removal together save bytes despite adding theResolvedAmount.mapandSafeCast160calls.Notes
PERMIT2_TRANSFER_FROM_BATCHrefactor issues onepermit2.transferFromper detail instead of one batch call; Permit2's batch implementation performs the same per-detail transfers, so the onchain behaviour is identicalTransientSlotsrefactor eliminates the class of bug where a consumer's duplicated literal drifts from the table — there is now exactly one definition per slot