fix: address review findings — CREATE2 guard, transition test, docs
- LiquidityManager.setFeeDestination: add CREATE2 bypass guard — also blocks re-assignment when the current feeDestination has since acquired bytecode (was a plain address when set, contract deployed to it later) - LiquidityManager.setFeeDestination: expand NatSpec to document the EOA-mutability trade-off and the CREATE2 guard explicitly - Test: add testSetFeeDestinationEOAToContract_Locks covering the realistic EOA→contract transition (the primary lock-activation path) - red-team.sh: add comment that DEPLOYER_PK is Anvil account-0 and must only be used against a local ephemeral Anvil instance - ARCHITECTURE.md: document feeDestination conditional-lock semantics and contrast with Kraiken's strictly set-once liquidityManager/stakingPool Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
9ff96ff137
commit
b902b89e3b
4 changed files with 35 additions and 4 deletions
|
|
@ -114,13 +114,24 @@ contract LiquidityManager is ThreePositionStrategy, PriceOracle {
|
|||
if (amount1Owed > 0) IERC20(poolKey.token1).safeTransfer(msg.sender, amount1Owed);
|
||||
}
|
||||
|
||||
/// @notice Sets the fee destination address (deployer only)
|
||||
/// @dev Any EOA can be set repeatedly. Once a contract address is set, locks permanently.
|
||||
/// @notice Sets the fee destination address (deployer only).
|
||||
/// @dev Conditional trapdoor: EOA addresses can be set repeatedly (allows setup/migration),
|
||||
/// but once a contract address is assigned, feeDestinationLocked is set and no further
|
||||
/// changes are allowed. Note: the deployer retains fee-redirect ability while feeDestination
|
||||
/// is an EOA; this is an intentional trade-off that enables staged deployment.
|
||||
///
|
||||
/// CREATE2 guard: also blocks re-assignment if the current feeDestination has since
|
||||
/// acquired bytecode (i.e. was a pre-computed EOA when set, later deployed to).
|
||||
/// @param feeDestination_ The address that will receive trading fees
|
||||
function setFeeDestination(address feeDestination_) external {
|
||||
require(msg.sender == deployer, "only deployer");
|
||||
if (address(0) == feeDestination_) revert ZeroAddressInSetter();
|
||||
require(!feeDestinationLocked, "fee destination locked");
|
||||
// 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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue