Skip to content

Commit

Permalink
Remove pull of protocol fee (#887)
Browse files Browse the repository at this point in the history
* Remove pull of protocol fee

* remove unused library

* Typo and remove unused error
  • Loading branch information
hensha256 authored Oct 10, 2024
1 parent f53af1b commit fc5b4cf
Show file tree
Hide file tree
Showing 44 changed files with 56 additions and 395 deletions.
Original file line number Diff line number Diff line change
@@ -1 +1 @@
144639
144663
2 changes: 1 addition & 1 deletion .forge-snapshots/addLiquidity CA fee.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
170935
170959
2 changes: 1 addition & 1 deletion .forge-snapshots/addLiquidity with empty hook.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
274240
274264
2 changes: 1 addition & 1 deletion .forge-snapshots/addLiquidity with native token.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
135129
135141
Original file line number Diff line number Diff line change
@@ -1 +1 @@
292831
292855
2 changes: 1 addition & 1 deletion .forge-snapshots/donate gas with 1 token.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
106321
106345
2 changes: 1 addition & 1 deletion .forge-snapshots/donate gas with 2 tokens.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
145742
145766
2 changes: 1 addition & 1 deletion .forge-snapshots/erc20 collect protocol fees.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
57442
57454
2 changes: 1 addition & 1 deletion .forge-snapshots/initialize.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
59536
51536
2 changes: 1 addition & 1 deletion .forge-snapshots/poolManager bytecode size.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
24001
23621
2 changes: 1 addition & 1 deletion .forge-snapshots/removeLiquidity CA fee.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
141195
141219
2 changes: 1 addition & 1 deletion .forge-snapshots/removeLiquidity with empty hook.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
130597
130621
2 changes: 1 addition & 1 deletion .forge-snapshots/removeLiquidity with native token.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
112525
112535
Original file line number Diff line number Diff line change
@@ -1 +1 @@
98838
98862
2 changes: 1 addition & 1 deletion .forge-snapshots/simple addLiquidity.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
161383
161407
Original file line number Diff line number Diff line change
@@ -1 +1 @@
92971
92995
2 changes: 1 addition & 1 deletion .forge-snapshots/simple removeLiquidity.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
85084
85108
2 changes: 1 addition & 1 deletion .forge-snapshots/simple swap with native.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
108503
108515
2 changes: 1 addition & 1 deletion .forge-snapshots/simple swap.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
123323
123347
2 changes: 1 addition & 1 deletion .forge-snapshots/swap CA custom curve + swap noop.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
124629
124653
2 changes: 1 addition & 1 deletion .forge-snapshots/swap CA fee on unspecified.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
154749
154773
Original file line number Diff line number Diff line change
@@ -1 +1 @@
105625
105637
2 changes: 1 addition & 1 deletion .forge-snapshots/swap against liquidity.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
116693
116717
2 changes: 1 addition & 1 deletion .forge-snapshots/swap burn 6909 for input.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
129257
129281
2 changes: 1 addition & 1 deletion .forge-snapshots/swap burn native 6909 for input.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
118713
118725
2 changes: 1 addition & 1 deletion .forge-snapshots/swap mint native output as 6909.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
139735
139747
2 changes: 1 addition & 1 deletion .forge-snapshots/swap mint output as 6909.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
155164
155188
Original file line number Diff line number Diff line change
@@ -1 +1 @@
206415
206403
2 changes: 1 addition & 1 deletion .forge-snapshots/swap with hooks.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
132321
132345
2 changes: 1 addition & 1 deletion .forge-snapshots/swap with return dynamic fee.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
145673
145661
7 changes: 3 additions & 4 deletions src/PoolManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -128,9 +128,8 @@ contract PoolManager is IPoolManager, ProtocolFees, NoDelegateCall, ERC6909Claim
key.hooks.beforeInitialize(key, sqrtPriceX96);

PoolId id = key.toId();
uint24 protocolFee = _fetchProtocolFee(key);

tick = _pools[id].initialize(sqrtPriceX96, protocolFee, lpFee);
tick = _pools[id].initialize(sqrtPriceX96, lpFee);

key.hooks.afterInitialize(key, sqrtPriceX96, tick);

Expand Down Expand Up @@ -174,7 +173,7 @@ contract PoolManager is IPoolManager, ProtocolFees, NoDelegateCall, ERC6909Claim
BalanceDelta hookDelta;
(callerDelta, hookDelta) = key.hooks.afterModifyLiquidity(key, params, callerDelta, feesAccrued, hookData);

// if the hook doesnt have the flag to be able to return deltas, hookDelta will always be 0
// if the hook doesn't have the flag to be able to return deltas, hookDelta will always be 0
if (hookDelta != BalanceDeltaLibrary.ZERO_DELTA) _accountPoolBalanceDelta(key, hookDelta, address(key.hooks));

_accountPoolBalanceDelta(key, callerDelta, msg.sender);
Expand Down Expand Up @@ -217,7 +216,7 @@ contract PoolManager is IPoolManager, ProtocolFees, NoDelegateCall, ERC6909Claim
BalanceDelta hookDelta;
(swapDelta, hookDelta) = key.hooks.afterSwap(key, params, swapDelta, hookData, beforeSwapDelta);

// if the hook doesnt have the flag to be able to return deltas, hookDelta will always be 0
// if the hook doesn't have the flag to be able to return deltas, hookDelta will always be 0
if (hookDelta != BalanceDeltaLibrary.ZERO_DELTA) _accountPoolBalanceDelta(key, hookDelta, address(key.hooks));

_accountPoolBalanceDelta(key, swapDelta, msg.sender);
Expand Down
42 changes: 0 additions & 42 deletions src/ProtocolFees.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import {IProtocolFeeController} from "./interfaces/IProtocolFeeController.sol";
import {IProtocolFees} from "./interfaces/IProtocolFees.sol";
import {PoolKey} from "./types/PoolKey.sol";
import {ProtocolFeeLibrary} from "./libraries/ProtocolFeeLibrary.sol";
import {BipsLibrary} from "./libraries/BipsLibrary.sol";
import {Owned} from "solmate/src/auth/Owned.sol";
import {PoolId} from "./types/PoolId.sol";
import {Pool} from "./libraries/Pool.sol";
Expand All @@ -17,18 +16,13 @@ abstract contract ProtocolFees is IProtocolFees, Owned {
using ProtocolFeeLibrary for uint24;
using Pool for Pool.State;
using CustomRevert for bytes4;
using BipsLibrary for uint256;

/// @inheritdoc IProtocolFees
mapping(Currency currency => uint256 amount) public protocolFeesAccrued;

/// @inheritdoc IProtocolFees
IProtocolFeeController public protocolFeeController;

// a percentage of the block.gaslimit denoted in basis points, used as the gas limit for fee controller calls
// 100 bps is 1%, at 30M gas, the limit is 300K
uint256 private constant BLOCK_LIMIT_BPS = 100;

constructor() Owned(msg.sender) {}

/// @inheritdoc IProtocolFees
Expand Down Expand Up @@ -66,42 +60,6 @@ abstract contract ProtocolFees is IProtocolFees, Owned {
/// @dev this is overridden in PoolManager.sol to give access to the _pools mapping
function _getPool(PoolId id) internal virtual returns (Pool.State storage);

/// @notice Fetch the protocol fees for a given pool
/// @dev the success of this function is false if the call fails or the returned fees are invalid
/// @dev to prevent an invalid protocol fee controller from blocking pools from being initialized
/// the success of this function is NOT checked on initialize and if the call fails, the protocol fees are set to 0.
function _fetchProtocolFee(PoolKey memory key) internal returns (uint24 protocolFee) {
if (address(protocolFeeController) != address(0)) {
uint256 controllerGasLimit = block.gaslimit.calculatePortion(BLOCK_LIMIT_BPS);

// note that EIP-150 mandates that calls requesting more than 63/64ths of remaining gas
// will be allotted no more than this amount, so controllerGasLimit must be set with this
// in mind.
if (gasleft() < controllerGasLimit) ProtocolFeeCannotBeFetched.selector.revertWith();

address toAddress = address(protocolFeeController);

bytes memory data = abi.encodeCall(IProtocolFeeController.protocolFeeForPool, (key));

bool success;
uint256 returnData;
assembly ("memory-safe") {
// only load the first 32 bytes of the return data to prevent gas griefing
success := call(controllerGasLimit, toAddress, 0, add(data, 0x20), mload(data), 0, 32)
// if success is false this wont actually be returned, instead 0 will be returned
returnData := mload(0)

// success if return data size is 32 bytes
success := and(success, eq(returndatasize(), 32))
}

// Ensure return data does not overflow a uint24 and that the underlying fees are within bounds.
protocolFee = success && (returnData == uint24(returnData)) && uint24(returnData).isValidProtocolFee()
? uint24(returnData)
: 0;
}
}

function _updateProtocolFees(Currency currency, uint256 amount) internal {
unchecked {
protocolFeesAccrued[currency] += amount;
Expand Down
3 changes: 1 addition & 2 deletions src/interfaces/IProtocolFees.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,9 @@ import {PoolKey} from "../types/PoolKey.sol";

/// @notice Interface for all protocol-fee related functions in the pool manager
interface IProtocolFees {
/// @notice Thrown when not enough gas is provided to look up the protocol fee
error ProtocolFeeCannotBeFetched();
/// @notice Thrown when protocol fee is set too high
error ProtocolFeeTooLarge(uint24 fee);

/// @notice Thrown when the contract is unlocked
error ContractUnlocked();

Expand Down
17 changes: 0 additions & 17 deletions src/libraries/BipsLibrary.sol

This file was deleted.

4 changes: 2 additions & 2 deletions src/libraries/Hooks.sol
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ library Hooks {
: (uint160(address(self)) & ALL_HOOK_MASK > 0 || fee.isDynamicFee());
}

/// @notice performs a hook call using the given calldata on the given hook that doesnt return a delta
/// @notice performs a hook call using the given calldata on the given hook that doesn't return a delta
/// @return result The complete data returned by the hook
function callHook(IHooks self, bytes memory data) internal returns (bytes memory result) {
bool success;
Expand Down Expand Up @@ -268,7 +268,7 @@ library Hooks {
// any return in unspecified is passed to the afterSwap hook for handling
int128 hookDeltaSpecified = hookReturn.getSpecifiedDelta();

// Update the swap amount according to the hook's return, and check that the swap type doesnt change (exact input/output)
// Update the swap amount according to the hook's return, and check that the swap type doesn't change (exact input/output)
if (hookDeltaSpecified != 0) {
bool exactInput = amountToSwap < 0;
amountToSwap += hookDeltaSpecified;
Expand Down
11 changes: 4 additions & 7 deletions src/libraries/Pool.sol
Original file line number Diff line number Diff line change
Expand Up @@ -94,16 +94,13 @@ library Pool {
if (tickUpper > TickMath.MAX_TICK) TickUpperOutOfBounds.selector.revertWith(tickUpper);
}

function initialize(State storage self, uint160 sqrtPriceX96, uint24 protocolFee, uint24 lpFee)
internal
returns (int24 tick)
{
function initialize(State storage self, uint160 sqrtPriceX96, uint24 lpFee) internal returns (int24 tick) {
if (self.slot0.sqrtPriceX96() != 0) PoolAlreadyInitialized.selector.revertWith();

tick = TickMath.getTickAtSqrtPrice(sqrtPriceX96);

self.slot0 = Slot0.wrap(bytes32(0)).setSqrtPriceX96(sqrtPriceX96).setTick(tick).setProtocolFee(protocolFee)
.setLpFee(lpFee);
// the initial protocolFee is 0 so doesn't need to be set
self.slot0 = Slot0.wrap(bytes32(0)).setSqrtPriceX96(sqrtPriceX96).setTick(tick).setLpFee(lpFee);
}

function setProtocolFee(State storage self, uint24 protocolFee) internal {
Expand Down Expand Up @@ -404,7 +401,7 @@ library Pool {
}

// Shift tick if we reached the next price, and preemptively decrement for zeroForOne swaps to tickNext - 1.
// If the swap doesnt continue (if amountRemaining == 0 or sqrtPriceLimit is met), slot0.tick will be 1 less
// If the swap doesn't continue (if amountRemaining == 0 or sqrtPriceLimit is met), slot0.tick will be 1 less
// than getTickAtSqrtPrice(slot0.sqrtPrice). This doesn't affect swaps, but donation calls should verify both
// price and tick to reward the correct LPs.
if (result.sqrtPriceX96 == step.sqrtPriceNextX96) {
Expand Down
39 changes: 0 additions & 39 deletions src/test/ProtocolFeeControllerTest.sol
Original file line number Diff line number Diff line change
Expand Up @@ -17,42 +17,3 @@ contract ProtocolFeeControllerTest is IProtocolFeeController {
protocolFee[id] = fee;
}
}

/// @notice Reverts on call
contract RevertingProtocolFeeControllerTest is IProtocolFeeController {
function protocolFeeForPool(PoolKey memory /* key */ ) external pure returns (uint24) {
revert();
}
}

/// @notice Returns an out of bounds protocol fee
contract OutOfBoundsProtocolFeeControllerTest is IProtocolFeeController {
function protocolFeeForPool(PoolKey memory /* key */ ) external pure returns (uint24) {
// set both protocol fees to 1001, which is greater than MAX_PROTOCOL_FEE
return (1001 << 12) | 1001;
}
}

/// @notice Return a value that overflows a uint24
contract OverflowProtocolFeeControllerTest is IProtocolFeeController {
function protocolFeeForPool(PoolKey memory /* key */ ) external pure returns (uint24) {
assembly {
let ptr := mload(0x40)
mstore(ptr, 0xFFFFAAA001)
return(ptr, 0x20)
}
}
}

/// @notice Returns data that is larger than a word
contract InvalidReturnSizeProtocolFeeControllerTest is IProtocolFeeController {
function protocolFeeForPool(PoolKey memory /* key */ ) external pure returns (uint24) {
address a = address(1);
assembly {
let ptr := mload(0x40)
mstore(ptr, a)
mstore(add(ptr, 0x20), a)
return(ptr, 0x40)
}
}
}
4 changes: 0 additions & 4 deletions src/test/ProtocolFeesImplementation.sol
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,6 @@ contract ProtocolFeesImplementation is ProtocolFees {
return isUnlocked;
}

function fetchProtocolFee(PoolKey memory key) public returns (uint24) {
return ProtocolFees._fetchProtocolFee(key);
}

function updateProtocolFees(Currency currency, uint256 amount) public {
ProtocolFees._updateProtocolFees(currency, amount);
}
Expand Down
3 changes: 1 addition & 2 deletions src/test/ProxyPoolManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,8 @@ contract ProxyPoolManager is IPoolManager, ProtocolFees, NoDelegateCall, ERC6909
key.hooks.beforeInitialize(key, sqrtPriceX96);

PoolId id = key.toId();
uint24 protocolFee = _fetchProtocolFee(key);

tick = _pools[id].initialize(sqrtPriceX96, protocolFee, lpFee);
tick = _pools[id].initialize(sqrtPriceX96, lpFee);

key.hooks.afterInitialize(key, sqrtPriceX96, tick);

Expand Down
Loading

0 comments on commit fc5b4cf

Please sign in to comment.