Haven1 - audit hSwap

CertiKFiles named in the report

CertiK reviewed Haven1 (Haven1 - audit hSwap) on 26 Feb 2025: 10 findings, 0 critical; 3 marked fixed, 7 open.

No open critical findings
Open the reportOpen Haven1’s security record

Report hosted on skynet.certik.com.

Trustblock does not review code.

Findings10

Statuses are the security firm’s own, from its report.

SeverityOpenAcknowledgedFixed
Critical000
High100
Medium100
Low503
HighCentralization Related RisksOpen

In the contract `UniswapV3Factory` the role owner has authority over the following functions: - function `setOwner()` - function `setRouter` - function `enableFeeAmount()` Any compromise to the owner account may allow a hacker to take advantage of this authority and modify default fee settings for swap pools or modify the whitelisted router address list. ----------------------------------------------------------------------- In the contract `UniswapV3Pool` the role `FactoryOwner` has authority over the following functions: - function `setFeeProtocol()` - function `collectProtocol()` Any compromise to the factory owner account may allow a hacker to take advantage of this authority and modify protocol fee or collect protocol fee. ----------------------------------------------------------------------- In the contract `H1NativeApplication` the role `association` has authority over the following functions: - function `_authorizeFeeContractAddressUpdate()` Any compromise to the `association` account may allow a hacker to take advantage of this authority and modify fee contract addresses through the function `updateFeeContractAddress`. ----------------------------------------------------------------------- In the contract `H1NativeApplication` the role `association` has authority over the following functions: - function `updateSwapRouter()` - function `updateQuoter()` - function `addBaseToken()` - function `removeBaseToken()` Any compromise to the `association` account may allow a hacker to take advantage of this authority and change Router/Quoter address and modify predefined basetoken lists when performing the on-chain swap routing.

MediumPotential Reentrancy RiskOpen

A reentrancy attack can occur when the contract creates a function that makes an external call to another untrusted contract before resolving any effects. The contract pays fees to `_feeContract` via a low-level call `(call{value: amount})` before finalizing state updates. Since the `_feeContract` can be modified by the `association` account, if the attacker can control the `_feeContract` address, a malicious fallback function or reentry call could invoke the original contract logic again. This allows the attacker to trigger functions and manipulate state that would otherwise only run once. ```solidity=100 modifier applicationFee(bool payableFunction, bool refundRemainingBalance) { _updateFee(); uint256 fee = _feeContract().getFeeForContract( address(this), msg.sender, msg.sig ); if (msg.value < fee || (address(this).balance < fee)) { revert H1NativeBase__InsufficientFunds(address(this).balance, fee); } H1NativeBaseStorage storage $ = _getH1NativeStorage(); if (payableFunction) $.msgValueAfterFee = (msg.value - fee); _payFee(fee); _; if (refundRemainingBalance && address(this).balance > 0) { _safeTransfer(msg.sender, address(this).balance); } delete $.msgValueAfterFee; } ```

