or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

access-control.mdaccount-abstraction.mdfinance.mdgovernance.mdindex.mdmathematical-utilities.mdmeta-transactions.mdproxy-patterns.mdsecurity-utilities.mdtoken-standards.md

meta-transactions.mddocs/

0

# Meta-transactions

1

2

ERC-2771 gasless transactions enabling users to interact with contracts without paying gas fees directly.

3

4

## Capabilities

5

6

### ERC2771 Context

7

8

Context implementation for contracts that support meta-transactions through trusted forwarders.

9

10

```solidity { .api }

11

/**

12

* Context variant that supports meta-transactions via ERC-2771

13

*/

14

abstract contract ERC2771Context is Context {

15

constructor(address trustedForwarder);

16

function isTrustedForwarder(address forwarder) public view virtual returns (bool);

17

function trustedForwarder() public view virtual returns (address);

18

function _msgSender() internal view virtual override returns (address);

19

function _msgData() internal view virtual override returns (bytes calldata);

20

function _contextSuffixLength() internal view virtual override returns (uint256);

21

}

22

```

23

24

**Usage Examples:**

25

26

```solidity

27

import "@openzeppelin/contracts/metatx/ERC2771Context.sol";

28

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

29

30

contract MyTokenWithMetaTx is ERC20, ERC2771Context {

31

constructor(address trustedForwarder)

32

ERC20("MyToken", "MTK")

33

ERC2771Context(trustedForwarder)

34

{}

35

36

function _msgSender() internal view override(Context, ERC2771Context) returns (address) {

37

return ERC2771Context._msgSender();

38

}

39

40

function _msgData() internal view override(Context, ERC2771Context) returns (bytes calldata) {

41

return ERC2771Context._msgData();

42

}

43

44

function _contextSuffixLength() internal view override(Context, ERC2771Context) returns (uint256) {

45

return ERC2771Context._contextSuffixLength();

46

}

47

}

48

```

49

50

### ERC2771 Forwarder

51

52

Trusted forwarder contract that validates signatures and executes meta-transactions.

53

54

```solidity { .api }

55

/**

56

* ERC-2771 compliant forwarder for executing meta-transactions

57

*/

58

contract ERC2771Forwarder is ERC165, EIP712, Nonces, IERC2771Forwarder {

59

constructor(string memory name);

60

function verify(ForwardRequestData calldata request) public view virtual returns (bool);

61

function execute(ForwardRequestData calldata request) public payable virtual returns (bool success, bytes memory returndata);

62

function executeBatch(ForwardRequestData[] calldata requests, address payable refundReceiver) public payable virtual;

63

function getNonce(address from) public view virtual override returns (uint256);

64

function nonces(address owner) public view virtual override returns (uint256);

65

}

66

```

67

68

**Advanced Functions:**

69

70

```solidity { .api }

71

// ERC2771Forwarder additional capabilities

72

contract ERC2771Forwarder {

73

function verifyAndExecute(ForwardRequestData calldata request, bytes calldata signature) external payable returns (bool success, bytes memory returndata);

74

function verifyAndExecuteBatch(ForwardRequestData[] calldata requests, bytes[] calldata signatures, address payable refundReceiver) external payable;

75

function aggregate(ForwardRequestData[] calldata requests, bytes[] calldata signatures) external payable returns (bool[] memory successes, bytes[] memory results);

76

function simulateExecute(ForwardRequestData calldata request, bytes calldata signature) external view returns (bool success, bytes memory returndata, uint256 gasUsed);

77

function estimateGas(ForwardRequestData calldata request, bytes calldata signature) external view returns (uint256 gasUsed);

78

}

79

```

80

81

**Usage Examples:**

82

83

```solidity

84

import "@openzeppelin/contracts/metatx/ERC2771Forwarder.sol";

85

86

// Deploy forwarder

87

ERC2771Forwarder forwarder = new ERC2771Forwarder("MyForwarder");

88

89

// Create forward request

90

ForwardRequestData memory request = ForwardRequestData({

91

from: user,

92

to: target,

93

value: 0,

94

gas: 100000,

95

nonce: forwarder.getNonce(user),

96

deadline: block.timestamp + 3600,

97

data: abi.encodeCall(MyContract.someFunction, (param1, param2))

98

});

99

100

// Execute meta-transaction

101

forwarder.execute(request);

102

```

103

104

### Meta-transaction Utilities

105

106

Utilities for managing meta-transaction signatures and validation.

107

108

```solidity { .api }

109

/**

110

* Meta-transaction signature utilities

111

*/

112

library MetaTxUtils {

113

function recoverSigner(ForwardRequestData calldata request, bytes calldata signature, bytes32 domainSeparator) internal pure returns (address);

114

function hashRequest(ForwardRequestData calldata request) internal pure returns (bytes32);

115

function validateSignature(ForwardRequestData calldata request, bytes calldata signature, bytes32 domainSeparator) internal view returns (bool);

116

function validateNonce(address from, uint256 nonce, mapping(address => uint256) storage nonces) internal view returns (bool);

117

}

118

```

119

120

## Types

121

122

```solidity { .api }

123

/**

124

* Forward request data structure for ERC-2771

125

*/

126

struct ForwardRequestData {

127

address from;

128

address to;

129

uint256 value;

130

uint256 gas;

131

uint48 deadline;

132

bytes data;

133

bytes signature;

134

}

135

136

/**

137

* Batch forward request for multiple transactions

138

*/

139

struct BatchForwardRequest {

140

ForwardRequestData[] requests;

141

bytes[] signatures;

142

address payable refundReceiver;

143

}

144

145

/**

146

* ERC-2771 Forwarder interface

147

*/

148

interface IERC2771Forwarder {

149

function verify(ForwardRequestData calldata request) external view returns (bool);

150

function execute(ForwardRequestData calldata request) external payable returns (bool success, bytes memory returndata);

151

function executeBatch(ForwardRequestData[] calldata requests, address payable refundReceiver) external payable;

152

function getNonce(address from) external view returns (uint256);

153

}

154

155

/**

156

* Meta-transaction events

157

*/

158

event ForwardedRequest(address indexed from, address indexed to, bool success, bytes returndata);

159

event BatchForwardedRequest(uint256 indexed batchId, address indexed refundReceiver);

160

161

/**

162

* Meta-transaction errors

163

*/

164

error ERC2771ForwarderInvalidSigner(address signer, address from);

165

error ERC2771ForwarderExpiredRequest(uint48 deadline);

166

error ERC2771ForwarderInvalidRequest(string reason);

167

error ERC2771ForwarderMismatchedValue(uint256 requestValue, uint256 msgValue);

168

error ERC2771ForwarderInvalidNonce(address from, uint256 nonce, uint256 currentNonce);

169

```