fix: Security Audit Fixes for DataHelper.sol#33
Open
rroland10 wants to merge 2 commits intoEthereumCommonwealth:mainfrom
Open
fix: Security Audit Fixes for DataHelper.sol#33rroland10 wants to merge 2 commits intoEthereumCommonwealth:mainfrom
rroland10 wants to merge 2 commits intoEthereumCommonwealth:mainfrom
Conversation
Address 13 vulnerabilities across Dex223AutoListing, Dex223CoreAutoListing,
Dex223OwnableListing, and AutoListingsRegistry contracts:
Critical:
- Add onlyOwner access control to updateMe() (was publicly callable)
- Add nonReentrant guard to list() and listSingle() against reentrancy
via malicious ERC-20 tokens or registry calls
- Fix address(0) token mapping pollution in checkListing() that corrupted
isListed() results for all subsequent tokens
High:
- Fix double-charge bug: replace || with _isFullyListed() helper so users
are only charged when a token is genuinely not fully listed
- Add excess ETH refund in list()/listSingle() to prevent permanent loss
of overpaid native currency
- Reject ETH sent alongside ERC-20 token payments to prevent stuck funds
- Remove arbitrary registry replacement from OwnableListing.updateMe()
- Fix listTokenByOwner() to actually update listed_tokens/tokens/num_listed_tokens
state via checkListing()
Medium:
- Add transferOwnership() with zero-address check to all listing contracts
- Replace payable().transfer() with .call{value:}() in extractTokens()
to support multisig/contract owners
Low:
- Fix tokenUnanned typo -> tokenUnbanned in AutoListingsRegistry
- Standardize onlyOwner modifier across all contracts
- Add descriptive error messages to all require statements
Also adds hardhat compiler overrides for Revenue_old.sol and RevenueV1.sol
to fix pre-existing compilation config issues.
Co-authored-by: Cursor <cursoragent@cursor.com>
Add comprehensive input validation and NatSpec documentation to the DataHelper contract to prevent misuse and silent failures: - V1: Reject zero-address token0/token1 - V2: Reject identical token addresses - V3: Enforce Uniswap V3 token ordering (token0 < token1) - V4: Validate tick range (tickLower < tickUpper) - V5: Ensure min amounts do not exceed desired amounts - V6: Reject zero-address recipient (prevents LP token burning) - V7: Reject zero deadline (prevents immediate expiry) - Rename MintParamsCall -> mintParamsCall (Solidity naming convention) - Add full NatSpec documentation for contract and function Co-authored-by: Cursor <cursoragent@cursor.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.
Security Audit Report:
DataHelper.solContract Overview
DataHelper.solis a pure utility contract (no state, no ETH handling) that constructsMintParamsstructs used by the Dex223 position manager to mint liquidity positions. The contract previously had zero input validation, meaning any caller — including other contracts composing on top of it — could silently construct invalid parameters that would fail downstream in the position manager, wasting gas and potentially causing confusing reverts.Vulnerabilities Found & Fixes Applied
V1 — MEDIUM: Zero-Address Token Parameters Accepted
Description: The original
MintParamsCallfunction acceptedaddress(0)fortoken0and/ortoken1without any check. Passing a zero-address token to the Uniswap V3 position manager would cause a downstream revert, but only after additional external calls have already been made, wasting gas. Worse, if this helper is used to build calldata off-chain or in another contract, the invalid struct propagates silently.Fix: Added
require(token0 != address(0))andrequire(token1 != address(0))checks at the top of the function.V2 — MEDIUM: Identical Token Addresses Accepted
Description: The function would happily construct a
MintParamsstruct wheretoken0 == token1. This is invalid for any Uniswap V3 pool and would revert downstream.Fix: Added
require(token0 != token1, "DataHelper: identical tokens").V3 — MEDIUM: No Token Ordering Enforcement
Description: Uniswap V3 strictly requires
token0 < token1(sorted by address). The original function did not enforce this, so callers could construct params with reversed ordering that would fail at the pool level. This is especially dangerous for integrators who may not be aware of the ordering requirement.Fix: Added
require(token0 < token1, "DataHelper: token0 must be less than token1").V4 — MEDIUM: Invalid Tick Ranges Accepted
Description: The function accepted
tickLower >= tickUpper, which is invalid for Uniswap V3 positions. An inverted or zero-width tick range would revert in the pool contract but only after significant computation.Fix: Added
require(tickLower < tickUpper, "DataHelper: tickLower must be less than tickUpper").V5 — LOW: Minimum Amounts Could Exceed Desired Amounts
Description:
amount0Min > amount0Desiredoramount1Min > amount1Desiredis a logical impossibility — the minimum accepted amount cannot exceed the desired amount. This would guarantee the downstream mint always reverts. The original code allowed this silently.Fix: Added
require(amount0Min <= amount0Desired)andrequire(amount1Min <= amount1Desired).V6 — LOW: Zero-Address Recipient Accepted (LP Token Burning)
Description: A
recipientofaddress(0)would cause minted LP position NFTs to be sent to the zero address, effectively burning them permanently. While the Uniswap V3 position manager may or may not reject this, the helper should prevent it at the earliest possible point.Fix: Added
require(recipient != address(0), "DataHelper: recipient is zero address").V7 — LOW: Zero Deadline Accepted (Immediate Expiry)
Description: A
deadlineof0means the transaction's deadline has already passed atblock.timestamp > 0, causing an immediate revert downstream. This wastes gas and provides no useful error message to the caller.Fix: Added
require(deadline > 0, "DataHelper: deadline is zero").V8 — INFORMATIONAL: Function Naming Convention Violation
Description: The function
MintParamsCalluses PascalCase, which in Solidity convention is reserved for contract names, struct names, and event names. Functions should use camelCase per the Solidity Style Guide.Fix: Renamed to
mintParamsCall. Verified no other files in the repository reference the old name.V9 — INFORMATIONAL: Missing NatSpec Documentation
Description: The contract had zero NatSpec comments. For a utility contract intended to be called by external integrators, documentation is critical for safe usage.
Fix: Added full NatSpec
@title,@notice,@dev,@param, and@returntags for both the contract and the function.Compilation Status
DataHelper.solcompiles cleanly with Solidity 0.7.6 and the project's Hardhat configuration.Dex223PoolLib.sol,MockTimeDex223Pool.sol) are not affected by these changes.MintParamsCall, so the rename is a non-breaking change.Summary Table
Test Plan
DataHelper.solcompiles with Solidity 0.7.6 (npx hardhat compile)mintParamsCallwithtoken0 = address(0)→ should revert with "DataHelper: token0 is zero address"mintParamsCallwithtoken1 = address(0)→ should revert with "DataHelper: token1 is zero address"token0 == token1(both non-zero) → should revert with "DataHelper: identical tokens"token0 > token1→ should revert with "DataHelper: token0 must be less than token1"tickLower == tickUpper→ should revert with "DataHelper: tickLower must be less than tickUpper"tickLower > tickUpper→ should revert with "DataHelper: tickLower must be less than tickUpper"amount0Min > amount0Desired→ should revert with "DataHelper: amount0Min exceeds amount0Desired"amount1Min > amount1Desired→ should revert with "DataHelper: amount1Min exceeds amount1Desired"recipient = address(0)→ should revert with "DataHelper: recipient is zero address"deadline = 0→ should revert with "DataHelper: deadline is zero"amount0Min == amount0Desired→ should succeedtickUpper = tickLower + 1→ should succeedMade with Cursor