diff --git a/.forge-snapshots/PositionManager_increaseLiquidity_erc20_withSettlePair.snap b/.forge-snapshots/PositionManager_increaseLiquidity_erc20_withSettlePair.snap index 25bb3638a..db4bd78fa 100644 --- a/.forge-snapshots/PositionManager_increaseLiquidity_erc20_withSettlePair.snap +++ b/.forge-snapshots/PositionManager_increaseLiquidity_erc20_withSettlePair.snap @@ -1 +1 @@ -154534 \ No newline at end of file +154533 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_increase_autocompound_clearExcess.snap b/.forge-snapshots/PositionManager_increase_autocompound_clearExcess.snap index 03125b1ba..1ba47495a 100644 --- a/.forge-snapshots/PositionManager_increase_autocompound_clearExcess.snap +++ b/.forge-snapshots/PositionManager_increase_autocompound_clearExcess.snap @@ -1 +1 @@ -144550 \ No newline at end of file +144548 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_mint_nativeWithSweep_withClose.snap b/.forge-snapshots/PositionManager_mint_nativeWithSweep_withClose.snap index 7874986d2..b50b4e031 100644 --- a/.forge-snapshots/PositionManager_mint_nativeWithSweep_withClose.snap +++ b/.forge-snapshots/PositionManager_mint_nativeWithSweep_withClose.snap @@ -1 +1 @@ -349846 \ No newline at end of file +349845 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_mint_nativeWithSweep_withSettlePair.snap b/.forge-snapshots/PositionManager_mint_nativeWithSweep_withSettlePair.snap index 774116d1d..989fe3283 100644 --- a/.forge-snapshots/PositionManager_mint_nativeWithSweep_withSettlePair.snap +++ b/.forge-snapshots/PositionManager_mint_nativeWithSweep_withSettlePair.snap @@ -1 +1 @@ -349149 \ No newline at end of file +349147 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_mint_settleWithBalance_sweep.snap b/.forge-snapshots/PositionManager_mint_settleWithBalance_sweep.snap index e58b7c5cf..85d82e1f7 100644 --- a/.forge-snapshots/PositionManager_mint_settleWithBalance_sweep.snap +++ b/.forge-snapshots/PositionManager_mint_settleWithBalance_sweep.snap @@ -1 +1 @@ -375379 \ No newline at end of file +375377 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_mint_withSettlePair.snap b/.forge-snapshots/PositionManager_mint_withSettlePair.snap index 22af148a2..be6c44420 100644 --- a/.forge-snapshots/PositionManager_mint_withSettlePair.snap +++ b/.forge-snapshots/PositionManager_mint_withSettlePair.snap @@ -1 +1 @@ -375794 \ No newline at end of file +375793 \ No newline at end of file diff --git a/src/base/Permit2Forwarder.sol b/src/base/Permit2Forwarder.sol index a81699032..b04de73b4 100644 --- a/src/base/Permit2Forwarder.sol +++ b/src/base/Permit2Forwarder.sol @@ -8,6 +8,8 @@ import {IAllowanceTransfer} from "permit2/src/interfaces/IAllowanceTransfer.sol" contract Permit2Forwarder { IAllowanceTransfer public immutable permit2; + error Wrap__Permit2Reverted(address _permit2, bytes reason); + constructor(IAllowanceTransfer _permit2) { permit2 = _permit2; } @@ -17,9 +19,13 @@ contract Permit2Forwarder { function permit(address owner, IAllowanceTransfer.PermitSingle calldata permitSingle, bytes calldata signature) external payable + returns (bytes memory err) { // use try/catch in case an actor front-runs the permit, which would DOS multicalls - try permit2.permit(owner, permitSingle, signature) {} catch {} + try permit2.permit(owner, permitSingle, signature) {} + catch (bytes memory reason) { + err = abi.encodeWithSelector(Wrap__Permit2Reverted.selector, address(permit2), reason); + } } /// @notice allows forwarding batch permits to permit2 @@ -27,8 +33,12 @@ contract Permit2Forwarder { function permitBatch(address owner, IAllowanceTransfer.PermitBatch calldata _permitBatch, bytes calldata signature) external payable + returns (bytes memory err) { // use try/catch in case an actor front-runs the permit, which would DOS multicalls - try permit2.permit(owner, _permitBatch, signature) {} catch {} + try permit2.permit(owner, _permitBatch, signature) {} + catch (bytes memory reason) { + err = abi.encodeWithSelector(Wrap__Permit2Reverted.selector, address(permit2), reason); + } } } diff --git a/test/position-managers/PositionManager.multicall.t.sol b/test/position-managers/PositionManager.multicall.t.sol index 8fa50d48c..d83a62885 100644 --- a/test/position-managers/PositionManager.multicall.t.sol +++ b/test/position-managers/PositionManager.multicall.t.sol @@ -56,6 +56,9 @@ contract PositionManagerMulticallTest is Test, Permit2SignatureHelpers, PosmTest uint48 permitExpiration = uint48(block.timestamp + 10e18); uint48 permitNonce = 0; + // redefine error from permit2/src/PermitErrors.sol since its hard-pinned to a solidity version + error InvalidNonce(); + bytes32 PERMIT2_DOMAIN_SEPARATOR; PositionConfig config; @@ -379,7 +382,27 @@ contract PositionManagerMulticallTest is Test, Permit2SignatureHelpers, PosmTest vm.expectRevert(); lpm.ownerOf(tokenId); // token does not exist - lpm.multicall(calls); + bytes[] memory results = lpm.multicall(calls); + assertEq( + results[0], + abi.encode( + abi.encodeWithSelector( + Permit2Forwarder.Wrap__Permit2Reverted.selector, + address(permit2), + abi.encodeWithSelector(InvalidNonce.selector) + ) + ) + ); + assertEq( + results[1], + abi.encode( + abi.encodeWithSelector( + Permit2Forwarder.Wrap__Permit2Reverted.selector, + address(permit2), + abi.encodeWithSelector(InvalidNonce.selector) + ) + ) + ); assertEq(lpm.ownerOf(tokenId), charlie); } @@ -428,7 +451,17 @@ contract PositionManagerMulticallTest is Test, Permit2SignatureHelpers, PosmTest vm.expectRevert(); lpm.ownerOf(tokenId); // token does not exist - lpm.multicall(calls); + bytes[] memory results = lpm.multicall(calls); + assertEq( + results[0], + abi.encode( + abi.encodeWithSelector( + Permit2Forwarder.Wrap__Permit2Reverted.selector, + address(permit2), + abi.encodeWithSelector(InvalidNonce.selector) + ) + ) + ); assertEq(lpm.ownerOf(tokenId), charlie); }