Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add rules for existing premints #31

Merged
merged 7 commits into from
Apr 17, 2024
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion src/controller.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,9 +172,22 @@ impl Controller {
}

async fn validate_and_insert(&self, premint: PremintTypes) -> eyre::Result<()> {
let metadata = premint.metadata();
let existing = match self
.store
.get_for_id_and_kind(&metadata.id, metadata.kind)
.await
{
Ok(existing) => Some(existing),
Err(report) => match report.downcast_ref::<sqlx::Error>() {
Some(sqlx::Error::RowNotFound) => None,
_ => return Err(report),
},
};

let evaluation = self
.rules
.evaluate(premint.clone(), RuleContext::new(self.store.clone()))
.evaluate(&premint, &RuleContext::new(self.store.clone(), existing))
.await;

if evaluation.is_accept() {
Expand Down
75 changes: 52 additions & 23 deletions src/premints/zora_premint_v2/rules.rs
Original file line number Diff line number Diff line change
@@ -1,34 +1,23 @@
use std::str::FromStr;

use alloy_primitives::Signature;
use alloy_sol_macro::sol;
use alloy_sol_types::SolStruct;

use crate::chain::contract_call;
use crate::chain_list::CHAINS;
use crate::premints::zora_premint_v2::types::ZoraPremintV2;
use crate::premints::zora_premint_v2::types::{IZoraPremintV2, ZoraPremintV2};
use crate::rules::Evaluation::{Accept, Reject};
use crate::rules::{Evaluation, Rule, RuleContext};
use crate::typed_rule;
use crate::types::{Premint, PremintTypes};

sol! {
contract PremintExecutor {
function isAuthorizedToCreatePremint(
address signer,
address premintContractConfigContractAdmin,
address contractAddress
) external view returns (bool isAuthorized);
}
}
use crate::types::PremintTypes;

// create premint v2 rule implementations here

pub async fn is_authorized_to_create_premint(
premint: ZoraPremintV2,
_context: RuleContext,
premint: &ZoraPremintV2,
_context: &RuleContext,
) -> eyre::Result<Evaluation> {
let call = PremintExecutor::isAuthorizedToCreatePremintCall {
let call = IZoraPremintV2::isAuthorizedToCreatePremintCall {
contractAddress: premint.collection_address,
signer: premint.collection.contractAdmin,
premintContractConfigContractAdmin: premint.collection.contractAdmin,
Expand All @@ -43,13 +32,50 @@ pub async fn is_authorized_to_create_premint(
}
}

pub async fn not_minted(
premint: &ZoraPremintV2,
_context: &RuleContext,
) -> eyre::Result<Evaluation> {
let call = IZoraPremintV2::premintStatusCall {
contractAddress: premint.collection_address,
uid: premint.premint.uid,
};

let provider = CHAINS.get_rpc(premint.chain_id).await?;
let result = contract_call(call, provider).await?;

match result.contractCreated && !result.tokenIdForPremint.is_zero() {
false => Ok(Accept),
true => Ok(Reject("Premint already minted".to_string())),
}
}
ligustah marked this conversation as resolved.
Show resolved Hide resolved

pub async fn premint_version_supported(
premint: &ZoraPremintV2,
_context: &RuleContext,
) -> eyre::Result<Evaluation> {
let call = IZoraPremintV2::supportedPremintSignatureVersionsCall {
contractAddress: premint.collection_address,
};
ligustah marked this conversation as resolved.
Show resolved Hide resolved

let provider = CHAINS.get_rpc(premint.chain_id).await?;
let result = contract_call(call, provider).await?;

match result.versions.contains(&"2".to_string()) {
true => Ok(Accept),
false => Ok(Reject(
"Premint version 2 not supported by contract".to_string(),
)),
}
}

// * signatureIsValid ( this can be performed entirely offline )
// * check if the signature is valid
// * check if the signature is equal to the proposed contract admin

pub async fn is_valid_signature(
premint: ZoraPremintV2,
_context: RuleContext,
premint: &ZoraPremintV2,
_context: &RuleContext,
) -> eyre::Result<Evaluation> {
// * if contract exists, check if the signer is the contract admin
// * if contract does not exist, check if the signer is the proposed contract admin
Expand All @@ -71,8 +97,8 @@ pub async fn is_valid_signature(
}

async fn is_chain_supported(
premint: ZoraPremintV2,
_context: RuleContext,
premint: &ZoraPremintV2,
_context: &RuleContext,
) -> eyre::Result<Evaluation> {
let supported_chains: Vec<u64> = vec![7777777, 999999999, 8453];
let chain_id = premint.chain_id;
Expand All @@ -88,14 +114,17 @@ pub fn all_rules() -> Vec<Box<dyn Rule>> {
typed_rule!(PremintTypes::ZoraV2, is_authorized_to_create_premint),
typed_rule!(PremintTypes::ZoraV2, is_valid_signature),
typed_rule!(PremintTypes::ZoraV2, is_chain_supported),
typed_rule!(PremintTypes::ZoraV2, not_minted),
typed_rule!(PremintTypes::ZoraV2, premint_version_supported),
]
}

#[cfg(test)]
mod test {
use super::*;
use crate::rules::Evaluation::Ignore;

use super::*;

const PREMINT_JSON: &str = include_str!(concat!(
env!("CARGO_MANIFEST_DIR"),
"/data/valid_zora_v2_premint.json"
Expand All @@ -105,7 +134,7 @@ mod test {
async fn test_is_valid_signature() {
let premint: ZoraPremintV2 = serde_json::from_str(PREMINT_JSON).unwrap();
let context = RuleContext::test_default().await;
let result = is_valid_signature(premint, context).await;
let result = is_valid_signature(&premint, &context).await;

match result {
Ok(Accept) => {}
Expand All @@ -119,7 +148,7 @@ mod test {
async fn test_is_authorized_to_create_premint() {
let premint: ZoraPremintV2 = serde_json::from_str(PREMINT_JSON).unwrap();
let context = RuleContext::test_default().await;
let result = is_authorized_to_create_premint(premint, context).await;
let result = is_authorized_to_create_premint(&premint, &context).await;

match result {
Ok(Accept) => {}
Expand Down
Loading
Loading