Skip to content

Commit

Permalink
Merge and update snapshots
Browse files Browse the repository at this point in the history
  • Loading branch information
shuhuiluo committed May 14, 2024
2 parents 07faa5c + 568f7c4 commit 991818e
Show file tree
Hide file tree
Showing 51 changed files with 319 additions and 143 deletions.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1 +1 @@
151062
151104
2 changes: 1 addition & 1 deletion .forge-snapshots/addLiquidity CA fee.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
329402
329444
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 @@
284043
284085
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 @@
141238
141237
2 changes: 1 addition & 1 deletion .forge-snapshots/addLiquidity.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
151038
151080
Original file line number Diff line number Diff line change
@@ -1 +1 @@
299590
299632
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 @@
108878
108687
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 @@
149370
149222
2 changes: 1 addition & 1 deletion .forge-snapshots/poolManager bytecode size.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
23450
23738
2 changes: 1 addition & 1 deletion .forge-snapshots/removeLiquidity CA fee.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
184975
184931
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 @@
121019
120975
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 @@
117794
117750
2 changes: 1 addition & 1 deletion .forge-snapshots/removeLiquidity.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
121007
120963
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 @@
130998
117339
2 changes: 1 addition & 1 deletion .forge-snapshots/simple swap.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
149357
132578
1 change: 1 addition & 0 deletions .forge-snapshots/sparse external sload.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
2023
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 @@
139347
135860
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 @@
184801
184809
Original file line number Diff line number Diff line change
@@ -1 +1 @@
113901
113800
2 changes: 1 addition & 1 deletion .forge-snapshots/swap against liquidity.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
125279
125221
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 @@
137268
137207
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 @@
126384
126323
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 @@
148403
148385
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 @@
165306
165202
Original file line number Diff line number Diff line change
@@ -1 +1 @@
224956
224701
2 changes: 1 addition & 1 deletion .forge-snapshots/swap with dynamic fee.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
149573
149469
2 changes: 1 addition & 1 deletion .forge-snapshots/swap with hooks.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
125291
125233
2 changes: 1 addition & 1 deletion .forge-snapshots/swap with lp fee and protocol fee.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
181915
181791
2 changes: 1 addition & 1 deletion .forge-snapshots/update dynamic fee in before swap.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
160206
160022
3 changes: 3 additions & 0 deletions .github/workflows/tests-pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ name: Tests

on:
pull_request:
branches:
- main
- dev

jobs:
forge-tests:
Expand Down
19 changes: 19 additions & 0 deletions src/Extsload.sol
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,23 @@ abstract contract Extsload is IExtsload {

return value;
}

/// @dev since the function is external and enters a new call context and exits right after execution, Solidity's memory management convention can be disregarded and a direct slice of memory can be returned
function extsload(bytes32[] calldata slots) external view returns (bytes32[] memory) {
assembly ("memory-safe") {
// abi offset for dynamic array
mstore(0, 0x20)
mstore(0x20, slots.length)
let end := add(0x40, shl(5, slots.length))
let memptr := 0x40
let calldataptr := slots.offset
for {} 1 {} {
mstore(memptr, sload(calldataload(calldataptr)))
memptr := add(memptr, 0x20)
calldataptr := add(calldataptr, 0x20)
if iszero(lt(memptr, end)) { break }
}
return(0, end)
}
}
}
7 changes: 4 additions & 3 deletions src/PoolManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {ProtocolFees} from "./ProtocolFees.sol";
import {ERC6909Claims} from "./ERC6909Claims.sol";
import {PoolId, PoolIdLibrary} from "./types/PoolId.sol";
import {BalanceDelta, BalanceDeltaLibrary, toBalanceDelta} from "./types/BalanceDelta.sol";
import {BeforeSwapDelta} from "./types/BeforeSwapDelta.sol";
import {Lock} from "./libraries/Lock.sol";
import {CurrencyDelta} from "./libraries/CurrencyDelta.sol";
import {NonZeroDeltaCount} from "./libraries/NonZeroDeltaCount.sol";
Expand Down Expand Up @@ -174,7 +175,7 @@ contract PoolManager is IPoolManager, ProtocolFees, NoDelegateCall, ERC6909Claim

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

