From 1a965f1b091725b0797577062eb09b9c51791f76 Mon Sep 17 00:00:00 2001 From: Jeff Huang Date: Fri, 17 Nov 2023 17:36:17 +0800 Subject: [PATCH] draft: pull token --- .changeset/young-geese-joke.md | 5 + src/logics/index.ts | 5 +- src/logics/permit2/abis/Permit2.json | 901 +++++++++++++++++ src/logics/permit2/configs.ts | 30 + src/logics/permit2/contracts/Permit2.ts | 922 ++++++++++++++++++ src/logics/permit2/contracts/common.ts | 30 + .../contracts/factories/Permit2__factory.ts | 919 +++++++++++++++++ .../permit2/contracts/factories/index.ts | 4 + src/logics/permit2/contracts/index.ts | 6 + src/logics/permit2/index.ts | 3 + src/logics/permit2/logic.pull-token.test.ts | 36 + src/logics/permit2/logic.pull-token.ts | 30 + test/logics/permit2/pull-token.test.ts | 65 ++ test/utils/router.ts | 24 +- 14 files changed, 2974 insertions(+), 6 deletions(-) create mode 100644 .changeset/young-geese-joke.md create mode 100644 src/logics/permit2/abis/Permit2.json create mode 100644 src/logics/permit2/configs.ts create mode 100644 src/logics/permit2/contracts/Permit2.ts create mode 100644 src/logics/permit2/contracts/common.ts create mode 100644 src/logics/permit2/contracts/factories/Permit2__factory.ts create mode 100644 src/logics/permit2/contracts/factories/index.ts create mode 100644 src/logics/permit2/contracts/index.ts create mode 100644 src/logics/permit2/index.ts create mode 100644 src/logics/permit2/logic.pull-token.test.ts create mode 100644 src/logics/permit2/logic.pull-token.ts create mode 100644 test/logics/permit2/pull-token.test.ts diff --git a/.changeset/young-geese-joke.md b/.changeset/young-geese-joke.md new file mode 100644 index 00000000..fff20b6f --- /dev/null +++ b/.changeset/young-geese-joke.md @@ -0,0 +1,5 @@ +--- +'@protocolink/logics': patch +--- + +add Permit2 pull token logics diff --git a/src/logics/index.ts b/src/logics/index.ts index 13b3c3de..0b4b2bac 100644 --- a/src/logics/index.ts +++ b/src/logics/index.ts @@ -3,9 +3,10 @@ export * as aavev3 from './aave-v3'; export * as balancerv2 from './balancer-v2'; export * as compoundv2 from './compound-v2'; export * as compoundv3 from './compound-v3'; +export * as openoceanv2 from './openocean-v2'; export * as paraswapv5 from './paraswap-v5'; +export * as permit2 from './permit2'; +export * as radiantv2 from './radiant-v2'; export * as syncswap from './syncswap'; export * as uniswapv3 from './uniswap-v3'; export * as utility from './utility'; -export * as radiantv2 from './radiant-v2'; -export * as openoceanv2 from './openocean-v2'; diff --git a/src/logics/permit2/abis/Permit2.json b/src/logics/permit2/abis/Permit2.json new file mode 100644 index 00000000..5bf1777d --- /dev/null +++ b/src/logics/permit2/abis/Permit2.json @@ -0,0 +1,901 @@ +[ + { + "inputs": [ + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "AllowanceExpired", + "type": "error" + }, + { + "inputs": [], + "name": "ExcessiveInvalidation", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "InsufficientAllowance", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "maxAmount", + "type": "uint256" + } + ], + "name": "InvalidAmount", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidContractSignature", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidNonce", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidSignature", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidSignatureLength", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidSigner", + "type": "error" + }, + { + "inputs": [], + "name": "LengthMismatch", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "signatureDeadline", + "type": "uint256" + } + ], + "name": "SignatureExpired", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint160", + "name": "amount", + "type": "uint160" + }, + { + "indexed": false, + "internalType": "uint48", + "name": "expiration", + "type": "uint48" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "Lockdown", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint48", + "name": "newNonce", + "type": "uint48" + }, + { + "indexed": false, + "internalType": "uint48", + "name": "oldNonce", + "type": "uint48" + } + ], + "name": "NonceInvalidation", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint160", + "name": "amount", + "type": "uint160" + }, + { + "indexed": false, + "internalType": "uint48", + "name": "expiration", + "type": "uint48" + }, + { + "indexed": false, + "internalType": "uint48", + "name": "nonce", + "type": "uint48" + } + ], + "name": "Permit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "word", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "mask", + "type": "uint256" + } + ], + "name": "UnorderedNonceInvalidation", + "type": "event" + }, + { + "inputs": [], + "name": "DOMAIN_SEPARATOR", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint160", + "name": "amount", + "type": "uint160" + }, + { + "internalType": "uint48", + "name": "expiration", + "type": "uint48" + }, + { + "internalType": "uint48", + "name": "nonce", + "type": "uint48" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint160", + "name": "amount", + "type": "uint160" + }, + { + "internalType": "uint48", + "name": "expiration", + "type": "uint48" + } + ], + "name": "approve", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint48", + "name": "newNonce", + "type": "uint48" + } + ], + "name": "invalidateNonces", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "wordPos", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "mask", + "type": "uint256" + } + ], + "name": "invalidateUnorderedNonces", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "internalType": "struct IAllowanceTransfer.TokenSpenderPair[]", + "name": "approvals", + "type": "tuple[]" + } + ], + "name": "lockdown", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "nonceBitmap", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "components": [ + { + "components": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint160", + "name": "amount", + "type": "uint160" + }, + { + "internalType": "uint48", + "name": "expiration", + "type": "uint48" + }, + { + "internalType": "uint48", + "name": "nonce", + "type": "uint48" + } + ], + "internalType": "struct IAllowanceTransfer.PermitDetails[]", + "name": "details", + "type": "tuple[]" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "sigDeadline", + "type": "uint256" + } + ], + "internalType": "struct IAllowanceTransfer.PermitBatch", + "name": "permitBatch", + "type": "tuple" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + } + ], + "name": "permit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "components": [ + { + "components": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint160", + "name": "amount", + "type": "uint160" + }, + { + "internalType": "uint48", + "name": "expiration", + "type": "uint48" + }, + { + "internalType": "uint48", + "name": "nonce", + "type": "uint48" + } + ], + "internalType": "struct IAllowanceTransfer.PermitDetails", + "name": "details", + "type": "tuple" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "sigDeadline", + "type": "uint256" + } + ], + "internalType": "struct IAllowanceTransfer.PermitSingle", + "name": "permitSingle", + "type": "tuple" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + } + ], + "name": "permit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "components": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "internalType": "struct ISignatureTransfer.TokenPermissions", + "name": "permitted", + "type": "tuple" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "internalType": "struct ISignatureTransfer.PermitTransferFrom", + "name": "permit", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "requestedAmount", + "type": "uint256" + } + ], + "internalType": "struct ISignatureTransfer.SignatureTransferDetails", + "name": "transferDetails", + "type": "tuple" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + } + ], + "name": "permitTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "components": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "internalType": "struct ISignatureTransfer.TokenPermissions[]", + "name": "permitted", + "type": "tuple[]" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "internalType": "struct ISignatureTransfer.PermitBatchTransferFrom", + "name": "permit", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "requestedAmount", + "type": "uint256" + } + ], + "internalType": "struct ISignatureTransfer.SignatureTransferDetails[]", + "name": "transferDetails", + "type": "tuple[]" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + } + ], + "name": "permitTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "components": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "internalType": "struct ISignatureTransfer.TokenPermissions", + "name": "permitted", + "type": "tuple" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "internalType": "struct ISignatureTransfer.PermitTransferFrom", + "name": "permit", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "requestedAmount", + "type": "uint256" + } + ], + "internalType": "struct ISignatureTransfer.SignatureTransferDetails", + "name": "transferDetails", + "type": "tuple" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "witness", + "type": "bytes32" + }, + { + "internalType": "string", + "name": "witnessTypeString", + "type": "string" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + } + ], + "name": "permitWitnessTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "components": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "internalType": "struct ISignatureTransfer.TokenPermissions[]", + "name": "permitted", + "type": "tuple[]" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "internalType": "struct ISignatureTransfer.PermitBatchTransferFrom", + "name": "permit", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "requestedAmount", + "type": "uint256" + } + ], + "internalType": "struct ISignatureTransfer.SignatureTransferDetails[]", + "name": "transferDetails", + "type": "tuple[]" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "witness", + "type": "bytes32" + }, + { + "internalType": "string", + "name": "witnessTypeString", + "type": "string" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + } + ], + "name": "permitWitnessTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint160", + "name": "amount", + "type": "uint160" + }, + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "internalType": "struct IAllowanceTransfer.AllowanceTransferDetails[]", + "name": "transferDetails", + "type": "tuple[]" + } + ], + "name": "transferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint160", + "name": "amount", + "type": "uint160" + }, + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "transferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/logics/permit2/configs.ts b/src/logics/permit2/configs.ts new file mode 100644 index 00000000..9ce91156 --- /dev/null +++ b/src/logics/permit2/configs.ts @@ -0,0 +1,30 @@ +import * as common from '@protocolink/common'; + +type ContractNames = 'Permit2'; + +interface Config { + chainId: number; + contract: Record; +} + +export const configs: Config[] = [ + { + chainId: common.ChainId.polygon, + contract: { + Permit2: '0x000000000022D473030F116dDEE9F6B43aC78BA3', + }, + }, +]; + +export const [supportedChainIds, configMap] = configs.reduce( + (accumulator, config) => { + accumulator[0].push(config.chainId); + accumulator[1][config.chainId] = config; + return accumulator; + }, + [[], {}] as [number[], Record] +); + +export function getContractAddress(chainId: number, name: ContractNames) { + return configMap[chainId].contract[name]; +} diff --git a/src/logics/permit2/contracts/Permit2.ts b/src/logics/permit2/contracts/Permit2.ts new file mode 100644 index 00000000..d261a25d --- /dev/null +++ b/src/logics/permit2/contracts/Permit2.ts @@ -0,0 +1,922 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ +import type { + BaseContract, + BigNumber, + BigNumberish, + BytesLike, + CallOverrides, + ContractTransaction, + Overrides, + PopulatedTransaction, + Signer, + utils, +} from 'ethers'; +import type { EventFragment, FunctionFragment, Result } from '@ethersproject/abi'; +import type { Listener, Provider } from '@ethersproject/providers'; +import type { OnEvent, TypedEvent, TypedEventFilter, TypedListener } from './common'; + +export declare namespace IAllowanceTransfer { + export type TokenSpenderPairStruct = { token: string; spender: string }; + + export type TokenSpenderPairStructOutput = [string, string] & { + token: string; + spender: string; + }; + + export type PermitDetailsStruct = { + token: string; + amount: BigNumberish; + expiration: BigNumberish; + nonce: BigNumberish; + }; + + export type PermitDetailsStructOutput = [string, BigNumber, number, number] & { + token: string; + amount: BigNumber; + expiration: number; + nonce: number; + }; + + export type PermitBatchStruct = { + details: IAllowanceTransfer.PermitDetailsStruct[]; + spender: string; + sigDeadline: BigNumberish; + }; + + export type PermitBatchStructOutput = [IAllowanceTransfer.PermitDetailsStructOutput[], string, BigNumber] & { + details: IAllowanceTransfer.PermitDetailsStructOutput[]; + spender: string; + sigDeadline: BigNumber; + }; + + export type PermitSingleStruct = { + details: IAllowanceTransfer.PermitDetailsStruct; + spender: string; + sigDeadline: BigNumberish; + }; + + export type PermitSingleStructOutput = [IAllowanceTransfer.PermitDetailsStructOutput, string, BigNumber] & { + details: IAllowanceTransfer.PermitDetailsStructOutput; + spender: string; + sigDeadline: BigNumber; + }; + + export type AllowanceTransferDetailsStruct = { + from: string; + to: string; + amount: BigNumberish; + token: string; + }; + + export type AllowanceTransferDetailsStructOutput = [string, string, BigNumber, string] & { + from: string; + to: string; + amount: BigNumber; + token: string; + }; +} + +export declare namespace ISignatureTransfer { + export type TokenPermissionsStruct = { token: string; amount: BigNumberish }; + + export type TokenPermissionsStructOutput = [string, BigNumber] & { + token: string; + amount: BigNumber; + }; + + export type PermitTransferFromStruct = { + permitted: ISignatureTransfer.TokenPermissionsStruct; + nonce: BigNumberish; + deadline: BigNumberish; + }; + + export type PermitTransferFromStructOutput = [ + ISignatureTransfer.TokenPermissionsStructOutput, + BigNumber, + BigNumber + ] & { + permitted: ISignatureTransfer.TokenPermissionsStructOutput; + nonce: BigNumber; + deadline: BigNumber; + }; + + export type SignatureTransferDetailsStruct = { + to: string; + requestedAmount: BigNumberish; + }; + + export type SignatureTransferDetailsStructOutput = [string, BigNumber] & { + to: string; + requestedAmount: BigNumber; + }; + + export type PermitBatchTransferFromStruct = { + permitted: ISignatureTransfer.TokenPermissionsStruct[]; + nonce: BigNumberish; + deadline: BigNumberish; + }; + + export type PermitBatchTransferFromStructOutput = [ + ISignatureTransfer.TokenPermissionsStructOutput[], + BigNumber, + BigNumber + ] & { + permitted: ISignatureTransfer.TokenPermissionsStructOutput[]; + nonce: BigNumber; + deadline: BigNumber; + }; +} + +export interface Permit2Interface extends utils.Interface { + functions: { + 'DOMAIN_SEPARATOR()': FunctionFragment; + 'allowance(address,address,address)': FunctionFragment; + 'approve(address,address,uint160,uint48)': FunctionFragment; + 'invalidateNonces(address,address,uint48)': FunctionFragment; + 'invalidateUnorderedNonces(uint256,uint256)': FunctionFragment; + 'lockdown((address,address)[])': FunctionFragment; + 'nonceBitmap(address,uint256)': FunctionFragment; + 'permit(address,((address,uint160,uint48,uint48)[],address,uint256),bytes)': FunctionFragment; + 'permit(address,((address,uint160,uint48,uint48),address,uint256),bytes)': FunctionFragment; + 'permitTransferFrom(((address,uint256),uint256,uint256),(address,uint256),address,bytes)': FunctionFragment; + 'permitTransferFrom(((address,uint256)[],uint256,uint256),(address,uint256)[],address,bytes)': FunctionFragment; + 'permitWitnessTransferFrom(((address,uint256),uint256,uint256),(address,uint256),address,bytes32,string,bytes)': FunctionFragment; + 'permitWitnessTransferFrom(((address,uint256)[],uint256,uint256),(address,uint256)[],address,bytes32,string,bytes)': FunctionFragment; + 'transferFrom((address,address,uint160,address)[])': FunctionFragment; + 'transferFrom(address,address,uint160,address)': FunctionFragment; + }; + + getFunction( + nameOrSignatureOrTopic: + | 'DOMAIN_SEPARATOR' + | 'allowance' + | 'approve' + | 'invalidateNonces' + | 'invalidateUnorderedNonces' + | 'lockdown' + | 'nonceBitmap' + | 'permit(address,((address,uint160,uint48,uint48)[],address,uint256),bytes)' + | 'permit(address,((address,uint160,uint48,uint48),address,uint256),bytes)' + | 'permitTransferFrom(((address,uint256),uint256,uint256),(address,uint256),address,bytes)' + | 'permitTransferFrom(((address,uint256)[],uint256,uint256),(address,uint256)[],address,bytes)' + | 'permitWitnessTransferFrom(((address,uint256),uint256,uint256),(address,uint256),address,bytes32,string,bytes)' + | 'permitWitnessTransferFrom(((address,uint256)[],uint256,uint256),(address,uint256)[],address,bytes32,string,bytes)' + | 'transferFrom((address,address,uint160,address)[])' + | 'transferFrom(address,address,uint160,address)' + ): FunctionFragment; + + encodeFunctionData(functionFragment: 'DOMAIN_SEPARATOR', values?: undefined): string; + encodeFunctionData(functionFragment: 'allowance', values: [string, string, string]): string; + encodeFunctionData(functionFragment: 'approve', values: [string, string, BigNumberish, BigNumberish]): string; + encodeFunctionData(functionFragment: 'invalidateNonces', values: [string, string, BigNumberish]): string; + encodeFunctionData(functionFragment: 'invalidateUnorderedNonces', values: [BigNumberish, BigNumberish]): string; + encodeFunctionData(functionFragment: 'lockdown', values: [IAllowanceTransfer.TokenSpenderPairStruct[]]): string; + encodeFunctionData(functionFragment: 'nonceBitmap', values: [string, BigNumberish]): string; + encodeFunctionData( + functionFragment: 'permit(address,((address,uint160,uint48,uint48)[],address,uint256),bytes)', + values: [string, IAllowanceTransfer.PermitBatchStruct, BytesLike] + ): string; + encodeFunctionData( + functionFragment: 'permit(address,((address,uint160,uint48,uint48),address,uint256),bytes)', + values: [string, IAllowanceTransfer.PermitSingleStruct, BytesLike] + ): string; + encodeFunctionData( + functionFragment: 'permitTransferFrom(((address,uint256),uint256,uint256),(address,uint256),address,bytes)', + values: [ + ISignatureTransfer.PermitTransferFromStruct, + ISignatureTransfer.SignatureTransferDetailsStruct, + string, + BytesLike + ] + ): string; + encodeFunctionData( + functionFragment: 'permitTransferFrom(((address,uint256)[],uint256,uint256),(address,uint256)[],address,bytes)', + values: [ + ISignatureTransfer.PermitBatchTransferFromStruct, + ISignatureTransfer.SignatureTransferDetailsStruct[], + string, + BytesLike + ] + ): string; + encodeFunctionData( + functionFragment: 'permitWitnessTransferFrom(((address,uint256),uint256,uint256),(address,uint256),address,bytes32,string,bytes)', + values: [ + ISignatureTransfer.PermitTransferFromStruct, + ISignatureTransfer.SignatureTransferDetailsStruct, + string, + BytesLike, + string, + BytesLike + ] + ): string; + encodeFunctionData( + functionFragment: 'permitWitnessTransferFrom(((address,uint256)[],uint256,uint256),(address,uint256)[],address,bytes32,string,bytes)', + values: [ + ISignatureTransfer.PermitBatchTransferFromStruct, + ISignatureTransfer.SignatureTransferDetailsStruct[], + string, + BytesLike, + string, + BytesLike + ] + ): string; + encodeFunctionData( + functionFragment: 'transferFrom((address,address,uint160,address)[])', + values: [IAllowanceTransfer.AllowanceTransferDetailsStruct[]] + ): string; + encodeFunctionData( + functionFragment: 'transferFrom(address,address,uint160,address)', + values: [string, string, BigNumberish, string] + ): string; + + decodeFunctionResult(functionFragment: 'DOMAIN_SEPARATOR', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'allowance', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'approve', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'invalidateNonces', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'invalidateUnorderedNonces', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'lockdown', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'nonceBitmap', data: BytesLike): Result; + decodeFunctionResult( + functionFragment: 'permit(address,((address,uint160,uint48,uint48)[],address,uint256),bytes)', + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: 'permit(address,((address,uint160,uint48,uint48),address,uint256),bytes)', + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: 'permitTransferFrom(((address,uint256),uint256,uint256),(address,uint256),address,bytes)', + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: 'permitTransferFrom(((address,uint256)[],uint256,uint256),(address,uint256)[],address,bytes)', + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: 'permitWitnessTransferFrom(((address,uint256),uint256,uint256),(address,uint256),address,bytes32,string,bytes)', + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: 'permitWitnessTransferFrom(((address,uint256)[],uint256,uint256),(address,uint256)[],address,bytes32,string,bytes)', + data: BytesLike + ): Result; + decodeFunctionResult(functionFragment: 'transferFrom((address,address,uint160,address)[])', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'transferFrom(address,address,uint160,address)', data: BytesLike): Result; + + events: { + 'Approval(address,address,address,uint160,uint48)': EventFragment; + 'Lockdown(address,address,address)': EventFragment; + 'NonceInvalidation(address,address,address,uint48,uint48)': EventFragment; + 'Permit(address,address,address,uint160,uint48,uint48)': EventFragment; + 'UnorderedNonceInvalidation(address,uint256,uint256)': EventFragment; + }; + + getEvent(nameOrSignatureOrTopic: 'Approval'): EventFragment; + getEvent(nameOrSignatureOrTopic: 'Lockdown'): EventFragment; + getEvent(nameOrSignatureOrTopic: 'NonceInvalidation'): EventFragment; + getEvent(nameOrSignatureOrTopic: 'Permit'): EventFragment; + getEvent(nameOrSignatureOrTopic: 'UnorderedNonceInvalidation'): EventFragment; +} + +export interface ApprovalEventObject { + owner: string; + token: string; + spender: string; + amount: BigNumber; + expiration: number; +} +export type ApprovalEvent = TypedEvent<[string, string, string, BigNumber, number], ApprovalEventObject>; + +export type ApprovalEventFilter = TypedEventFilter; + +export interface LockdownEventObject { + owner: string; + token: string; + spender: string; +} +export type LockdownEvent = TypedEvent<[string, string, string], LockdownEventObject>; + +export type LockdownEventFilter = TypedEventFilter; + +export interface NonceInvalidationEventObject { + owner: string; + token: string; + spender: string; + newNonce: number; + oldNonce: number; +} +export type NonceInvalidationEvent = TypedEvent<[string, string, string, number, number], NonceInvalidationEventObject>; + +export type NonceInvalidationEventFilter = TypedEventFilter; + +export interface PermitEventObject { + owner: string; + token: string; + spender: string; + amount: BigNumber; + expiration: number; + nonce: number; +} +export type PermitEvent = TypedEvent<[string, string, string, BigNumber, number, number], PermitEventObject>; + +export type PermitEventFilter = TypedEventFilter; + +export interface UnorderedNonceInvalidationEventObject { + owner: string; + word: BigNumber; + mask: BigNumber; +} +export type UnorderedNonceInvalidationEvent = TypedEvent< + [string, BigNumber, BigNumber], + UnorderedNonceInvalidationEventObject +>; + +export type UnorderedNonceInvalidationEventFilter = TypedEventFilter; + +export interface Permit2 extends BaseContract { + connect(signerOrProvider: Signer | Provider | string): this; + attach(addressOrName: string): this; + deployed(): Promise; + + interface: Permit2Interface; + + queryFilter( + event: TypedEventFilter, + fromBlockOrBlockhash?: string | number | undefined, + toBlock?: string | number | undefined + ): Promise>; + + listeners(eventFilter?: TypedEventFilter): Array>; + listeners(eventName?: string): Array; + removeAllListeners(eventFilter: TypedEventFilter): this; + removeAllListeners(eventName?: string): this; + off: OnEvent; + on: OnEvent; + once: OnEvent; + removeListener: OnEvent; + + functions: { + DOMAIN_SEPARATOR(overrides?: CallOverrides): Promise<[string]>; + + allowance( + arg0: string, + arg1: string, + arg2: string, + overrides?: CallOverrides + ): Promise< + [BigNumber, number, number] & { + amount: BigNumber; + expiration: number; + nonce: number; + } + >; + + approve( + token: string, + spender: string, + amount: BigNumberish, + expiration: BigNumberish, + overrides?: Overrides & { from?: string } + ): Promise; + + invalidateNonces( + token: string, + spender: string, + newNonce: BigNumberish, + overrides?: Overrides & { from?: string } + ): Promise; + + invalidateUnorderedNonces( + wordPos: BigNumberish, + mask: BigNumberish, + overrides?: Overrides & { from?: string } + ): Promise; + + lockdown( + approvals: IAllowanceTransfer.TokenSpenderPairStruct[], + overrides?: Overrides & { from?: string } + ): Promise; + + nonceBitmap(arg0: string, arg1: BigNumberish, overrides?: CallOverrides): Promise<[BigNumber]>; + + 'permit(address,((address,uint160,uint48,uint48)[],address,uint256),bytes)'( + owner: string, + permitBatch: IAllowanceTransfer.PermitBatchStruct, + signature: BytesLike, + overrides?: Overrides & { from?: string } + ): Promise; + + 'permit(address,((address,uint160,uint48,uint48),address,uint256),bytes)'( + owner: string, + permitSingle: IAllowanceTransfer.PermitSingleStruct, + signature: BytesLike, + overrides?: Overrides & { from?: string } + ): Promise; + + 'permitTransferFrom(((address,uint256),uint256,uint256),(address,uint256),address,bytes)'( + permit: ISignatureTransfer.PermitTransferFromStruct, + transferDetails: ISignatureTransfer.SignatureTransferDetailsStruct, + owner: string, + signature: BytesLike, + overrides?: Overrides & { from?: string } + ): Promise; + + 'permitTransferFrom(((address,uint256)[],uint256,uint256),(address,uint256)[],address,bytes)'( + permit: ISignatureTransfer.PermitBatchTransferFromStruct, + transferDetails: ISignatureTransfer.SignatureTransferDetailsStruct[], + owner: string, + signature: BytesLike, + overrides?: Overrides & { from?: string } + ): Promise; + + 'permitWitnessTransferFrom(((address,uint256),uint256,uint256),(address,uint256),address,bytes32,string,bytes)'( + permit: ISignatureTransfer.PermitTransferFromStruct, + transferDetails: ISignatureTransfer.SignatureTransferDetailsStruct, + owner: string, + witness: BytesLike, + witnessTypeString: string, + signature: BytesLike, + overrides?: Overrides & { from?: string } + ): Promise; + + 'permitWitnessTransferFrom(((address,uint256)[],uint256,uint256),(address,uint256)[],address,bytes32,string,bytes)'( + permit: ISignatureTransfer.PermitBatchTransferFromStruct, + transferDetails: ISignatureTransfer.SignatureTransferDetailsStruct[], + owner: string, + witness: BytesLike, + witnessTypeString: string, + signature: BytesLike, + overrides?: Overrides & { from?: string } + ): Promise; + + 'transferFrom((address,address,uint160,address)[])'( + transferDetails: IAllowanceTransfer.AllowanceTransferDetailsStruct[], + overrides?: Overrides & { from?: string } + ): Promise; + + 'transferFrom(address,address,uint160,address)'( + from: string, + to: string, + amount: BigNumberish, + token: string, + overrides?: Overrides & { from?: string } + ): Promise; + }; + + DOMAIN_SEPARATOR(overrides?: CallOverrides): Promise; + + allowance( + arg0: string, + arg1: string, + arg2: string, + overrides?: CallOverrides + ): Promise< + [BigNumber, number, number] & { + amount: BigNumber; + expiration: number; + nonce: number; + } + >; + + approve( + token: string, + spender: string, + amount: BigNumberish, + expiration: BigNumberish, + overrides?: Overrides & { from?: string } + ): Promise; + + invalidateNonces( + token: string, + spender: string, + newNonce: BigNumberish, + overrides?: Overrides & { from?: string } + ): Promise; + + invalidateUnorderedNonces( + wordPos: BigNumberish, + mask: BigNumberish, + overrides?: Overrides & { from?: string } + ): Promise; + + lockdown( + approvals: IAllowanceTransfer.TokenSpenderPairStruct[], + overrides?: Overrides & { from?: string } + ): Promise; + + nonceBitmap(arg0: string, arg1: BigNumberish, overrides?: CallOverrides): Promise; + + 'permit(address,((address,uint160,uint48,uint48)[],address,uint256),bytes)'( + owner: string, + permitBatch: IAllowanceTransfer.PermitBatchStruct, + signature: BytesLike, + overrides?: Overrides & { from?: string } + ): Promise; + + 'permit(address,((address,uint160,uint48,uint48),address,uint256),bytes)'( + owner: string, + permitSingle: IAllowanceTransfer.PermitSingleStruct, + signature: BytesLike, + overrides?: Overrides & { from?: string } + ): Promise; + + 'permitTransferFrom(((address,uint256),uint256,uint256),(address,uint256),address,bytes)'( + permit: ISignatureTransfer.PermitTransferFromStruct, + transferDetails: ISignatureTransfer.SignatureTransferDetailsStruct, + owner: string, + signature: BytesLike, + overrides?: Overrides & { from?: string } + ): Promise; + + 'permitTransferFrom(((address,uint256)[],uint256,uint256),(address,uint256)[],address,bytes)'( + permit: ISignatureTransfer.PermitBatchTransferFromStruct, + transferDetails: ISignatureTransfer.SignatureTransferDetailsStruct[], + owner: string, + signature: BytesLike, + overrides?: Overrides & { from?: string } + ): Promise; + + 'permitWitnessTransferFrom(((address,uint256),uint256,uint256),(address,uint256),address,bytes32,string,bytes)'( + permit: ISignatureTransfer.PermitTransferFromStruct, + transferDetails: ISignatureTransfer.SignatureTransferDetailsStruct, + owner: string, + witness: BytesLike, + witnessTypeString: string, + signature: BytesLike, + overrides?: Overrides & { from?: string } + ): Promise; + + 'permitWitnessTransferFrom(((address,uint256)[],uint256,uint256),(address,uint256)[],address,bytes32,string,bytes)'( + permit: ISignatureTransfer.PermitBatchTransferFromStruct, + transferDetails: ISignatureTransfer.SignatureTransferDetailsStruct[], + owner: string, + witness: BytesLike, + witnessTypeString: string, + signature: BytesLike, + overrides?: Overrides & { from?: string } + ): Promise; + + 'transferFrom((address,address,uint160,address)[])'( + transferDetails: IAllowanceTransfer.AllowanceTransferDetailsStruct[], + overrides?: Overrides & { from?: string } + ): Promise; + + 'transferFrom(address,address,uint160,address)'( + from: string, + to: string, + amount: BigNumberish, + token: string, + overrides?: Overrides & { from?: string } + ): Promise; + + callStatic: { + DOMAIN_SEPARATOR(overrides?: CallOverrides): Promise; + + allowance( + arg0: string, + arg1: string, + arg2: string, + overrides?: CallOverrides + ): Promise< + [BigNumber, number, number] & { + amount: BigNumber; + expiration: number; + nonce: number; + } + >; + + approve( + token: string, + spender: string, + amount: BigNumberish, + expiration: BigNumberish, + overrides?: CallOverrides + ): Promise; + + invalidateNonces(token: string, spender: string, newNonce: BigNumberish, overrides?: CallOverrides): Promise; + + invalidateUnorderedNonces(wordPos: BigNumberish, mask: BigNumberish, overrides?: CallOverrides): Promise; + + lockdown(approvals: IAllowanceTransfer.TokenSpenderPairStruct[], overrides?: CallOverrides): Promise; + + nonceBitmap(arg0: string, arg1: BigNumberish, overrides?: CallOverrides): Promise; + + 'permit(address,((address,uint160,uint48,uint48)[],address,uint256),bytes)'( + owner: string, + permitBatch: IAllowanceTransfer.PermitBatchStruct, + signature: BytesLike, + overrides?: CallOverrides + ): Promise; + + 'permit(address,((address,uint160,uint48,uint48),address,uint256),bytes)'( + owner: string, + permitSingle: IAllowanceTransfer.PermitSingleStruct, + signature: BytesLike, + overrides?: CallOverrides + ): Promise; + + 'permitTransferFrom(((address,uint256),uint256,uint256),(address,uint256),address,bytes)'( + permit: ISignatureTransfer.PermitTransferFromStruct, + transferDetails: ISignatureTransfer.SignatureTransferDetailsStruct, + owner: string, + signature: BytesLike, + overrides?: CallOverrides + ): Promise; + + 'permitTransferFrom(((address,uint256)[],uint256,uint256),(address,uint256)[],address,bytes)'( + permit: ISignatureTransfer.PermitBatchTransferFromStruct, + transferDetails: ISignatureTransfer.SignatureTransferDetailsStruct[], + owner: string, + signature: BytesLike, + overrides?: CallOverrides + ): Promise; + + 'permitWitnessTransferFrom(((address,uint256),uint256,uint256),(address,uint256),address,bytes32,string,bytes)'( + permit: ISignatureTransfer.PermitTransferFromStruct, + transferDetails: ISignatureTransfer.SignatureTransferDetailsStruct, + owner: string, + witness: BytesLike, + witnessTypeString: string, + signature: BytesLike, + overrides?: CallOverrides + ): Promise; + + 'permitWitnessTransferFrom(((address,uint256)[],uint256,uint256),(address,uint256)[],address,bytes32,string,bytes)'( + permit: ISignatureTransfer.PermitBatchTransferFromStruct, + transferDetails: ISignatureTransfer.SignatureTransferDetailsStruct[], + owner: string, + witness: BytesLike, + witnessTypeString: string, + signature: BytesLike, + overrides?: CallOverrides + ): Promise; + + 'transferFrom((address,address,uint160,address)[])'( + transferDetails: IAllowanceTransfer.AllowanceTransferDetailsStruct[], + overrides?: CallOverrides + ): Promise; + + 'transferFrom(address,address,uint160,address)'( + from: string, + to: string, + amount: BigNumberish, + token: string, + overrides?: CallOverrides + ): Promise; + }; + + filters: { + 'Approval(address,address,address,uint160,uint48)'( + owner?: string | null, + token?: string | null, + spender?: string | null, + amount?: null, + expiration?: null + ): ApprovalEventFilter; + Approval( + owner?: string | null, + token?: string | null, + spender?: string | null, + amount?: null, + expiration?: null + ): ApprovalEventFilter; + + 'Lockdown(address,address,address)'(owner?: string | null, token?: null, spender?: null): LockdownEventFilter; + Lockdown(owner?: string | null, token?: null, spender?: null): LockdownEventFilter; + + 'NonceInvalidation(address,address,address,uint48,uint48)'( + owner?: string | null, + token?: string | null, + spender?: string | null, + newNonce?: null, + oldNonce?: null + ): NonceInvalidationEventFilter; + NonceInvalidation( + owner?: string | null, + token?: string | null, + spender?: string | null, + newNonce?: null, + oldNonce?: null + ): NonceInvalidationEventFilter; + + 'Permit(address,address,address,uint160,uint48,uint48)'( + owner?: string | null, + token?: string | null, + spender?: string | null, + amount?: null, + expiration?: null, + nonce?: null + ): PermitEventFilter; + Permit( + owner?: string | null, + token?: string | null, + spender?: string | null, + amount?: null, + expiration?: null, + nonce?: null + ): PermitEventFilter; + + 'UnorderedNonceInvalidation(address,uint256,uint256)'( + owner?: string | null, + word?: null, + mask?: null + ): UnorderedNonceInvalidationEventFilter; + UnorderedNonceInvalidation(owner?: string | null, word?: null, mask?: null): UnorderedNonceInvalidationEventFilter; + }; + + estimateGas: { + DOMAIN_SEPARATOR(overrides?: CallOverrides): Promise; + + allowance(arg0: string, arg1: string, arg2: string, overrides?: CallOverrides): Promise; + + approve( + token: string, + spender: string, + amount: BigNumberish, + expiration: BigNumberish, + overrides?: Overrides & { from?: string } + ): Promise; + + invalidateNonces( + token: string, + spender: string, + newNonce: BigNumberish, + overrides?: Overrides & { from?: string } + ): Promise; + + invalidateUnorderedNonces( + wordPos: BigNumberish, + mask: BigNumberish, + overrides?: Overrides & { from?: string } + ): Promise; + + lockdown( + approvals: IAllowanceTransfer.TokenSpenderPairStruct[], + overrides?: Overrides & { from?: string } + ): Promise; + + nonceBitmap(arg0: string, arg1: BigNumberish, overrides?: CallOverrides): Promise; + + 'permit(address,((address,uint160,uint48,uint48)[],address,uint256),bytes)'( + owner: string, + permitBatch: IAllowanceTransfer.PermitBatchStruct, + signature: BytesLike, + overrides?: Overrides & { from?: string } + ): Promise; + + 'permit(address,((address,uint160,uint48,uint48),address,uint256),bytes)'( + owner: string, + permitSingle: IAllowanceTransfer.PermitSingleStruct, + signature: BytesLike, + overrides?: Overrides & { from?: string } + ): Promise; + + 'permitTransferFrom(((address,uint256),uint256,uint256),(address,uint256),address,bytes)'( + permit: ISignatureTransfer.PermitTransferFromStruct, + transferDetails: ISignatureTransfer.SignatureTransferDetailsStruct, + owner: string, + signature: BytesLike, + overrides?: Overrides & { from?: string } + ): Promise; + + 'permitTransferFrom(((address,uint256)[],uint256,uint256),(address,uint256)[],address,bytes)'( + permit: ISignatureTransfer.PermitBatchTransferFromStruct, + transferDetails: ISignatureTransfer.SignatureTransferDetailsStruct[], + owner: string, + signature: BytesLike, + overrides?: Overrides & { from?: string } + ): Promise; + + 'permitWitnessTransferFrom(((address,uint256),uint256,uint256),(address,uint256),address,bytes32,string,bytes)'( + permit: ISignatureTransfer.PermitTransferFromStruct, + transferDetails: ISignatureTransfer.SignatureTransferDetailsStruct, + owner: string, + witness: BytesLike, + witnessTypeString: string, + signature: BytesLike, + overrides?: Overrides & { from?: string } + ): Promise; + + 'permitWitnessTransferFrom(((address,uint256)[],uint256,uint256),(address,uint256)[],address,bytes32,string,bytes)'( + permit: ISignatureTransfer.PermitBatchTransferFromStruct, + transferDetails: ISignatureTransfer.SignatureTransferDetailsStruct[], + owner: string, + witness: BytesLike, + witnessTypeString: string, + signature: BytesLike, + overrides?: Overrides & { from?: string } + ): Promise; + + 'transferFrom((address,address,uint160,address)[])'( + transferDetails: IAllowanceTransfer.AllowanceTransferDetailsStruct[], + overrides?: Overrides & { from?: string } + ): Promise; + + 'transferFrom(address,address,uint160,address)'( + from: string, + to: string, + amount: BigNumberish, + token: string, + overrides?: Overrides & { from?: string } + ): Promise; + }; + + populateTransaction: { + DOMAIN_SEPARATOR(overrides?: CallOverrides): Promise; + + allowance(arg0: string, arg1: string, arg2: string, overrides?: CallOverrides): Promise; + + approve( + token: string, + spender: string, + amount: BigNumberish, + expiration: BigNumberish, + overrides?: Overrides & { from?: string } + ): Promise; + + invalidateNonces( + token: string, + spender: string, + newNonce: BigNumberish, + overrides?: Overrides & { from?: string } + ): Promise; + + invalidateUnorderedNonces( + wordPos: BigNumberish, + mask: BigNumberish, + overrides?: Overrides & { from?: string } + ): Promise; + + lockdown( + approvals: IAllowanceTransfer.TokenSpenderPairStruct[], + overrides?: Overrides & { from?: string } + ): Promise; + + nonceBitmap(arg0: string, arg1: BigNumberish, overrides?: CallOverrides): Promise; + + 'permit(address,((address,uint160,uint48,uint48)[],address,uint256),bytes)'( + owner: string, + permitBatch: IAllowanceTransfer.PermitBatchStruct, + signature: BytesLike, + overrides?: Overrides & { from?: string } + ): Promise; + + 'permit(address,((address,uint160,uint48,uint48),address,uint256),bytes)'( + owner: string, + permitSingle: IAllowanceTransfer.PermitSingleStruct, + signature: BytesLike, + overrides?: Overrides & { from?: string } + ): Promise; + + 'permitTransferFrom(((address,uint256),uint256,uint256),(address,uint256),address,bytes)'( + permit: ISignatureTransfer.PermitTransferFromStruct, + transferDetails: ISignatureTransfer.SignatureTransferDetailsStruct, + owner: string, + signature: BytesLike, + overrides?: Overrides & { from?: string } + ): Promise; + + 'permitTransferFrom(((address,uint256)[],uint256,uint256),(address,uint256)[],address,bytes)'( + permit: ISignatureTransfer.PermitBatchTransferFromStruct, + transferDetails: ISignatureTransfer.SignatureTransferDetailsStruct[], + owner: string, + signature: BytesLike, + overrides?: Overrides & { from?: string } + ): Promise; + + 'permitWitnessTransferFrom(((address,uint256),uint256,uint256),(address,uint256),address,bytes32,string,bytes)'( + permit: ISignatureTransfer.PermitTransferFromStruct, + transferDetails: ISignatureTransfer.SignatureTransferDetailsStruct, + owner: string, + witness: BytesLike, + witnessTypeString: string, + signature: BytesLike, + overrides?: Overrides & { from?: string } + ): Promise; + + 'permitWitnessTransferFrom(((address,uint256)[],uint256,uint256),(address,uint256)[],address,bytes32,string,bytes)'( + permit: ISignatureTransfer.PermitBatchTransferFromStruct, + transferDetails: ISignatureTransfer.SignatureTransferDetailsStruct[], + owner: string, + witness: BytesLike, + witnessTypeString: string, + signature: BytesLike, + overrides?: Overrides & { from?: string } + ): Promise; + + 'transferFrom((address,address,uint160,address)[])'( + transferDetails: IAllowanceTransfer.AllowanceTransferDetailsStruct[], + overrides?: Overrides & { from?: string } + ): Promise; + + 'transferFrom(address,address,uint160,address)'( + from: string, + to: string, + amount: BigNumberish, + token: string, + overrides?: Overrides & { from?: string } + ): Promise; + }; +} diff --git a/src/logics/permit2/contracts/common.ts b/src/logics/permit2/contracts/common.ts new file mode 100644 index 00000000..2627dd8a --- /dev/null +++ b/src/logics/permit2/contracts/common.ts @@ -0,0 +1,30 @@ +import type { Event, EventFilter } from 'ethers'; +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ +import type { Listener } from '@ethersproject/providers'; + +export interface TypedEvent = any, TArgsObject = any> extends Event { + args: TArgsArray & TArgsObject; +} + +export interface TypedEventFilter<_TEvent extends TypedEvent> extends EventFilter {} + +export interface TypedListener { + (...listenerArg: [...__TypechainArgsArray, TEvent]): void; +} + +type __TypechainArgsArray = T extends TypedEvent ? U : never; + +export interface OnEvent { + (eventFilter: TypedEventFilter, listener: TypedListener): TRes; + (eventName: string, listener: Listener): TRes; +} + +export type MinEthersFactory = { + deploy(...a: ARGS[]): Promise; +}; + +export type GetContractTypeFromFactory = F extends MinEthersFactory ? C : never; + +export type GetARGsTypeFromFactory = F extends MinEthersFactory ? Parameters : never; diff --git a/src/logics/permit2/contracts/factories/Permit2__factory.ts b/src/logics/permit2/contracts/factories/Permit2__factory.ts new file mode 100644 index 00000000..42d76383 --- /dev/null +++ b/src/logics/permit2/contracts/factories/Permit2__factory.ts @@ -0,0 +1,919 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ + +import { Contract, Signer, utils } from 'ethers'; +import type { Permit2, Permit2Interface } from '../Permit2'; +import type { Provider } from '@ethersproject/providers'; + +const _abi = [ + { + inputs: [ + { + internalType: 'uint256', + name: 'deadline', + type: 'uint256', + }, + ], + name: 'AllowanceExpired', + type: 'error', + }, + { + inputs: [], + name: 'ExcessiveInvalidation', + type: 'error', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'InsufficientAllowance', + type: 'error', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'maxAmount', + type: 'uint256', + }, + ], + name: 'InvalidAmount', + type: 'error', + }, + { + inputs: [], + name: 'InvalidContractSignature', + type: 'error', + }, + { + inputs: [], + name: 'InvalidNonce', + type: 'error', + }, + { + inputs: [], + name: 'InvalidSignature', + type: 'error', + }, + { + inputs: [], + name: 'InvalidSignatureLength', + type: 'error', + }, + { + inputs: [], + name: 'InvalidSigner', + type: 'error', + }, + { + inputs: [], + name: 'LengthMismatch', + type: 'error', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'signatureDeadline', + type: 'uint256', + }, + ], + name: 'SignatureExpired', + type: 'error', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'token', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint160', + name: 'amount', + type: 'uint160', + }, + { + indexed: false, + internalType: 'uint48', + name: 'expiration', + type: 'uint48', + }, + ], + name: 'Approval', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'token', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'spender', + type: 'address', + }, + ], + name: 'Lockdown', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'token', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint48', + name: 'newNonce', + type: 'uint48', + }, + { + indexed: false, + internalType: 'uint48', + name: 'oldNonce', + type: 'uint48', + }, + ], + name: 'NonceInvalidation', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'token', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint160', + name: 'amount', + type: 'uint160', + }, + { + indexed: false, + internalType: 'uint48', + name: 'expiration', + type: 'uint48', + }, + { + indexed: false, + internalType: 'uint48', + name: 'nonce', + type: 'uint48', + }, + ], + name: 'Permit', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'word', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'mask', + type: 'uint256', + }, + ], + name: 'UnorderedNonceInvalidation', + type: 'event', + }, + { + inputs: [], + name: 'DOMAIN_SEPARATOR', + outputs: [ + { + internalType: 'bytes32', + name: '', + type: 'bytes32', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + { + internalType: 'address', + name: '', + type: 'address', + }, + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + name: 'allowance', + outputs: [ + { + internalType: 'uint160', + name: 'amount', + type: 'uint160', + }, + { + internalType: 'uint48', + name: 'expiration', + type: 'uint48', + }, + { + internalType: 'uint48', + name: 'nonce', + type: 'uint48', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'token', + type: 'address', + }, + { + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + internalType: 'uint160', + name: 'amount', + type: 'uint160', + }, + { + internalType: 'uint48', + name: 'expiration', + type: 'uint48', + }, + ], + name: 'approve', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'token', + type: 'address', + }, + { + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + internalType: 'uint48', + name: 'newNonce', + type: 'uint48', + }, + ], + name: 'invalidateNonces', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'wordPos', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'mask', + type: 'uint256', + }, + ], + name: 'invalidateUnorderedNonces', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + components: [ + { + internalType: 'address', + name: 'token', + type: 'address', + }, + { + internalType: 'address', + name: 'spender', + type: 'address', + }, + ], + internalType: 'struct IAllowanceTransfer.TokenSpenderPair[]', + name: 'approvals', + type: 'tuple[]', + }, + ], + name: 'lockdown', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + name: 'nonceBitmap', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + components: [ + { + components: [ + { + internalType: 'address', + name: 'token', + type: 'address', + }, + { + internalType: 'uint160', + name: 'amount', + type: 'uint160', + }, + { + internalType: 'uint48', + name: 'expiration', + type: 'uint48', + }, + { + internalType: 'uint48', + name: 'nonce', + type: 'uint48', + }, + ], + internalType: 'struct IAllowanceTransfer.PermitDetails[]', + name: 'details', + type: 'tuple[]', + }, + { + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + internalType: 'uint256', + name: 'sigDeadline', + type: 'uint256', + }, + ], + internalType: 'struct IAllowanceTransfer.PermitBatch', + name: 'permitBatch', + type: 'tuple', + }, + { + internalType: 'bytes', + name: 'signature', + type: 'bytes', + }, + ], + name: 'permit', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + components: [ + { + components: [ + { + internalType: 'address', + name: 'token', + type: 'address', + }, + { + internalType: 'uint160', + name: 'amount', + type: 'uint160', + }, + { + internalType: 'uint48', + name: 'expiration', + type: 'uint48', + }, + { + internalType: 'uint48', + name: 'nonce', + type: 'uint48', + }, + ], + internalType: 'struct IAllowanceTransfer.PermitDetails', + name: 'details', + type: 'tuple', + }, + { + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + internalType: 'uint256', + name: 'sigDeadline', + type: 'uint256', + }, + ], + internalType: 'struct IAllowanceTransfer.PermitSingle', + name: 'permitSingle', + type: 'tuple', + }, + { + internalType: 'bytes', + name: 'signature', + type: 'bytes', + }, + ], + name: 'permit', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + components: [ + { + components: [ + { + internalType: 'address', + name: 'token', + type: 'address', + }, + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + internalType: 'struct ISignatureTransfer.TokenPermissions', + name: 'permitted', + type: 'tuple', + }, + { + internalType: 'uint256', + name: 'nonce', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'deadline', + type: 'uint256', + }, + ], + internalType: 'struct ISignatureTransfer.PermitTransferFrom', + name: 'permit', + type: 'tuple', + }, + { + components: [ + { + internalType: 'address', + name: 'to', + type: 'address', + }, + { + internalType: 'uint256', + name: 'requestedAmount', + type: 'uint256', + }, + ], + internalType: 'struct ISignatureTransfer.SignatureTransferDetails', + name: 'transferDetails', + type: 'tuple', + }, + { + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + internalType: 'bytes', + name: 'signature', + type: 'bytes', + }, + ], + name: 'permitTransferFrom', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + components: [ + { + components: [ + { + internalType: 'address', + name: 'token', + type: 'address', + }, + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + internalType: 'struct ISignatureTransfer.TokenPermissions[]', + name: 'permitted', + type: 'tuple[]', + }, + { + internalType: 'uint256', + name: 'nonce', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'deadline', + type: 'uint256', + }, + ], + internalType: 'struct ISignatureTransfer.PermitBatchTransferFrom', + name: 'permit', + type: 'tuple', + }, + { + components: [ + { + internalType: 'address', + name: 'to', + type: 'address', + }, + { + internalType: 'uint256', + name: 'requestedAmount', + type: 'uint256', + }, + ], + internalType: 'struct ISignatureTransfer.SignatureTransferDetails[]', + name: 'transferDetails', + type: 'tuple[]', + }, + { + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + internalType: 'bytes', + name: 'signature', + type: 'bytes', + }, + ], + name: 'permitTransferFrom', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + components: [ + { + components: [ + { + internalType: 'address', + name: 'token', + type: 'address', + }, + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + internalType: 'struct ISignatureTransfer.TokenPermissions', + name: 'permitted', + type: 'tuple', + }, + { + internalType: 'uint256', + name: 'nonce', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'deadline', + type: 'uint256', + }, + ], + internalType: 'struct ISignatureTransfer.PermitTransferFrom', + name: 'permit', + type: 'tuple', + }, + { + components: [ + { + internalType: 'address', + name: 'to', + type: 'address', + }, + { + internalType: 'uint256', + name: 'requestedAmount', + type: 'uint256', + }, + ], + internalType: 'struct ISignatureTransfer.SignatureTransferDetails', + name: 'transferDetails', + type: 'tuple', + }, + { + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + internalType: 'bytes32', + name: 'witness', + type: 'bytes32', + }, + { + internalType: 'string', + name: 'witnessTypeString', + type: 'string', + }, + { + internalType: 'bytes', + name: 'signature', + type: 'bytes', + }, + ], + name: 'permitWitnessTransferFrom', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + components: [ + { + components: [ + { + internalType: 'address', + name: 'token', + type: 'address', + }, + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + internalType: 'struct ISignatureTransfer.TokenPermissions[]', + name: 'permitted', + type: 'tuple[]', + }, + { + internalType: 'uint256', + name: 'nonce', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'deadline', + type: 'uint256', + }, + ], + internalType: 'struct ISignatureTransfer.PermitBatchTransferFrom', + name: 'permit', + type: 'tuple', + }, + { + components: [ + { + internalType: 'address', + name: 'to', + type: 'address', + }, + { + internalType: 'uint256', + name: 'requestedAmount', + type: 'uint256', + }, + ], + internalType: 'struct ISignatureTransfer.SignatureTransferDetails[]', + name: 'transferDetails', + type: 'tuple[]', + }, + { + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + internalType: 'bytes32', + name: 'witness', + type: 'bytes32', + }, + { + internalType: 'string', + name: 'witnessTypeString', + type: 'string', + }, + { + internalType: 'bytes', + name: 'signature', + type: 'bytes', + }, + ], + name: 'permitWitnessTransferFrom', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + components: [ + { + internalType: 'address', + name: 'from', + type: 'address', + }, + { + internalType: 'address', + name: 'to', + type: 'address', + }, + { + internalType: 'uint160', + name: 'amount', + type: 'uint160', + }, + { + internalType: 'address', + name: 'token', + type: 'address', + }, + ], + internalType: 'struct IAllowanceTransfer.AllowanceTransferDetails[]', + name: 'transferDetails', + type: 'tuple[]', + }, + ], + name: 'transferFrom', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'from', + type: 'address', + }, + { + internalType: 'address', + name: 'to', + type: 'address', + }, + { + internalType: 'uint160', + name: 'amount', + type: 'uint160', + }, + { + internalType: 'address', + name: 'token', + type: 'address', + }, + ], + name: 'transferFrom', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, +] as const; + +export class Permit2__factory { + static readonly abi = _abi; + static createInterface(): Permit2Interface { + return new utils.Interface(_abi) as Permit2Interface; + } + static connect(address: string, signerOrProvider: Signer | Provider): Permit2 { + return new Contract(address, _abi, signerOrProvider) as Permit2; + } +} diff --git a/src/logics/permit2/contracts/factories/index.ts b/src/logics/permit2/contracts/factories/index.ts new file mode 100644 index 00000000..5c94b461 --- /dev/null +++ b/src/logics/permit2/contracts/factories/index.ts @@ -0,0 +1,4 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ +export { Permit2__factory } from './Permit2__factory'; diff --git a/src/logics/permit2/contracts/index.ts b/src/logics/permit2/contracts/index.ts new file mode 100644 index 00000000..2822e483 --- /dev/null +++ b/src/logics/permit2/contracts/index.ts @@ -0,0 +1,6 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ +export type { Permit2 } from './Permit2'; +export * as factories from './factories'; +export { Permit2__factory } from './factories/Permit2__factory'; diff --git a/src/logics/permit2/index.ts b/src/logics/permit2/index.ts new file mode 100644 index 00000000..0e4f89d0 --- /dev/null +++ b/src/logics/permit2/index.ts @@ -0,0 +1,3 @@ +export * from './configs'; +export * from './contracts'; +export * from './logic.pull-token'; diff --git a/src/logics/permit2/logic.pull-token.test.ts b/src/logics/permit2/logic.pull-token.test.ts new file mode 100644 index 00000000..f63ede3e --- /dev/null +++ b/src/logics/permit2/logic.pull-token.test.ts @@ -0,0 +1,36 @@ +import { LogicTestCase } from 'test/types'; +import { Permit2__factory } from './contracts'; +import { PullTokenLogic, PullTokenLogicFields } from './logic.pull-token'; +import * as common from '@protocolink/common'; +import { constants, utils } from 'ethers'; +import { expect } from 'chai'; +import { getContractAddress } from './configs'; +import { polygonTokens } from '@protocolink/test-helpers'; + +describe('Permit2 PullTokenLogic', function () { + const chainId = common.ChainId.polygon; + const logic = new PullTokenLogic(chainId); + + context('Test build', function () { + const account = '0xaAaAaAaaAaAaAaaAaAAAAAAAAaaaAaAaAaaAaaAa'; + const iface = Permit2__factory.createInterface(); + + const testCases: LogicTestCase[] = [ + { fields: { input: new common.TokenAmount(polygonTokens.WETH, '1') } }, + ]; + + testCases.forEach(({ fields }, i) => { + it(`case ${i + 1}`, async function () { + const routerLogic = await logic.build(fields, { account }); + const sig = routerLogic.data.substring(0, 10); + + expect(routerLogic.to).to.eq(getContractAddress(chainId, 'Permit2')); + expect(utils.isBytesLike(routerLogic.data)).to.be.true; + expect(sig).to.eq(iface.getSighash('transferFrom(address,address,uint160,address)')); + expect(routerLogic.inputs).to.deep.eq([]); + expect(routerLogic.approveTo).to.eq(constants.AddressZero); + expect(routerLogic.callback).to.eq(constants.AddressZero); + }); + }); + }); +}); diff --git a/src/logics/permit2/logic.pull-token.ts b/src/logics/permit2/logic.pull-token.ts new file mode 100644 index 00000000..b94c8e4f --- /dev/null +++ b/src/logics/permit2/logic.pull-token.ts @@ -0,0 +1,30 @@ +import { Permit2__factory } from './contracts'; +import * as core from '@protocolink/core'; +import { getContractAddress, supportedChainIds } from './configs'; + +export type PullTokenLogicFields = core.TokenInFields; + +export type PullTokenLogicOptions = Pick; + +@core.LogicDefinitionDecorator() +export class PullTokenLogic extends core.Logic implements core.LogicBuilderInterface { + static readonly supportedChainIds = supportedChainIds; + + async build(fields: PullTokenLogicFields, options: PullTokenLogicOptions) { + const { input } = fields; + const { account } = options; + const userAgent = await this.calcAgent(account); + + const to = getContractAddress(this.chainId, 'Permit2'); + const iface = Permit2__factory.createInterface(); + + const data = iface.encodeFunctionData('transferFrom(address,address,uint160,address)', [ + account, + userAgent, + input.amountWei, + input.token.address, + ]); + + return core.newLogic({ to, data }); + } +} diff --git a/test/logics/permit2/pull-token.test.ts b/test/logics/permit2/pull-token.test.ts new file mode 100644 index 00000000..d6ef050d --- /dev/null +++ b/test/logics/permit2/pull-token.test.ts @@ -0,0 +1,65 @@ +import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers'; +import { claimToken, getChainId, polygonTokens, snapshotAndRevertEach } from '@protocolink/test-helpers'; +import * as common from '@protocolink/common'; +import * as core from '@protocolink/core'; +import { expect } from 'chai'; +import hre from 'hardhat'; +import * as permit2 from 'src/logics/permit2'; +import * as utils from 'test/utils'; + +describe('polygon: Test Permit2 PullToken Logic', function () { + let chainId: number; + let user: SignerWithAddress; + let routerKit: core.RouterKit; + let agent: string; + + before(async function () { + chainId = await getChainId(); + [, user] = await hre.ethers.getSigners(); + routerKit = new core.RouterKit(chainId); + agent = await routerKit.calcAgent(user.address); + + await claimToken(chainId, user.address, polygonTokens.USDC, '100', '0xe7804c37c13166fF0b37F5aE0BB07A3aEbb6e245'); + await claimToken(chainId, user.address, polygonTokens.WETH, '100', '0x1eED63EfBA5f81D95bfe37d82C8E736b974F477b'); + }); + + snapshotAndRevertEach(); + + const testCases = [ + { + fields: { input: new common.TokenAmount(polygonTokens.USDC, '1') }, + }, + { + fields: { input: new common.TokenAmount(polygonTokens.WETH, '1') }, + }, + ]; + + testCases.forEach(({ fields }, i) => { + it(`case ${i + 1}`, async function () { + // 1. build tokensReturn + const input = fields.input; + const permit2PullTokenLogic = new permit2.PullTokenLogic(chainId); + const tokensReturn: string[] = []; + const funds = new common.TokenAmounts(fields.input); + + // 2. build router logics + const routerLogics: core.DataType.LogicStruct[] = []; + routerLogics.push(await permit2PullTokenLogic.build(fields, { account: user.address })); + + // 3. get router permit2 datas + const permit2Datas = await utils.approvePermit2AndGetPermit2Datas(chainId, user, funds.erc20); + + // 4. send router tx + const transactionRequest = routerKit.buildExecuteTransactionRequest({ + permit2Datas, + routerLogics, + tokensReturn, + value: funds.native?.amountWei ?? 0, + }); + + await expect(user.sendTransaction(transactionRequest)).to.not.be.reverted; + await expect(user.address).to.changeBalance(input.token, -input.amount); + await expect(agent).to.changeBalance(input.token, input.amount); + }); + }); +}); diff --git a/test/utils/router.ts b/test/utils/router.ts index 456e0489..81dd6f29 100644 --- a/test/utils/router.ts +++ b/test/utils/router.ts @@ -17,6 +17,26 @@ export function calcRequiredAmountByBalanceBps(input: common.TokenAmount, balanc } export async function getRouterPermit2Datas(chainId: number, user: SignerWithAddress, inputs: common.TokenAmounts) { + const permit2Datas: string[] = []; + if (!inputs.isEmpty) { + // 1. approve permit2 and get permit2 permit call data + const permit2DatasWithoutTransferFrom = await approvePermit2AndGetPermit2Datas(chainId, user, inputs); + permit2Datas.push(...permit2DatasWithoutTransferFrom); + + // 2. get permit2 transferFrom data + const router = new core.RouterKit(chainId, hre.ethers.provider); + const transferFromCallData = await router.encodePermit2TransferFrom(user.address, inputs); + permit2Datas.push(transferFromCallData); + } + + return permit2Datas; +} + +export async function approvePermit2AndGetPermit2Datas( + chainId: number, + user: SignerWithAddress, + inputs: common.TokenAmounts +) { const permit2Datas: string[] = []; if (!inputs.isEmpty) { const router = new core.RouterKit(chainId, hre.ethers.provider); @@ -32,10 +52,6 @@ export async function getRouterPermit2Datas(chainId: number, user: SignerWithAdd const permitCallData = router.encodePermit2Permit(user.address, permitData.values, permitSig); permit2Datas.push(permitCallData); } - - // 3. get permit2 transferFrom data - const transferFromCallData = await router.encodePermit2TransferFrom(user.address, inputs); - permit2Datas.push(transferFromCallData); } return permit2Datas;