@@ -39,6 +39,8 @@ const FAUCET_DEPTH = 8;
3939
4040const TREE_LEAVES = AIRDROP_LEAVES + FAUCET_LEAVES ;
4141
42+ const MAX_PROOF_SIZE = 3000 ; // 2811
43+
4244/**
4345 * AirdropProof
4446 */
@@ -103,8 +105,23 @@ class AirdropProof extends bio.Struct {
103105 return bw ;
104106 }
105107
108+ decode ( data ) {
109+ const br = bio . read ( data ) ;
110+
111+ if ( data . length > MAX_PROOF_SIZE )
112+ throw new Error ( 'Proof too large.' ) ;
113+
114+ this . read ( br ) ;
115+
116+ if ( br . left ( ) !== 0 )
117+ throw new Error ( 'Trailing data.' ) ;
118+
119+ return this ;
120+ }
121+
106122 read ( br ) {
107123 this . index = br . readU32 ( ) ;
124+ assert ( this . index < AIRDROP_LEAVES ) ;
108125
109126 const count = br . readU8 ( ) ;
110127 assert ( count <= AIRDROP_DEPTH ) ;
@@ -115,6 +132,7 @@ class AirdropProof extends bio.Struct {
115132 }
116133
117134 this . subindex = br . readU8 ( ) ;
135+ assert ( this . subindex < AIRDROP_SUBLEAVES ) ;
118136
119137 const total = br . readU8 ( ) ;
120138 assert ( total <= AIRDROP_SUBDEPTH ) ;
@@ -304,7 +322,12 @@ class AirdropProof extends bio.Struct {
304322 if ( this . address . length < 2 || this . address . length > 40 )
305323 return false ;
306324
307- if ( this . fee > this . getValue ( ) )
325+ const value = this . getValue ( ) ;
326+
327+ if ( value < 0 || value > consensus . MAX_MONEY )
328+ return false ;
329+
330+ if ( this . fee < 0 || this . fee > value )
308331 return false ;
309332
310333 if ( this . isAddress ( ) ) {
@@ -335,6 +358,9 @@ class AirdropProof extends bio.Struct {
335358 if ( this . index >= AIRDROP_LEAVES )
336359 return false ;
337360
361+ if ( this . getSize ( ) > MAX_PROOF_SIZE )
362+ return false ;
363+
338364 return true ;
339365 }
340366
0 commit comments