Skip to content

Commit

Permalink
Added permit2
Browse files Browse the repository at this point in the history
  • Loading branch information
mehranhydary committed Sep 12, 2024
1 parent f899217 commit 1363daa
Show file tree
Hide file tree
Showing 7 changed files with 2,632 additions and 715 deletions.
1,740 changes: 1,740 additions & 0 deletions contracts/broadcast/MiladyPoolDeployer.s.sol/31337/run-1726119694.json

Large diffs are not rendered by default.

1,406 changes: 703 additions & 703 deletions contracts/broadcast/MiladyPoolDeployer.s.sol/31337/run-latest.json

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
{
"addresses": {
"erc20Mock": "0xF8e31cb472bc70500f08Cd84917E5A1912Ec8397",
"erc20MockStrategy": "0xc0F115A19107322cFBf1cDBC7ea011C19EbDB4F8",
"miladyPoolServiceManager": "0x22753E4264FDDc6181dc7cce468904A80a363E44",
"miladyPoolServiceManagerImplementation": "0x5fc748f1FEb28d7b76fa1c6B07D8ba2d5535177c",
"miladyPoolTaskManager": "0xA7c59f010700930003b33aB25a7a0679C860f29c",
"miladyPoolTaskManagerImplementation": "0x73ff110Ec4CdA4F761e2d21C9FAdf293880B10C8",
"operatorStateRetriever": "0x5bf5b11053e734690269C6B9D438F8C9d48F528A",
"registryCoordinator": "0xfaAddC93baf78e89DCf37bA67943E1bE8F37Bb8c",
"registryCoordinatorImplementation": "0x525C7063E7C20997BaaE9bDa922159152D0e8417"
"erc20Mock": "0x8A93d247134d91e0de6f96547cB0204e5BE8e5D8",
"erc20MockStrategy": "0x40918Ba7f132E0aCba2CE4de4c4baF9BD2D7D849",
"miladyPoolServiceManager": "0xCA8c8688914e0F7096c920146cd0Ad85cD7Ae8b9",
"miladyPoolServiceManagerImplementation": "0x5302E909d1e93e30F05B5D6Eea766363D14F9892",
"miladyPoolTaskManager": "0xB0f05d25e41FbC2b52013099ED9616f1206Ae21B",
"miladyPoolTaskManagerImplementation": "0x537c407139353F5A6086a4b017fbDd8B179310C8",
"operatorStateRetriever": "0xfcDB4564c18A9134002b9771816092C9693622e3",
"registryCoordinator": "0x5FeaeBfB4439F3516c74939A9D04e95AFE82C4ae",
"registryCoordinatorImplementation": "0xFD6F7A6a5c21A3f503EBaE7a473639974379c351"
}
}
39 changes: 37 additions & 2 deletions contracts/src/base/Hook.sol
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,15 @@ import {Currency, CurrencyLibrary} from "v4-core/types/Currency.sol";
import {TickMath} from "v4-core/libraries/TickMath.sol";
import {WyvernInspired} from "./WyvernInspired.sol";
import {PublicValuesStruct, Sig} from "./Structs.sol";
import {ISignatureTransfer} from "permit2/src/interfaces/ISignatureTransfer.sol";

