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
|
|
@ -1028,7 +1028,7 @@ contract LiquidityManagerTest is UniSwapHelper {
|
|||
}
|
||||
|
||||
/**
|
||||
* @notice Setting fee destination to a contract locks it permanently
|
||||
* @notice Setting fee destination to a contract locks it permanently (direct path)
|
||||
*/
|
||||
function testSetFeeDestinationContract_Locks() public {
|
||||
LiquidityManager freshLm = new LiquidityManager(address(factory), address(weth), address(harberg), address(optimizer));
|
||||
|
|
@ -1038,6 +1038,23 @@ contract LiquidityManagerTest is UniSwapHelper {
|
|||
assertEq(freshLm.feeDestination(), address(harberg));
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Realistic deployment path: set EOA first, then upgrade to a contract — lock triggers on transition
|
||||
*/
|
||||
function testSetFeeDestinationEOAToContract_Locks() public {
|
||||
LiquidityManager freshLm = new LiquidityManager(address(factory), address(weth), address(harberg), address(optimizer));
|
||||
// Step 1: set to an EOA during setup — allowed, not locked
|
||||
freshLm.setFeeDestination(makeAddr("treasuryEOA"));
|
||||
assertFalse(freshLm.feeDestinationLocked(), "not locked after EOA set");
|
||||
// Step 2: upgrade to treasury contract once it is deployed — locks permanently
|
||||
freshLm.setFeeDestination(address(harberg));
|
||||
assertTrue(freshLm.feeDestinationLocked(), "locked after contract set");
|
||||
assertEq(freshLm.feeDestination(), address(harberg));
|
||||
// Step 3: any further attempt reverts
|
||||
vm.expectRevert("fee destination locked");
|
||||
freshLm.setFeeDestination(makeAddr("attacker"));
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Once locked, setFeeDestination reverts
|
||||
*/
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue