11// Copyright 2023-, Semiotic AI, Inc.
22// SPDX-License-Identifier: Apache-2.0
33
4- use std:: collections:: hash_set;
4+ use std:: collections:: { hash_set, HashSet } ;
55
66use alloy_primitives:: Address ;
7- use alloy_sol_types:: Eip712Domain ;
8- use anyhow:: { Ok , Result } ;
7+ use alloy_sol_types:: { Eip712Domain , SolStruct } ;
8+ use anyhow:: { bail , Ok , Result } ;
99use ethers_core:: types:: Signature ;
10- use ethers_signers:: { LocalWallet , Signer } ;
10+ use ethers_signers:: LocalWallet ;
1111
1212use tap_core:: {
1313 eip_712_signed_message:: EIP712SignedMessage ,
@@ -19,22 +19,26 @@ pub async fn check_and_aggregate_receipts(
1919 receipts : & [ EIP712SignedMessage < Receipt > ] ,
2020 previous_rav : Option < EIP712SignedMessage < ReceiptAggregateVoucher > > ,
2121 wallet : & LocalWallet ,
22+ accepted_addresses : & HashSet < Address > ,
2223) -> Result < EIP712SignedMessage < ReceiptAggregateVoucher > > {
23- // Get the address of the wallet
24- let address: [ u8 ; 20 ] = wallet. address ( ) . into ( ) ;
25- let address: Address = address. into ( ) ;
26-
27- // Check that the receipts are unique
2824 check_signatures_unique ( receipts) ?;
2925
30- // Check that the receipts are signed by ourselves
31- receipts
32- . iter ( )
33- . try_for_each ( |receipt| receipt. verify ( domain_separator, address) ) ?;
26+ // Check that the receipts are signed by an accepted signer address
27+ receipts. iter ( ) . try_for_each ( |receipt| {
28+ check_signature_is_from_one_of_addresses (
29+ receipt. clone ( ) ,
30+ domain_separator,
31+ accepted_addresses,
32+ )
33+ } ) ?;
3434
35- // Check that the previous rav is signed by ourselves
35+ // Check that the previous rav is signed by an accepted signer address
3636 if let Some ( previous_rav) = & previous_rav {
37- previous_rav. verify ( domain_separator, address) ?;
37+ check_signature_is_from_one_of_addresses (
38+ previous_rav. clone ( ) ,
39+ domain_separator,
40+ accepted_addresses,
41+ ) ?;
3842 }
3943
4044 // Check that the receipts timestamp is greater than the previous rav
@@ -68,6 +72,20 @@ pub async fn check_and_aggregate_receipts(
6872 Ok ( EIP712SignedMessage :: new ( domain_separator, rav, wallet) . await ?)
6973}
7074
75+ fn check_signature_is_from_one_of_addresses < M : SolStruct > (
76+ message : EIP712SignedMessage < M > ,
77+ domain_separator : & Eip712Domain ,
78+ accepted_addresses : & HashSet < Address > ,
79+ ) -> Result < ( ) > {
80+ let recovered_address = message. recover_signer ( domain_separator) ?;
81+ if !accepted_addresses. contains ( & recovered_address) {
82+ bail ! ( tap_core:: Error :: InvalidRecoveredSigner {
83+ address: recovered_address,
84+ } ) ;
85+ }
86+ Ok ( ( ) )
87+ }
88+
7189fn check_allocation_id (
7290 receipts : & [ EIP712SignedMessage < Receipt > ] ,
7391 allocation_id : Address ,
0 commit comments