@@ -47,13 +47,53 @@ describe("PrivateAirdrop", async () => {
47
47
48
48
// Collect
49
49
let keyHash = toHex ( pedersenHash ( key ) )
50
+
50
51
let execute = await (
51
52
await airdrop . connect ( redeemer ) . collectAirdrop ( callData , keyHash ) ) . wait ( )
52
53
expect ( execute . status ) . to . be . eq ( 1 )
53
54
let contractBalanceUpdated : BigNumber = await erc20 . balanceOf ( airdrop . address ) ;
54
55
expect ( contractBalanceUpdated . toNumber ( ) ) . to . be . eq ( contractBalanceInit . toNumber ( ) - NUM_ERC20_PER_REDEMPTION )
55
56
let redeemerBalance : BigNumber = await erc20 . balanceOf ( redeemer . address ) ;
56
57
expect ( redeemerBalance . toNumber ( ) ) . to . be . eq ( NUM_ERC20_PER_REDEMPTION )
58
+
59
+ } )
60
+
61
+ it ( "cannot exploit using public inputs larger than the scalar field" , async ( ) => {
62
+ // Deploy contracts
63
+ let hexRoot = toHex ( merkleTreeAndSource . merkleTree . root . val )
64
+ let [ universalOwnerSigner , erc20SupplyHolder , redeemer ] = await ethers . getSigners ( ) ;
65
+ let { erc20, verifier, airdrop} =
66
+ await deployContracts (
67
+ universalOwnerSigner ,
68
+ erc20SupplyHolder . address ,
69
+ hexRoot ) ;
70
+
71
+ // Transfer airdroppable tokens to contract
72
+ await erc20 . connect ( erc20SupplyHolder ) . transfer ( airdrop . address , NUM_ERC20_TO_DISTRIBUTE ) ;
73
+ let contractBalanceInit : BigNumber = await erc20 . balanceOf ( airdrop . address ) ;
74
+ expect ( contractBalanceInit . toNumber ( ) ) . to . be . eq ( NUM_ERC20_TO_DISTRIBUTE ) ;
75
+
76
+ let merkleTree = merkleTreeAndSource . merkleTree ;
77
+
78
+ // Generate proof
79
+ let leafIndex = 7 ;
80
+ let key = merkleTreeAndSource . leafNullifiers [ leafIndex ] ;
81
+ let secret = merkleTreeAndSource . leafSecrets [ leafIndex ] ;
82
+ let callData = await generateProofCallData ( merkleTree , key , secret , redeemer . address , WASM_BUFF , ZKEY_BUFF ) ;
83
+
84
+ // Collect
85
+ let keyHash = toHex ( pedersenHash ( key ) )
86
+ let keyHashTwo = toHex ( BigInt ( keyHash ) + BigInt ( '21888242871839275222246405745257275088548364400416034343698204186575808495617' ) )
87
+
88
+ let execute = await (
89
+ await airdrop . connect ( redeemer ) . collectAirdrop ( callData , keyHash ) ) . wait ( )
90
+ expect ( execute . status ) . to . be . eq ( 1 )
91
+ let contractBalanceUpdated : BigNumber = await erc20 . balanceOf ( airdrop . address ) ;
92
+ expect ( contractBalanceUpdated . toNumber ( ) ) . to . be . eq ( contractBalanceInit . toNumber ( ) - NUM_ERC20_PER_REDEMPTION )
93
+ let redeemerBalance : BigNumber = await erc20 . balanceOf ( redeemer . address ) ;
94
+ expect ( redeemerBalance . toNumber ( ) ) . to . be . eq ( NUM_ERC20_PER_REDEMPTION )
95
+ await expect ( airdrop . connect ( redeemer ) . collectAirdrop ( callData , keyHashTwo ) ) . to . be . revertedWith ( "Nullifier is not within the field" )
96
+
57
97
} )
58
98
59
99
it ( "cannot be front-run by another party" , async ( ) => {
@@ -176,4 +216,4 @@ async function deployContracts(
176
216
root
177
217
) ) as PrivateAirdrop
178
218
return { erc20, verifier, airdrop}
179
- }
219
+ }
0 commit comments