abstract contract Hook is BaseHook, WyvernInspired {
using StateLibrary for IPoolManager;
using PoolIdLibrary for PoolKey;
using CurrencyLibrary for Currency;

address constant PERMIT2 = 0x000000000022D473030F116dDEE9F6B43aC78BA3;

// TODO: Figure out if we need latest order id, order hashes, zkps, matching order ids, responses, challenges, etc.
mapping(PoolId poolId => int24 lastTick) public lastTicks;
mapping(bytes => bool) public pendingOrders;
Expand Down Expand Up @@ -103,7 +106,9 @@ abstract contract Hook is BaseHook, WyvernInspired {
uint24 fee,
int24 tickSpacing,
address hooks,
bytes32 permit2Signature
bytes memory permit2Signature,
uint256 permit2Nonce,
uint256 permit2Deadline
) = (
_publicValues.walletAddress,
_publicValues.tickToSellAt,
Expand All @@ -116,11 +121,41 @@ abstract contract Hook is BaseHook, WyvernInspired {
_publicValues.fee,
_publicValues.tickSpacing,
_publicValues.hooks,
_publicValues.permit2Signature
_publicValues.permit2Signature,
_publicValues.permit2Nonce,
_publicValues.permit2Deadline
);

// TODO: Refactor this section; not gonna work because
// you have to activate the permit 2 signature
// Look here: https://blog.uniswap.org/permit2-integration-guide

// Use Permit2 to transfer tokens from the user to this contract
ISignatureTransfer.PermitTransferFrom memory permit = ISignatureTransfer
.PermitTransferFrom({
permitted: ISignatureTransfer.TokenPermissions({
token: tokenInput,
amount: inputAmount
}),
nonce: permit2Nonce,
deadline: permit2Deadline
});

ISignatureTransfer.SignatureTransferDetails
memory transferDetails = ISignatureTransfer
.SignatureTransferDetails({
to: address(this),
requestedAmount: inputAmount
});

// Assuming PERMIT2 is a constant address of the Permit2 contract
ISignatureTransfer(PERMIT2).permitTransferFrom(
permit,
transferDetails,
walletAddress,
permit2Signature
);

BalanceDelta delta = poolManager.swap(
key,
IPoolManager.SwapParams({
Expand Down
4 changes: 3 additions & 1 deletion contracts/src/base/Structs.sol
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ struct PublicValuesStruct {
uint24 fee;
int24 tickSpacing;
address hooks; // Should be passed into IHooks interface
bytes32 permit2Signature;
bytes permit2Signature;
uint256 permit2Nonce;
uint256 permit2Deadline;
}

struct Sig {
Expand Down
6 changes: 6 additions & 0 deletions contracts/src/interfaces/IEIP712.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface IEIP712 {
function DOMAIN_SEPARATOR() external view returns (bytes32);
}
134 changes: 134 additions & 0 deletions contracts/src/interfaces/ISignatureTransfer.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {IEIP712} from "./IEIP712.sol";

/// @title SignatureTransfer
/// @notice Handles ERC20 token transfers through signature based actions
/// @dev Requires user's token approval on the Permit2 contract
interface ISignatureTransfer is IEIP712 {
/// @notice Thrown when the requested amount for a transfer is larger than the permissioned amount
/// @param maxAmount The maximum amount a spender can request to transfer
error InvalidAmount(uint256 maxAmount);

/// @notice Thrown when the number of tokens permissioned to a spender does not match the number of tokens being transferred
/// @dev If the spender does not need to transfer the number of tokens permitted, the spender can request amount 0 to be transferred
error LengthMismatch();

/// @notice Emits an event when the owner successfully invalidates an unordered nonce.
event UnorderedNonceInvalidation(address indexed owner, uint256 word, uint256 mask);

/// @notice The token and amount details for a transfer signed in the permit transfer signature
struct TokenPermissions {
// ERC20 token address
address token;
// the maximum amount that can be spent
uint256 amount;
}

/// @notice The signed permit message for a single token transfer
struct PermitTransferFrom {
TokenPermissions permitted;
// a unique value for every token owner's signature to prevent signature replays
uint256 nonce;
// deadline on the permit signature
uint256 deadline;
}

/// @notice Specifies the recipient address and amount for batched transfers.
/// @dev Recipients and amounts correspond to the index of the signed token permissions array.
/// @dev Reverts if the requested amount is greater than the permitted signed amount.
struct SignatureTransferDetails {
// recipient address
address to;
// spender requested amount
uint256 requestedAmount;
}

/// @notice Used to reconstruct the signed permit message for multiple token transfers
/// @dev Do not need to pass in spender address as it is required that it is msg.sender
/// @dev Note that a user still signs over a spender address
struct PermitBatchTransferFrom {
// the tokens and corresponding amounts permitted for a transfer
TokenPermissions[] permitted;
// a unique value for every token owner's signature to prevent signature replays
uint256 nonce;
// deadline on the permit signature
uint256 deadline;
}

/// @notice A map from token owner address and a caller specified word index to a bitmap. Used to set bits in the bitmap to prevent against signature replay protection
/// @dev Uses unordered nonces so that permit messages do not need to be spent in a certain order
/// @dev The mapping is indexed first by the token owner, then by an index specified in the nonce
/// @dev It returns a uint256 bitmap
/// @dev The index, or wordPosition is capped at type(uint248).max
function nonceBitmap(address, uint256) external view returns (uint256);

/// @notice Transfers a token using a signed permit message
/// @dev Reverts if the requested amount is greater than the permitted signed amount
/// @param permit The permit data signed over by the owner
/// @param owner The owner of the tokens to transfer
/// @param transferDetails The spender's requested transfer details for the permitted token
/// @param signature The signature to verify
function permitTransferFrom(
PermitTransferFrom memory permit,
SignatureTransferDetails calldata transferDetails,
address owner,
bytes calldata signature
) external;

/// @notice Transfers a token using a signed permit message
/// @notice Includes extra data provided by the caller to verify signature over
/// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition
/// @dev Reverts if the requested amount is greater than the permitted signed amount
/// @param permit The permit data signed over by the owner
/// @param owner The owner of the tokens to transfer
/// @param transferDetails The spender's requested transfer details for the permitted token
/// @param witness Extra data to include when checking the user signature
/// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash
/// @param signature The signature to verify
function permitWitnessTransferFrom(
PermitTransferFrom memory permit,
SignatureTransferDetails calldata transferDetails,
address owner,
bytes32 witness,
string calldata witnessTypeString,
bytes calldata signature
) external;

/// @notice Transfers multiple tokens using a signed permit message
/// @param permit The permit data signed over by the owner
/// @param owner The owner of the tokens to transfer
/// @param transferDetails Specifies the recipient and requested amount for the token transfer
/// @param signature The signature to verify
function permitTransferFrom(
PermitBatchTransferFrom memory permit,
SignatureTransferDetails[] calldata transferDetails,
address owner,
bytes calldata signature
) external;

/// @notice Transfers multiple tokens using a signed permit message
/// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition
/// @notice Includes extra data provided by the caller to verify signature over
/// @param permit The permit data signed over by the owner
/// @param owner The owner of the tokens to transfer
/// @param transferDetails Specifies the recipient and requested amount for the token transfer
/// @param witness Extra data to include when checking the user signature
/// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash
/// @param signature The signature to verify
function permitWitnessTransferFrom(
PermitBatchTransferFrom memory permit,
SignatureTransferDetails[] calldata transferDetails,
address owner,
bytes32 witness,
string calldata witnessTypeString,
bytes calldata signature
) external;

/// @notice Invalidates the bits specified in mask for the bitmap at the word position
/// @dev The wordPos is maxed at type(uint248).max
/// @param wordPos A number to index the nonceBitmap at
/// @param mask A bitmap masked against msg.sender's current bitmap at the word position
function invalidateUnorderedNonces(uint256 wordPos, uint256 mask) external;
}

0 comments on commit 1363daa

Please sign in to comment.