Skip to content

Commit

Permalink
++
Browse files Browse the repository at this point in the history
  • Loading branch information
qalisander committed Oct 4, 2024
1 parent c20ee4c commit 6bafbce
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 39 deletions.
25 changes: 12 additions & 13 deletions contracts/src/token/erc721/extensions/consecutive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,18 +43,20 @@ use crate::{
structs::{
bitmap::BitMap,
checkpoints,
checkpoints::{Trace160, U96},
checkpoints::{trace::Trace, Size, S160},
},
},
};

type U96 = <S160 as Size>::Key;

sol_storage! {
/// State of an [`Erc721Consecutive`] token.
pub struct Erc721Consecutive {
/// Erc721 contract storage.
Erc721 erc721;
/// Checkpoint library contract for sequential ownership.
Trace160 _sequential_ownership;
Trace<S160> _sequential_ownership;
/// BitMap library contract for sequential burn of tokens.
BitMap _sequential_burn;
/// Used to offset the first token id in
Expand Down Expand Up @@ -114,7 +116,7 @@ pub enum Error {
/// Error type from [`Erc721`] contract [`erc721::Error`].
Erc721(erc721::Error),
/// Error type from checkpoint contract [`checkpoints::Error`].
Checkpoints(checkpoints::Error),
Checkpoints(checkpoints::trace::Error),
/// Batch mint is restricted to the constructor.
/// Any batch mint not emitting the [`Transfer`] event outside of
/// the constructor is non ERC-721 compliant.
Expand Down Expand Up @@ -793,18 +795,15 @@ mod tests {
use alloy_primitives::{address, uint, Address, U256};
use stylus_sdk::msg;

use crate::{
token::{
erc721,
erc721::{
extensions::consecutive::{
ERC721ExceededMaxBatchMint, Erc721Consecutive, Error,
},
tests::random_token_id,
ERC721InvalidReceiver, ERC721NonexistentToken, IErc721,
use crate::token::{
erc721,
erc721::{
extensions::consecutive::{
ERC721ExceededMaxBatchMint, Erc721Consecutive, Error, U96,
},
tests::random_token_id,
ERC721InvalidReceiver, ERC721NonexistentToken, IErc721,
},
utils::structs::checkpoints::U96,
};

const BOB: Address = address!("F4EaCDAbEf3c8f1EdE91b6f2A6840bc2E4DD3526");
Expand Down
44 changes: 25 additions & 19 deletions contracts/src/utils/structs/checkpoints/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,29 +14,36 @@ use core::ops::{Add, Div, Mul, Sub};
use alloy_primitives::Uint;
use stylus_sdk::prelude::*;

// Trait that associates types of specific size for checkpoints key and value.
/// Trait that associates types of specific size for checkpoints key and value.
pub trait Size {
/// Type of the key in abi.
type Key: Num;

/// Type of the key in storage.
type KeyStorage: for<'a> StorageType<Wraps<'a> = Self::Key>
+ Accessor<Wrap = Self::Key>;

/// Type of the value in abi.
type Value: Num;

/// Type of the value in storage.
type ValueStorage: for<'a> StorageType<Wraps<'a> = Self::Value>
+ Accessor<Wrap = Self::Value>;
type Key: Num;
type Value: Num;
}

// Size of checkpoint storage contract corresponding to the size of 96 bits of
// the key and size 160 bits of the value.
/// Size of checkpoint storage contract corresponding to the size of 96 bits of
/// the key and size 160 bits of the value.
pub type S160 = SpecificSize<96, 2, 160, 3>;

// Size of checkpoint storage contract corresponding to the size of 32 bits of
// the key and size 224 bits of the value.
/// Size of checkpoint storage contract corresponding to the size of 32 bits of
/// the key and size 224 bits of the value.
pub type S224 = SpecificSize<32, 1, 224, 4>;

// Size of checkpoint storage contract corresponding to the size of 48 bits of
// the key and size 208 bits of the value.
/// Size of checkpoint storage contract corresponding to the size of 48 bits of
/// the key and size 208 bits of the value.
pub type S208 = SpecificSize<48, 1, 208, 4>;

// Contains the size of checkpoint's key and value in bits.
/// Contains the size of checkpoint's key and value in bits.
pub struct SpecificSize<
const KEY_BITS: usize,
const KEY_LIMBS: usize,
Expand All @@ -53,26 +60,25 @@ impl<const KB: usize, const KL: usize, const VB: usize, const VL: usize> Size
type ValueStorage = stylus_sdk::storage::StorageUint<VB, VL>;
}

// Abstracts number inside the checkpoint contract.
pub(crate) trait Num:
Add + Sub + Mul + Div + Ord + Sized + Copy
{
/// Abstracts number inside the checkpoint contract.
pub trait Num: Add + Sub + Mul + Div + Ord + Sized + Copy {
/// Zero value of the number.
const ZERO: Self;
}

impl<const B: usize, const L: usize> Num for Uint<B, L> {
const ZERO: Self = Self::ZERO;
}

// Abstracts accessor inside the checkpoint contract
trait Accessor {
// Type of the number associated with the storage type.
/// Abstracts accessor inside the checkpoint contract
pub trait Accessor {
/// Type of the number associated with the storage type.
type Wrap: Num;

// Get underlying element from storage.
/// Gets underlying element [`Self::Wrap`] from persistent storage.
fn get(&self) -> Self::Wrap;

// Set underlying element to storage.
/// Sets underlying element [`Self::Wrap`] in persistent storage.
fn set(&mut self, value: Self::Wrap);
}

Expand Down
13 changes: 6 additions & 7 deletions contracts/src/utils/structs/checkpoints/trace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@

use alloy_primitives::{uint, U256, U32};
use alloy_sol_types::sol;
use stylus_proc::{solidity_storage, SolidityError};
use stylus_proc::{storage, SolidityError};
use stylus_sdk::{
call::MethodError,
storage::{StorageGuard, StorageGuardMut},
storage::{StorageGuard, StorageGuardMut, StorageVec},
};

use super::{Accessor, Num, Size};
Expand All @@ -32,15 +32,14 @@ impl MethodError for Error {
}

/// State of the checkpoint library contract.
#[solidity_storage]
#[cfg_attr(all(test, feature = "std"), derive(motsu::DefaultStorageLayout))]
#[storage]
pub struct Trace<T: Size> {
/// Stores checkpoints in a dynamic array sorted by key.
_checkpoints: stylus_sdk::storage::StorageVec<Checkpoint<T>>,
_checkpoints: StorageVec<Checkpoint<T>>,
}

// State of a single checkpoint.
#[solidity_storage]
/// State of a single checkpoint.
#[storage]
pub struct Checkpoint<T: Size> {
/// The key of the checkpoint. Used as a sorting key.
_key: T::KeyStorage,
Expand Down

0 comments on commit 6bafbce

Please sign in to comment.