From e3ec155fbdaa58ea3cc4f2ae2f22a661b57c4e54 Mon Sep 17 00:00:00 2001 From: chefburger Date: Wed, 21 Aug 2024 15:54:02 +0800 Subject: [PATCH 1/3] feat: add sample dynamicFee hook --- ...3_DeployBinVeCakeExclusiveHook.s copy.sol} | 0 script/04_DeploySampleCLDynamicFeeHook.s.sol | 30 ++++++ script/05_DeploySampleBinDynamicFeeHook.s.sol | 30 ++++++ .../dynamic-fee/SampleBinDynamicFeeHook.sol | 91 +++++++++++++++++++ .../dynamic-fee/SampleCLDynamicFeeHook.sol | 80 ++++++++++++++++ 5 files changed, 231 insertions(+) rename script/{03_DeployBinVeCakeExclusiveHook.s.sol => 03_DeployBinVeCakeExclusiveHook.s copy.sol} (100%) create mode 100644 script/04_DeploySampleCLDynamicFeeHook.s.sol create mode 100644 script/05_DeploySampleBinDynamicFeeHook.s.sol create mode 100644 src/pool-bin/dynamic-fee/SampleBinDynamicFeeHook.sol create mode 100644 src/pool-cl/dynamic-fee/SampleCLDynamicFeeHook.sol diff --git a/script/03_DeployBinVeCakeExclusiveHook.s.sol b/script/03_DeployBinVeCakeExclusiveHook.s copy.sol similarity index 100% rename from script/03_DeployBinVeCakeExclusiveHook.s.sol rename to script/03_DeployBinVeCakeExclusiveHook.s copy.sol diff --git a/script/04_DeploySampleCLDynamicFeeHook.s.sol b/script/04_DeploySampleCLDynamicFeeHook.s.sol new file mode 100644 index 0000000..11a968f --- /dev/null +++ b/script/04_DeploySampleCLDynamicFeeHook.s.sol @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.24; + +import "forge-std/Script.sol"; +import {BaseScript} from "./BaseScript.sol"; + +import {SampleCLDynamicFeeHook} from "../src/pool-cl/dynamic-fee/SampleCLDynamicFeeHook.sol"; +import {ICLPoolManager} from "pancake-v4-core/src/pool-cl/interfaces/ICLPoolManager.sol"; + +/** + * forge script script/04_DeploySampleCLDynamicFeeHook.s.sol:DeploySampleCLDynamicFeeHookScript -vvv \ + * --rpc-url $RPC_URL \ + * --broadcast \ + * --slow \ + * --verify + */ +contract DeploySampleCLDynamicFeeHookScript is BaseScript { + function run() public { + uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY"); + vm.startBroadcast(deployerPrivateKey); + + address clPoolManager = getAddressFromConfig("clPoolManager"); + emit log_named_address("CLPoolManager", clPoolManager); + + SampleCLDynamicFeeHook hookAddr = new SampleCLDynamicFeeHook(ICLPoolManager(clPoolManager)); + emit log_named_address("SampleCLDynamicFeeHook", address(hookAddr)); + + vm.stopBroadcast(); + } +} diff --git a/script/05_DeploySampleBinDynamicFeeHook.s.sol b/script/05_DeploySampleBinDynamicFeeHook.s.sol new file mode 100644 index 0000000..454ac97 --- /dev/null +++ b/script/05_DeploySampleBinDynamicFeeHook.s.sol @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.24; + +import "forge-std/Script.sol"; +import {BaseScript} from "./BaseScript.sol"; + +import {SampleBinDynamicFeeHook} from "../src/pool-bin/dynamic-fee/SampleBinDynamicFeeHook.sol"; +import {IBinPoolManager} from "pancake-v4-core/src/pool-bin/interfaces/IBinPoolManager.sol"; + +/** + * forge script script/05_DeploySampleBinDynamicFeeHook.s.sol:DeploySampleBinDynamicFeeHookScript -vvv \ + * --rpc-url $RPC_URL \ + * --broadcast \ + * --slow \ + * --verify + */ +contract DeploySampleBinDynamicFeeHookScript is BaseScript { + function run() public { + uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY"); + vm.startBroadcast(deployerPrivateKey); + + address binPoolManager = getAddressFromConfig("binPoolManager"); + emit log_named_address("BinPoolManager", binPoolManager); + + SampleBinDynamicFeeHook feeHook = new SampleBinDynamicFeeHook(IBinPoolManager(binPoolManager)); + emit log_named_address("SampleBinDynamicFeeHook", address(feeHook)); + + vm.stopBroadcast(); + } +} diff --git a/src/pool-bin/dynamic-fee/SampleBinDynamicFeeHook.sol b/src/pool-bin/dynamic-fee/SampleBinDynamicFeeHook.sol new file mode 100644 index 0000000..e5fbeff --- /dev/null +++ b/src/pool-bin/dynamic-fee/SampleBinDynamicFeeHook.sol @@ -0,0 +1,91 @@ +pragma solidity ^0.8.19; + +import "pancake-v4-core/src/pool-cl/interfaces/ICLHooks.sol"; +import {PoolKey} from "pancake-v4-core/src/types/PoolKey.sol"; +import {PoolId, PoolIdLibrary} from "pancake-v4-core/src/types/PoolId.sol"; +import {Currency} from "pancake-v4-core/src/types/Currency.sol"; +import {IBinPoolManager} from "pancake-v4-core/src/pool-bin/interfaces/IBinPoolManager.sol"; +import {BinPoolManager} from "pancake-v4-core/src/pool-bin/BinPoolManager.sol"; +import {LPFeeLibrary} from "pancake-v4-core/src/libraries/LPFeeLibrary.sol"; +import {BeforeSwapDelta, BeforeSwapDeltaLibrary} from "pancake-v4-core/src/types/BeforeSwapDelta.sol"; +import {BinBaseHook} from "../BinBaseHook.sol"; + +contract SampleBinDynamicFeeHook is BinBaseHook { + using PoolIdLibrary for PoolKey; + + uint24 DEFAULT_LP_FEE = 3000; + uint24 FREE_LP_FEE = 0; + + bool enableLPFeeOverride = false; + + constructor(IBinPoolManager poolManager) BinBaseHook(poolManager) {} + + function toggleLPFeeOverride() external { + enableLPFeeOverride = !enableLPFeeOverride; + } + + function setDynamicLpFee(PoolKey memory key, uint24 fee) public { + poolManager.updateDynamicLPFee(key, fee); + } + + function getHooksRegistrationBitmap() external pure override returns (uint16) { + return _hooksRegistrationBitmapFrom( + Permissions({ + beforeInitialize: false, + afterInitialize: true, + beforeMint: true, + afterMint: false, + beforeBurn: false, + afterBurn: false, + beforeSwap: true, + afterSwap: false, + beforeDonate: false, + afterDonate: false, + beforeSwapReturnDelta: false, + afterSwapReturnDelta: false, + afterMintReturnDelta: false, + afterBurnReturnDelta: false + }) + ); + } + + function afterInitialize(address, PoolKey calldata key, uint24, bytes calldata) + external + override + returns (bytes4) + { + setDynamicLpFee(key, DEFAULT_LP_FEE); + return this.beforeInitialize.selector; + } + + function beforeMint(address, PoolKey calldata, IBinPoolManager.MintParams calldata, bytes calldata) + external + override + returns (bytes4, uint24) + { + // if enableLPFeeOverride, the lp fee for the ongoing inner swap will be 0 + if (enableLPFeeOverride) { + return (this.beforeMint.selector, LPFeeLibrary.OVERRIDE_FEE_FLAG & FREE_LP_FEE); + } + + // otherwise, the lp fee will just be the default value + return (this.beforeMint.selector, 0); + } + + function beforeSwap(address, PoolKey calldata, bool, int128, bytes calldata) + external + override + returns (bytes4, BeforeSwapDelta, uint24) + { + // if enableLPFeeOverride, the lp fee for the ongoing swap will be 0 + if (enableLPFeeOverride) { + return ( + this.beforeSwap.selector, + BeforeSwapDeltaLibrary.ZERO_DELTA, + LPFeeLibrary.OVERRIDE_FEE_FLAG & FREE_LP_FEE + ); + } + + return (this.beforeSwap.selector, BeforeSwapDeltaLibrary.ZERO_DELTA, 0); + } +} diff --git a/src/pool-cl/dynamic-fee/SampleCLDynamicFeeHook.sol b/src/pool-cl/dynamic-fee/SampleCLDynamicFeeHook.sol new file mode 100644 index 0000000..40d914f --- /dev/null +++ b/src/pool-cl/dynamic-fee/SampleCLDynamicFeeHook.sol @@ -0,0 +1,80 @@ +pragma solidity ^0.8.19; + +import "pancake-v4-core/src/pool-cl/interfaces/ICLHooks.sol"; +import {PoolKey} from "pancake-v4-core/src/types/PoolKey.sol"; +import {PoolId, PoolIdLibrary} from "pancake-v4-core/src/types/PoolId.sol"; +import {Currency} from "pancake-v4-core/src/types/Currency.sol"; +import {ICLPoolManager} from "pancake-v4-core/src/pool-cl/interfaces/ICLPoolManager.sol"; +import {CLPoolManager} from "pancake-v4-core/src/pool-cl/CLPoolManager.sol"; +import {LPFeeLibrary} from "pancake-v4-core/src/libraries/LPFeeLibrary.sol"; +import {BeforeSwapDelta, BeforeSwapDeltaLibrary} from "pancake-v4-core/src/types/BeforeSwapDelta.sol"; +import {CLBaseHook} from "../CLBaseHook.sol"; + +contract SampleCLDynamicFeeHook is CLBaseHook { + using PoolIdLibrary for PoolKey; + + uint24 DEFAULT_LP_FEE = 3000; + uint24 FREE_LP_FEE = 0; + + bool enableLPFeeOverride = false; + + constructor(ICLPoolManager poolManager) CLBaseHook(poolManager) {} + + function toggleLPFeeOverride() external { + enableLPFeeOverride = !enableLPFeeOverride; + } + + function setDynamicLpFee(PoolKey memory key, uint24 fee) public { + poolManager.updateDynamicLPFee(key, fee); + } + + function getHooksRegistrationBitmap() external pure override returns (uint16) { + return _hooksRegistrationBitmapFrom( + Permissions({ + beforeInitialize: false, + afterInitialize: true, + beforeAddLiquidity: false, + afterAddLiquidity: false, + beforeRemoveLiquidity: false, + afterRemoveLiquidity: false, + beforeSwap: true, + afterSwap: false, + beforeDonate: false, + afterDonate: false, + beforeSwapReturnsDelta: false, + afterSwapReturnsDelta: false, + afterAddLiquidiyReturnsDelta: false, + afterRemoveLiquidiyReturnsDelta: false + }) + ); + } + + function afterInitialize( + address sender, + PoolKey calldata key, + uint160 sqrtPriceX96, + int24 tick, + bytes calldata hookData + ) external override returns (bytes4) { + setDynamicLpFee(key, DEFAULT_LP_FEE); + return this.beforeInitialize.selector; + } + + function beforeSwap( + address sender, + PoolKey calldata key, + ICLPoolManager.SwapParams calldata params, + bytes calldata hookData + ) external override returns (bytes4, BeforeSwapDelta, uint24) { + // if enableLPFeeOverride, the lp fee for the ongoing swap will be 0 + if (enableLPFeeOverride) { + return ( + this.beforeSwap.selector, + BeforeSwapDeltaLibrary.ZERO_DELTA, + LPFeeLibrary.OVERRIDE_FEE_FLAG & FREE_LP_FEE + ); + } + + return (this.beforeSwap.selector, BeforeSwapDeltaLibrary.ZERO_DELTA, 0); + } +} From 41fe5118e773fb4e18cd1febfc4e8edd2fe468fc Mon Sep 17 00:00:00 2001 From: chefburger Date: Thu, 29 Aug 2024 14:18:43 +0800 Subject: [PATCH 2/3] chore: redeploy sample dynamic fee hook --- ...eHook.s copy.sol => 03_DeployBinVeCakeExclusiveHook.s.sol} | 0 script/config/bsc-testnet.json | 4 +++- 2 files changed, 3 insertions(+), 1 deletion(-) rename script/{03_DeployBinVeCakeExclusiveHook.s copy.sol => 03_DeployBinVeCakeExclusiveHook.s.sol} (100%) diff --git a/script/03_DeployBinVeCakeExclusiveHook.s copy.sol b/script/03_DeployBinVeCakeExclusiveHook.s.sol similarity index 100% rename from script/03_DeployBinVeCakeExclusiveHook.s copy.sol rename to script/03_DeployBinVeCakeExclusiveHook.s.sol diff --git a/script/config/bsc-testnet.json b/script/config/bsc-testnet.json index 14fd062..00bc2bc 100644 --- a/script/config/bsc-testnet.json +++ b/script/config/bsc-testnet.json @@ -6,6 +6,8 @@ "binPositionManager": "0x26008c91a2D47147d6739db3fFd3598A27da859d", "mockVeCake": "0x86668337a40CaAd59F463E89550c6Aa59C056988", "clVeCakeExclusiveHook": "0x3290880eB5b48Ee5CF1E8e381DDe932F7D696B27", - "binVeCakeExclusiveHook": "0x6203377AE3B7e1592806909836F6DC6b39026a60" + "binVeCakeExclusiveHook": "0x6203377AE3B7e1592806909836F6DC6b39026a60", + "sampleCLDynamicFeeHook": "0x0b9A17ACD77Ab0a55ae9324381E996eC29E57a1f", + "sampleBinDynamicFeeHook": "0x76e4E397c02E370E6bCf96177e7bed3D12bF57fD" } \ No newline at end of file From 6a4664b848bf2c096a2defb00d34e2bdc5867061 Mon Sep 17 00:00:00 2001 From: chefburger Date: Thu, 26 Sep 2024 11:14:42 +0800 Subject: [PATCH 3/3] chore: redeploy the latest contracts --- script/config/bsc-testnet.json | 4 ++-- script/config/ethereum-sepolia.json | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/script/config/bsc-testnet.json b/script/config/bsc-testnet.json index 00bc2bc..2f0077b 100644 --- a/script/config/bsc-testnet.json +++ b/script/config/bsc-testnet.json @@ -7,7 +7,7 @@ "mockVeCake": "0x86668337a40CaAd59F463E89550c6Aa59C056988", "clVeCakeExclusiveHook": "0x3290880eB5b48Ee5CF1E8e381DDe932F7D696B27", "binVeCakeExclusiveHook": "0x6203377AE3B7e1592806909836F6DC6b39026a60", - "sampleCLDynamicFeeHook": "0x0b9A17ACD77Ab0a55ae9324381E996eC29E57a1f", - "sampleBinDynamicFeeHook": "0x76e4E397c02E370E6bCf96177e7bed3D12bF57fD" + "sampleCLDynamicFeeHook": "0x9D596b40A6C9eAcCd90B3556500e93A489BB8Ba7", + "sampleBinDynamicFeeHook": "0x07728d3e6CD6aE8010F8F07D132E28e4e32c55E3" } \ No newline at end of file diff --git a/script/config/ethereum-sepolia.json b/script/config/ethereum-sepolia.json index c681ff8..25fe602 100644 --- a/script/config/ethereum-sepolia.json +++ b/script/config/ethereum-sepolia.json @@ -6,6 +6,8 @@ "binPositionManager": "0x21015eF9927e06b7Fc19D986A214e449Aa22FF7d", "mockVeCake": "0xA25ECd559680c77185a00a00e33BD9df14a5133e", "clVeCakeExclusiveHook": "0x549D196225706804c0A0fa9296c7a32fE6963850", - "binVeCakeExclusiveHook": "0xCc22705eA9433c8C35a1C93778bbFF76A19F3d55" + "binVeCakeExclusiveHook": "0xCc22705eA9433c8C35a1C93778bbFF76A19F3d55", + "sampleCLDynamicFeeHook": "0x6B1fdFc5dFB10DC5735bB242D014B4d4F1fb2c7A", + "sampleBinDynamicFeeHook": "0x470a9995c3bf588eE90A7F8e1b5372da1643Bca1" } \ No newline at end of file