Skip to content

Commit

Permalink
Merge branch 'main' into posm-clear-or-take
Browse files Browse the repository at this point in the history
  • Loading branch information
saucepoint authored Aug 2, 2024
2 parents 2ca05a5 + ebf7a4d commit 294826a
Show file tree
Hide file tree
Showing 63 changed files with 886 additions and 159 deletions.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
134126
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
134264

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
126921
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
127059
2 changes: 1 addition & 1 deletion .forge-snapshots/PositionManager_mint.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
372012
371963
2 changes: 1 addition & 1 deletion .forge-snapshots/PositionManager_mint_native.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
336712
336663
2 changes: 1 addition & 1 deletion .forge-snapshots/PositionManager_mint_nativeWithSweep.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
345244
345146
2 changes: 1 addition & 1 deletion .forge-snapshots/PositionManager_mint_onSameTickLower.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
314694
314645
2 changes: 1 addition & 1 deletion .forge-snapshots/PositionManager_mint_onSameTickUpper.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
315336
315287
2 changes: 1 addition & 1 deletion .forge-snapshots/PositionManager_mint_sameRange.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
240918
240869
Original file line number Diff line number Diff line change
@@ -1 +1 @@
370018
370009
Original file line number Diff line number Diff line change
@@ -1 +1 @@
320712
320663
Original file line number Diff line number Diff line change
@@ -1 +1 @@
416388
416316
2 changes: 1 addition & 1 deletion .forge-snapshots/V4Router_Bytecode.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
6942
7342
2 changes: 1 addition & 1 deletion .forge-snapshots/V4Router_ExactIn1Hop_nativeIn.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
120501
120464
2 changes: 1 addition & 1 deletion .forge-snapshots/V4Router_ExactIn1Hop_nativeOut.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
119696
119659
2 changes: 1 addition & 1 deletion .forge-snapshots/V4Router_ExactIn1Hop_oneForZero.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
128568
128531
2 changes: 1 addition & 1 deletion .forge-snapshots/V4Router_ExactIn1Hop_zeroForOne.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
135398
135361
2 changes: 1 addition & 1 deletion .forge-snapshots/V4Router_ExactIn2Hops.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
186897
186868
2 changes: 1 addition & 1 deletion .forge-snapshots/V4Router_ExactIn2Hops_nativeIn.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
178832
178803
2 changes: 1 addition & 1 deletion .forge-snapshots/V4Router_ExactIn3Hops.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
238421
238400
2 changes: 1 addition & 1 deletion .forge-snapshots/V4Router_ExactIn3Hops_nativeIn.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
230380
230359
2 changes: 1 addition & 1 deletion .forge-snapshots/V4Router_ExactInputSingle.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
134171
134126
2 changes: 1 addition & 1 deletion .forge-snapshots/V4Router_ExactInputSingle_nativeIn.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
119274
119229
2 changes: 1 addition & 1 deletion .forge-snapshots/V4Router_ExactInputSingle_nativeOut.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
118447
118402
Original file line number Diff line number Diff line change
@@ -1 +1 @@
126298
126261
2 changes: 1 addition & 1 deletion .forge-snapshots/V4Router_ExactOut1Hop_nativeOut.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
120531
120494
2 changes: 1 addition & 1 deletion .forge-snapshots/V4Router_ExactOut1Hop_oneForZero.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
129403
129366
2 changes: 1 addition & 1 deletion .forge-snapshots/V4Router_ExactOut1Hop_zeroForOne.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
134204
134167
2 changes: 1 addition & 1 deletion .forge-snapshots/V4Router_ExactOut2Hops.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
186306
186277
2 changes: 1 addition & 1 deletion .forge-snapshots/V4Router_ExactOut2Hops_nativeIn.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
183201
183172
2 changes: 1 addition & 1 deletion .forge-snapshots/V4Router_ExactOut3Hops.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
238448
238427
2 changes: 1 addition & 1 deletion .forge-snapshots/V4Router_ExactOut3Hops_nativeIn.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
235367
235346
2 changes: 1 addition & 1 deletion .forge-snapshots/V4Router_ExactOut3Hops_nativeOut.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
229600
229579
2 changes: 1 addition & 1 deletion .forge-snapshots/V4Router_ExactOutputSingle.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
132975
132930
Original file line number Diff line number Diff line change
@@ -1 +1 @@
125069
125024
2 changes: 1 addition & 1 deletion .forge-snapshots/V4Router_ExactOutputSingle_nativeOut.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
119360
119315
15 changes: 7 additions & 8 deletions src/PositionManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {PositionConfig, PositionConfigLibrary} from "./libraries/PositionConfig.
import {BaseActionsRouter} from "./base/BaseActionsRouter.sol";
import {Actions} from "./libraries/Actions.sol";
import {CalldataDecoder} from "./libraries/CalldataDecoder.sol";
import {Permit2Forwarder} from "./base/Permit2Forwarder.sol";
import {SlippageCheckLibrary} from "./libraries/SlippageCheck.sol";

