|  | @@ -108,10 +108,17 @@ impl Mint {
 | 
	
		
			
				|  |  |              return Err(Error::Amount);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        let mut secrets = Vec::with_capacity(split_request.proofs.len());
 | 
	
		
			
				|  |  | -        for proof in &split_request.proofs {
 | 
	
		
			
				|  |  | -            secrets.push(self.verify_proof(proof)?);
 | 
	
		
			
				|  |  | -            self.spent_secrets.insert(proof.secret.clone());
 | 
	
		
			
				|  |  | +        let proof_count = split_request.proofs.len();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        let secrets: HashSet<String> = split_request.proofs.into_iter().map(|p| p.secret).collect();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // Check that there are no duplicate proofs in request
 | 
	
		
			
				|  |  | +        if secrets.len().ne(&proof_count) {
 | 
	
		
			
				|  |  | +            return Err(Error::DuplicateProofs);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        for secret in secrets {
 | 
	
		
			
				|  |  | +            self.spent_secrets.insert(secret);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          match &split_request.amount {
 | 
	
	
		
			
				|  | @@ -146,7 +153,7 @@ impl Mint {
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    pub fn verify_proof(&self, proof: &Proof) -> Result<String, Error> {
 | 
	
		
			
				|  |  | +    pub fn verify_proof(&self, proof: &Proof) -> Result<(), Error> {
 | 
	
		
			
				|  |  |          if self.spent_secrets.contains(&proof.secret) {
 | 
	
		
			
				|  |  |              return Err(Error::TokenSpent);
 | 
	
		
			
				|  |  |          }
 | 
	
	
		
			
				|  | @@ -172,7 +179,7 @@ impl Mint {
 | 
	
		
			
				|  |  |              &proof.secret,
 | 
	
		
			
				|  |  |          )?;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        Ok(proof.secret.clone())
 | 
	
		
			
				|  |  | +        Ok(())
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      pub fn check_spendable(
 | 
	
	
		
			
				|  | @@ -202,9 +209,15 @@ impl Mint {
 | 
	
		
			
				|  |  |              return Err(Error::Amount);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        let mut secrets = Vec::with_capacity(melt_request.proofs.len());
 | 
	
		
			
				|  |  | -        for proof in &melt_request.proofs {
 | 
	
		
			
				|  |  | -            secrets.push(self.verify_proof(proof)?);
 | 
	
		
			
				|  |  | +        let secrets: HashSet<&str> = melt_request
 | 
	
		
			
				|  |  | +            .proofs
 | 
	
		
			
				|  |  | +            .iter()
 | 
	
		
			
				|  |  | +            .map(|p| p.secret.as_str())
 | 
	
		
			
				|  |  | +            .collect();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // Ensure proofs are unique and not being double spent
 | 
	
		
			
				|  |  | +        if melt_request.proofs.len().ne(&secrets.len()) {
 | 
	
		
			
				|  |  | +            return Err(Error::DuplicateProofs);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          Ok(())
 |