mirror of
https://github.com/Instadapp/fluid-contracts-public.git
synced 2024-07-29 21:57:37 +00:00
177 lines
7.7 KiB
Solidity
177 lines
7.7 KiB
Solidity
// SPDX-License-Identifier: MIT
|
|
pragma solidity 0.8.21;
|
|
|
|
/// @title AllowanceTransfer
|
|
/// @notice Handles ERC20 token permissions through signature based allowance setting and ERC20 token transfers by checking allowed amounts
|
|
/// @dev Requires user's token approval on the Permit2 contract
|
|
/// from https://github.com/Uniswap/permit2/blob/main/src/interfaces/ISignatureTransfer.sol.
|
|
/// Copyright (c) 2022 Uniswap Labs
|
|
interface IAllowanceTransfer {
|
|
function DOMAIN_SEPARATOR() external view returns (bytes32);
|
|
|
|
/// @notice Thrown when an allowance on a token has expired.
|
|
/// @param deadline The timestamp at which the allowed amount is no longer valid
|
|
error AllowanceExpired(uint256 deadline);
|
|
|
|
/// @notice Thrown when an allowance on a token has been depleted.
|
|
/// @param amount The maximum amount allowed
|
|
error InsufficientAllowance(uint256 amount);
|
|
|
|
/// @notice Thrown when too many nonces are invalidated.
|
|
error ExcessiveInvalidation();
|
|
|
|
/// @notice Emits an event when the owner successfully invalidates an ordered nonce.
|
|
event NonceInvalidation(
|
|
address indexed owner,
|
|
address indexed token,
|
|
address indexed spender,
|
|
uint48 newNonce,
|
|
uint48 oldNonce
|
|
);
|
|
|
|
/// @notice Emits an event when the owner successfully sets permissions on a token for the spender.
|
|
event Approval(
|
|
address indexed owner,
|
|
address indexed token,
|
|
address indexed spender,
|
|
uint160 amount,
|
|
uint48 expiration
|
|
);
|
|
|
|
/// @notice Emits an event when the owner successfully sets permissions using a permit signature on a token for the spender.
|
|
event Permit(
|
|
address indexed owner,
|
|
address indexed token,
|
|
address indexed spender,
|
|
uint160 amount,
|
|
uint48 expiration,
|
|
uint48 nonce
|
|
);
|
|
|
|
/// @notice Emits an event when the owner sets the allowance back to 0 with the lockdown function.
|
|
event Lockdown(address indexed owner, address token, address spender);
|
|
|
|
/// @notice The permit data for a token
|
|
struct PermitDetails {
|
|
// ERC20 token address
|
|
address token;
|
|
// the maximum amount allowed to spend
|
|
uint160 amount;
|
|
// timestamp at which a spender's token allowances become invalid
|
|
uint48 expiration;
|
|
// an incrementing value indexed per owner,token,and spender for each signature
|
|
uint48 nonce;
|
|
}
|
|
|
|
/// @notice The permit message signed for a single token allownce
|
|
struct PermitSingle {
|
|
// the permit data for a single token alownce
|
|
PermitDetails details;
|
|
// address permissioned on the allowed tokens
|
|
address spender;
|
|
// deadline on the permit signature
|
|
uint256 sigDeadline;
|
|
}
|
|
|
|
/// @notice The permit message signed for multiple token allowances
|
|
struct PermitBatch {
|
|
// the permit data for multiple token allowances
|
|
PermitDetails[] details;
|
|
// address permissioned on the allowed tokens
|
|
address spender;
|
|
// deadline on the permit signature
|
|
uint256 sigDeadline;
|
|
}
|
|
|
|
/// @notice The saved permissions
|
|
/// @dev This info is saved per owner, per token, per spender and all signed over in the permit message
|
|
/// @dev Setting amount to type(uint160).max sets an unlimited approval
|
|
struct PackedAllowance {
|
|
// amount allowed
|
|
uint160 amount;
|
|
// permission expiry
|
|
uint48 expiration;
|
|
// an incrementing value indexed per owner,token,and spender for each signature
|
|
uint48 nonce;
|
|
}
|
|
|
|
/// @notice A token spender pair.
|
|
struct TokenSpenderPair {
|
|
// the token the spender is approved
|
|
address token;
|
|
// the spender address
|
|
address spender;
|
|
}
|
|
|
|
/// @notice Details for a token transfer.
|
|
struct AllowanceTransferDetails {
|
|
// the owner of the token
|
|
address from;
|
|
// the recipient of the token
|
|
address to;
|
|
// the amount of the token
|
|
uint160 amount;
|
|
// the token to be transferred
|
|
address token;
|
|
}
|
|
|
|
/// @notice A mapping from owner address to token address to spender address to PackedAllowance struct, which contains details and conditions of the approval.
|
|
/// @notice The mapping is indexed in the above order see: allowance[ownerAddress][tokenAddress][spenderAddress]
|
|
/// @dev The packed slot holds the allowed amount, expiration at which the allowed amount is no longer valid, and current nonce thats updated on any signature based approvals.
|
|
function allowance(
|
|
address user,
|
|
address token,
|
|
address spender
|
|
) external view returns (uint160 amount, uint48 expiration, uint48 nonce);
|
|
|
|
/// @notice Approves the spender to use up to amount of the specified token up until the expiration
|
|
/// @param token The token to approve
|
|
/// @param spender The spender address to approve
|
|
/// @param amount The approved amount of the token
|
|
/// @param expiration The timestamp at which the approval is no longer valid
|
|
/// @dev The packed allowance also holds a nonce, which will stay unchanged in approve
|
|
/// @dev Setting amount to type(uint160).max sets an unlimited approval
|
|
function approve(address token, address spender, uint160 amount, uint48 expiration) external;
|
|
|
|
/// @notice Permit a spender to a given amount of the owners token via the owner's EIP-712 signature
|
|
/// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce
|
|
/// @param owner The owner of the tokens being approved
|
|
/// @param permitSingle Data signed over by the owner specifying the terms of approval
|
|
/// @param signature The owner's signature over the permit data
|
|
function permit(address owner, PermitSingle memory permitSingle, bytes calldata signature) external;
|
|
|
|
/// @notice Permit a spender to the signed amounts of the owners tokens via the owner's EIP-712 signature
|
|
/// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce
|
|
/// @param owner The owner of the tokens being approved
|
|
/// @param permitBatch Data signed over by the owner specifying the terms of approval
|
|
/// @param signature The owner's signature over the permit data
|
|
function permit(address owner, PermitBatch memory permitBatch, bytes calldata signature) external;
|
|
|
|
/// @notice Transfer approved tokens from one address to another
|
|
/// @param from The address to transfer from
|
|
/// @param to The address of the recipient
|
|
/// @param amount The amount of the token to transfer
|
|
/// @param token The token address to transfer
|
|
/// @dev Requires the from address to have approved at least the desired amount
|
|
/// of tokens to msg.sender.
|
|
function transferFrom(address from, address to, uint160 amount, address token) external;
|
|
|
|
/// @notice Transfer approved tokens in a batch
|
|
/// @param transferDetails Array of owners, recipients, amounts, and tokens for the transfers
|
|
/// @dev Requires the from addresses to have approved at least the desired amount
|
|
/// of tokens to msg.sender.
|
|
function transferFrom(AllowanceTransferDetails[] calldata transferDetails) external;
|
|
|
|
/// @notice Enables performing a "lockdown" of the sender's Permit2 identity
|
|
/// by batch revoking approvals
|
|
/// @param approvals Array of approvals to revoke.
|
|
function lockdown(TokenSpenderPair[] calldata approvals) external;
|
|
|
|
/// @notice Invalidate nonces for a given (token, spender) pair
|
|
/// @param token The token to invalidate nonces for
|
|
/// @param spender The spender to invalidate nonces for
|
|
/// @param newNonce The new nonce to set. Invalidates all nonces less than it.
|
|
/// @dev Can't invalidate more than 2**16 nonces per transaction.
|
|
function invalidateNonces(address token, address spender, uint48 newNonce) external;
|
|
}
|