Low`collectBlockNumber` not returned in function `poOpen

The `positions()` function is intended to expose details about a specific position. While the function successfully returns most of the details, it omits the `collectBlockNumber` field that is available in the Position struct. ```solidity=185 function positions( uint256 tokenId ) external view override returns ( uint96 nonce, address operator, address token0, address token1, uint24 fee, int24 tickLower, int24 tickUpper, uint128 liquidity, uint256 feeGrowthInside0LastX128, uint256 feeGrowthInside1LastX128, uint128 tokensOwed0, uint128 tokensOwed1 ) ```

Low`safeApprove()` is deprecatedOpen

`safeApprove()` has been [Deprecated](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/bfff03c0d2a59bcd8e2ead1da9aed9edf0080d05/contracts/token/ERC20/utils/SafeERC20.sol#L38-L45) in favor of `safeIncreaseAllowance()` and `safeDecreaseAllowance()`. If only setting the initial allowance to the value that means infinite, `safeIncreaseAllowance()` can be used instead. The function may currently work, but if a bug is found in this version of OpenZeppelin, and the version that you're forced to upgrade to no longer has this function, you'll encounter unnecessary delays in porting and testing replacement contracts.

Low`safeTransfer` Function Requires Token ExistenceOpen

The `safeTransfer` function does not check for the existence of the ERC20 token contract , `TransferHelper.sol` performs a transfer with a low-level call without confirming the contract's existence ```solidity function safeTransfer( address token, address to, uint256 value ) internal { (bool success, bytes memory data) = token.call(abi.encodeWithSelector(IERC20Minimal.transfer.selector, to, value)); require(success && (data.length == 0 || abi.decode(data, (bool))), 'TF'); } ``` The low-level functions call, delegatecall and staticcall return true as their first return value if the account called is non-existent, as part of the design of the EVM. Account existence must be checked prior to calling if needed.

LowEvent Not IndexedOpen

If an event is not indexed in a smart contract, it means that the event's parameters are not tagged with the `indexed` keyword. This has implications for how the event data can be searched and filtered when looking through blockchain logs. Without indexing, the event will still emit the data as part of the transaction log, but users won't be able to query for these events using the parameters. They'll have to retrieve the entire set of logs and manually sift through them to find events with the specific data. This can be less efficient and more time-consuming, especially on a blockchain with a high volume of transactions and events.

LowThird-Party DependenciesOpen

The `H1NativeBase` contract is serving as the underlying entity to interact with third-party `_feeContract` address to get the application fee amount. The scope of the audit treats third-party entities as black boxes and assumes their functional correctness. However, in the real world, third parties can be compromised and external call to a malicious contract may lead to lost or stolen assets. ```solidity=100 modifier applicationFee(bool payableFunction, bool refundRemainingBalance) { _updateFee(); uint256 fee = _feeContract().getFeeForContract( address(this), msg.sender, msg.sig ); ```

Contracts in scope

No deployed address is recorded for this audit.

The report names a repository or files. Open the report to see its scope.

Repository and files the report names (105)

  • v3-core/contracts/libraries/FixedPoint128.sol
  • v3-periphery/contracts/NonfungiblePositionManager.sol
  • universal-router/contracts/modules/PaymentsImmutables.sol
  • v3-periphery/contracts/lens/QuoterV2.sol
  • v3-core/contracts/UniswapV3Pool.sol
  • v3-core/contracts/interfaces/callback/IUniswapV3FlashCallback.sol
  • v3-periphery/contracts/base/LiquidityManagement.sol
  • v3-periphery/contracts/libraries/NFTSVG.sol
  • universal-router/contracts/UniversalRouter.sol
  • v3-periphery/contracts/libraries/TransferHelper.sol
  • v3-core/contracts/interfaces/callback/IUniswapV3SwapCallback.sol
  • universal-router/contracts/interfaces/IUniversalRouter.sol
  • v3-core/contracts/libraries/LowGasSafeMath.sol
  • v3-core/contracts/interfaces/pool/IUniswapV3PoolEvents.sol
  • v3-core/contracts/interfaces/IUniswapV3PoolDeployer.sol
  • universal-router/contracts/modules/uniswap/v2/V2SwapRouter.sol
  • v3-periphery/contracts/h1/H1FlashRouter.sol
  • v3-periphery/contracts/h1/base/H1NativeBaseV07Downgrade.sol
  • v3-core/contracts/UniswapV3Factory.sol
  • v3-periphery/contracts/libraries/Path.sol
  • v3-periphery/contracts/libraries/OracleLibrary.sol
  • universal-router/contracts/modules/Payments.sol
  • v3-core/contracts/interfaces/callback/IUniswapV3MintCallback.sol
  • v3-core/contracts/libraries/TickMath.sol
  • v3-core/contracts/interfaces/pool/IUniswapV3PoolActions.sol
  • v3-periphery/contracts/h1/interfaces/IFeeContractV07Downgrade.sol
  • v3-core/contracts/libraries/Position.sol
  • universal-router/contracts/base/Dispatcher.sol
  • v3-core/contracts/libraries/SafeCast.sol
  • universal-router/contracts/deploy/UnsupportedProtocol.sol
  • v3-periphery/contracts/SwapRouter.sol
  • v3-periphery/contracts/libraries/LiquidityAmounts.sol
  • v3-periphery/contracts/libraries/PoolAddress.sol
  • contracts/utils/UniswapV3Helper_WIP.sol
  • v3-core/contracts/libraries/BitMath.sol
  • v3-core/contracts/interfaces/IUniswapV3Pool.sol
  • v3-core/contracts/interfaces/pool/IUniswapV3PoolState.sol
  • v3-periphery/contracts/NonfungibleTokenPositionDescriptor.sol
  • v3-periphery/contracts/base/PeripheryValidation.sol
  • v3-periphery/contracts/libraries/ChainId.sol
  • v3-core/contracts/libraries/Tick.sol
  • v3-periphery/contracts/base/PoolInitializer.sol
  • v3-core/contracts/libraries/SqrtPriceMath.sol
  • universal-router/contracts/modules/uniswap/v3/V3Path.sol
  • universal-router/contracts/modules/h1-native-application/IFeeContract.sol
  • v3-periphery/contracts/libraries/BytesLib.sol
  • v3-periphery/contracts/lens/TickLens.sol
  • universal-router/contracts/interfaces/IRewardsCollector.sol
  • v3-periphery/contracts/libraries/NFTDescriptor.sol
  • universal-router/contracts/base/RouterImmutables.sol
  • v3-core/contracts/libraries/LiquidityMath.sol
  • universal-router/contracts/modules/h1-native-application/H1NativeApplication.sol
  • v3-periphery/contracts/base/PeripheryPaymentsWithFee.sol
  • v3-core/contracts/libraries/Oracle.sol
  • v3-core/contracts/libraries/TransferHelper.sol
  • v3-periphery/contracts/libraries/PositionKey.sol
  • v3-periphery/contracts/h1/H1Multicall.sol
  • v3-core/contracts/NoDelegateCall.sol
  • v3-core/contracts/libraries/FullMath.sol
  • v3-periphery/contracts/libraries/PoolTicksCounter.sol
  • v3-periphery/contracts/V3Migrator.sol
  • v3-core/contracts/interfaces/IERC20Minimal.sol
  • v3-periphery/contracts/libraries/SqrtPriceMathPartial.sol
  • v3-periphery/contracts/libraries/CallbackValidation.sol
  • universal-router/contracts/interfaces/external/IWETH9.sol
  • contracts/utils/OnChainRouting.sol
  • universal-router/contracts/modules/NFTImmutables.sol
  • v3-periphery/contracts/libraries/HexStrings.sol
  • v3-core/contracts/interfaces/pool/IUniswapV3PoolDerivedState.sol
  • v3-periphery/contracts/lens/UniswapInterfaceMulticall.sol
  • v3-periphery/contracts/h1/H1NativeApplicationV07Downgrade.sol
  • v3-core/contracts/UniswapV3PoolDeployer.sol
  • v3-core/contracts/libraries/SwapMath.sol
  • v3-periphery/contracts/libraries/TokenRatioSortOrder.sol
  • universal-router/contracts/modules/uniswap/v2/UniswapV2Library.sol
  • v3-periphery/contracts/h1/MockFeeContract.sol
  • contracts/utils/Address.sol
  • universal-router/contracts/modules/uniswap/UniswapImmutables.sol
  • universal-router/contracts/base/Callbacks.sol
  • v3-core/contracts/interfaces/pool/IUniswapV3PoolImmutables.sol
  • v3-periphery/contracts/h1/IH1FlashRouter.sol
  • v3-periphery/contracts/base/Multicall.sol
  • contracts/vendor/uniswapV3/libraries/v3-periphery/PoolAddress.sol
  • v3-core/contracts/libraries/UnsafeMath.sol
  • universal-router/contracts/interfaces/external/ICryptoPunksMarket.sol
  • universal-router/contracts/libraries/Commands.sol
  • v3-periphery/contracts/base/BlockTimestamp.sol
  • contracts/vendor/uniswapV3/libraries/base64.sol
  • v3-periphery/contracts/base/SelfPermit.sol
  • v3-core/contracts/libraries/TickBitmap.sol
  • v3-core/contracts/libraries/FixedPoint96.sol
  • v3-core/contracts/interfaces/IUniswapV3Factory.sol
  • v3-periphery/contracts/base/PeripheryImmutableState.sol
  • universal-router/contracts/modules/uniswap/v3/BytesLib.sol
  • universal-router/contracts/modules/Permit2Payments.sol
  • universal-router/contracts/modules/uniswap/v3/V3SwapRouter.sol
  • v3-periphery/contracts/base/ERC721Permit.sol
  • v3-periphery/contracts/base/PeripheryPayments.sol
  • universal-router/contracts/base/LockAndMsgSender.sol
  • v3-periphery/contracts/lens/Quoter.sol
  • universal-router/contracts/base/RewardsCollector.sol
  • universal-router/contracts/libraries/Constants.sol
  • universal-router/contracts/modules/h1-native-application/H1NativeBase.sol
  • v3-periphery/contracts/libraries/PositionValue.sol
  • v3-core/contracts/interfaces/pool/IUniswapV3PoolOwnerActions.sol

Part of Haven1’s security record

Haven1
Audits2 audits by 1 firmLast audit Mar 2025, by CertiK.
Critical findingsNo open critical findingsAcross the 2 reports, 4 critical findings were reported. Each is marked fixed by the firm that reported it.
Open Haven1’s security record

Security firm

CertiK

1,044 projects reviewed · 1,375 reports · latest May 2025

See CertiK’s audits

Something wrong on this page? A missing report, a wrong date, a finding that was fixed since. Tell us and we check it against its source.

Tell us