From b9a13a4dbdf36359fc16de368998c5e047a3589f Mon Sep 17 00:00:00 2001 From: raz0r Date: Mon, 2 Jun 2025 21:15:32 +0300 Subject: [PATCH] Add HookNotImplemented and NotImplemented errors to Uniswap v4 callback contract; update YAML rules to exclude functions that revert with these errors --- .../uniswap-v4-callback-not-protected.sol | 215 ++++++++++++++++++ .../uniswap-v4-callback-not-protected.yaml | 12 + 2 files changed, 227 insertions(+) diff --git a/solidity/security/uniswap-v4-callback-not-protected.sol b/solidity/security/uniswap-v4-callback-not-protected.sol index 34dede3..2fb2650 100644 --- a/solidity/security/uniswap-v4-callback-not-protected.sol +++ b/solidity/security/uniswap-v4-callback-not-protected.sol @@ -33,6 +33,9 @@ struct BeforeSwapDelta { int128 deltaAmountUnspecified; } +error HookNotImplemented(); +error NotImplemented(); + contract Test { modifier onlyPoolManager() { require(msg.sender == address(poolManager), "Not authorized"); @@ -176,6 +179,218 @@ contract Test { return bytes4(0); } + // ok: uniswap-v4-callback-not-protected - functions that revert with HookNotImplemented() should not be detected + function beforeSwap( + address, + PoolKey calldata, + IPoolManager.SwapParams calldata, + bytes calldata + ) external pure override returns (bytes4, BeforeSwapDelta memory, uint24) { + revert HookNotImplemented(); + } + + // ok: uniswap-v4-callback-not-protected - functions that revert with HookNotImplemented() should not be detected + function afterInitialize( + address, + PoolKey calldata, + uint160, + int24, + bytes calldata + ) external pure override returns (bytes4) { + revert HookNotImplemented(); + } + + // ok: uniswap-v4-callback-not-protected - functions that revert with HookNotImplemented() should not be detected + function beforeAddLiquidity( + address, + PoolKey calldata, + IPoolManager.ModifyLiquidityParams calldata, + bytes calldata + ) external pure override returns (bytes4) { + revert HookNotImplemented(); + } + + // ok: uniswap-v4-callback-not-protected - functions that revert with HookNotImplemented() should not be detected + function afterRemoveLiquidity( + address, + PoolKey calldata, + IPoolManager.ModifyLiquidityParams calldata, + BeforeSwapDelta memory, + bytes calldata + ) external pure override returns (bytes4) { + revert HookNotImplemented(); + } + + // ok: uniswap-v4-callback-not-protected - functions that revert with HookNotImplemented() should not be detected + function beforeDonate( + address, + PoolKey calldata, + uint256, + uint256, + bytes calldata + ) external pure override returns (bytes4) { + revert HookNotImplemented(); + } + + // ok: uniswap-v4-callback-not-protected - functions that revert with HookNotImplemented() should not be detected + function afterSwap( + address, + PoolKey calldata, + IPoolManager.SwapParams calldata, + BeforeSwapDelta memory, + bytes calldata + ) external pure override returns (bytes4) { + revert HookNotImplemented(); + } + + // ok: uniswap-v4-callback-not-protected - functions that revert with HookNotImplemented() should not be detected + function afterDonate( + address, + PoolKey calldata, + uint256, + uint256, + bytes calldata + ) external pure override returns (bytes4) { + revert HookNotImplemented(); + } + + // ok: uniswap-v4-callback-not-protected - functions that revert with HookNotImplemented() should not be detected + function beforeRemoveLiquidity( + address, + PoolKey calldata, + IPoolManager.ModifyLiquidityParams calldata, + bytes calldata + ) external pure override returns (bytes4) { + revert HookNotImplemented(); + } + + // ok: uniswap-v4-callback-not-protected - functions that revert with HookNotImplemented() should not be detected + function beforeInitialize( + address, + PoolKey calldata, + uint160, + bytes calldata + ) external pure override returns (bytes4) { + revert HookNotImplemented(); + } + + // ok: uniswap-v4-callback-not-protected - functions that revert with HookNotImplemented() should not be detected + function afterAddLiquidity( + address, + PoolKey calldata, + IPoolManager.ModifyLiquidityParams calldata, + BeforeSwapDelta memory, + bytes calldata + ) external pure override returns (bytes4) { + revert HookNotImplemented(); + } + + // ok: uniswap-v4-callback-not-protected - functions that revert with NotImplemented() should not be detected + function beforeSwap( + address, + PoolKey calldata, + IPoolManager.SwapParams calldata, + bytes calldata + ) external pure override returns (bytes4, BeforeSwapDelta memory, uint24) { + revert NotImplemented(); + } + + // ok: uniswap-v4-callback-not-protected - functions that revert with NotImplemented() should not be detected + function afterInitialize( + address, + PoolKey calldata, + uint160, + int24, + bytes calldata + ) external pure override returns (bytes4) { + revert NotImplemented(); + } + + // ok: uniswap-v4-callback-not-protected - functions that revert with NotImplemented() should not be detected + function beforeAddLiquidity( + address, + PoolKey calldata, + IPoolManager.ModifyLiquidityParams calldata, + bytes calldata + ) external pure override returns (bytes4) { + revert NotImplemented(); + } + + // ok: uniswap-v4-callback-not-protected - functions that revert with NotImplemented() should not be detected + function afterRemoveLiquidity( + address, + PoolKey calldata, + IPoolManager.ModifyLiquidityParams calldata, + BeforeSwapDelta memory, + bytes calldata + ) external pure override returns (bytes4) { + revert NotImplemented(); + } + + // ok: uniswap-v4-callback-not-protected - functions that revert with NotImplemented() should not be detected + function beforeDonate( + address, + PoolKey calldata, + uint256, + uint256, + bytes calldata + ) external pure override returns (bytes4) { + revert NotImplemented(); + } + + // ok: uniswap-v4-callback-not-protected - functions that revert with NotImplemented() should not be detected + function afterSwap( + address, + PoolKey calldata, + IPoolManager.SwapParams calldata, + BeforeSwapDelta memory, + bytes calldata + ) external pure override returns (bytes4) { + revert NotImplemented(); + } + + // ok: uniswap-v4-callback-not-protected - functions that revert with NotImplemented() should not be detected + function afterDonate( + address, + PoolKey calldata, + uint256, + uint256, + bytes calldata + ) external pure override returns (bytes4) { + revert NotImplemented(); + } + + // ok: uniswap-v4-callback-not-protected - functions that revert with NotImplemented() should not be detected + function beforeRemoveLiquidity( + address, + PoolKey calldata, + IPoolManager.ModifyLiquidityParams calldata, + bytes calldata + ) external pure override returns (bytes4) { + revert NotImplemented(); + } + + // ok: uniswap-v4-callback-not-protected - functions that revert with NotImplemented() should not be detected + function beforeInitialize( + address, + PoolKey calldata, + uint160, + bytes calldata + ) external pure override returns (bytes4) { + revert NotImplemented(); + } + + // ok: uniswap-v4-callback-not-protected - functions that revert with NotImplemented() should not be detected + function afterAddLiquidity( + address, + PoolKey calldata, + IPoolManager.ModifyLiquidityParams calldata, + BeforeSwapDelta memory, + bytes calldata + ) external pure override returns (bytes4) { + revert NotImplemented(); + } + // ruleid: uniswap-v4-callback-not-protected function beforeSwap( address sender, diff --git a/solidity/security/uniswap-v4-callback-not-protected.yaml b/solidity/security/uniswap-v4-callback-not-protected.yaml index a13875e..e469017 100644 --- a/solidity/security/uniswap-v4-callback-not-protected.yaml +++ b/solidity/security/uniswap-v4-callback-not-protected.yaml @@ -30,6 +30,18 @@ rules: - pattern-not: function $CALLBACK(...) external view onlyPoolManager whenNotPaused {...} - pattern-not: function $CALLBACK(...) external override onlyPoolManager whenNotPaused {...} - pattern-not: function $CALLBACK(...) external view override onlyPoolManager whenNotPaused {...} + - pattern-not: | + function $CALLBACK(...) external {... + ... + revert HookNotImplemented(); + ... + } + - pattern-not: | + function $CALLBACK(...) external {... + ... + revert NotImplemented(); + ... + } - pattern-not: | function $CALLBACK(...) external {... ...