@@ -11,26 +11,23 @@ import Web3Core
11
11
class ABIElementErrorDecodingTest : XCTestCase {
12
12
typealias EthError = ABI . Element . EthError
13
13
14
- /// Function with any parameters should be able to decode `require` and `revert` calls in soliditiy.
15
- /// Note: `require(expression)` and `revert()` without a message return 0 bytes thus we cannot guarantee
16
- /// that 0 bytes response will be interpreted correctly.
17
- private let emptyFunction = ABI . Element. Function ( name: " any " ,
18
- inputs: [ ] ,
19
- outputs: [ ] ,
20
- constant: false ,
21
- payable: false )
22
- private let oneOutputFunction = ABI . Element. Function ( name: " any " ,
23
- inputs: [ ] ,
24
- outputs: [ . init( name: " " , type: . bool) ] ,
25
- constant: false ,
26
- payable: false )
27
-
28
14
func testErrorRepresentation( ) {
29
15
XCTAssertEqual ( EthError ( name: " Error " , inputs: [ ] ) . errorDeclaration, " Error() " )
30
16
XCTAssertEqual ( EthError ( name: " Error " , inputs: [ . init( name: " " , type: . address) ] ) . errorDeclaration, " Error(address) " )
31
- XCTAssertEqual ( EthError ( name: " Error " , inputs: [ . init( name: " " , type: . address) ] ) . errorDeclaration, " Error(address) " )
32
- XCTAssertEqual ( EthError ( name: " Error " , inputs: [ . init( name: " " , type: . address) , . init( name: " " , type: . uint( bits: 256 ) ) ] ) . errorDeclaration, " Error(address,uint256) " )
33
- XCTAssertEqual ( EthError ( name: " Error " , inputs: [ . init( name: " sender " , type: . address) , . init( name: " " , type: . uint( bits: 256 ) ) ] ) . errorDeclaration, " Error(address sender,uint256) " )
17
+ XCTAssertEqual (
18
+ EthError ( name: " Error " , inputs: [ . init( name: " " , type: . address) ] ) . errorDeclaration,
19
+ " Error(address) "
20
+ )
21
+ XCTAssertEqual (
22
+ EthError ( name: " Error " , inputs: [ . init( name: " " , type: . address) , . init( name: " " , type: . uint( bits: 256 ) ) ] )
23
+ . errorDeclaration,
24
+ " Error(address,uint256) "
25
+ )
26
+ XCTAssertEqual (
27
+ EthError ( name: " Error " , inputs: [ . init( name: " sender " , type: . address) , . init( name: " " , type: . uint( bits: 256 ) ) ] )
28
+ . errorDeclaration,
29
+ " Error(address sender,uint256) "
30
+ )
34
31
// Not all types are supported in errors, e.g. tuples and functions are not supported
35
32
let allTypesNamedAndNot : [ ABI . Element . InOut ] = [
36
33
. init( name: " sender " , type: . address) ,
@@ -67,38 +64,43 @@ class ABIElementErrorDecodingTest: XCTestCase {
67
64
68
65
/// `require(expression)` and `revert()` without a message return 0 bytes,
69
66
/// we can noly catch an error when function has a return value
70
- func testDecodeEmptyErrorOnOneOutputFunction( ) throws {
71
- let contract = try EthereumContract ( abi: [ . function( emptyFunction) ] )
72
- do {
73
- try contract. decodeReturnData ( emptyFunction. signature, data: Data ( ) )
74
- } catch {
75
- XCTFail ( )
76
- }
77
-
78
- let contract2 = try EthereumContract ( abi: [ . function( oneOutputFunction) ] )
79
- do {
80
- try contract2. decodeReturnData ( oneOutputFunction. signature, data: Data ( ) )
81
- XCTFail ( )
82
- } catch {
83
- print ( error)
84
- }
85
- }
86
-
87
- /// Data is decoded as a call of `revert` or `require` with a message no matter the number of outputs configured in the ``ABI/Element/Function``.
88
- /// `revert(message)` and `require(false,message)`return at least 128 bytes. We cannot differentiate between `require` or `revert`.
67
+ // func testDecodeEmptyErrorOnOneOutputFunction() throws {
68
+ // let contract = try EthereumContract(abi: [.function(emptyFunction)])
69
+ // do {
70
+ // try contract.decodeReturnData(emptyFunction.signature, data: Data())
71
+ // } catch {
72
+ // XCTFail()
73
+ // }
74
+
75
+ // let contract2 = try EthereumContract(abi: [.function(oneOutputFunction)])
76
+ // do {
77
+ // try contract2.decodeReturnData(oneOutputFunction.signature, data: Data())
78
+ // XCTFail()
79
+ // } catch {
80
+ // print(error)
81
+ // }
82
+ // }
83
+
84
+ /// Data is decoded as a call of `revert` or `require` with a message no matter the number of outputs configured in the
85
+ /// ``ABI/Element/Function``.
86
+ /// `revert(message)` and `require(false,message)`return at least 128 bytes. We cannot differentiate between `require` or
87
+ /// `revert`.
89
88
func testDecodeDefaultErrorWithMessage( ) throws {
90
89
/// 08c379a0 - Error(string) function selector
91
90
/// 0000000000000000000000000000000000000000000000000000000000000020 - Data offset
92
91
/// 000000000000000000000000000000000000000000000000000000000000001a - Message length
93
92
/// 4e6f7420656e6f7567682045746865722070726f76696465642e000000000000 - Message + 0 bytes padding
94
93
/// 0000... - some more 0 bytes padding to make the number of bytes match 32 bytes chunks
95
- let errorResponse = Data . fromHex ( " 08c379a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001a4e6f7420656e6f7567682045746865722070726f76696465642e0000000000000000000000000000000000000000000000000000000000000000000000000000 " ) !
94
+ let errorResponse = Data
95
+ . fromHex (
96
+ " 08c379a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001a4e6f7420656e6f7567682045746865722070726f76696465642e0000000000000000000000000000000000000000000000000000000000000000000000000000 "
97
+ ) !
96
98
let contract = try EthereumContract ( abi: [ . function( emptyFunction) ] )
97
99
98
100
do {
99
101
try contract. decodeReturnData ( emptyFunction. signature, data: errorResponse)
100
102
XCTFail ( " decode function should throw an error " )
101
- } catch Web3Error . revert( _, let reason) {
103
+ } catch let Web3Error . revert( _, reason) {
102
104
XCTAssertEqual ( reason, " Not enough Ether provided. " )
103
105
}
104
106
@@ -111,12 +113,12 @@ class ABIElementErrorDecodingTest: XCTestCase {
111
113
/// 00000000000000000000000000000000000000000000000000000000 - padding bytes
112
114
let errorResponse = Data . fromHex ( " 82b429000000000000000000000000000000000000000000000000000000000000000000 " ) !
113
115
let error = ABI . Element. EthError ( name: " Unauthorized " , inputs: [ ] )
114
- let contract = try EthereumContract ( abi: [ . function( emptyFunction) , . error( error) ] )
116
+ let contract = try EthereumContract ( abi: [ . function( emptyFunction) , . error( error) ] )
115
117
116
118
do {
117
119
try contract. decodeReturnData ( emptyFunction. signature, data: errorResponse)
118
120
XCTFail ( " decode function should throw an error " )
119
- } catch Web3Error . revertCustom( let signature, let args) {
121
+ } catch let Web3Error . revertCustom( signature, args) {
120
122
XCTAssertEqual ( signature, " Unauthorized() " )
121
123
XCTAssertTrue ( args. isEmpty)
122
124
}
@@ -135,12 +137,12 @@ class ABIElementErrorDecodingTest: XCTestCase {
135
137
/// 00000000000000000000000000000000000000000000000000000000 - padding bytes
136
138
let errorResponse = Data . fromHex ( " 5caef9920000000000000000000000000000000000000000000000000000000000000000 " ) !
137
139
let error = ABI . Element. EthError ( name: " Unauthorized " , inputs: [ . init( name: " " , type: . bool) ] )
138
- let contract = try EthereumContract ( abi: [ . function( oneOutputFunction) , . error( error) ] )
140
+ let contract = try EthereumContract ( abi: [ . function( oneOutputFunction) , . error( error) ] )
139
141
140
142
do {
141
143
try contract. decodeReturnData ( oneOutputFunction. signature, data: errorResponse)
142
144
XCTFail ( " decode function should throw an error " )
143
- } catch Web3Error . revertCustom( let signature, let args) {
145
+ } catch let Web3Error . revertCustom( signature, args) {
144
146
XCTAssertEqual ( signature, " Unauthorized(bool) " )
145
147
XCTAssertEqual ( args [ " 0 " ] as? Bool , false )
146
148
}
@@ -160,14 +162,17 @@ class ABIElementErrorDecodingTest: XCTestCase {
160
162
/// 0000000000000000000000000000000000000000000000000000000000000006 - first custom argument length
161
163
/// 526561736f6e0000000000000000000000000000000000000000000000000000 - first custom argument bytes + 0 bytes padding
162
164
/// 0000... - some more 0 bytes padding to make the number of bytes match 32 bytes chunks
163
- let errorResponse = Data . fromHex ( " 973d02cb00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000006526561736f6e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 " ) !
165
+ let errorResponse = Data
166
+ . fromHex (
167
+ " 973d02cb00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000006526561736f6e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 "
168
+ ) !
164
169
let error = ABI . Element. EthError ( name: " Unauthorized " , inputs: [ . init( name: " message_arg " , type: . string) ] )
165
170
let contract = try EthereumContract ( abi: [ . function( emptyFunction) , . error( error) ] )
166
171
167
172
do {
168
173
try contract. decodeReturnData ( emptyFunction. signature, data: errorResponse)
169
174
XCTFail ( " decode function should throw an error " )
170
- } catch Web3Error . revertCustom( let signature, let args) {
175
+ } catch let Web3Error . revertCustom( signature, args) {
171
176
XCTAssertEqual ( signature, " Unauthorized(string) " )
172
177
XCTAssertEqual ( args [ " 0 " ] as? String , " Reason " )
173
178
XCTAssertEqual ( args [ " message_arg " ] as? String , " Reason " )
@@ -194,11 +199,25 @@ class ABIElementErrorDecodingTest: XCTestCase {
194
199
195
200
do {
196
201
try contract. decodeReturnData ( emptyFunction. signature, data: errorResponse)
197
- } catch Web3Error . revert( let message, let code) {
202
+ } catch let Web3Error . revert( message, code) {
198
203
XCTAssertTrue ( message. contains ( " reverted with panic code 0x01 " ) )
199
204
XCTAssertEqual ( code, " 0x01 " )
200
205
}
201
206
202
207
XCTAssertEqual ( EthError . decodePanicError ( errorResponse [ 4 ... ] ) , 1 )
203
208
}
209
+
210
+ /// Function with any parameters should be able to decode `require` and `revert` calls in soliditiy.
211
+ /// Note: `require(expression)` and `revert()` without a message return 0 bytes thus we cannot guarantee
212
+ /// that 0 bytes response will be interpreted correctly.
213
+ private let emptyFunction = ABI . Element. Function ( name: " any " ,
214
+ inputs: [ ] ,
215
+ outputs: [ ] ,
216
+ constant: false ,
217
+ payable: false )
218
+ private let oneOutputFunction = ABI . Element. Function ( name: " any " ,
219
+ inputs: [ ] ,
220
+ outputs: [ . init( name: " " , type: . bool) ] ,
221
+ constant: false ,
222
+ payable: false )
204
223
}
0 commit comments