From cd67e8c1fda3109f99cde06497c2c6b3640a38b7 Mon Sep 17 00:00:00 2001 From: openhands Date: Tue, 17 Mar 2026 14:08:45 +0000 Subject: [PATCH] fix: setFeeDestination in snippet uses stale AddressAlreadySet one-time-setter pattern (#886) --- landing/src/views/docs/CodeDocs.vue | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/landing/src/views/docs/CodeDocs.vue b/landing/src/views/docs/CodeDocs.vue index b6334bb..4f15397 100644 --- a/landing/src/views/docs/CodeDocs.vue +++ b/landing/src/views/docs/CodeDocs.vue @@ -264,6 +264,7 @@ contract LiquidityManager is ThreePositionStrategy, PriceOracle { address private immutable deployer; address public feeDestination; + bool public feeDestinationLocked; int24 public lastRecenterTick; uint256 public lastRecenterTime; @@ -272,7 +273,6 @@ contract LiquidityManager is ThreePositionStrategy, PriceOracle { event Recentered(int24 indexed currentTick, bool indexed isUp); error ZeroAddressInSetter(); - error AddressAlreadySet(); constructor(address _factory, address _WETH9, address _kraiken, address _optimizer) { deployer = msg.sender; @@ -303,8 +303,16 @@ contract LiquidityManager is ThreePositionStrategy, PriceOracle { function setFeeDestination(address feeDestination_) external { require(msg.sender == deployer, "only deployer"); if (address(0) == feeDestination_) revert ZeroAddressInSetter(); - if (feeDestination != address(0)) revert AddressAlreadySet(); + // Block if explicitly locked OR if the current destination has since become a contract + // (guards CREATE2 bypass: address looked like an EOA when set, bytecode deployed later) + require( + !feeDestinationLocked && (feeDestination == address(0) || feeDestination.code.length == 0), + "fee destination locked" + ); feeDestination = feeDestination_; + if (feeDestination_.code.length > 0) { + feeDestinationLocked = true; + } } function recenter() external returns (bool isUp) {