Skip to content

Commit

Permalink
Merge pull request #11 from pancakeswap/feat/dynamic-fee-hook
Browse files Browse the repository at this point in the history
[Reference ]Feat/dynamic fee hook
  • Loading branch information
chefburger authored Nov 21, 2024
2 parents 7d553d9 + 278c024 commit 8b8035f
Show file tree
Hide file tree
Showing 6 changed files with 250 additions and 2 deletions.
30 changes: 30 additions & 0 deletions script/04_DeploySampleCLDynamicFeeHook.s.sol
Original file line number Diff line number Diff line change
@@ -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();
}
}
30 changes: 30 additions & 0 deletions script/05_DeploySampleBinDynamicFeeHook.s.sol
Original file line number Diff line number Diff line change
@@ -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();
}
}
4 changes: 3 additions & 1 deletion script/config/bsc-testnet.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
"binPositionManager": "0x26008c91a2D47147d6739db3fFd3598A27da859d",
"mockVeCake": "0x86668337a40CaAd59F463E89550c6Aa59C056988",
"clVeCakeExclusiveHook": "0x3290880eB5b48Ee5CF1E8e381DDe932F7D696B27",
"binVeCakeExclusiveHook": "0x6203377AE3B7e1592806909836F6DC6b39026a60"
"binVeCakeExclusiveHook": "0x6203377AE3B7e1592806909836F6DC6b39026a60",
"sampleCLDynamicFeeHook": "0xbD63244010D2ee0C909F6aa652FA21d9606BBb65",
"sampleBinDynamicFeeHook": "0xaaD9dD9AfF7ad8317b1466965Bfa63235d5d3628"
}

4 changes: 3 additions & 1 deletion script/config/ethereum-sepolia.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
"binPositionManager": "0x21015eF9927e06b7Fc19D986A214e449Aa22FF7d",
"mockVeCake": "0xA25ECd559680c77185a00a00e33BD9df14a5133e",
"clVeCakeExclusiveHook": "0x549D196225706804c0A0fa9296c7a32fE6963850",
"binVeCakeExclusiveHook": "0xCc22705eA9433c8C35a1C93778bbFF76A19F3d55"
"binVeCakeExclusiveHook": "0xCc22705eA9433c8C35a1C93778bbFF76A19F3d55",
"sampleCLDynamicFeeHook": "0x0E647d71d3b5dfcd2Ad5d77c36723Ef646784664",
"sampleBinDynamicFeeHook": "0x8F3654C0eA6712C69bAC45644478942cDe955Db2"
}

104 changes: 104 additions & 0 deletions src/pool-bin/dynamic-fee/SampleBinDynamicFeeHook.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
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.afterInitialize.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);
}
}
80 changes: 80 additions & 0 deletions src/pool-cl/dynamic-fee/SampleCLDynamicFeeHook.sol
Original file line number Diff line number Diff line change
@@ -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.afterInitialize.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);
}
}

0 comments on commit 8b8035f

Please sign in to comment.