contract PositionManager is
Expand All @@ -34,7 +35,8 @@ contract PositionManager is
Multicall,
DeltaResolver,
ReentrancyLock,
BaseActionsRouter
BaseActionsRouter,
Permit2Forwarder
{
using SafeTransferLib for *;
using CurrencyLibrary for Currency;
Expand All @@ -53,14 +55,11 @@ contract PositionManager is
/// @inheritdoc IPositionManager
mapping(uint256 tokenId => bytes32 configId) public positionConfigs;

IAllowanceTransfer public immutable permit2;

constructor(IPoolManager _poolManager, IAllowanceTransfer _permit2)
BaseActionsRouter(_poolManager)
Permit2Forwarder(_permit2)
ERC721Permit("Uniswap V4 Positions NFT", "UNI-V4-POSM", "1")
{
permit2 = _permit2;
}
{}

modifier checkDeadline(uint256 deadline) {
if (block.timestamp > deadline) revert DeadlinePassed();
Expand Down Expand Up @@ -108,7 +107,7 @@ contract PositionManager is
address owner,
bytes calldata hookData
) = params.decodeMintParams();
_mint(config, liquidity, amount0Max, amount1Max, owner, hookData);
_mint(config, liquidity, amount0Max, amount1Max, _map(owner), hookData);
} else if (action == Actions.CLOSE_CURRENCY) {
Currency currency = params.decodeCurrency();
_close(currency);
Expand All @@ -130,7 +129,7 @@ contract PositionManager is
_settleWithBalance(currency);
} else if (action == Actions.SWEEP) {
(Currency currency, address to) = params.decodeCurrencyAndAddress();
_sweep(currency, to);
_sweep(currency, _map(to));
} else {
revert UnsupportedAction(action);
}
Expand Down
8 changes: 6 additions & 2 deletions src/V4Router.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {TickMath} from "@uniswap/v4-core/src/libraries/TickMath.sol";

