@@ -213,17 +213,32 @@ def _try_fold(self, node):
213
213
214
214
elif isinstance (target_typedef , AddressT ):
215
215
if isinstance (value , vy_ast .Hex ):
216
- if len (value .value ) != 42 : # 0x + 40 hex chars
217
- raise InvalidLiteral ("Address must be exactly 20 bytes" , node .args [0 ])
218
- result = value .value
216
+ if not value .value .startswith ("0x" ):
217
+ raise InvalidLiteral ("Address must start with 0x" , node .args [0 ])
218
+ try :
219
+ addr_bytes = value .bytes_value
220
+ if len (addr_bytes ) != 20 :
221
+ raise InvalidLiteral ("Address must be exactly 20 bytes" , node .args [0 ])
222
+ result = value .value
223
+ except ValueError :
224
+ raise InvalidLiteral ("Invalid hex literal for address" , node .args [0 ])
225
+ elif isinstance (value , vy_ast .Int ):
226
+ # Convert integer to address (right-padded with zeros)
227
+ addr_bytes = value .value .to_bytes (32 , "big" )[- 20 :]
228
+ result = f"0x{ addr_bytes .hex ()} "
219
229
else :
220
230
raise UnfoldableNode
221
231
return vy_ast .Hex .from_node (node , value = result )
222
232
223
233
elif isinstance (target_typedef , IntegerT ):
224
- if not isinstance (value , (vy_ast .Int , vy_ast .Decimal )):
234
+ if isinstance (value , vy_ast .Decimal ):
235
+ if value .value % 1 != 0 :
236
+ raise InvalidLiteral ("Cannot truncate decimal when converting to integer" , node .args [0 ])
237
+ result = int (value .value )
238
+ elif isinstance (value , vy_ast .Int ):
239
+ result = value .value
240
+ else :
225
241
raise UnfoldableNode
226
- result = int (value .value )
227
242
lo , hi = target_typedef .ast_bounds
228
243
if result < lo or result > hi :
229
244
raise InvalidLiteral (
@@ -233,12 +248,30 @@ def _try_fold(self, node):
233
248
234
249
elif isinstance (target_typedef , BytesM_T ):
235
250
if isinstance (value , vy_ast .Hex ):
236
- if len (value .bytes_value ) != target_typedef .length :
251
+ if not value .value .startswith ("0x" ):
252
+ raise InvalidLiteral ("Bytes must start with 0x" , node .args [0 ])
253
+ try :
254
+ bytes_value = value .bytes_value
255
+ if len (bytes_value ) > target_typedef .length :
256
+ raise InvalidLiteral (
257
+ f"Bytes literal too long for { target_typedef } " , node .args [0 ]
258
+ )
259
+ # Left-pad with zeros if shorter than target length
260
+ if len (bytes_value ) < target_typedef .length :
261
+ bytes_value = bytes_value .rjust (target_typedef .length , b"\x00 " )
262
+ result = f"0x{ bytes_value .hex ()} "
263
+ except ValueError :
264
+ raise InvalidLiteral ("Invalid hex literal for bytes" , node .args [0 ])
265
+ elif isinstance (value , vy_ast .Bytes ):
266
+ bytes_value = value .value
267
+ if len (bytes_value ) > target_typedef .length :
237
268
raise InvalidLiteral (
238
- f"Expected { target_typedef .length } bytes, got { len (value .bytes_value )} " ,
239
- node .args [0 ]
269
+ f"Bytes literal too long for { target_typedef } " , node .args [0 ]
240
270
)
241
- result = value .value
271
+ # Left-pad with zeros if shorter than target length
272
+ if len (bytes_value ) < target_typedef .length :
273
+ bytes_value = bytes_value .rjust (target_typedef .length , b"\x00 " )
274
+ result = f"0x{ bytes_value .hex ()} "
242
275
else :
243
276
raise UnfoldableNode
244
277
return vy_ast .Hex .from_node (node , value = result )
@@ -247,15 +280,13 @@ def _try_fold(self, node):
247
280
248
281
def fetch_call_return (self , node ):
249
282
_ , target_typedef = self .infer_arg_types (node )
250
-
251
- # note: more type conversion validation happens in convert.py
252
283
return target_typedef .typedef
253
284
254
285
def infer_arg_types (self , node , expected_return_typ = None ):
255
286
self ._validate_arg_types (node )
256
287
possible = sorted (
257
288
get_possible_types_from_node (node .args [0 ]),
258
- key = lambda t : (t .typ , getattr (t , "bits" , 0 ))
289
+ key = lambda t : (str ( t .typ ) , getattr (t , "bits" , 0 ))
259
290
)
260
291
value_type = possible [0 ]
261
292
target_type = type_from_annotation (node .args [1 ])
@@ -419,7 +450,7 @@ def infer_arg_types(self, node, expected_return_typ=None):
419
450
self ._validate_arg_types (node )
420
451
possible = sorted (
421
452
get_possible_types_from_node (node .args [0 ]),
422
- key = lambda t : (t .typ , getattr (t , "bits" , 0 ))
453
+ key = lambda t : (str ( t .typ ) , getattr (t , "bits" , 0 ))
423
454
)
424
455
b_type = possible [0 ]
425
456
return [b_type , self ._inputs [1 ][1 ], self ._inputs [2 ][1 ]]
@@ -950,11 +981,15 @@ def _try_fold(self, node):
950
981
raise UnfoldableNode
951
982
952
983
if isinstance (output_type , BytesM_T ):
984
+ expected = output_type .length
985
+ if expected != 32 :
986
+ result = result [:expected ]
953
987
return vy_ast .Hex .from_node (node , value = f"0x{ result .hex ()} " )
954
988
elif isinstance (output_type , IntegerT ):
955
989
return vy_ast .Int .from_node (node , value = int .from_bytes (result , "big" ))
956
990
elif isinstance (output_type , AddressT ):
957
- return vy_ast .Hex .from_node (node , value = f"0x{ result .hex ()} " )
991
+ # right-align as per ABI: take the last 20 bytes
992
+ return vy_ast .Hex .from_node (node , value = f"0x{ result [- 20 :].hex ()} " )
958
993
else :
959
994
raise UnfoldableNode
960
995
@@ -967,7 +1002,7 @@ def infer_arg_types(self, node, expected_return_typ=None):
967
1002
self ._validate_arg_types (node )
968
1003
possible = sorted (
969
1004
get_possible_types_from_node (node .args [0 ]),
970
- key = lambda t : (t .typ , getattr (t , "bits" , 0 ))
1005
+ key = lambda t : (str ( t .typ ) , getattr (t , "bits" , 0 ))
971
1006
)
972
1007
input_type = possible [0 ]
973
1008
return [input_type , UINT256_T ]
0 commit comments