diff --git a/circuits/prover/src/pool/ffi.rs b/circuits/prover/src/pool/ffi.rs index 5afe466..c496534 100644 --- a/circuits/prover/src/pool/ffi.rs +++ b/circuits/prover/src/pool/ffi.rs @@ -683,6 +683,10 @@ mod end_to_end { "sig_s": sig_s, "anchor_pk_x": fr_hex(&anchor.pk.x), "anchor_pk_y": fr_hex(&anchor.pk.y), + // Explicit rather than relying on serde's default: this test exists to prove a phone's + // proof is accepted on-chain, and the contract supplies this value itself. Letting the + // default fill it would still pass while testing a different statement. + "min_kyc_level": credential::MIN_KYC_LEVEL, "current_time": 1_700_000_000u64, }) .to_string(); @@ -712,8 +716,10 @@ mod end_to_end { fr_from_hex(result["enc1_rho"].as_str().unwrap()).unwrap(), fr_from_hex(result["enc2_amount"].as_str().unwrap()).unwrap(), fr_from_hex(result["enc2_rho"].as_str().unwrap()).unwrap(), + // Appended last, matching the circuit's allocation order and the contract's IC layout. + Fr::from(credential::MIN_KYC_LEVEL), ]; - assert_eq!(public.len(), 15, "spend has 15 public inputs"); + assert_eq!(public.len(), 16, "spend has 16 public inputs"); // The blob above is in Soroban's encoding, which the contract parses. Verifying here uses // the arkworks form of the same statement, rebuilt from the identical witness. @@ -771,6 +777,7 @@ mod end_to_end { &cred, point(&arg.anchor_pk_x, &arg.anchor_pk_y).unwrap(), arg.current_time, + arg.min_kyc_level, ); Groth16::::prove(spend_key(), circuit, &mut OsRng).unwrap() } diff --git a/circuits/prover/src/pool/spend.rs b/circuits/prover/src/pool/spend.rs index c01ba90..48b02de 100644 --- a/circuits/prover/src/pool/spend.rs +++ b/circuits/prover/src/pool/spend.rs @@ -275,7 +275,8 @@ impl ConstraintSynthesizer for SpendCircuit { // every proof fails verification with nothing to indicate why. let min_kyc_level = FpVar::new_input(cs.clone(), || { Ok(Fr::from( - self.min_kyc_level.ok_or(SynthesisError::AssignmentMissing)?, + self.min_kyc_level + .ok_or(SynthesisError::AssignmentMissing)?, )) })?; diff --git a/circuits/prover/tests/pool_circuits.rs b/circuits/prover/tests/pool_circuits.rs index c22654c..a034fab 100644 --- a/circuits/prover/tests/pool_circuits.rs +++ b/circuits/prover/tests/pool_circuits.rs @@ -273,9 +273,16 @@ fn report_circuit_sizes() { ("shield", { let cs = ConstraintSystem::::new_ref(); let s = Scenario::new(71, 1000); - ShieldCircuit::new(s.cfg.clone(), 1000, s.owner_pk, s.rho, s.enc.pk, JubjubFr::from(7u64)) - .generate_constraints(cs.clone()) - .unwrap(); + ShieldCircuit::new( + s.cfg.clone(), + 1000, + s.owner_pk, + s.rho, + s.enc.pk, + JubjubFr::from(7u64), + ) + .generate_constraints(cs.clone()) + .unwrap(); cs }), ] { diff --git a/contracts/pool/src/test.rs b/contracts/pool/src/test.rs index c6e6a6a..bac20de 100644 --- a/contracts/pool/src/test.rs +++ b/contracts/pool/src/test.rs @@ -915,7 +915,13 @@ fn initialize_is_one_shot() { let z = BytesN::from_array(&f.env, &[0u8; 32]); let err = f .pool - .try_initialize(&f.admin, &f.pool.address, &z, &z, &crate::DEFAULT_MIN_KYC_LEVEL) + .try_initialize( + &f.admin, + &f.pool.address, + &z, + &z, + &crate::DEFAULT_MIN_KYC_LEVEL, + ) .expect_err("re-initialising would let the token or anchor be swapped"); assert_eq!(err, Ok(Error::AlreadyInitialized)); }