import {PathKey, PathKeyLib} from "./libraries/PathKey.sol";
import {CalldataDecoder} from "./libraries/CalldataDecoder.sol";
import {BipsLibrary} from "./libraries/BipsLibrary.sol";
import {IV4Router} from "./interfaces/IV4Router.sol";
import {BaseActionsRouter} from "./base/BaseActionsRouter.sol";
import {DeltaResolver} from "./base/DeltaResolver.sol";
Expand All @@ -23,6 +24,7 @@ abstract contract V4Router is IV4Router, BaseActionsRouter, DeltaResolver {
using SafeCastTemp for *;
using PathKeyLib for PathKey;
using CalldataDecoder for bytes;
using BipsLibrary for uint256;

constructor(IPoolManager _poolManager) BaseActionsRouter(_poolManager) {}

Expand Down Expand Up @@ -58,8 +60,10 @@ abstract contract V4Router is IV4Router, BaseActionsRouter, DeltaResolver {
uint256 amount = _getFullTakeAmount(currency);

// TODO should _take have a minAmountOut added slippage check?
// TODO recipient mapping
_take(currency, recipient, amount);
_take(currency, _map(recipient), amount);
} else if (action == Actions.TAKE_PORTION) {
(Currency currency, address recipient, uint256 bips) = params.decodeCurrencyAddressAndUint256();
_take(currency, _map(recipient), _getFullTakeAmount(currency).calculatePortion(bips));
} else {
revert UnsupportedAction(action);
}
Expand Down
14 changes: 14 additions & 0 deletions src/base/BaseActionsRouter.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ pragma solidity ^0.8.24;
import {IPoolManager} from "@uniswap/v4-core/src/interfaces/IPoolManager.sol";
import {SafeCallback} from "./SafeCallback.sol";
import {CalldataDecoder} from "../libraries/CalldataDecoder.sol";
import {Actions} from "../libraries/Actions.sol";

/// @notice Abstract contract for performing a combination of actions on Uniswap v4.
/// @dev Suggested uint256 action values are defined in Actions.sol, however any definition can be used
Expand Down Expand Up @@ -52,4 +53,17 @@ abstract contract BaseActionsRouter is SafeCallback {
/// `msg.sender` shouldnt be used, as this will be the v4 pool manager contract that calls `unlockCallback`
/// If using ReentrancyLock.sol, this function can return _getLocker()
function _msgSender() internal view virtual returns (address);

/// @notice Calculates the address for a action
/// @param recipient The address or address-flag for the action
/// @return output The resultant address for the action
function _map(address recipient) internal view returns (address) {
if (recipient == Actions.MSG_SENDER) {
return _msgSender();
} else if (recipient == Actions.ADDRESS_THIS) {
return address(this);
} else {
return recipient;
}
}
}
32 changes: 32 additions & 0 deletions src/base/Permit2Forwarder.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity ^0.8.24;

import {IAllowanceTransfer} from "permit2/src/interfaces/IAllowanceTransfer.sol";

/// @notice PermitForwarder allows permitting this contract as a spender on permit2
/// @dev This contract does not enforce the spender to be this contract, but that is the intended use case
contract Permit2Forwarder {
IAllowanceTransfer public immutable permit2;

constructor(IAllowanceTransfer _permit2) {
permit2 = _permit2;
}

/// @notice allows forwarding a single permit to permit2
/// @dev this function is payable to allow multicall with NATIVE based actions
function permit(address owner, IAllowanceTransfer.PermitSingle calldata permitSingle, bytes calldata signature)
external
payable
{
permit2.permit(owner, permitSingle, signature);
}

/// @notice allows forwarding batch permits to permit2
/// @dev this function is payable to allow multicall with NATIVE based actions
function permitBatch(address owner, IAllowanceTransfer.PermitBatch calldata permitBatch, bytes calldata signature)
external
payable
{
permit2.permit(owner, permitBatch, signature);
}
}
7 changes: 7 additions & 0 deletions src/libraries/Actions.sol
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,11 @@ library Actions {
// minting/burning 6909s to close deltas
uint256 constant MINT_6909 = 0x20;
uint256 constant BURN_6909 = 0x21;

// helper constants to signal certain addresses
// Used as a flag for identifying that msg.sender should be used
address internal constant MSG_SENDER = address(1);

// Used as a flag for identifying address(this) should be used
address internal constant ADDRESS_THIS = address(2);
}
17 changes: 17 additions & 0 deletions src/libraries/BipsLibrary.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity ^0.8.19;

/// @title For calculating a percentage of an amount, using bips
library BipsLibrary {
uint256 internal constant BIPS_BASE = 10_000;

/// @notice emitted when an invalid percentage is provided
error InvalidBips();

/// @param amount The total amount to calculate a percentage of
/// @param bips The percentage to calculate, in bips
function calculatePortion(uint256 amount, uint256 bips) internal pure returns (uint256) {
if (bips > BIPS_BASE) revert InvalidBips();
return (amount * bips) / BIPS_BASE;
}
}
13 changes: 13 additions & 0 deletions src/libraries/CalldataDecoder.sol
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,19 @@ library CalldataDecoder {
}
}

/// @dev equivalent to: abi.decode(params, (Currency, address, uint256)) in calldata
function decodeCurrencyAddressAndUint256(bytes calldata params)
internal
pure
returns (Currency currency, address _address, uint256 amount)
{
assembly ("memory-safe") {
currency := calldataload(params.offset)
_address := calldataload(add(params.offset, 0x20))
amount := calldataload(add(params.offset, 0x40))
}
}

/// @dev equivalent to: abi.decode(params, (Currency, uint256)) in calldata
function decodeCurrencyAndUint256(bytes calldata params)
internal
Expand Down
11 changes: 11 additions & 0 deletions test/BaseActionsRouter.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -137,4 +137,15 @@ contract BaseActionsRouterTest is Test, Deployers, GasSnapshot {
router.executeActions(data);
assertEq(router.burnCount(), 10);
}

function test_fuzz_map(address recipient) public view {
address mappedRecipient = router.map(recipient);
if (recipient == Actions.MSG_SENDER) {
assertEq(mappedRecipient, address(0xdeadbeef));
} else if (recipient == Actions.ADDRESS_THIS) {
assertEq(mappedRecipient, address(router));
} else {
assertEq(mappedRecipient, recipient);
}
}
}
Loading

0 comments on commit 294826a

Please sign in to comment.