@@ -149,7 +149,7 @@ class ValueOutOfBounds(EncodingError):
149
149
def decint (n ):
150
150
if isinstance (n , str ):
151
151
n = utils .to_string (n )
152
- if is_numeric (n ) and n < 2 ** 256 and n > - 2 ** 255 :
152
+ if is_numeric (n ) and n < 2 ** 256 and n >= - 2 ** 255 :
153
153
return n
154
154
elif is_numeric (n ):
155
155
raise EncodingError ("Number out of range: %r" % n )
@@ -186,21 +186,22 @@ def encode_single(typ, arg):
186
186
elif base == 'int' :
187
187
sub = int (sub )
188
188
i = decint (arg )
189
- if not - 2 ** (sub - 1 ) <= i < 2 ** sub :
189
+ if not - 2 ** (sub - 1 ) <= i < 2 ** ( sub - 1 ) :
190
190
raise ValueOutOfBounds (repr (arg ))
191
191
return zpad (encode_int (i % 2 ** sub ), 32 )
192
192
# Unsigned reals: ureal<high>x<low>
193
193
elif base == 'ureal' :
194
194
high , low = [int (x ) for x in sub .split ('x' )]
195
195
if not 0 <= arg < 2 ** high :
196
196
raise ValueOutOfBounds (repr (arg ))
197
- return zpad (encode_int (arg * 2 ** low ), 32 )
197
+ return zpad (encode_int (int ( arg * 2 ** low ) ), 32 )
198
198
# Signed reals: real<high>x<low>
199
199
elif base == 'real' :
200
200
high , low = [int (x ) for x in sub .split ('x' )]
201
201
if not - 2 ** (high - 1 ) <= arg < 2 ** (high - 1 ):
202
202
raise ValueOutOfBounds (repr (arg ))
203
- return zpad (encode_int ((arg % 2 ** high ) * 2 ** low ), 32 )
203
+ i = int (arg * 2 ** low )
204
+ return zpad (encode_int (i % 2 ** (high + low )), 32 )
204
205
# Strings
205
206
elif base == 'string' or base == 'bytes' :
206
207
if not is_string (arg ):
@@ -221,9 +222,9 @@ def encode_single(typ, arg):
221
222
raise EncodingError ("too long: %r" % arg )
222
223
if isnumeric (arg ):
223
224
return zpad (encode_int (arg ), 32 )
224
- elif len (arg ) == len (sub ):
225
+ elif len (arg ) == int (sub ):
225
226
return zpad (arg , 32 )
226
- elif len (arg ) == len (sub ) * 2 :
227
+ elif len (arg ) == int (sub ) * 2 :
227
228
return zpad (decode_hex (arg ), 32 )
228
229
else :
229
230
raise EncodingError ("Could not parse hash: %r" % arg )
@@ -236,7 +237,7 @@ def encode_single(typ, arg):
236
237
return zpad (arg , 32 )
237
238
elif len (arg ) == 40 :
238
239
return zpad (decode_hex (arg ), 32 )
239
- elif len (arg ) == 42 and arg [2 : ] == '0x' :
240
+ elif len (arg ) == 42 and arg [: 2 ] == '0x' :
240
241
return zpad (decode_hex (arg [2 :]), 32 )
241
242
else :
242
243
raise EncodingError ("Could not parse address: %r" % arg )
@@ -255,6 +256,8 @@ def process_type(typ):
255
256
if base == 'string' or base == 'bytes' :
256
257
assert re .match ('^[0-9]*$' , sub ), \
257
258
"String type must have no suffix or numerical suffix"
259
+ assert not sub or int (sub ) <= 32 , \
260
+ "Maximum 32 bytes for fixed-length str or bytes"
258
261
# Check validity of integer type
259
262
elif base == 'uint' or base == 'int' :
260
263
assert re .match ('^[0-9]+$' , sub ), \
@@ -263,12 +266,6 @@ def process_type(typ):
263
266
"Integer size out of bounds"
264
267
assert int (sub ) % 8 == 0 , \
265
268
"Integer size must be multiple of 8"
266
- # Check validity of string type
267
- if base == 'string' or base == 'bytes' :
268
- assert re .match ('^[0-9]*$' , sub ), \
269
- "String type must have no suffix or numerical suffix"
270
- assert not sub or int (sub ) <= 32 , \
271
- "Maximum 32 bytes for fixed-length str or bytes"
272
269
# Check validity of real type
273
270
elif base == 'ureal' or base == 'real' :
274
271
assert re .match ('^[0-9]+x[0-9]+$' , sub ), \
@@ -375,8 +372,14 @@ def decode_single(typ, data):
375
372
base , sub , _ = typ
376
373
if base == 'address' :
377
374
return encode_hex (data [12 :])
378
- elif base == 'string' or base == 'bytes' or base == 'hash' :
379
- return data [:int (sub )] if len (sub ) else data
375
+ elif base == 'hash' :
376
+ return data [32 - int (sub ):]
377
+ elif base == 'string' or base == 'bytes' :
378
+ if len (sub ):
379
+ return data [:int (sub )]
380
+ else :
381
+ l = big_endian_to_int (data [0 :32 ])
382
+ return data [32 :][:l ]
380
383
elif base == 'uint' :
381
384
return big_endian_to_int (data )
382
385
elif base == 'int' :
@@ -387,7 +390,9 @@ def decode_single(typ, data):
387
390
return big_endian_to_int (data ) * 1.0 / 2 ** low
388
391
elif base == 'real' :
389
392
high , low = [int (x ) for x in sub .split ('x' )]
390
- return (big_endian_to_int (data ) * 1.0 / 2 ** low ) % 2 ** high
393
+ o = big_endian_to_int (data )
394
+ i = (o - 2 ** (high + low )) if o >= 2 ** (high + low - 1 ) else o
395
+ return (i * 1.0 / 2 ** low )
391
396
elif base == 'bool' :
392
397
return bool (int (data .encode ('hex' ), 16 ))
393
398
0 commit comments