Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
37ng committed Apr 5, 2024
1 parent 5fb27e0 commit aed4a46
Showing 1 changed file with 34 additions and 33 deletions.
67 changes: 34 additions & 33 deletions xmtp_id/src/erc1271_verifier.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use anyhow::Error;
use ethers::contract::abigen;
use ethers::providers::{Http, Middleware, Provider};
use ethers::providers::{Http, Provider};
use ethers::types::{Address, BlockNumber, Bytes};
use std::convert::TryFrom;
use std::sync::Arc;
Expand Down Expand Up @@ -32,18 +32,18 @@ impl ERC1271Verifier {
/// * `wallet_address` - Address of the ERC1271 wallet.
/// * `block_number` - Block number to verify the signature at.
/// * `hash`, `signature` - Inputs to ERC-1271, used for signer verification.
pub async fn is_valid_signature<M: Middleware>(
pub async fn is_valid_signature(
&self,
wallet_address: Address,
block_number: BlockNumber,
block_number: Option<BlockNumber>,
hash: [u8; 32],
signature: Bytes,
) -> Result<bool, Error> {
let erc1271 = ERC1271::new(wallet_address, self.provider.clone());

let res: [u8; 4] = erc1271
.is_valid_signature(hash, signature)
.block(block_number)
.block(block_number.unwrap_or_default())
.call()
.await?
.into();
Expand All @@ -56,18 +56,16 @@ impl ERC1271Verifier {
mod tests {
use super::*;
use ethers::{
abi::{self, encode, Token},
abi::{self, Token},
providers::{Http, Middleware, Provider},
types::{Bytes, H256, U256},
utils::AnvilInstance,
};

use ethers::{
core::utils::Anvil,
middleware::SignerMiddleware,
signers::{LocalWallet, Signer as _},
};
use futures::Future;
use std::{convert::TryFrom, sync::Arc};

abigen!(
Expand All @@ -84,9 +82,7 @@ mod tests {

#[tokio::test]
async fn test_coinbase_smart_wallet() {
let anvil = Anvil::new()
.args(vec!["--base-fee", "100"])
.spawn();
let anvil = Anvil::new().args(vec!["--base-fee", "100"]).spawn();
let owner0: LocalWallet = anvil.keys()[1].clone().into();
let owner1: LocalWallet = anvil.keys()[2].clone().into();
let owners = vec![
Expand Down Expand Up @@ -128,48 +124,52 @@ mod tests {
let replay_safe_hash = smart_wallet.replay_safe_hash(hash).call().await.unwrap();
// owner 0
let sig0 = owner0.sign_hash(replay_safe_hash.into()).unwrap();
let res = smart_wallet

let res = verifier
.is_valid_signature(
smart_wallet_address,
None,
hash,
abi::encode(&[Token::Tuple(vec![
Token::Uint(U256::from(0)),
Token::Bytes(sig0.to_vec()),
])])
.into(),
)
.call()
.await
.unwrap();
assert_eq!(res, EIP1271_MAGIC_VALUE);
assert_eq!(res, true);
// owner1
let sig1 = owner1.sign_hash(replay_safe_hash.into()).unwrap();
let res = smart_wallet
let res = verifier
.is_valid_signature(
smart_wallet_address,
None,
hash,
encode(&[Token::Tuple(vec![
Token::Uint(1.into()),
abi::encode(&[Token::Tuple(vec![
Token::Uint(U256::from(1)),
Token::Bytes(sig1.to_vec()),
])])
.into(),
)
.call()
.await
.unwrap();
assert_eq!(res, EIP1271_MAGIC_VALUE);
// owner0 siganture won't be seen valid as from owner 1
let res = smart_wallet
assert_eq!(res, true);
// owner0 siganture won't be deemed as signed by owner1
let res = verifier
.is_valid_signature(
smart_wallet_address,
None,
hash,
abi::encode(&[Token::Tuple(vec![
Token::Uint(U256::from(1)),
Token::Bytes(sig0.to_vec()),
])])
.into(),
)
.call()
.await
.unwrap();
assert_ne!(res, EIP1271_MAGIC_VALUE);
assert_eq!(res, false);

// get block number before removing
let block_number = provider.get_block_number().await.unwrap();
Expand All @@ -179,33 +179,34 @@ mod tests {
let pending_tx = tx.send().await.unwrap();
let _ = pending_tx.await.unwrap();

let res = smart_wallet
let res = verifier
.is_valid_signature(
smart_wallet_address,
None,
hash,
encode(&[Token::Tuple(vec![
Token::Uint(1.into()),
abi::encode(&[Token::Tuple(vec![
Token::Uint(U256::from(1)),
Token::Bytes(sig1.to_vec()),
])])
.into(),
)
.call()
.await;
assert!(res.is_err());
assert!(res.is_err()); // when verify a non-existing owner, it errors

// use pre-removal block number to verify owner1 signature
let res = smart_wallet
let res = verifier
.is_valid_signature(
smart_wallet_address,
Some(BlockNumber::Number(block_number)),
hash,
encode(&[Token::Tuple(vec![
Token::Uint(1.into()),
abi::encode(&[Token::Tuple(vec![
Token::Uint(U256::from(1)),
Token::Bytes(sig1.to_vec()),
])])
.into(),
)
.block(block_number)
.call()
.await
.unwrap();
assert_eq!(res, EIP1271_MAGIC_VALUE);
assert_eq!(res, true);
}
}

0 comments on commit aed4a46

Please sign in to comment.