diff --git a/src/base/BaseCustomAccounting.sol b/src/base/BaseCustomAccounting.sol index 3cccb29..1fde02f 100644 --- a/src/base/BaseCustomAccounting.sol +++ b/src/base/BaseCustomAccounting.sol @@ -39,11 +39,17 @@ abstract contract BaseCustomAccounting is BaseHook { override returns (bytes4, BeforeSwapDelta, uint24) { + // Determine if the swap is exact input or exact output bool exactInput = params.amountSpecified < 0; + + // Determine which currency is specified and which is unspecified (Currency specified, Currency unspecified) = (params.zeroForOne == exactInput) ? (key.currency0, key.currency1) : (key.currency1, key.currency0); + // Get the positive specified amount uint256 specifiedAmount = exactInput ? uint256(-params.amountSpecified) : uint256(params.amountSpecified); + + // Get the amount of the unspecified currency to be taken or settled uint256 unspecifiedAmount = _getAmount( specifiedAmount, exactInput ? specified : unspecified, @@ -51,24 +57,29 @@ abstract contract BaseCustomAccounting is BaseHook { params.zeroForOne, exactInput ); + + // New delta must be returned, so store in memory BeforeSwapDelta returnDelta; + if (exactInput) { specified.take(poolManager, address(this), specifiedAmount, true); unspecified.settle(poolManager, address(this), unspecifiedAmount, true); + // On exact input, amount0 is specified and amount1 is unspecified. returnDelta = toBeforeSwapDelta(specifiedAmount.toInt128(), -unspecifiedAmount.toInt128()); } else { unspecified.take(poolManager, address(this), unspecifiedAmount, true); specified.settle(poolManager, address(this), specifiedAmount, true); + // On exact output, amount1 is specified and amount0 is unspecified. returnDelta = toBeforeSwapDelta(-specifiedAmount.toInt128(), unspecifiedAmount.toInt128()); } - return (BaseHook.beforeSwap.selector, returnDelta, 0); + return (this.beforeSwap.selector, returnDelta, 0); } /** - * @dev Calculate the amount of tokens to be take or settle. + * @dev Calculate the amount of tokens to take or send (settle). */ function _getAmount(uint256 amountIn, Currency input, Currency output, bool zeroForOne, bool exactInput) internal diff --git a/src/base/BaseNoOp.sol b/src/base/BaseNoOp.sol index e09a9f7..776d310 100644 --- a/src/base/BaseNoOp.sol +++ b/src/base/BaseNoOp.sol @@ -41,9 +41,9 @@ abstract contract BaseNoOp is BaseHook { uint256 amountTaken = uint256(-params.amountSpecified); Currency input = params.zeroForOne ? key.currency0 : key.currency1; poolManager.mint(address(this), input.toId(), amountTaken); - return (BaseHook.beforeSwap.selector, toBeforeSwapDelta(amountTaken.toInt128(), 0), 0); + return (this.beforeSwap.selector, toBeforeSwapDelta(amountTaken.toInt128(), 0), 0); } else { - return (BaseHook.beforeSwap.selector, BeforeSwapDeltaLibrary.ZERO_DELTA, 0); + return (this.beforeSwap.selector, BeforeSwapDeltaLibrary.ZERO_DELTA, 0); } } diff --git a/src/fee/BaseDynamicFee.sol b/src/fee/BaseDynamicFee.sol index 88c57ec..4d61b35 100644 --- a/src/fee/BaseDynamicFee.sol +++ b/src/fee/BaseDynamicFee.sol @@ -38,7 +38,7 @@ abstract contract BaseDynamicFee is BaseHook { returns (bytes4) { poolManager.updateDynamicLPFee(key, _getFee(key)); - return BaseHook.afterInitialize.selector; + return this.afterInitialize.selector; } /** diff --git a/src/fee/BaseOverrideFee.sol b/src/fee/BaseOverrideFee.sol index 30a2a7a..21adf0e 100644 --- a/src/fee/BaseOverrideFee.sol +++ b/src/fee/BaseOverrideFee.sol @@ -42,7 +42,7 @@ abstract contract BaseOverrideFee is BaseHook { bytes calldata hookData ) internal virtual override returns (bytes4, BeforeSwapDelta, uint24) { uint24 fee = _getFee(sender, key, params, hookData); - return (BaseHook.beforeSwap.selector, BeforeSwapDeltaLibrary.ZERO_DELTA, fee | LPFeeLibrary.OVERRIDE_FEE_FLAG); + return (this.beforeSwap.selector, BeforeSwapDeltaLibrary.ZERO_DELTA, fee | LPFeeLibrary.OVERRIDE_FEE_FLAG); } /** diff --git a/src/fee/DynamicAfterFee.sol b/src/fee/DynamicAfterFee.sol index 2b6160c..9f7c2c5 100644 --- a/src/fee/DynamicAfterFee.sol +++ b/src/fee/DynamicAfterFee.sol @@ -44,24 +44,30 @@ abstract contract DynamicAfterFee is BaseHook { BalanceDelta delta, bytes calldata ) internal virtual override returns (bytes4, int128) { + // Only apply target delta for exact-input swaps if (params.amountSpecified < 0) { PoolId poolId = key.toId(); BalanceDelta targetDelta = _targetDeltas[poolId]; int128 feeAmount = 0; + // Skip empty/undefined target delta if (BalanceDelta.unwrap(targetDelta) != 0) { // Reset storage target delta to 0 and use one stored in memory _targetDeltas[poolId] = BalanceDelta.wrap(0); if (delta.amount0() == targetDelta.amount0() && delta.amount1() > targetDelta.amount1()) { feeAmount = delta.amount1() - targetDelta.amount1(); + + // feeAmount is positive and int128, so we can safely cast to uint128 given that uint128 + // has a larger maximum value. poolManager.donate(key, 0, uint256(uint128(feeAmount)), ""); } - // Apply target delta to only exact-input swaps if (delta.amount1() == targetDelta.amount1() && delta.amount0() > targetDelta.amount0()) { feeAmount = delta.amount0() - targetDelta.amount0(); - // feeAmount is positive and int128, so we can safely cast to uint128 and then to uint256 + + // feeAmount is positive and int128, so we can safely cast to uint128 given that uint128 + // has a larger maximum value. poolManager.donate(key, uint256(uint128(feeAmount)), 0, ""); } }