// On intitalize we emit the key's fee, which tells us all fee settings a pool can have: either a static swap fee or dynamic swap fee and if the hook has enabled swap or withdraw fees.
// On initialize we emit the key's fee, which tells us all fee settings a pool can have: either a static swap fee or dynamic swap fee and if the hook has enabled swap or withdraw fees.
emit Initialize(id, key.currency0, key.currency1, key.fee, key.tickSpacing, key.hooks);
}

Expand Down Expand Up @@ -270,7 +271,7 @@ contract PoolManager is IPoolManager, ProtocolFees, NoDelegateCall, ERC6909Claim
PoolId id = key.toId();
_checkPoolInitialized(id);

(int256 amountToSwap, int128 hookDeltaSpecified) = key.hooks.beforeSwap(key, params, hookData);
(int256 amountToSwap, BeforeSwapDelta beforeSwapDelta) = key.hooks.beforeSwap(key, params, hookData);

// execute swap, account protocol fees, and emit swap event
swapDelta = _swap(
Expand All @@ -285,7 +286,7 @@ contract PoolManager is IPoolManager, ProtocolFees, NoDelegateCall, ERC6909Claim
);

BalanceDelta hookDelta;
(swapDelta, hookDelta) = key.hooks.afterSwap(key, params, swapDelta, hookData, hookDeltaSpecified);
(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 (hookDelta != BalanceDeltaLibrary.ZERO_DELTA) _accountPoolBalanceDelta(key, hookDelta, address(key.hooks));
Expand Down
5 changes: 5 additions & 0 deletions src/interfaces/IExtsload.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,9 @@ interface IExtsload {
/// @param nSlots Number of slots to load into return value
/// @return value The value of the sload-ed slots concatenated as dynamic bytes
function extsload(bytes32 slot, uint256 nSlots) external view returns (bytes memory value);

/// @notice Called by external contracts to access sparse pool state
/// @param slots List of slots to SLOAD from.
/// @return values List of loaded values.
function extsload(bytes32[] calldata slots) external view returns (bytes32[] memory values);
}
5 changes: 3 additions & 2 deletions src/interfaces/IHooks.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ pragma solidity ^0.8.24;
import {PoolKey} from "../types/PoolKey.sol";
import {BalanceDelta} from "../types/BalanceDelta.sol";
import {IPoolManager} from "./IPoolManager.sol";
import {BeforeSwapDelta} from "../types/BeforeSwapDelta.sol";

/// @notice The PoolManager contract decides whether to invoke specific hooks by inspecting the leading bits
/// of the hooks contract address. For example, a 1 bit in the first bit of the address will
Expand Down Expand Up @@ -97,13 +98,13 @@ interface IHooks {
/// @param params The parameters for the swap
/// @param hookData Arbitrary data handed into the PoolManager by the swapper to be be passed on to the hook
/// @return bytes4 The function selector for the hook
/// @return int128 The hook's delta in specified currency. Positive: the hook is owed/took currency, negative: the hook owes/sent currency
/// @return BeforeSwapDelta The hook's delta in specified and unspecified currencies. Positive: the hook is owed/took currency, negative: the hook owes/sent currency
function beforeSwap(
address sender,
PoolKey calldata key,
IPoolManager.SwapParams calldata params,
bytes calldata hookData
) external returns (bytes4, int128);
) external returns (bytes4, BeforeSwapDelta);

/// @notice The hook called after a swap
/// @param sender The initial msg.sender for the swap call
Expand Down
50 changes: 33 additions & 17 deletions src/libraries/Hooks.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {IHooks} from "../interfaces/IHooks.sol";
import {SafeCast} from "../libraries/SafeCast.sol";
import {LPFeeLibrary} from "./LPFeeLibrary.sol";
import {BalanceDelta, toBalanceDelta, BalanceDeltaLibrary} from "../types/BalanceDelta.sol";
import {BeforeSwapDelta, BeforeSwapDeltaLibrary} from "../types/BeforeSwapDelta.sol";
import {IPoolManager} from "../interfaces/IPoolManager.sol";

/// @notice V4 decides whether to invoke specific hooks by inspecting the leading bits of the address that
Expand All @@ -16,6 +17,7 @@ library Hooks {
using LPFeeLibrary for uint24;
using Hooks for IHooks;
using SafeCast for int256;
using BeforeSwapDeltaLibrary for BeforeSwapDelta;

uint256 internal constant BEFORE_INITIALIZE_FLAG = 1 << 159;
uint256 internal constant AFTER_INITIALIZE_FLAG = 1 << 158;
Expand Down Expand Up @@ -141,6 +143,7 @@ library Hooks {
{
bytes memory result = callHook(self, data);

// If this hook wasnt meant to return something, default to 0 delta
if (!parseReturn) return 0;
(, delta) = abi.decode(result, (bytes4, int256));
}
Expand Down Expand Up @@ -233,21 +236,31 @@ library Hooks {
/// @notice calls beforeSwap hook if permissioned and validates return value
function beforeSwap(IHooks self, PoolKey memory key, IPoolManager.SwapParams memory params, bytes calldata hookData)
internal
returns (int256 amountToSwap, int128 hookDeltaSpecified)
returns (int256 amountToSwap, BeforeSwapDelta hookReturn)
{
amountToSwap = params.amountSpecified;
if (msg.sender == address(self)) return (amountToSwap, hookDeltaSpecified);
if (msg.sender == address(self)) return (amountToSwap, BeforeSwapDeltaLibrary.ZERO_DELTA);

if (self.hasPermission(BEFORE_SWAP_FLAG)) {
hookDeltaSpecified = self.callHookWithReturnDelta(
abi.encodeWithSelector(IHooks.beforeSwap.selector, msg.sender, key, params, hookData),
self.hasPermission(BEFORE_SWAP_RETURNS_DELTA_FLAG)
).toInt128();
bool canReturnDelta = self.hasPermission(BEFORE_SWAP_RETURNS_DELTA_FLAG);
hookReturn = BeforeSwapDelta.wrap(
self.callHookWithReturnDelta(
abi.encodeWithSelector(IHooks.beforeSwap.selector, msg.sender, key, params, hookData),
canReturnDelta
)
);

// Update the swap amount according to the hook's return, and check that the swap type doesnt change (exact input/output)
if (hookDeltaSpecified != 0) {
bool exactInput = amountToSwap < 0;
amountToSwap += hookDeltaSpecified;
if (exactInput ? amountToSwap > 0 : amountToSwap < 0) revert HookDeltaExceedsSwapAmount();
// skip this logic for the case where the hook return is 0
if (canReturnDelta) {
// 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)
if (hookDeltaSpecified != 0) {
bool exactInput = amountToSwap < 0;
amountToSwap += hookDeltaSpecified;
if (exactInput ? amountToSwap > 0 : amountToSwap < 0) revert HookDeltaExceedsSwapAmount();
}
}
}
}
Expand All @@ -259,27 +272,30 @@ library Hooks {
IPoolManager.SwapParams memory params,
BalanceDelta swapDelta,
bytes calldata hookData,
int128 hookDeltaSpecified
) internal returns (BalanceDelta swapperDelta, BalanceDelta hookDelta) {
BeforeSwapDelta beforeSwapHookReturn
) internal returns (BalanceDelta, BalanceDelta) {
if (msg.sender == address(self)) return (swapDelta, BalanceDeltaLibrary.ZERO_DELTA);

int128 hookDeltaUnspecified;
swapperDelta = swapDelta;
int128 hookDeltaSpecified = beforeSwapHookReturn.getSpecifiedDelta();
int128 hookDeltaUnspecified = beforeSwapHookReturn.getUnspecifiedDelta();

if (self.hasPermission(AFTER_SWAP_FLAG)) {
hookDeltaUnspecified = self.callHookWithReturnDelta(
hookDeltaUnspecified += self.callHookWithReturnDelta(
abi.encodeWithSelector(IHooks.afterSwap.selector, msg.sender, key, params, swapDelta, hookData),
self.hasPermission(AFTER_SWAP_RETURNS_DELTA_FLAG)
).toInt128();
}

BalanceDelta hookDelta;
if (hookDeltaUnspecified != 0 || hookDeltaSpecified != 0) {
hookDelta = (params.amountSpecified < 0 == params.zeroForOne)
? toBalanceDelta(hookDeltaSpecified, hookDeltaUnspecified)
: toBalanceDelta(hookDeltaUnspecified, hookDeltaSpecified);

// the caller has to pay for (or receive) the hook's delta
swapperDelta = swapDelta - hookDelta;
swapDelta = swapDelta - hookDelta;
}
return (swapDelta, hookDelta);
}

/// @notice calls beforeDonate hook if permissioned and validates return value
Expand Down
Loading

0 comments on commit 991818e

Please sign in to comment.