From 5f4c6abbc62d8180ab6cc3c2090b5e6fb7a982cf Mon Sep 17 00:00:00 2001 From: jhernadnezb Date: Tue, 17 Dec 2024 12:50:54 -0600 Subject: [PATCH 01/10] add sg-minter-utils --- packages/sg-minter-utils/cargo.toml | 37 +++ packages/sg-minter-utils/src/lib.rs | 377 ++++++++++++++++++++++++++++ 2 files changed, 414 insertions(+) create mode 100644 packages/sg-minter-utils/cargo.toml create mode 100644 packages/sg-minter-utils/src/lib.rs diff --git a/packages/sg-minter-utils/cargo.toml b/packages/sg-minter-utils/cargo.toml new file mode 100644 index 000000000..eac86b651 --- /dev/null +++ b/packages/sg-minter-utils/cargo.toml @@ -0,0 +1,37 @@ +[package] +name = "sg-minter-utils" +authors = ["Jorge Hernandez "] +description = "Stargaze Minter Utils" +version = { workspace = true } +edition = { workspace = true } +homepage = { workspace = true } +repository = { workspace = true } +license = { workspace = true } + +exclude = [ + # Those files are rust-optimizer artifacts. You might want to commit them for convenience but they should not be part of the source code publication. + "contract.wasm", + "hash.txt", +] + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[lib] +crate-type = ["cdylib", "rlib"] + +[features] +# for more explicit tests, cargo test --features=backtraces +backtraces = ["cosmwasm-std/backtraces"] +# use library feature to disable all instantiate/execute/query exports +library = [] + +[dependencies] +cosmwasm-schema = { workspace = true } +cosmwasm-std = { workspace = true } +serde = { workspace = true } +thiserror = { workspace = true } +cw-storage-plus = { workspace = true } +nois = { version = "2.0.0" } + +[dev-dependencies] +cw-multi-test = { workspace = true } diff --git a/packages/sg-minter-utils/src/lib.rs b/packages/sg-minter-utils/src/lib.rs new file mode 100644 index 000000000..f10709633 --- /dev/null +++ b/packages/sg-minter-utils/src/lib.rs @@ -0,0 +1,377 @@ +use cosmwasm_schema::cw_serde; +use cosmwasm_std::testing::mock_dependencies; +use cosmwasm_std::{StdError, Storage}; +use cw_storage_plus::Item; +use nois::{int_in_range, sub_randomness_with_key}; +use thiserror::Error; +// BUCKET_SIZE is limited to 256 to efficiently store ids as u8 partitioning into multiple buckets +const BUCKET_SIZE: u32 = 256; + +const MAX_SIZE: u32 = 256 * 256; + +// buckets returns the number of necessary buckets for a given collection size. +// it returns the number of buckets and the size of the last bucket +fn buckets(size: u32) -> (u32, u32) { + let buckets = size / BUCKET_SIZE; + let remainder = size % BUCKET_SIZE; + if remainder > 0 { + return (buckets + 1, remainder); + } + (buckets, BUCKET_SIZE) +} + +// bucket_key returns the key for a given bucket id +pub fn bucket_key(bucket_id: u8) -> [u8; 4] { + [ + 0xAA, // prefix + b'v', // vending + b'm', // minter + bucket_id, + ] +} + +const AVAILABLE_BUCKETS_KEY: [u8; 3] = [0xAA, b'a', b'b']; + +pub const COUNTERS: Item = Item::new("counters"); + +#[cw_serde] +pub struct Counters { + pub available_buckets: u32, + pub available_items: u32, +} + +#[derive(Error, Debug, PartialEq)] +pub enum MinterUtilsError { + #[error(transparent)] + Std(#[from] StdError), + + #[error("Invalid collection size {size}. Max size is {max}")] + InvalidSize { size: u32, max: u32 }, + + #[error("No available buckets")] + NoAvailableBuckets {}, + + #[error("Invalid bucket {bucket_id}")] + InvalidBucket { bucket_id: u32 }, + + #[error("Invalid token id {token_id}")] + InvalidTokenId { token_id: u32 }, +} + +pub fn initialize(storage: &mut dyn Storage, size: u32) -> Result<(), MinterUtilsError> { + if size > MAX_SIZE { + return Err(MinterUtilsError::InvalidSize { + size, + max: MAX_SIZE, + }); + } + let (buckets, last_bucket_size) = buckets(size); + for bucket in 0..buckets { + let key = bucket_key(bucket as u8); + let size = if bucket == buckets - 1 { + last_bucket_size + } else { + BUCKET_SIZE + }; + let bucket_contents: Vec = (0..size).map(|x| x as u8).collect(); + storage.set(&key, &bucket_contents); + } + let available_buckets: Vec = (0..buckets).map(|x| x as u8).collect(); + storage.set(&AVAILABLE_BUCKETS_KEY, &available_buckets); + + let counters = Counters { + available_buckets: buckets, + available_items: size, + }; + COUNTERS.save(storage, &counters)?; + Ok(()) +} + +fn get_bucket_and_index(token_id: u32) -> (u32, u32) { + let bucket_id = (token_id - 1) / BUCKET_SIZE; + let index = (token_id - 1) % BUCKET_SIZE; + (bucket_id, index) +} + +fn get_token_id(bucket_id: u32, index: u32) -> u32 { + bucket_id * BUCKET_SIZE + index + 1 +} + +pub fn pick_any(storage: &mut dyn Storage, seed: [u8; 32]) -> Result { + let Some(mut available_buckets) = storage.get(&AVAILABLE_BUCKETS_KEY) else { + return Err(MinterUtilsError::NoAvailableBuckets {}); + }; + let bucket_index = int_in_range(seed, 0, available_buckets.len() - 1) as u32; + let bucket_id = available_buckets[bucket_index as usize]; + let bucket_key = bucket_key(bucket_id); + let Some(mut bucket) = storage.get(&bucket_key) else { + return Err(MinterUtilsError::InvalidBucket { + bucket_id: bucket_id as u32, + }); + }; + + let index = int_in_range(seed, 0, bucket.len() - 1) as u32; + + // available correlative + let correlative = bucket[index as usize]; + let token_id = get_token_id(bucket_id as u32, correlative as u32); + // item has been picked, remove it from the bucket + bucket.remove(index as usize); + + // if the bucket is empty, remove it from the available buckets + if bucket.is_empty() { + available_buckets.remove(bucket_index as usize); + // if there are no more buckets, remove the available buckets key else update it with the remaining buckets + if available_buckets.is_empty() { + storage.remove(&AVAILABLE_BUCKETS_KEY); + } else { + storage.set(&AVAILABLE_BUCKETS_KEY, &available_buckets); + } + storage.remove(&bucket_key); + } else { + storage.set(&bucket_key, &bucket); + } + Ok(token_id) +} + +pub fn pick_token(storage: &mut dyn Storage, token_id: u32) -> Result { + let Some(mut available_buckets) = storage.get(&AVAILABLE_BUCKETS_KEY) else { + return Err(MinterUtilsError::NoAvailableBuckets {}); + }; + let (bucket_id, correlative) = get_bucket_and_index(token_id); + + let bucket_id = bucket_id as u8; + let Ok(bucket_index) = available_buckets.binary_search(&bucket_id) else { + return Err(MinterUtilsError::InvalidBucket { + bucket_id: bucket_id as u32, + }); + }; + + let bucket_key = bucket_key(bucket_id); + let Some(mut bucket) = storage.get(&bucket_key) else { + return Err(MinterUtilsError::InvalidBucket { + bucket_id: bucket_id as u32, + }); + }; + let correlative = correlative as u8; + let Ok(token_index) = bucket.binary_search(&correlative) else { + return Err(MinterUtilsError::InvalidTokenId { token_id }); + }; + + // item has been picked, remove it from the bucket + bucket.remove(token_index as usize); + + // if the bucket is empty, remove it from the available buckets + if bucket.is_empty() { + available_buckets.remove(bucket_index as usize); + // if there are no more buckets, remove the available buckets key else update it with the remaining buckets + if available_buckets.is_empty() { + storage.remove(&AVAILABLE_BUCKETS_KEY); + } else { + dbg!("Removing bucket {:?} {:?}", bucket_id, &available_buckets); + storage.set(&AVAILABLE_BUCKETS_KEY, &available_buckets); + } + storage.remove(&bucket_key); + } else { + storage.set(&bucket_key, &bucket); + } + + Ok(token_id) +} + +#[cfg(test)] +mod tests { + use super::*; + use cosmwasm_std::testing::mock_dependencies; + use nois::sub_randomness_with_key; + + #[test] + fn test_initialize() { + let mut deps = mock_dependencies(); + initialize(&mut deps.storage, 256).unwrap(); + let counters = COUNTERS.load(&deps.storage).unwrap(); + assert_eq!(counters.available_buckets, 1); + assert_eq!(counters.available_items, 256); + + initialize(&mut deps.storage, 10000).unwrap(); + let counters = COUNTERS.load(&deps.storage).unwrap(); + assert_eq!(counters.available_buckets, 40); + assert_eq!(counters.available_items, 10000); + + let available_buckets = deps.storage.get(&AVAILABLE_BUCKETS_KEY).unwrap(); + assert_eq!(available_buckets.len(), 40); + assert_eq!( + available_buckets, + (0..40).map(|x| x as u8).collect::>() + ); + for bucket in 0..40 { + let key = bucket_key(bucket as u8); + let bucket_contents = deps.storage.get(&key).unwrap(); + if bucket == 39 { + assert_eq!(bucket_contents.len(), 10000 % 256); + assert_eq!( + bucket_contents, + (0..10000 % 256).map(|x| x as u8).collect::>() + ); + } else { + assert_eq!(bucket_contents.len(), 256); + assert_eq!( + bucket_contents, + (0..256).map(|x| x as u8).collect::>() + ); + } + } + } + + #[test] + fn test_find_bucket_and_correlative() { + let (n_buckets, last_bucket_size) = buckets(1); + assert_eq!(n_buckets, 1); + assert_eq!(last_bucket_size, 1); + + let (n_buckets, last_bucket_size) = buckets(BUCKET_SIZE); + assert_eq!(n_buckets, 1); + assert_eq!(last_bucket_size, BUCKET_SIZE); + + let (n_buckets, last_bucket_size) = buckets(BUCKET_SIZE + 1); + assert_eq!(n_buckets, 2); + assert_eq!(last_bucket_size, 1); + + let (n_buckets, last_bucket_size) = buckets(BUCKET_SIZE * 2); + assert_eq!(n_buckets, 2); + assert_eq!(last_bucket_size, BUCKET_SIZE); + + let (n_buckets, last_bucket_size) = buckets(BUCKET_SIZE * 2 + 1); + assert_eq!(n_buckets, 3); + assert_eq!(last_bucket_size, 1); + + let (n_buckets, last_bucket_size) = buckets(10_000); + // there is 40 buckets but the last one hast only 55 tokens + assert_eq!(n_buckets, 40); + assert_eq!(last_bucket_size, 16); + } + #[test] + fn test_generate_mintable_tokens() { + let mut deps = mock_dependencies(); + initialize(&mut deps.storage, 10_000); + let available_buckets = deps.storage.get(&AVAILABLE_BUCKETS_KEY).unwrap(); + assert_eq!(available_buckets.len(), 40); + let bucket = deps.storage.get(&bucket_key(0)).unwrap(); + assert_eq!(bucket.len(), BUCKET_SIZE as usize); + assert_eq!( + bucket, + (0..BUCKET_SIZE).map(|x| x as u8).collect::>() + ); + let bucket = deps.storage.get(&bucket_key(39)).unwrap(); + assert_eq!(bucket.len(), 16); + assert_eq!(bucket, (0..16).map(|x| x as u8).collect::>()); + } + + #[test] + fn test_get_bucket_and_index() { + let (bucket_id, index) = get_bucket_and_index(1); + assert_eq!(bucket_id, 0); + assert_eq!(index, 0); + let token_id = get_token_id(bucket_id, index); + assert_eq!(token_id, 1); + + let (bucket_id, index) = get_bucket_and_index(256); + assert_eq!(bucket_id, 0); + assert_eq!(index, 255); + let token_id = get_token_id(bucket_id, index); + assert_eq!(token_id, 256); + + let (bucket_id, index) = get_bucket_and_index(257); + assert_eq!(bucket_id, 1); + assert_eq!(index, 0); + let token_id = get_token_id(bucket_id, index); + assert_eq!(token_id, 257); + + let (bucket_id, index) = get_bucket_and_index(10_000); + assert_eq!(bucket_id, 39); + assert_eq!(index, 15); + let token_id = get_token_id(bucket_id, index); + assert_eq!(token_id, 10_000); + + let (bucket_id, index) = get_bucket_and_index(5_000); + assert_eq!(bucket_id, 19); + assert_eq!(index, 135); + let token_id = get_token_id(bucket_id, index); + assert_eq!(token_id, 5_000); + } + + #[test] + fn test_pick_any() { + let mut provider = sub_randomness_with_key([0; 32], b"token_generator"); + let mut deps = mock_dependencies(); + let r = initialize(&mut deps.storage, 10_000); + assert!(r.is_ok()); + let token_id = pick_any(&mut deps.storage, provider.provide()).unwrap(); + assert_eq!(token_id, 7659); + + let (bucket_id, _) = get_bucket_and_index(token_id); + let bucket = deps.storage.get(&bucket_key(bucket_id as u8)).unwrap(); + assert_eq!(bucket.len(), BUCKET_SIZE as usize - 1); + let token_id = pick_any(&mut deps.storage, provider.provide()).unwrap(); + assert_eq!(token_id, 3181); + let (bucket_id, _) = get_bucket_and_index(token_id); + let bucket = deps.storage.get(&bucket_key(bucket_id as u8)).unwrap(); + assert_eq!(bucket.len(), BUCKET_SIZE as usize - 1); + } + #[test] + fn test_pick_all() { + let mut provider = sub_randomness_with_key([0; 32], b"token_generator"); + let mut deps = mock_dependencies(); + let r = initialize(&mut deps.storage, 1000); + assert!(r.is_ok()); + let mut picked = vec![]; + for _ in 0..1000 { + let result = pick_any(&mut deps.storage, provider.provide()); + + if result.is_err() { + dbg!("Error: {:?}", &result); + } + assert!(result.is_ok()); + picked.push(result.unwrap()); + } + let r = pick_any(&mut deps.storage, provider.provide()); + assert!(r.is_err()); + let available_buckets = deps.storage.get(&AVAILABLE_BUCKETS_KEY); + picked.sort(); + picked.dedup(); + assert_eq!(picked.len(), 1000); + assert!(available_buckets.is_none()); + } + + #[test] + fn test_pick_all_with_pick_token() { + let mut provider = sub_randomness_with_key([0; 32], b"token_generator"); + let mut deps = mock_dependencies(); + let r = initialize(&mut deps.storage, 1000); + assert!(r.is_ok()); + let mut picked = vec![]; + let to_be_picked = vec![1, 257, 500, 750, 1000]; + for token_id in to_be_picked { + let result = pick_token(&mut deps.storage, token_id); + assert!(result.is_ok()); + picked.push(result.unwrap()); + } + for idx in 0..1000 { + let result = pick_any(&mut deps.storage, provider.provide()); + // we should not be able to pick more than 995 tokens because we already picked 5 + if idx >= 995 { + assert!(result.is_err()); + } else { + assert!(result.is_ok()); + picked.push(result.unwrap()); + } + } + let r = pick_any(&mut deps.storage, provider.provide()); + assert!(r.is_err()); + let available_buckets = deps.storage.get(&AVAILABLE_BUCKETS_KEY); + picked.sort(); + picked.dedup(); + assert_eq!(picked.len(), 1000); + assert!(available_buckets.is_none()); + } +} From 7f7bb4b5a4656ab30f2b67a05f14986b7b36203a Mon Sep 17 00:00:00 2001 From: jhernadnezb Date: Tue, 17 Dec 2024 13:42:00 -0600 Subject: [PATCH 02/10] update vending minter --- Cargo.lock | 731 +++++++++++++++--- Cargo.toml | 109 +-- contracts/minters/vending-minter/Cargo.toml | 64 +- .../minters/vending-minter/src/contract.rs | 289 ++++--- contracts/minters/vending-minter/src/error.rs | 4 + contracts/minters/vending-minter/src/state.rs | 2 +- packages/sg-minter-utils/src/lib.rs | 14 +- 7 files changed, 846 insertions(+), 367 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d3e1a6e33..f8cc46fc5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "addr2line" @@ -39,6 +39,18 @@ dependencies = [ "version_check", ] +[[package]] +name = "ahash" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy", +] + [[package]] name = "aho-corasick" version = "1.1.3" @@ -48,12 +60,139 @@ dependencies = [ "memchr", ] +[[package]] +name = "allocator-api2" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" + [[package]] name = "anyhow" version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6" +[[package]] +name = "ark-bls12-381" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c775f0d12169cba7aae4caeb547bb6a50781c7449a8aa53793827c9ec4abf488" +dependencies = [ + "ark-ec", + "ark-ff", + "ark-serialize", + "ark-std", +] + +[[package]] +name = "ark-ec" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "defd9a439d56ac24968cca0571f598a61bc8c55f71d50a89cda591cb750670ba" +dependencies = [ + "ark-ff", + "ark-poly", + "ark-serialize", + "ark-std", + "derivative", + "hashbrown 0.13.2", + "itertools", + "num-traits", + "rayon", + "zeroize", +] + +[[package]] +name = "ark-ff" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec847af850f44ad29048935519032c33da8aa03340876d351dfab5660d2966ba" +dependencies = [ + "ark-ff-asm", + "ark-ff-macros", + "ark-serialize", + "ark-std", + "derivative", + "digest 0.10.7", + "itertools", + "num-bigint", + "num-traits", + "paste", + "rayon", + "rustc_version", + "zeroize", +] + +[[package]] +name = "ark-ff-asm" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ed4aa4fe255d0bc6d79373f7e31d2ea147bcf486cba1be5ba7ea85abdb92348" +dependencies = [ + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-ff-macros" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" +dependencies = [ + "num-bigint", + "num-traits", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-poly" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d320bfc44ee185d899ccbadfa8bc31aab923ce1558716e1997a1e74057fe86bf" +dependencies = [ + "ark-ff", + "ark-serialize", + "ark-std", + "derivative", + "hashbrown 0.13.2", +] + +[[package]] +name = "ark-serialize" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" +dependencies = [ + "ark-serialize-derive", + "ark-std", + "digest 0.10.7", + "num-bigint", +] + +[[package]] +name = "ark-serialize-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae3281bc6d0fd7e549af32b52511e1302185bd688fd3359fa36423346ff682ea" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-std" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" +dependencies = [ + "num-traits", + "rand", + "rayon", +] + [[package]] name = "arrayvec" version = "0.7.6" @@ -310,8 +449,8 @@ dependencies = [ name = "base-factory" version = "3.15.0" dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", + "cosmwasm-schema 1.5.7", + "cosmwasm-std 1.5.7", "cw-storage-plus 1.2.0", "cw-utils 1.0.3", "cw2 1.1.2", @@ -329,8 +468,8 @@ name = "base-minter" version = "3.15.0" dependencies = [ "base-factory", - "cosmwasm-schema", - "cosmwasm-std", + "cosmwasm-schema 1.5.7", + "cosmwasm-std 1.5.7", "cw-storage-plus 1.2.0", "cw-utils 1.0.3", "cw2 1.1.2", @@ -394,6 +533,12 @@ version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + [[package]] name = "base64ct" version = "1.6.0" @@ -412,6 +557,12 @@ version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d86b93f97252c47b41663388e6d155714a9d0c398b99f1005cbc5f978b29f445" +[[package]] +name = "bech32" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d965446196e3b7decd44aa7ee49e31d630118f90ef12f97900f262eb915c951d" + [[package]] name = "bincode" version = "1.3.3" @@ -540,6 +691,12 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56953345e39537a3e18bdaeba4cb0c58a78c1f61f361dc0fa7c5c7340ae87c5f" +[[package]] +name = "bnum" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e31ea183f6ee62ac8b8a8cf7feddd766317adfb13ff469de57ce033efd6a790" + [[package]] name = "borsh" version = "1.5.1" @@ -848,6 +1005,12 @@ dependencies = [ "thiserror", ] +[[package]] +name = "cosmwasm-core" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c34c440d4d8e3ecec783d0f9c89d25565168b0f4cdb80a1f6a387cf2168c0740" + [[package]] name = "cosmwasm-crypto" version = "1.5.7" @@ -855,12 +1018,36 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0f862b355f7e47711e0acfe6af92cb3fd8fd5936b66a9eaa338b51edabd1e77d" dependencies = [ "digest 0.10.7", - "ed25519-zebra", + "ed25519-zebra 3.1.0", "k256 0.13.3", "rand_core 0.6.4", "thiserror", ] +[[package]] +name = "cosmwasm-crypto" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "134e765161d60228cc27635032d2a466542ca83fd6c87f3c87f4963c0bd51008" +dependencies = [ + "ark-bls12-381", + "ark-ec", + "ark-ff", + "ark-serialize", + "cosmwasm-core", + "curve25519-dalek 4.1.3", + "digest 0.10.7", + "ecdsa 0.16.9", + "ed25519-zebra 4.0.3", + "k256 0.13.3", + "num-traits", + "p256", + "rand_core 0.6.4", + "rayon", + "sha2 0.10.8", + "thiserror", +] + [[package]] name = "cosmwasm-derive" version = "1.5.7" @@ -870,13 +1057,37 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "cosmwasm-derive" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c94a4b93e722c91d2e58471cfe69480f4a656cfccacd8bfda5638f2a5d4512b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.77", +] + [[package]] name = "cosmwasm-schema" version = "1.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b4cd28147a66eba73720b47636a58097a979ad8c8bfdb4ed437ebcbfe362576" dependencies = [ - "cosmwasm-schema-derive", + "cosmwasm-schema-derive 1.5.7", + "schemars", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "cosmwasm-schema" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e9a7b56d154870ec4b57b224509854f706c9744449548d8a3bf91ac75c59192" +dependencies = [ + "cosmwasm-schema-derive 2.2.0", "schemars", "serde", "serde_json", @@ -894,6 +1105,17 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "cosmwasm-schema-derive" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edd3d80310cd7b86b09dbe886f4f2ca235a5ddb8d478493c6e50e720a3b38a42" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.77", +] + [[package]] name = "cosmwasm-std" version = "1.5.7" @@ -902,15 +1124,39 @@ checksum = "2685c2182624b2e9e17f7596192de49a3f86b7a0c9a5f6b25c1df5e24592e836" dependencies = [ "base64 0.21.7", "bech32 0.9.1", - "bnum", - "cosmwasm-crypto", - "cosmwasm-derive", + "bnum 0.10.0", + "cosmwasm-crypto 1.5.7", + "cosmwasm-derive 1.5.7", "derivative", "forward_ref", "hex", "schemars", "serde", - "serde-json-wasm", + "serde-json-wasm 0.5.2", + "sha2 0.10.8", + "static_assertions", + "thiserror", +] + +[[package]] +name = "cosmwasm-std" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4434e556b0aebff34bf082e75d175b5d7edbcf1d90d4cedb59623a1249fff567" +dependencies = [ + "base64 0.22.1", + "bech32 0.11.0", + "bnum 0.11.0", + "cosmwasm-core", + "cosmwasm-crypto 2.2.0", + "cosmwasm-derive 2.2.0", + "derive_more 1.0.0", + "hex", + "rand_core 0.6.4", + "rmp-serde", + "schemars", + "serde", + "serde-json-wasm 1.0.1", "sha2 0.10.8", "static_assertions", "thiserror", @@ -925,6 +1171,25 @@ dependencies = [ "libc", ] +[[package]] +name = "crossbeam-deque" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + [[package]] name = "crossbeam-utils" version = "0.8.20" @@ -1002,13 +1267,40 @@ dependencies = [ "zeroize", ] +[[package]] +name = "curve25519-dalek" +version = "4.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" +dependencies = [ + "cfg-if", + "cpufeatures", + "curve25519-dalek-derive", + "digest 0.10.7", + "fiat-crypto", + "rustc_version", + "subtle", + "zeroize", +] + +[[package]] +name = "curve25519-dalek-derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.77", +] + [[package]] name = "cw-address-like" version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "451a4691083a88a3c0630a8a88799e9d4cd6679b7ce8ff22b8da2873ff31d380" dependencies = [ - "cosmwasm-std", + "cosmwasm-std 1.5.7", ] [[package]] @@ -1017,8 +1309,8 @@ version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24bd6738c3fd59c87d2f84911c1cad1e4f2d1c58ecaa6e52549b4f78f4ed6f07" dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", + "cosmwasm-schema 1.5.7", + "cosmwasm-std 1.5.7", "cw-storage-plus 0.16.0", "cw-utils 0.16.0", "schemars", @@ -1032,8 +1324,8 @@ version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57de8d3761e46be863e3ac1eba8c8a976362a48c6abf240df1e26c3e421ee9e8" dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", + "cosmwasm-schema 1.5.7", + "cosmwasm-std 1.5.7", "cw-storage-plus 1.2.0", "cw-utils 1.0.3", "schemars", @@ -1048,7 +1340,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "127c7bb95853b8e828bdab97065c81cb5ddc20f7339180b61b2300565aaa99d1" dependencies = [ "anyhow", - "cosmwasm-std", + "cosmwasm-std 1.5.7", "cw-storage-plus 1.2.0", "cw-utils 1.0.3", "derivative", @@ -1066,8 +1358,8 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "093dfb4520c48b5848274dd88ea99e280a04bc08729603341c7fb0d758c74321" dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", + "cosmwasm-schema 1.5.7", + "cosmwasm-std 1.5.7", "cw-address-like", "cw-ownable-derive", "cw-storage-plus 1.2.0", @@ -1092,7 +1384,7 @@ version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9b6f91c0b94481a3e9ef1ceb183c37d00764f8751e39b45fc09f4d9b970d469" dependencies = [ - "cosmwasm-std", + "cosmwasm-std 1.5.7", "schemars", "serde", ] @@ -1103,7 +1395,7 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d5ff29294ee99373e2cd5fd21786a3c0ced99a52fec2ca347d565489c61b723c" dependencies = [ - "cosmwasm-std", + "cosmwasm-std 1.5.7", "schemars", "serde", ] @@ -1114,8 +1406,8 @@ version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6a84c6c1c0acc3616398eba50783934bd6c964bad6974241eaee3460c8f5b26" dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", + "cosmwasm-schema 1.5.7", + "cosmwasm-std 1.5.7", "cw2 0.16.0", "schemars", "semver", @@ -1129,8 +1421,8 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1c4a657e5caacc3a0d00ee96ca8618745d050b8f757c709babafb81208d4239c" dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", + "cosmwasm-schema 1.5.7", + "cosmwasm-std 1.5.7", "cw2 1.1.2", "schemars", "semver", @@ -1144,8 +1436,8 @@ version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "91398113b806f4d2a8d5f8d05684704a20ffd5968bf87e3473e1973710b884ad" dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", + "cosmwasm-schema 1.5.7", + "cosmwasm-std 1.5.7", "cw-storage-plus 0.16.0", "schemars", "serde", @@ -1157,8 +1449,8 @@ version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c6c120b24fbbf5c3bedebb97f2cc85fbfa1c3287e09223428e7e597b5293c1fa" dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", + "cosmwasm-schema 1.5.7", + "cosmwasm-std 1.5.7", "cw-storage-plus 1.2.0", "schemars", "semver", @@ -1172,8 +1464,8 @@ version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24754ff6e45f2a1c60adc409d9b2eb87666012c44021329141ffaab3388fccd2" dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", + "cosmwasm-schema 1.5.7", + "cosmwasm-std 1.5.7", "cw-storage-plus 1.2.0", "schemars", "serde", @@ -1185,8 +1477,8 @@ version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e24a22c3af54c52edf528673b420a67a1648be2c159b8ec778d2fbf543df24b" dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", + "cosmwasm-schema 1.5.7", + "cosmwasm-std 1.5.7", "cw-controllers 1.1.2", "cw-storage-plus 1.2.0", "cw-utils 1.0.3", @@ -1203,8 +1495,8 @@ version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94a1ea6e6277bdd6dfc043a9b1380697fe29d6e24b072597439523658d21d791" dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", + "cosmwasm-schema 1.5.7", + "cosmwasm-std 1.5.7", "cw-utils 0.16.0", "schemars", "serde", @@ -1216,8 +1508,8 @@ version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3c4d286625ccadc957fe480dd3bdc54ada19e0e6b5b9325379db3130569e914" dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", + "cosmwasm-schema 1.5.7", + "cosmwasm-std 1.5.7", "cw-utils 1.0.3", "schemars", "serde", @@ -1229,8 +1521,8 @@ version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77518e27431d43214cff4cdfbd788a7508f68d9b1f32389e6fce513e7eaccbef" dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", + "cosmwasm-schema 1.5.7", + "cosmwasm-std 1.5.7", "cw-storage-plus 0.16.0", "cw-utils 0.16.0", "cw2 0.16.0", @@ -1246,8 +1538,8 @@ version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da518d9f68bfda7d972cbaca2e8fcf04651d0edc3de72b04ae2bcd9289c81614" dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", + "cosmwasm-schema 1.5.7", + "cosmwasm-std 1.5.7", "cw-ownable", "cw-storage-plus 1.2.0", "cw-utils 1.0.3", @@ -1310,6 +1602,27 @@ dependencies = [ "syn 2.0.77", ] +[[package]] +name = "derive_more" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a9b99b9cbbe49445b21764dc0625032a89b145a2642e67603e1c936f5458d05" +dependencies = [ + "derive_more-impl", +] + +[[package]] +name = "derive_more-impl" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.77", + "unicode-xid", +] + [[package]] name = "digest" version = "0.8.1" @@ -1359,7 +1672,7 @@ dependencies = [ "assert_matches", "cosm-orc", "cosm-tome", - "cosmwasm-std", + "cosmwasm-std 1.5.7", "env_logger", "once_cell", "open-edition-factory", @@ -1411,14 +1724,23 @@ dependencies = [ "signature 1.6.4", ] +[[package]] +name = "ed25519" +version = "2.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" +dependencies = [ + "signature 2.2.0", +] + [[package]] name = "ed25519-dalek" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" dependencies = [ - "curve25519-dalek", - "ed25519", + "curve25519-dalek 3.2.0", + "ed25519 1.5.3", "sha2 0.9.9", "zeroize", ] @@ -1429,7 +1751,7 @@ version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c24f403d068ad0b359e577a77f92392118be3f3c927538f2bb544a5ecd828c6" dependencies = [ - "curve25519-dalek", + "curve25519-dalek 3.2.0", "hashbrown 0.12.3", "hex", "rand_core 0.6.4", @@ -1438,6 +1760,21 @@ dependencies = [ "zeroize", ] +[[package]] +name = "ed25519-zebra" +version = "4.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d9ce6874da5d4415896cd45ffbc4d1cfc0c4f9c079427bd870742c30f2f65a9" +dependencies = [ + "curve25519-dalek 4.1.3", + "ed25519 2.2.3", + "hashbrown 0.14.5", + "hex", + "rand_core 0.6.4", + "sha2 0.10.8", + "zeroize", +] + [[package]] name = "either" version = "1.13.0" @@ -1595,8 +1932,8 @@ dependencies = [ name = "ethereum-verify" version = "3.15.0" dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", + "cosmwasm-schema 1.5.7", + "cosmwasm-std 1.5.7", "hex", "sha2 0.10.8", "sha3", @@ -1718,6 +2055,12 @@ dependencies = [ "subtle", ] +[[package]] +name = "fiat-crypto" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" + [[package]] name = "fixed-hash" version = "0.8.0" @@ -1967,7 +2310,16 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" dependencies = [ - "ahash", + "ahash 0.7.8", +] + +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +dependencies = [ + "ahash 0.8.11", ] [[package]] @@ -1975,6 +2327,10 @@ name = "hashbrown" version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +dependencies = [ + "ahash 0.8.11", + "allocator-api2", +] [[package]] name = "headers" @@ -2396,6 +2752,23 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "nois" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdccfb08f1341b4477f430df82e635a5f4efeeb199826d9c872e9bb27c877997" +dependencies = [ + "cosmwasm-schema 2.2.0", + "cosmwasm-std 2.2.0", + "hex", + "rand", + "rand_xoshiro", + "serde", + "sha2 0.10.8", + "thiserror", + "xxhash-rust", +] + [[package]] name = "nom" version = "7.1.3" @@ -2406,6 +2779,16 @@ dependencies = [ "minimal-lexical", ] +[[package]] +name = "num-bigint" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +dependencies = [ + "num-integer", + "num-traits", +] + [[package]] name = "num-conv" version = "0.1.0" @@ -2423,6 +2806,15 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + [[package]] name = "num-traits" version = "0.2.19" @@ -2464,8 +2856,8 @@ name = "open-edition-factory" version = "3.15.0" dependencies = [ "base-factory", - "cosmwasm-schema", - "cosmwasm-std", + "cosmwasm-schema 1.5.7", + "cosmwasm-std 1.5.7", "cw-storage-plus 1.2.0", "cw-utils 1.0.3", "cw2 1.1.2", @@ -2482,8 +2874,8 @@ dependencies = [ name = "open-edition-minter" version = "3.15.0" dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", + "cosmwasm-schema 1.5.7", + "cosmwasm-std 1.5.7", "cw-storage-plus 1.2.0", "cw-utils 1.0.3", "cw2 1.1.2", @@ -2507,8 +2899,8 @@ dependencies = [ name = "open-edition-minter-merkle-wl" version = "3.15.0" dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", + "cosmwasm-schema 1.5.7", + "cosmwasm-std 1.5.7", "cw-storage-plus 1.2.0", "cw-utils 1.0.3", "cw2 1.1.2", @@ -2533,8 +2925,8 @@ dependencies = [ name = "open-edition-minter-wl-flex" version = "3.15.0" dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", + "cosmwasm-schema 1.5.7", + "cosmwasm-std 1.5.7", "cw-storage-plus 1.2.0", "cw-utils 1.0.3", "cw2 1.1.2", @@ -2595,6 +2987,18 @@ dependencies = [ "hashbrown 0.12.3", ] +[[package]] +name = "p256" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b" +dependencies = [ + "ecdsa 0.16.9", + "elliptic-curve 0.13.8", + "primeorder", + "sha2 0.10.8", +] + [[package]] name = "parity-scale-codec" version = "3.6.12" @@ -2833,6 +3237,15 @@ dependencies = [ "zerocopy", ] +[[package]] +name = "primeorder" +version = "0.13.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6" +dependencies = [ + "elliptic-curve 0.13.8", +] + [[package]] name = "primitive-types" version = "0.12.2" @@ -3029,6 +3442,26 @@ dependencies = [ "rand_core 0.6.4", ] +[[package]] +name = "rayon" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + [[package]] name = "regex" version = "1.10.6" @@ -3173,6 +3606,28 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "rmp" +version = "0.8.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "228ed7c16fa39782c3b3468e974aec2795e9089153cd08ee2e9aefb3613334c4" +dependencies = [ + "byteorder", + "num-traits", + "paste", +] + +[[package]] +name = "rmp-serde" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52e599a477cf9840e92f2cde9a7189e67b42c57532749bf90aea6ec10facd4db" +dependencies = [ + "byteorder", + "rmp", + "serde", +] + [[package]] name = "ron" version = "0.7.1" @@ -3231,6 +3686,15 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + [[package]] name = "rustix" version = "0.38.37" @@ -3306,7 +3770,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eca070c12893629e2cc820a9761bedf6ce1dcddc9852984d1dc734b8bd9bd024" dependencies = [ "cfg-if", - "derive_more", + "derive_more 0.99.18", "parity-scale-codec", "scale-info-derive", ] @@ -3459,6 +3923,15 @@ dependencies = [ "serde", ] +[[package]] +name = "serde-json-wasm" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f05da0d153dd4595bdffd5099dc0e9ce425b205ee648eb93437ff7302af8c9a5" +dependencies = [ + "serde", +] + [[package]] name = "serde_bytes" version = "0.11.15" @@ -3517,8 +3990,8 @@ dependencies = [ name = "sg-controllers" version = "3.15.0" dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", + "cosmwasm-schema 1.5.7", + "cosmwasm-std 1.5.7", "cw-storage-plus 1.2.0", "cw-utils 1.0.3", "schemars", @@ -3533,8 +4006,8 @@ version = "3.15.0" dependencies = [ "anyhow", "async-std", - "cosmwasm-schema", - "cosmwasm-std", + "cosmwasm-schema 1.5.7", + "cosmwasm-std 1.5.7", "cw-multi-test", "cw-storage-plus 1.2.0", "cw-utils 1.0.3", @@ -3566,7 +4039,7 @@ dependencies = [ name = "sg-metadata" version = "3.15.0" dependencies = [ - "cosmwasm-schema", + "cosmwasm-schema 1.5.7", "schemars", "serde", ] @@ -3575,8 +4048,8 @@ dependencies = [ name = "sg-mint-hooks" version = "3.15.0" dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", + "cosmwasm-schema 1.5.7", + "cosmwasm-std 1.5.7", "cw-storage-plus 1.2.0", "schemars", "serde", @@ -3596,6 +4069,19 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "sg-minter-utils" +version = "3.15.0" +dependencies = [ + "cosmwasm-schema 1.5.7", + "cosmwasm-std 1.5.7", + "cw-multi-test", + "cw-storage-plus 1.2.0", + "nois", + "serde", + "thiserror", +] + [[package]] name = "sg-multi-test" version = "3.1.0" @@ -3603,7 +4089,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "20744734b8049c64747bfb083bbc06a3c7204d1d34881ed3d89698e182aa9f97" dependencies = [ "anyhow", - "cosmwasm-std", + "cosmwasm-std 1.5.7", "cw-multi-test", "schemars", "serde", @@ -3614,8 +4100,8 @@ dependencies = [ name = "sg-splits" version = "3.15.0" dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", + "cosmwasm-schema 1.5.7", + "cosmwasm-std 1.5.7", "cw-controllers 1.1.2", "cw-storage-plus 1.2.0", "cw-utils 1.0.3", @@ -3635,8 +4121,8 @@ version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4db53aebc2b4f981dc20a51213544adde8beaace6880345627f4babe2e1bc3ab" dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", + "cosmwasm-schema 1.5.7", + "cosmwasm-std 1.5.7", "cw-utils 1.0.3", "cw721 0.18.0", "schemars", @@ -3648,8 +4134,8 @@ dependencies = [ name = "sg-tiered-whitelist" version = "3.15.0" dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", + "cosmwasm-schema 1.5.7", + "cosmwasm-std 1.5.7", "cw-storage-plus 1.2.0", "cw-utils 1.0.3", "cw2 1.1.2", @@ -3665,8 +4151,8 @@ dependencies = [ name = "sg-tiered-whitelist-flex" version = "3.15.0" dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", + "cosmwasm-schema 1.5.7", + "cosmwasm-std 1.5.7", "cw-storage-plus 1.2.0", "cw-utils 1.0.3", "cw2 1.1.2", @@ -3682,8 +4168,8 @@ dependencies = [ name = "sg-whitelist" version = "3.15.0" dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", + "cosmwasm-schema 1.5.7", + "cosmwasm-std 1.5.7", "cw-storage-plus 1.2.0", "cw-utils 1.0.3", "cw2 1.1.2", @@ -3699,8 +4185,8 @@ dependencies = [ name = "sg-whitelist-flex" version = "3.15.0" dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", + "cosmwasm-schema 1.5.7", + "cosmwasm-std 1.5.7", "cw-storage-plus 1.2.0", "cw-utils 1.0.3", "cw2 1.1.2", @@ -3716,7 +4202,7 @@ dependencies = [ name = "sg1" version = "3.15.0" dependencies = [ - "cosmwasm-std", + "cosmwasm-std 1.5.7", "cw-utils 1.0.3", "serde", "sg-std", @@ -3727,8 +4213,8 @@ dependencies = [ name = "sg2" version = "3.15.0" dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", + "cosmwasm-schema 1.5.7", + "cosmwasm-std 1.5.7", "cw-storage-plus 1.2.0", "cw-utils 1.0.3", "schemars", @@ -3741,8 +4227,8 @@ dependencies = [ name = "sg4" version = "3.15.0" dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", + "cosmwasm-schema 1.5.7", + "cosmwasm-std 1.5.7", "schemars", "serde", "thiserror", @@ -3752,8 +4238,8 @@ dependencies = [ name = "sg721" version = "3.15.0" dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", + "cosmwasm-schema 1.5.7", + "cosmwasm-std 1.5.7", "cw-multi-test", "cw-ownable", "cw-utils 1.0.3", @@ -3766,8 +4252,8 @@ dependencies = [ name = "sg721-base" version = "3.15.0" dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", + "cosmwasm-schema 1.5.7", + "cosmwasm-std 1.5.7", "cw-ownable", "cw-storage-plus 1.2.0", "cw-utils 1.0.3", @@ -3785,8 +4271,8 @@ dependencies = [ name = "sg721-metadata-onchain" version = "3.15.0" dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", + "cosmwasm-schema 1.5.7", + "cosmwasm-std 1.5.7", "cw-ownable", "cw2 1.1.2", "cw721 0.18.0", @@ -3804,8 +4290,8 @@ dependencies = [ name = "sg721-nt" version = "3.15.0" dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", + "cosmwasm-schema 1.5.7", + "cosmwasm-std 1.5.7", "cw-utils 1.0.3", "cw2 1.1.2", "cw721 0.18.0", @@ -3821,8 +4307,8 @@ dependencies = [ name = "sg721-updatable" version = "3.15.0" dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", + "cosmwasm-schema 1.5.7", + "cosmwasm-std 1.5.7", "cw-multi-test", "cw-storage-plus 1.2.0", "cw-utils 1.0.3", @@ -4079,7 +4565,7 @@ checksum = "baa1d2d0ec1b531ba7d196f0dbee5e78ed2a82bfba928e88dff64aeec0b26073" dependencies = [ "async-trait", "bytes", - "ed25519", + "ed25519 1.5.3", "ed25519-dalek", "flex-error", "futures", @@ -4206,8 +4692,8 @@ dependencies = [ "async-std", "base-factory", "base-minter", - "cosmwasm-schema", - "cosmwasm-std", + "cosmwasm-schema 1.5.7", + "cosmwasm-std 1.5.7", "cw-multi-test", "cw-ownable", "cw-storage-plus 1.2.0", @@ -4277,8 +4763,8 @@ dependencies = [ name = "tiered-whitelist-merkletree" version = "3.15.0" dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", + "cosmwasm-schema 1.5.7", + "cosmwasm-std 1.5.7", "cw-storage-plus 1.2.0", "cw-utils 1.0.3", "cw2 1.1.2", @@ -4354,8 +4840,8 @@ name = "token-merge-factory" version = "3.15.0" dependencies = [ "base-factory", - "cosmwasm-schema", - "cosmwasm-std", + "cosmwasm-schema 1.5.7", + "cosmwasm-std 1.5.7", "cw-storage-plus 1.2.0", "cw-utils 1.0.3", "cw2 1.1.2", @@ -4372,8 +4858,8 @@ dependencies = [ name = "token-merge-minter" version = "3.15.0" dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", + "cosmwasm-schema 1.5.7", + "cosmwasm-std 1.5.7", "cw-storage-plus 1.2.0", "cw-utils 1.0.3", "cw2 1.1.2", @@ -4706,8 +5192,8 @@ name = "vending-factory" version = "3.15.0" dependencies = [ "base-factory", - "cosmwasm-schema", - "cosmwasm-std", + "cosmwasm-schema 1.5.7", + "cosmwasm-std 1.5.7", "cw-storage-plus 1.2.0", "cw-utils 1.0.3", "cw2 1.1.2", @@ -4725,8 +5211,8 @@ dependencies = [ name = "vending-minter" version = "3.15.0" dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", + "cosmwasm-schema 1.5.7", + "cosmwasm-std 1.5.7", "cw-storage-plus 1.2.0", "cw-utils 1.0.3", "cw2 1.1.2", @@ -4737,6 +5223,7 @@ dependencies = [ "schemars", "semver", "serde", + "sg-minter-utils", "sg-std", "sg-tiered-whitelist", "sg-whitelist", @@ -4755,8 +5242,8 @@ dependencies = [ name = "vending-minter-featured" version = "3.15.0" dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", + "cosmwasm-schema 1.5.7", + "cosmwasm-std 1.5.7", "cw-storage-plus 1.2.0", "cw-utils 1.0.3", "cw2 1.1.2", @@ -4785,8 +5272,8 @@ dependencies = [ name = "vending-minter-merkle-wl" version = "3.15.0" dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", + "cosmwasm-schema 1.5.7", + "cosmwasm-std 1.5.7", "cw-storage-plus 1.2.0", "cw-utils 1.0.3", "cw2 1.1.2", @@ -4816,8 +5303,8 @@ dependencies = [ name = "vending-minter-merkle-wl-featured" version = "3.15.0" dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", + "cosmwasm-schema 1.5.7", + "cosmwasm-std 1.5.7", "cw-storage-plus 1.2.0", "cw-utils 1.0.3", "cw2 1.1.2", @@ -4847,8 +5334,8 @@ dependencies = [ name = "vending-minter-wl-flex" version = "3.15.0" dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", + "cosmwasm-schema 1.5.7", + "cosmwasm-std 1.5.7", "cw-storage-plus 1.2.0", "cw-utils 1.0.3", "cw2 1.1.2", @@ -4877,8 +5364,8 @@ dependencies = [ name = "vending-minter-wl-flex-featured" version = "3.15.0" dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", + "cosmwasm-schema 1.5.7", + "cosmwasm-std 1.5.7", "cw-storage-plus 1.2.0", "cw-utils 1.0.3", "cw2 1.1.2", @@ -5034,8 +5521,8 @@ dependencies = [ name = "whitelist-immutable" version = "3.15.0" dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", + "cosmwasm-schema 1.5.7", + "cosmwasm-std 1.5.7", "cw-controllers 0.16.0", "cw-storage-plus 1.2.0", "cw-utils 1.0.3", @@ -5051,8 +5538,8 @@ dependencies = [ name = "whitelist-mtree" version = "3.15.0" dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", + "cosmwasm-schema 1.5.7", + "cosmwasm-std 1.5.7", "cw-storage-plus 1.2.0", "cw-utils 1.0.3", "cw2 1.1.2", @@ -5200,6 +5687,12 @@ dependencies = [ "tap", ] +[[package]] +name = "xxhash-rust" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a5cbf750400958819fb6178eaa83bee5cd9c29a26a40cc241df8c70fdd46984" + [[package]] name = "yaml-rust" version = "0.4.5" diff --git a/Cargo.toml b/Cargo.toml index 6b590d58e..ca2580c1c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,66 +12,67 @@ members = [ resolver = "2" [workspace.package] -version = "3.15.0" +version = "3.15.0" rust-version = "1.73.0" -edition = "2021" -homepage = "https://stargaze.zone" -repository = "https://github.com/public-awesome/launchpad" -license = "Apache-2.0" +edition = "2021" +homepage = "https://stargaze.zone" +repository = "https://github.com/public-awesome/launchpad" +license = "Apache-2.0" [workspace.dependencies] -base-factory = { version = "3.14.0", path = "contracts/factories/base-factory" } -base-minter = { version = "3.14.0", path = "contracts/minters/base-minter" } -cosmwasm-schema = "1.2.1" -cosmwasm-std = "1.2.1" -cw-controllers = "1.1.0" -cw2 = "1.1.0" -cw4 = "1.1.0" -cw4-group = "1.1.0" -cw721 = "0.18.0" -cw721-base = "0.18.0" -cw-multi-test = "0.16.2" -cw-storage-plus = "1.1.0" -cw-utils = "1.0.1" -schemars = "0.8.11" -serde = { version = "1.0.145", default-features = false, features = ["derive"] } -sg1 = { version = "3.14.0", path = "packages/sg1" } -sg2 = { version = "3.14.0", path = "packages/sg2" } -sg4 = { version = "3.14.0", path = "packages/sg4" } -sg721 = { version = "3.14.0", path = "packages/sg721" } -sg721-base = { version = "3.14.0", path = "contracts/collections/sg721-base" } -sg721-nt = { version = "3.14.0", path = "contracts/collections/sg721-nt" } -sg721-updatable = { version = "3.14.0", path = "contracts/collections/sg721-updatable" } -sg-controllers = { version = "3.14.0", path = "packages/controllers" } -sg-metadata = { version = "3.14.0", path = "packages/sg-metadata" } -sg-mint-hooks = { version = "3.14.0", path = "packages/mint-hooks" } -sg-multi-test = { version = "3.1.0" } -sg-splits = { version = "3.14.0", path = "contracts/splits" } -sg-std = { version = "3.2.0" } -sg-whitelist = { version = "3.14.0", path = "contracts/whitelists/whitelist" } -sg-tiered-whitelist = { version = "3.14.0", path = "contracts/whitelists/tiered-whitelist" } -thiserror = "1.0.31" -url = "2.2.2" -sha2 = { version = "0.10.2", default-features = false } +base-factory = { version = "3.14.0", path = "contracts/factories/base-factory" } +base-minter = { version = "3.14.0", path = "contracts/minters/base-minter" } +cosmwasm-schema = "1.2.1" +cosmwasm-std = "1.2.1" +cw-controllers = "1.1.0" +cw2 = "1.1.0" +cw4 = "1.1.0" +cw4-group = "1.1.0" +cw721 = "0.18.0" +cw721-base = "0.18.0" +cw-multi-test = "0.16.2" +cw-storage-plus = "1.1.0" +cw-utils = "1.0.1" +schemars = "0.8.11" +serde = { version = "1.0.145", default-features = false, features = ["derive"] } +sg1 = { version = "3.14.0", path = "packages/sg1" } +sg2 = { version = "3.14.0", path = "packages/sg2" } +sg4 = { version = "3.14.0", path = "packages/sg4" } +sg721 = { version = "3.14.0", path = "packages/sg721" } +sg721-base = { version = "3.14.0", path = "contracts/collections/sg721-base" } +sg721-nt = { version = "3.14.0", path = "contracts/collections/sg721-nt" } +sg721-updatable = { version = "3.14.0", path = "contracts/collections/sg721-updatable" } +sg-controllers = { version = "3.14.0", path = "packages/controllers" } +sg-metadata = { version = "3.14.0", path = "packages/sg-metadata" } +sg-mint-hooks = { version = "3.14.0", path = "packages/mint-hooks" } +sg-multi-test = { version = "3.1.0" } +sg-splits = { version = "3.14.0", path = "contracts/splits" } +sg-std = { version = "3.2.0" } +sg-whitelist = { version = "3.14.0", path = "contracts/whitelists/whitelist" } +sg-tiered-whitelist = { version = "3.14.0", path = "contracts/whitelists/tiered-whitelist" } +sg-minter-utils = { version = "3.14.0", path = "packages/sg-minter-utils" } +thiserror = "1.0.31" +url = "2.2.2" +sha2 = { version = "0.10.2", default-features = false } whitelist-mtree = { version = "3.14.0", path = "contracts/whitelists/whitelist-merkletree" } -tiered-whitelist-merkletree = { version = "3.14.0", path = "contracts/whitelists/tiered-whitelist-merkletree" } +tiered-whitelist-merkletree = { version = "3.14.0", path = "contracts/whitelists/tiered-whitelist-merkletree" } vending-minter-merkle-wl = { version = "3.14.0", path = "contracts/minters/vending-minter-merkle-wl" } -vending-factory = { version = "3.14.0", path = "contracts/factories/vending-factory" } -vending-minter = { version = "3.14.0", path = "contracts/minters/vending-minter" } -open-edition-factory = { version = "3.14.0", path = "contracts/factories/open-edition-factory" } -open-edition-minter = { version = "3.14.0", path = "contracts/minters/open-edition-minter" } -token-merge-factory = { version = "3.14.0", path = "contracts/factories/token-merge-factory" } -token-merge-minter = { version = "3.14.0", path = "contracts/minters/token-merge-minter" } -whitelist-immutable = { version = "3.14.0", path = "contracts/whitelists/whitelist-immutable" } -sg-whitelist-flex = { version = "3.14.0", path = "contracts/whitelists/whitelist-flex" } -sg-tiered-whitelist-flex = { version = "3.14.0", path = "contracts/whitelists/tiered-whitelist-flex" } -ethereum-verify = { version = "3.14.0", path = "packages/ethereum-verify" } -sg-eth-airdrop = { version = "3.14.0", path = "contracts/sg-eth-airdrop" } -test-suite = { version = "3.14.0", path = "test-suite" } - -semver = "1" -cw-ownable = "0.5.1" +vending-factory = { version = "3.14.0", path = "contracts/factories/vending-factory" } +vending-minter = { version = "3.14.0", path = "contracts/minters/vending-minter" } +open-edition-factory = { version = "3.14.0", path = "contracts/factories/open-edition-factory" } +open-edition-minter = { version = "3.14.0", path = "contracts/minters/open-edition-minter" } +token-merge-factory = { version = "3.14.0", path = "contracts/factories/token-merge-factory" } +token-merge-minter = { version = "3.14.0", path = "contracts/minters/token-merge-minter" } +whitelist-immutable = { version = "3.14.0", path = "contracts/whitelists/whitelist-immutable" } +sg-whitelist-flex = { version = "3.14.0", path = "contracts/whitelists/whitelist-flex" } +sg-tiered-whitelist-flex = { version = "3.14.0", path = "contracts/whitelists/tiered-whitelist-flex" } +ethereum-verify = { version = "3.14.0", path = "packages/ethereum-verify" } +sg-eth-airdrop = { version = "3.14.0", path = "contracts/sg-eth-airdrop" } +test-suite = { version = "3.14.0", path = "test-suite" } + +semver = "1" +cw-ownable = "0.5.1" [profile.release.package.sg721] codegen-units = 1 diff --git a/contracts/minters/vending-minter/Cargo.toml b/contracts/minters/vending-minter/Cargo.toml index 810ad3662..a38f271ae 100644 --- a/contracts/minters/vending-minter/Cargo.toml +++ b/contracts/minters/vending-minter/Cargo.toml @@ -1,15 +1,12 @@ [package] -name = "vending-minter" -authors = [ - "Jake Hartnell ", - "Shane Vitarana ", -] +name = "vending-minter" +authors = ["Jake Hartnell ", "Shane Vitarana "] description = "Stargaze vending minter contract" -version = { workspace = true } -edition = { workspace = true } -homepage = { workspace = true } -repository = { workspace = true } -license = { workspace = true } +version = { workspace = true } +edition = { workspace = true } +homepage = { workspace = true } +repository = { workspace = true } +license = { workspace = true } exclude = [ # Those files are rust-optimizer artifacts. You might want to commit them for convenience but they should not be part of the source code publication. @@ -29,27 +26,28 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cosmwasm-schema = { workspace = true } -cosmwasm-std = { workspace = true } -cw2 = { workspace = true } -cw721 = { workspace = true } -cw721-base = { workspace = true, features = ["library"] } -cw-storage-plus = { workspace = true } -cw-utils = { workspace = true } -rand_core = { version = "0.6.4", default-features = false } -rand_xoshiro = { version = "0.6.0", default-features = false } -schemars = { workspace = true } -serde = { workspace = true } -sha2 = { workspace = true } -shuffle = { git = "https://github.com/webmaster128/shuffle", branch = "rm-getrandom", version = "0.1.7" } -sg1 = { workspace = true } -sg2 = { workspace = true } -sg4 = { workspace = true } -sg721 = { workspace = true } -sg-std = { workspace = true } -sg-whitelist = { workspace = true, features = ["library"] } +cosmwasm-schema = { workspace = true } +cosmwasm-std = { workspace = true } +cw2 = { workspace = true } +cw721 = { workspace = true } +cw721-base = { workspace = true, features = ["library"] } +cw-storage-plus = { workspace = true } +cw-utils = { workspace = true } +rand_core = { version = "0.6.4", default-features = false } +rand_xoshiro = { version = "0.6.0", default-features = false } +schemars = { workspace = true } +serde = { workspace = true } +sha2 = { workspace = true } +shuffle = { git = "https://github.com/webmaster128/shuffle", branch = "rm-getrandom", version = "0.1.7" } +sg1 = { workspace = true } +sg2 = { workspace = true } +sg4 = { workspace = true } +sg721 = { workspace = true } +sg-std = { workspace = true } +sg-whitelist = { workspace = true, features = ["library"] } sg-tiered-whitelist = { workspace = true, features = ["library"] } -thiserror = { workspace = true } -url = { workspace = true } -vending-factory = { workspace = true, features = ["library"] } -semver = {workspace = true } +thiserror = { workspace = true } +url = { workspace = true } +vending-factory = { workspace = true, features = ["library"] } +semver = { workspace = true } +sg-minter-utils = { workspace = true } diff --git a/contracts/minters/vending-minter/src/contract.rs b/contracts/minters/vending-minter/src/contract.rs index 2be1f57f3..2f649743a 100644 --- a/contracts/minters/vending-minter/src/contract.rs +++ b/contracts/minters/vending-minter/src/contract.rs @@ -4,9 +4,9 @@ use crate::msg::{ QueryMsg, StartTimeResponse, }; use crate::state::{ - Config, ConfigExtension, CONFIG, LAST_DISCOUNT_TIME, MINTABLE_NUM_TOKENS, - MINTABLE_TOKEN_POSITIONS, MINTER_ADDRS, SG721_ADDRESS, STATUS, WHITELIST_FS_MINTER_ADDRS, - WHITELIST_MINTER_ADDRS, WHITELIST_SS_MINTER_ADDRS, WHITELIST_TS_MINTER_ADDRS, + Config, ConfigExtension, CONFIG, LAST_DISCOUNT_TIME, MINTABLE_NUM_TOKENS, MINTER_ADDRS, + SG721_ADDRESS, STATUS, WHITELIST_FS_MINTER_ADDRS, WHITELIST_MINTER_ADDRS, + WHITELIST_SS_MINTER_ADDRS, WHITELIST_TS_MINTER_ADDRS, }; use crate::validation::{check_dynamic_per_address_limit, get_three_percent_of_tokens}; #[cfg(not(feature = "library"))] @@ -19,10 +19,9 @@ use cosmwasm_std::{ use cw2::set_contract_version; use cw721_base::Extension; use cw_utils::{may_pay, maybe_addr, nonpayable, parse_reply_instantiate_data}; -use rand_core::{RngCore, SeedableRng}; -use rand_xoshiro::Xoshiro128PlusPlus; + use semver::Version; -use sg1::{checked_fair_burn, distribute_mint_fees}; +use sg1::distribute_mint_fees; use sg2::query::Sg2QueryMsg; use sg4::{MinterConfig, Status, StatusResponse, SudoMsg}; use sg721::{ExecuteMsg as Sg721ExecuteMsg, InstantiateMsg as Sg721InstantiateMsg}; @@ -32,8 +31,7 @@ use sg_whitelist::msg::{ ConfigResponse as WhitelistConfigResponse, HasMemberResponse, QueryMsg as WhitelistQueryMsg, }; use sha2::{Digest, Sha256}; -use shuffle::{fy::FisherYates, shuffler::Shuffler}; -use std::convert::TryInto; + use url::Url; use vending_factory::msg::{ParamsResponse, VendingMinterCreateMsg}; use vending_factory::state::VendingMinterParams; @@ -170,18 +168,8 @@ pub fn instantiate( let last_discount_time = env.block.time.minus_seconds(60 * 60 * 12); LAST_DISCOUNT_TIME.save(deps.storage, &last_discount_time)?; - let token_ids = random_token_list( - &env, - deps.api - .addr_validate(&msg.collection_params.info.creator)?, - (1..=msg.init_msg.num_tokens).collect::>(), - )?; - // Save mintable token ids map - let mut token_position = 1; - for token_id in token_ids { - MINTABLE_TOKEN_POSITIONS.save(deps.storage, token_position, &token_id)?; - token_position += 1; - } + sg_minter_utils::initialize(deps.storage, msg.init_msg.num_tokens) + .map_err(ContractError::MinterUtils)?; // Submessage to instantiate sg721 contract let submsg = SubMsg { @@ -354,45 +342,41 @@ pub fn execute_purge( // Introduces another source of randomness to minting // There's a fee because this action is expensive. pub fn execute_shuffle( - deps: DepsMut, - env: Env, + _deps: DepsMut, + _env: Env, info: MessageInfo, ) -> Result { - let mut res = Response::new(); - - let config = CONFIG.load(deps.storage)?; - - let factory: ParamsResponse = deps - .querier - .query_wasm_smart(config.factory, &Sg2QueryMsg::Params {})?; - let factory_params = factory.params; - - // Check exact shuffle fee payment included in message - checked_fair_burn( - &info, - factory_params.extension.shuffle_fee.amount.u128(), - None, - &mut res, - )?; - - // Check not sold out - let mintable_num_tokens = MINTABLE_NUM_TOKENS.load(deps.storage)?; - if mintable_num_tokens == 0 { - return Err(ContractError::SoldOut {}); - } - - // get positions and token_ids, then randomize token_ids and reassign positions - let mut positions = vec![]; - let mut token_ids = vec![]; - for mapping in MINTABLE_TOKEN_POSITIONS.range(deps.storage, None, None, Order::Ascending) { - let (position, token_id) = mapping?; - positions.push(position); - token_ids.push(token_id); - } - let randomized_token_ids = random_token_list(&env, info.sender.clone(), token_ids.clone())?; - for (i, position) in positions.iter().enumerate() { - MINTABLE_TOKEN_POSITIONS.save(deps.storage, *position, &randomized_token_ids[i])?; - } + let res = Response::new(); + + // let config = CONFIG.load(deps.storage)?; + + // let factory: ParamsResponse = deps + // .querier + // .query_wasm_smart(config.factory, &Sg2QueryMsg::Params {})?; + // let factory_params = factory.params; + + // // Check exact shuffle fee payment included in message + // checked_fair_burn( + // &info, + // factory_params.extension.shuffle_fee.amount.u128(), + // None, + // &mut res, + // )?; + + // // Check not sold out + // let mintable_num_tokens = MINTABLE_NUM_TOKENS.load(deps.storage)?; + // if mintable_num_tokens == 0 { + // return Err(ContractError::SoldOut {}); + // } + + // // get positions and token_ids, then randomize token_ids and reassign positions + // let mut positions = vec![]; + // let mut token_ids = vec![]; + // for mapping in MINTABLE_TOKEN_POSITIONS.range(deps.storage, None, None, Order::Ascending) { + // let (position, token_id) = mapping?; + // positions.push(position); + // token_ids.push(token_id); + // } Ok(res .add_attribute("action", "shuffle") @@ -677,35 +661,33 @@ fn _execute_mint( )?; } - let mintable_token_mapping = match token_id { - Some(token_id) => { - // set position to invalid value, iterate to find matching token_id - // if token_id not found, token_id is already sold, position is unchanged and throw err - // otherwise return position and token_id - let mut position = 0; - for res in MINTABLE_TOKEN_POSITIONS.range(deps.storage, None, None, Order::Ascending) { - let (pos, id) = res?; - if id == token_id { - position = pos; - break; - } - } - if position == 0 { - return Err(ContractError::TokenIdAlreadySold { token_id }); - } - TokenPositionMapping { position, token_id } + let token_id = match token_id { + Some(token_id) => sg_minter_utils::pick_token(deps.storage, token_id)?, + None => { + let sha256 = Sha256::digest( + format!( + "{}{}{}{}{}", + info.sender, + env.block.height, + mintable_num_tokens, + env.block.time.nanos(), + env.transaction.map_or(0, |tx| tx.index), + ) + .into_bytes(), + ); + let randomness: [u8; 32] = sha256.to_vec()[0..32].try_into().map_err(|_| { + ContractError::Std(StdError::generic_err("Failed to convert sha256 to array")) + })?; + + sg_minter_utils::pick_any(deps.storage, randomness)? } - None => random_mintable_token_mapping(deps.as_ref(), env, info.sender.clone())?, }; // Create mint msgs let mint_msg = Sg721ExecuteMsg::::Mint { - token_id: mintable_token_mapping.token_id.to_string(), + token_id: token_id.to_string(), owner: recipient_addr.to_string(), - token_uri: Some(format!( - "{}/{}", - config.extension.base_token_uri, mintable_token_mapping.token_id - )), + token_uri: Some(format!("{}/{}", config.extension.base_token_uri, token_id)), extension: None, }; let msg = CosmosMsg::Wasm(WasmMsg::Execute { @@ -715,8 +697,6 @@ fn _execute_mint( }); res = res.add_message(msg); - // Remove mintable token position from map - MINTABLE_TOKEN_POSITIONS.remove(deps.storage, mintable_token_mapping.position); let mintable_num_tokens = MINTABLE_NUM_TOKENS.load(deps.storage)?; // Decrement mintable num tokens MINTABLE_NUM_TOKENS.save(deps.storage, &(mintable_num_tokens - 1))?; @@ -758,7 +738,7 @@ fn _execute_mint( .add_attribute("action", action) .add_attribute("sender", info.sender) .add_attribute("recipient", recipient_addr) - .add_attribute("token_id", mintable_token_mapping.token_id.to_string()) + .add_attribute("token_id", token_id.to_string()) .add_attribute( "network_fee", coin(network_fee.u128(), mint_price.clone().denom).to_string(), @@ -770,69 +750,69 @@ fn _execute_mint( )) } -fn random_token_list( - env: &Env, - sender: Addr, - mut tokens: Vec, -) -> Result, ContractError> { - let tx_index = if let Some(tx) = &env.transaction { - tx.index - } else { - 0 - }; - let sha256 = Sha256::digest( - format!("{}{}{}{}", sender, env.block.height, tokens.len(), tx_index).into_bytes(), - ); - // Cut first 16 bytes from 32 byte value - let randomness: [u8; 16] = sha256.to_vec()[0..16].try_into().unwrap(); - let mut rng = Xoshiro128PlusPlus::from_seed(randomness); - let mut shuffler = FisherYates::default(); - shuffler - .shuffle(&mut tokens, &mut rng) - .map_err(StdError::generic_err)?; - Ok(tokens) -} +// fn random_token_list( +// env: &Env, +// sender: Addr, +// mut tokens: Vec, +// ) -> Result, ContractError> { +// let tx_index = if let Some(tx) = &env.transaction { +// tx.index +// } else { +// 0 +// }; +// let sha256 = Sha256::digest( +// format!("{}{}{}{}", sender, env.block.height, tokens.len(), tx_index).into_bytes(), +// ); +// // Cut first 16 bytes from 32 byte value +// let randomness: [u8; 16] = sha256.to_vec()[0..16].try_into().unwrap(); +// let mut rng = Xoshiro128PlusPlus::from_seed(randomness); +// let mut shuffler = FisherYates::default(); +// shuffler +// .shuffle(&mut tokens, &mut rng) +// .map_err(StdError::generic_err)?; +// Ok(tokens) +// } // Does a baby shuffle, picking a token_id from the first or last 50 mintable positions. -fn random_mintable_token_mapping( - deps: Deps, - env: Env, - sender: Addr, -) -> Result { - let num_tokens = MINTABLE_NUM_TOKENS.load(deps.storage)?; - let tx_index = if let Some(tx) = &env.transaction { - tx.index - } else { - 0 - }; - let sha256 = Sha256::digest( - format!("{}{}{}{}", sender, num_tokens, env.block.height, tx_index).into_bytes(), - ); - // Cut first 16 bytes from 32 byte value - let randomness: [u8; 16] = sha256.to_vec()[0..16].try_into().unwrap(); - - let mut rng = Xoshiro128PlusPlus::from_seed(randomness); - - let r = rng.next_u32(); - - let order = match r % 2 { - 1 => Order::Descending, - _ => Order::Ascending, - }; - let mut rem = 50; - if rem > num_tokens { - rem = num_tokens; - } - let n = r % rem; - let position = MINTABLE_TOKEN_POSITIONS - .keys(deps.storage, None, None, order) - .skip(n as usize) - .take(1) - .collect::>>()?[0]; - - let token_id = MINTABLE_TOKEN_POSITIONS.load(deps.storage, position)?; - Ok(TokenPositionMapping { position, token_id }) -} +// fn random_mintable_token_mapping( +// deps: Deps, +// env: Env, +// sender: Addr, +// ) -> Result { +// let num_tokens = MINTABLE_NUM_TOKENS.load(deps.storage)?; +// let tx_index = if let Some(tx) = &env.transaction { +// tx.index +// } else { +// 0 +// }; +// let sha256 = Sha256::digest( +// format!("{}{}{}{}", sender, num_tokens, env.block.height, tx_index).into_bytes(), +// ); +// // Cut first 16 bytes from 32 byte value +// let randomness: [u8; 16] = sha256.to_vec()[0..16].try_into().unwrap(); + +// let mut rng = Xoshiro128PlusPlus::from_seed(randomness); + +// let r = rng.next_u32(); + +// let order = match r % 2 { +// 1 => Order::Descending, +// _ => Order::Ascending, +// }; +// let mut rem = 50; +// if rem > num_tokens { +// rem = num_tokens; +// } +// let n = r % rem; +// let position = MINTABLE_TOKEN_POSITIONS +// .keys(deps.storage, None, None, order) +// .skip(n as usize) +// .take(1) +// .collect::>>()?[0]; + +// let token_id = MINTABLE_TOKEN_POSITIONS.load(deps.storage, position)?; +// Ok(TokenPositionMapping { position, token_id }) +// } pub fn execute_update_mint_price( deps: DepsMut, @@ -1040,20 +1020,21 @@ pub fn execute_burn_remaining( return Err(ContractError::SoldOut {}); } - let keys = MINTABLE_TOKEN_POSITIONS - .keys(deps.storage, None, None, Order::Ascending) - .collect::>(); - let mut total: u32 = 0; - for key in keys { - total += 1; - MINTABLE_TOKEN_POSITIONS.remove(deps.storage, key?); - } + // TODO: implement purge in sg_minter_utils + // let keys = MINTABLE_TOKEN_POSITIONS + // .keys(deps.storage, None, None, Order::Ascending) + // .collect::>(); + // let mut total: u32 = 0; + // for key in keys { + // total += 1; + // MINTABLE_TOKEN_POSITIONS.remove(deps.storage, key?); + // } // Decrement mintable num tokens - MINTABLE_NUM_TOKENS.save(deps.storage, &(mintable_num_tokens - total))?; + MINTABLE_NUM_TOKENS.save(deps.storage, &0)?; let event = Event::new("burn-remaining") .add_attribute("sender", info.sender) - .add_attribute("tokens_burned", total.to_string()) + .add_attribute("tokens_burned", mintable_num_tokens.to_string()) .add_attribute("minter", env.contract.address.to_string()); Ok(Response::new().add_event(event)) } diff --git a/contracts/minters/vending-minter/src/error.rs b/contracts/minters/vending-minter/src/error.rs index cfdd78c85..9522fe79f 100644 --- a/contracts/minters/vending-minter/src/error.rs +++ b/contracts/minters/vending-minter/src/error.rs @@ -1,6 +1,7 @@ use cosmwasm_std::{Coin, StdError, Timestamp}; use cw_utils::PaymentError; use sg1::FeeError; +use sg_minter_utils::MinterUtilsError; use thiserror::Error; use url::ParseError; #[derive(Error, Debug, PartialEq)] @@ -8,6 +9,9 @@ pub enum ContractError { #[error("{0}")] Std(#[from] StdError), + #[error("{0}")] + MinterUtils(#[from] MinterUtilsError), + #[error("{0}")] Payment(#[from] PaymentError), diff --git a/contracts/minters/vending-minter/src/state.rs b/contracts/minters/vending-minter/src/state.rs index 395709578..f565eb8f5 100644 --- a/contracts/minters/vending-minter/src/state.rs +++ b/contracts/minters/vending-minter/src/state.rs @@ -19,7 +19,7 @@ pub type Config = MinterConfig; pub const CONFIG: Item = Item::new("config"); pub const SG721_ADDRESS: Item = Item::new("sg721_address"); // map of index position and token id -pub const MINTABLE_TOKEN_POSITIONS: Map = Map::new("mt"); +// pub const MINTABLE_TOKEN_POSITIONS: Map = Map::new("mt"); pub const MINTABLE_NUM_TOKENS: Item = Item::new("mintable_num_tokens"); pub const MINTER_ADDRS: Map<&Addr, u32> = Map::new("ma"); diff --git a/packages/sg-minter-utils/src/lib.rs b/packages/sg-minter-utils/src/lib.rs index f10709633..9cdd757e4 100644 --- a/packages/sg-minter-utils/src/lib.rs +++ b/packages/sg-minter-utils/src/lib.rs @@ -1,5 +1,5 @@ use cosmwasm_schema::cw_serde; -use cosmwasm_std::testing::mock_dependencies; + use cosmwasm_std::{StdError, Storage}; use cw_storage_plus::Item; use nois::{int_in_range, sub_randomness_with_key}; @@ -101,7 +101,8 @@ pub fn pick_any(storage: &mut dyn Storage, seed: [u8; 32]) -> Result Result Date: Tue, 17 Dec 2024 13:45:14 -0600 Subject: [PATCH 03/10] delete file --- packages/sg-minter-utils/cargo.toml | 37 ----------------------------- 1 file changed, 37 deletions(-) delete mode 100644 packages/sg-minter-utils/cargo.toml diff --git a/packages/sg-minter-utils/cargo.toml b/packages/sg-minter-utils/cargo.toml deleted file mode 100644 index eac86b651..000000000 --- a/packages/sg-minter-utils/cargo.toml +++ /dev/null @@ -1,37 +0,0 @@ -[package] -name = "sg-minter-utils" -authors = ["Jorge Hernandez "] -description = "Stargaze Minter Utils" -version = { workspace = true } -edition = { workspace = true } -homepage = { workspace = true } -repository = { workspace = true } -license = { workspace = true } - -exclude = [ - # Those files are rust-optimizer artifacts. You might want to commit them for convenience but they should not be part of the source code publication. - "contract.wasm", - "hash.txt", -] - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[lib] -crate-type = ["cdylib", "rlib"] - -[features] -# for more explicit tests, cargo test --features=backtraces -backtraces = ["cosmwasm-std/backtraces"] -# use library feature to disable all instantiate/execute/query exports -library = [] - -[dependencies] -cosmwasm-schema = { workspace = true } -cosmwasm-std = { workspace = true } -serde = { workspace = true } -thiserror = { workspace = true } -cw-storage-plus = { workspace = true } -nois = { version = "2.0.0" } - -[dev-dependencies] -cw-multi-test = { workspace = true } From 582be7f47e0dfd8b29dacd14e4c4988329af4b21 Mon Sep 17 00:00:00 2001 From: jhernadnezb Date: Tue, 17 Dec 2024 13:45:38 -0600 Subject: [PATCH 04/10] add file --- packages/sg-minter-utils/Cargo.toml | 37 +++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 packages/sg-minter-utils/Cargo.toml diff --git a/packages/sg-minter-utils/Cargo.toml b/packages/sg-minter-utils/Cargo.toml new file mode 100644 index 000000000..eac86b651 --- /dev/null +++ b/packages/sg-minter-utils/Cargo.toml @@ -0,0 +1,37 @@ +[package] +name = "sg-minter-utils" +authors = ["Jorge Hernandez "] +description = "Stargaze Minter Utils" +version = { workspace = true } +edition = { workspace = true } +homepage = { workspace = true } +repository = { workspace = true } +license = { workspace = true } + +exclude = [ + # Those files are rust-optimizer artifacts. You might want to commit them for convenience but they should not be part of the source code publication. + "contract.wasm", + "hash.txt", +] + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[lib] +crate-type = ["cdylib", "rlib"] + +[features] +# for more explicit tests, cargo test --features=backtraces +backtraces = ["cosmwasm-std/backtraces"] +# use library feature to disable all instantiate/execute/query exports +library = [] + +[dependencies] +cosmwasm-schema = { workspace = true } +cosmwasm-std = { workspace = true } +serde = { workspace = true } +thiserror = { workspace = true } +cw-storage-plus = { workspace = true } +nois = { version = "2.0.0" } + +[dev-dependencies] +cw-multi-test = { workspace = true } From b57cf3580e3a69362d921aa0925f31057efa35e8 Mon Sep 17 00:00:00 2001 From: jhernadnezb Date: Tue, 17 Dec 2024 13:48:34 -0600 Subject: [PATCH 05/10] bump rust --- .circleci/config.yml | 90 ++++++++++++++++++++++---------------------- 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 0b299111a..52898cda2 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -31,7 +31,7 @@ workflows: jobs: contract_sg721_base: docker: - - image: rust:1.75.0 + - image: rust:1.78.0 working_directory: ~/project/contracts/collections/sg721-base steps: - checkout: @@ -41,7 +41,7 @@ jobs: command: rustc --version; cargo --version; rustup --version - restore_cache: keys: - - cargocache-sg721-rust:1.75.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-sg721-rust:1.78.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Unit Tests environment: @@ -63,11 +63,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-sg721-rust:1.75.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-sg721-rust:1.78.0-{{ checksum "~/project/Cargo.lock" }} contract_sg721_nt: docker: - - image: rust:1.75.0 + - image: rust:1.78.0 working_directory: ~/project/contracts/collections/sg721-nt steps: - checkout: @@ -77,7 +77,7 @@ jobs: command: rustc --version; cargo --version; rustup --version - restore_cache: keys: - - cargocache-sg721-nt-rust:1.75.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-sg721-nt-rust:1.78.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Unit Tests environment: @@ -99,11 +99,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-sg721-nt-rust:1.75.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-sg721-nt-rust:1.78.0-{{ checksum "~/project/Cargo.lock" }} contract_base_factory: docker: - - image: rust:1.75.0 + - image: rust:1.78.0 working_directory: ~/project/contracts/factories/base-factory steps: - checkout: @@ -113,7 +113,7 @@ jobs: command: rustc --version; cargo --version; rustup --version - restore_cache: keys: - - cargocache-base-factory-rust:1.75.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-base-factory-rust:1.78.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Unit Tests environment: @@ -135,11 +135,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-base-factory-rust:1.75.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-base-factory-rust:1.78.0-{{ checksum "~/project/Cargo.lock" }} contract_base_minter: docker: - - image: rust:1.75.0 + - image: rust:1.78.0 working_directory: ~/project/contracts/minters/base-minter steps: - checkout: @@ -149,7 +149,7 @@ jobs: command: rustc --version; cargo --version; rustup --version - restore_cache: keys: - - cargocache-base-minter-rust:1.75.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-base-minter-rust:1.78.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Unit Tests environment: @@ -171,11 +171,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-base-minter-rust:1.75.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-base-minter-rust:1.78.0-{{ checksum "~/project/Cargo.lock" }} contract_vending_factory: docker: - - image: rust:1.75.0 + - image: rust:1.78.0 working_directory: ~/project/contracts/factories/vending-factory steps: - checkout: @@ -185,7 +185,7 @@ jobs: command: rustc --version; cargo --version; rustup --version - restore_cache: keys: - - cargocache-vending-factory-rust:1.75.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-vending-factory-rust:1.78.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Unit Tests environment: @@ -207,11 +207,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-vending-factory-rust:1.75.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-vending-factory-rust:1.78.0-{{ checksum "~/project/Cargo.lock" }} contract_vending_minter: docker: - - image: rust:1.75.0 + - image: rust:1.78.0 working_directory: ~/project/contracts/minters/vending-minter steps: - checkout: @@ -221,7 +221,7 @@ jobs: command: rustc --version; cargo --version; rustup --version - restore_cache: keys: - - cargocache-vending-minter-rust:1.75.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-vending-minter-rust:1.78.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Unit Tests environment: @@ -243,11 +243,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-vending-minter-rust:1.75.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-vending-minter-rust:1.78.0-{{ checksum "~/project/Cargo.lock" }} contract_open_edition_factory: docker: - - image: rust:1.75.0 + - image: rust:1.78.0 working_directory: ~/project/contracts/factories/open-edition-factory steps: - checkout: @@ -257,7 +257,7 @@ jobs: command: rustc --version; cargo --version; rustup --version - restore_cache: keys: - - cargocache-open-edition-factory-rust:1.75.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-open-edition-factory-rust:1.78.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Unit Tests environment: @@ -279,11 +279,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-open-edition-factory-rust:1.75.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-open-edition-factory-rust:1.78.0-{{ checksum "~/project/Cargo.lock" }} contract_open_edition_minter: docker: - - image: rust:1.75.0 + - image: rust:1.78.0 working_directory: ~/project/contracts/minters/open-edition-minter steps: - checkout: @@ -293,7 +293,7 @@ jobs: command: rustc --version; cargo --version; rustup --version - restore_cache: keys: - - cargocache-open-edition-minter-rust:1.75.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-open-edition-minter-rust:1.78.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Unit Tests environment: @@ -315,11 +315,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-open-edition-minter-rust:1.75.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-open-edition-minter-rust:1.78.0-{{ checksum "~/project/Cargo.lock" }} contract_whitelist: docker: - - image: rust:1.75.0 + - image: rust:1.78.0 working_directory: ~/project/contracts/whitelists/whitelist steps: - checkout: @@ -329,7 +329,7 @@ jobs: command: rustc --version; cargo --version; rustup --version - restore_cache: keys: - - cargocache-whitelist-rust:1.75.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-whitelist-rust:1.78.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Unit Tests environment: @@ -351,10 +351,10 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-whitelist-rust:1.75.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-whitelist-rust:1.78.0-{{ checksum "~/project/Cargo.lock" }} test-suite: docker: - - image: rust:1.75.0 + - image: rust:1.78.0 working_directory: ~/project/test-suite steps: - checkout: @@ -364,7 +364,7 @@ jobs: command: rustc --version; cargo --version; rustup --version - restore_cache: keys: - - cargocache-test-suite-rust:1.75.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-test-suite-rust:1.78.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Unit Tests environment: @@ -374,11 +374,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-test-suite-rust:1.75.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-test-suite-rust:1.78.0-{{ checksum "~/project/Cargo.lock" }} package_sg_std: docker: - - image: rust:1.75.0 + - image: rust:1.78.0 working_directory: ~/project/package/sg-std steps: - checkout: @@ -388,7 +388,7 @@ jobs: command: rustc --version; cargo --version; rustup --version - restore_cache: keys: - - cargocache-sg-std-rust:1.75.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-sg-std-rust:1.78.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Unit Tests environment: @@ -398,11 +398,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-sg-std-rust:1.75.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-sg-std-rust:1.78.0-{{ checksum "~/project/Cargo.lock" }} package_sg_utils: docker: - - image: rust:1.75.0 + - image: rust:1.78.0 working_directory: ~/project/package/sg-utils steps: - checkout: @@ -412,7 +412,7 @@ jobs: command: rustc --version; cargo --version; rustup --version - restore_cache: keys: - - cargocache-sg-utils-rust:1.75.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-sg-utils-rust:1.78.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Unit Tests environment: @@ -422,11 +422,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-sg-utils-rust:1.75.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-sg-utils-rust:1.78.0-{{ checksum "~/project/Cargo.lock" }} sg-eth-airdrop: docker: - - image: rust:1.75.0 + - image: rust:1.78.0 working_directory: ~/project/contracts/sg-eth-airdrop steps: - checkout: @@ -436,7 +436,7 @@ jobs: command: rustc --version; cargo --version; rustup --version - restore_cache: keys: - - cargocache-sg-eth-airdrop-rust:1.75.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-sg-eth-airdrop-rust:1.78.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Unit Tests environment: @@ -458,11 +458,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-sg-eth-airdrop-rust:1.75.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-sg-eth-airdrop-rust:1.78.0-{{ checksum "~/project/Cargo.lock" }} lint: docker: - - image: rust:1.75.0 + - image: rust:1.78.0 steps: - checkout - run: @@ -470,7 +470,7 @@ jobs: command: rustc --version; cargo --version; rustup --version; rustup target list --installed - restore_cache: keys: - - cargocache-v2-lint-rust:1.75.0-{{ checksum "Cargo.lock" }} + - cargocache-v2-lint-rust:1.78.0-{{ checksum "Cargo.lock" }} - run: name: Add rustfmt component command: rustup component add rustfmt @@ -489,7 +489,7 @@ jobs: - target/debug/.fingerprint - target/debug/build - target/debug/deps - key: cargocache-v2-lint-rust:1.75.0-{{ checksum "Cargo.lock" }} + key: cargocache-v2-lint-rust:1.78.0-{{ checksum "Cargo.lock" }} # This runs one time on the top level to ensure all contracts compile properly into wasm. # We don't run the wasm build per contract build, and then reuse a lot of the same dependencies, so this speeds up CI time @@ -497,7 +497,7 @@ jobs: # We also sanity-check the resultant wasm files. wasm-build: docker: - - image: rust:1.75.0 + - image: rust:1.78.0 steps: - checkout: path: ~/project @@ -506,7 +506,7 @@ jobs: command: rustc --version; cargo --version; rustup --version - restore_cache: keys: - - cargocache-wasm-rust-no-wasm:1.75.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-wasm-rust-no-wasm:1.78.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Add wasm32 target command: rustup target add wasm32-unknown-unknown @@ -553,7 +553,7 @@ jobs: - /target/debug - /target/release - /target/tarpaulin - key: cargocache-wasm-rust-no-wasm:1.75.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-wasm-rust-no-wasm:1.78.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Check wasm contracts command: | From 222386122952fc8c224a67fa56d72496dd6b159c Mon Sep 17 00:00:00 2001 From: jhernadnezb Date: Tue, 17 Dec 2024 13:52:35 -0600 Subject: [PATCH 06/10] fix linter --- packages/sg-minter-utils/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/sg-minter-utils/src/lib.rs b/packages/sg-minter-utils/src/lib.rs index 9cdd757e4..e664d712f 100644 --- a/packages/sg-minter-utils/src/lib.rs +++ b/packages/sg-minter-utils/src/lib.rs @@ -160,11 +160,11 @@ pub fn pick_token(storage: &mut dyn Storage, token_id: u32) -> Result Date: Thu, 19 Dec 2024 14:19:49 -0600 Subject: [PATCH 07/10] add purge method --- packages/sg-minter-utils/src/lib.rs | 62 +++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/packages/sg-minter-utils/src/lib.rs b/packages/sg-minter-utils/src/lib.rs index e664d712f..e7642cbe3 100644 --- a/packages/sg-minter-utils/src/lib.rs +++ b/packages/sg-minter-utils/src/lib.rs @@ -135,6 +135,30 @@ pub fn pick_any(storage: &mut dyn Storage, seed: [u8; 32]) -> Result Result { + let Some(mut available_buckets) = storage.get(&AVAILABLE_BUCKETS_KEY) else { + return Err(MinterUtilsError::NoAvailableBuckets {}); + }; + let mut buckets_to_remove = 0; + for i in 0..available_buckets.len() { + if i as u32 >= max_buckets { + break; + } + let bucket_key = bucket_key(available_buckets[i]); + storage.remove(&bucket_key); + buckets_to_remove += 1; + } + + // remove from the end of the vector + available_buckets.truncate(available_buckets.len() - buckets_to_remove); + if available_buckets.is_empty() { + storage.remove(&AVAILABLE_BUCKETS_KEY); + } else { + storage.set(&AVAILABLE_BUCKETS_KEY, &available_buckets); + } + Ok(buckets_to_remove as u32) +} + pub fn pick_token(storage: &mut dyn Storage, token_id: u32) -> Result { let Some(mut available_buckets) = storage.get(&AVAILABLE_BUCKETS_KEY) else { return Err(MinterUtilsError::NoAvailableBuckets {}); @@ -376,4 +400,42 @@ mod tests { assert_eq!(picked.len(), 1000); assert!(available_buckets.is_none()); } + + #[test] + fn test_pick_twice() { + let mut deps = mock_dependencies(); + let r = initialize(&mut deps.storage, 10_000); + assert!(r.is_ok()); + let token_id = pick_token(&mut deps.storage, 975).unwrap(); + assert_eq!(token_id, 975); + let res = pick_token(&mut deps.storage, 975); + assert!(res.is_err()); + } + #[test] + fn test_purge_buckets() { + let mut deps = mock_dependencies(); + let r = initialize(&mut deps.storage, 10_000); + assert!(r.is_ok()); + let r = purge_buckets(&mut deps.storage, 10); + assert!(r.is_ok()); + assert_eq!(r.unwrap(), 10); + let available_buckets = deps.storage.get(&AVAILABLE_BUCKETS_KEY).unwrap(); + assert_eq!(available_buckets.len(), 30); + assert_eq!( + available_buckets, + (0..30).map(|x| x as u8).collect::>() + ); + } + + #[test] + fn test_purge_all() { + let mut deps = mock_dependencies(); + let r = initialize(&mut deps.storage, 10_000); + assert!(r.is_ok()); + let r = purge_buckets(&mut deps.storage, 40); + assert!(r.is_ok()); + assert_eq!(r.unwrap(), 40); + let available_buckets = deps.storage.get(&AVAILABLE_BUCKETS_KEY); + assert!(available_buckets.is_none()); + } } From 3e5688ec2ca9c6bdd736a463e84e238ae029b906 Mon Sep 17 00:00:00 2001 From: jhernadnezb Date: Thu, 19 Dec 2024 15:17:35 -0600 Subject: [PATCH 08/10] add shuffle and purge_buckets --- .../minters/vending-minter/src/contract.rs | 154 +++++------------- packages/sg-minter-utils/src/lib.rs | 55 ++++++- 2 files changed, 94 insertions(+), 115 deletions(-) diff --git a/contracts/minters/vending-minter/src/contract.rs b/contracts/minters/vending-minter/src/contract.rs index 2f649743a..43a51f081 100644 --- a/contracts/minters/vending-minter/src/contract.rs +++ b/contracts/minters/vending-minter/src/contract.rs @@ -21,7 +21,7 @@ use cw721_base::Extension; use cw_utils::{may_pay, maybe_addr, nonpayable, parse_reply_instantiate_data}; use semver::Version; -use sg1::distribute_mint_fees; +use sg1::{checked_fair_burn, distribute_mint_fees}; use sg2::query::Sg2QueryMsg; use sg4::{MinterConfig, Status, StatusResponse, SudoMsg}; use sg721::{ExecuteMsg as Sg721ExecuteMsg, InstantiateMsg as Sg721InstantiateMsg}; @@ -31,7 +31,6 @@ use sg_whitelist::msg::{ ConfigResponse as WhitelistConfigResponse, HasMemberResponse, QueryMsg as WhitelistQueryMsg, }; use sha2::{Digest, Sha256}; - use url::Url; use vending_factory::msg::{ParamsResponse, VendingMinterCreateMsg}; use vending_factory::state::VendingMinterParams; @@ -342,42 +341,49 @@ pub fn execute_purge( // Introduces another source of randomness to minting // There's a fee because this action is expensive. pub fn execute_shuffle( - _deps: DepsMut, - _env: Env, + deps: DepsMut, + env: Env, info: MessageInfo, ) -> Result { - let res = Response::new(); - - // let config = CONFIG.load(deps.storage)?; - - // let factory: ParamsResponse = deps - // .querier - // .query_wasm_smart(config.factory, &Sg2QueryMsg::Params {})?; - // let factory_params = factory.params; - - // // Check exact shuffle fee payment included in message - // checked_fair_burn( - // &info, - // factory_params.extension.shuffle_fee.amount.u128(), - // None, - // &mut res, - // )?; - - // // Check not sold out - // let mintable_num_tokens = MINTABLE_NUM_TOKENS.load(deps.storage)?; - // if mintable_num_tokens == 0 { - // return Err(ContractError::SoldOut {}); - // } - - // // get positions and token_ids, then randomize token_ids and reassign positions - // let mut positions = vec![]; - // let mut token_ids = vec![]; - // for mapping in MINTABLE_TOKEN_POSITIONS.range(deps.storage, None, None, Order::Ascending) { - // let (position, token_id) = mapping?; - // positions.push(position); - // token_ids.push(token_id); - // } + let mut res = Response::new(); + + let config = CONFIG.load(deps.storage)?; + let factory: ParamsResponse = deps + .querier + .query_wasm_smart(config.factory, &Sg2QueryMsg::Params {})?; + let factory_params = factory.params; + + // Check exact shuffle fee payment included in message + checked_fair_burn( + &info, + factory_params.extension.shuffle_fee.amount.u128(), + None, + &mut res, + )?; + + // Check not sold out + let mintable_num_tokens = MINTABLE_NUM_TOKENS.load(deps.storage)?; + if mintable_num_tokens == 0 { + return Err(ContractError::SoldOut {}); + } + + let sha256 = Sha256::digest( + format!( + "{}{}{}{}{}", + info.sender, + env.block.height, + mintable_num_tokens, + env.block.time.nanos(), + env.transaction.map_or(0, |tx| tx.index), + ) + .into_bytes(), + ); + let randomness: [u8; 32] = sha256.to_vec()[0..32].try_into().map_err(|_| { + ContractError::Std(StdError::generic_err("Failed to convert sha256 to array")) + })?; + + sg_minter_utils::shuffle(deps.storage, randomness)?; Ok(res .add_attribute("action", "shuffle") .add_attribute("sender", info.sender)) @@ -750,70 +756,6 @@ fn _execute_mint( )) } -// fn random_token_list( -// env: &Env, -// sender: Addr, -// mut tokens: Vec, -// ) -> Result, ContractError> { -// let tx_index = if let Some(tx) = &env.transaction { -// tx.index -// } else { -// 0 -// }; -// let sha256 = Sha256::digest( -// format!("{}{}{}{}", sender, env.block.height, tokens.len(), tx_index).into_bytes(), -// ); -// // Cut first 16 bytes from 32 byte value -// let randomness: [u8; 16] = sha256.to_vec()[0..16].try_into().unwrap(); -// let mut rng = Xoshiro128PlusPlus::from_seed(randomness); -// let mut shuffler = FisherYates::default(); -// shuffler -// .shuffle(&mut tokens, &mut rng) -// .map_err(StdError::generic_err)?; -// Ok(tokens) -// } - -// Does a baby shuffle, picking a token_id from the first or last 50 mintable positions. -// fn random_mintable_token_mapping( -// deps: Deps, -// env: Env, -// sender: Addr, -// ) -> Result { -// let num_tokens = MINTABLE_NUM_TOKENS.load(deps.storage)?; -// let tx_index = if let Some(tx) = &env.transaction { -// tx.index -// } else { -// 0 -// }; -// let sha256 = Sha256::digest( -// format!("{}{}{}{}", sender, num_tokens, env.block.height, tx_index).into_bytes(), -// ); -// // Cut first 16 bytes from 32 byte value -// let randomness: [u8; 16] = sha256.to_vec()[0..16].try_into().unwrap(); - -// let mut rng = Xoshiro128PlusPlus::from_seed(randomness); - -// let r = rng.next_u32(); - -// let order = match r % 2 { -// 1 => Order::Descending, -// _ => Order::Ascending, -// }; -// let mut rem = 50; -// if rem > num_tokens { -// rem = num_tokens; -// } -// let n = r % rem; -// let position = MINTABLE_TOKEN_POSITIONS -// .keys(deps.storage, None, None, order) -// .skip(n as usize) -// .take(1) -// .collect::>>()?[0]; - -// let token_id = MINTABLE_TOKEN_POSITIONS.load(deps.storage, position)?; -// Ok(TokenPositionMapping { position, token_id }) -// } - pub fn execute_update_mint_price( deps: DepsMut, env: Env, @@ -1019,17 +961,9 @@ pub fn execute_burn_remaining( if mintable_num_tokens == 0 { return Err(ContractError::SoldOut {}); } - - // TODO: implement purge in sg_minter_utils - // let keys = MINTABLE_TOKEN_POSITIONS - // .keys(deps.storage, None, None, Order::Ascending) - // .collect::>(); - // let mut total: u32 = 0; - // for key in keys { - // total += 1; - // MINTABLE_TOKEN_POSITIONS.remove(deps.storage, key?); - // } - // Decrement mintable num tokens + // purge all buckets + sg_minter_utils::purge_buckets(deps.storage, sg_minter_utils::MAX_BUCKETS)?; + // Set mintable num tokens to 0 MINTABLE_NUM_TOKENS.save(deps.storage, &0)?; let event = Event::new("burn-remaining") diff --git a/packages/sg-minter-utils/src/lib.rs b/packages/sg-minter-utils/src/lib.rs index e7642cbe3..a07527980 100644 --- a/packages/sg-minter-utils/src/lib.rs +++ b/packages/sg-minter-utils/src/lib.rs @@ -2,12 +2,12 @@ use cosmwasm_schema::cw_serde; use cosmwasm_std::{StdError, Storage}; use cw_storage_plus::Item; -use nois::{int_in_range, sub_randomness_with_key}; +use nois::{int_in_range, shuffle as nois_shuffle, sub_randomness_with_key}; use thiserror::Error; // BUCKET_SIZE is limited to 256 to efficiently store ids as u8 partitioning into multiple buckets -const BUCKET_SIZE: u32 = 256; - -const MAX_SIZE: u32 = 256 * 256; +pub const BUCKET_SIZE: u32 = 256; +pub const MAX_BUCKETS: u32 = 256; +pub const MAX_SIZE: u32 = MAX_BUCKETS * BUCKET_SIZE; // buckets returns the number of necessary buckets for a given collection size. // it returns the number of buckets and the size of the last bucket @@ -159,6 +159,16 @@ pub fn purge_buckets(storage: &mut dyn Storage, max_buckets: u32) -> Result Result<(), MinterUtilsError> { + let mut provider = sub_randomness_with_key(random_seed, b"shuffle"); + let Some(available_buckets) = storage.get(&AVAILABLE_BUCKETS_KEY) else { + return Err(MinterUtilsError::NoAvailableBuckets {}); + }; + let shuffled = nois_shuffle(provider.provide(), available_buckets); + storage.set(&AVAILABLE_BUCKETS_KEY, &shuffled); + Ok(()) +} + pub fn pick_token(storage: &mut dyn Storage, token_id: u32) -> Result { let Some(mut available_buckets) = storage.get(&AVAILABLE_BUCKETS_KEY) else { return Err(MinterUtilsError::NoAvailableBuckets {}); @@ -166,7 +176,8 @@ pub fn pick_token(storage: &mut dyn Storage, token_id: u32) -> Result Result>() + ); + assert_eq!( + available_buckets, + [ + 21, 30, 37, 23, 11, 2, 29, 27, 8, 0, 7, 5, 15, 17, 6, 32, 25, 9, 36, 26, 13, 31, + 24, 10, 39, 35, 33, 12, 20, 16, 28, 18, 34, 19, 1, 4, 38, 22, 14, 3 + ] + ); + } + + #[test] + fn test_shuffle_and_pick_token() { + let mut deps = mock_dependencies(); + + let r = initialize(&mut deps.storage, 10_000); + assert!(r.is_ok()); + let r = shuffle(&mut deps.storage, [0; 32]); + assert!(r.is_ok()); + let token_id = pick_token(&mut deps.storage, 975).unwrap(); + assert_eq!(token_id, 975); + } } From 77123ea6bbbeb7587ddbcc97ca984705700e183d Mon Sep 17 00:00:00 2001 From: jhernadnezb Date: Thu, 19 Dec 2024 15:39:28 -0600 Subject: [PATCH 09/10] initialize and shuffle --- .../minters/vending-minter/src/contract.rs | 16 +++++++++- packages/sg-minter-utils/src/lib.rs | 31 +++++++++++++++++++ 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/contracts/minters/vending-minter/src/contract.rs b/contracts/minters/vending-minter/src/contract.rs index 43a51f081..159ec293e 100644 --- a/contracts/minters/vending-minter/src/contract.rs +++ b/contracts/minters/vending-minter/src/contract.rs @@ -167,7 +167,21 @@ pub fn instantiate( let last_discount_time = env.block.time.minus_seconds(60 * 60 * 12); LAST_DISCOUNT_TIME.save(deps.storage, &last_discount_time)?; - sg_minter_utils::initialize(deps.storage, msg.init_msg.num_tokens) + let sha256 = Sha256::digest( + format!( + "{}{}{}{}{}", + info.sender, + env.block.height, + &msg.init_msg.num_tokens, + env.block.time.nanos(), + env.transaction.map_or(0, |tx| tx.index), + ) + .into_bytes(), + ); + let randomness: [u8; 32] = sha256.to_vec()[0..32].try_into().map_err(|_| { + ContractError::Std(StdError::generic_err("Failed to convert sha256 to array")) + })?; + sg_minter_utils::initialize_and_shuffle(deps.storage, msg.init_msg.num_tokens, randomness) .map_err(ContractError::MinterUtils)?; // Submessage to instantiate sg721 contract diff --git a/packages/sg-minter-utils/src/lib.rs b/packages/sg-minter-utils/src/lib.rs index a07527980..dfdcb08c3 100644 --- a/packages/sg-minter-utils/src/lib.rs +++ b/packages/sg-minter-utils/src/lib.rs @@ -58,6 +58,16 @@ pub enum MinterUtilsError { InvalidTokenId { token_id: u32 }, } +pub fn initialize_and_shuffle( + storage: &mut dyn Storage, + size: u32, + random_seed: [u8; 32], +) -> Result<(), MinterUtilsError> { + initialize(storage, size)?; + shuffle(storage, random_seed)?; + Ok(()) +} + pub fn initialize(storage: &mut dyn Storage, size: u32) -> Result<(), MinterUtilsError> { if size > MAX_SIZE { return Err(MinterUtilsError::InvalidSize { @@ -472,6 +482,27 @@ mod tests { ); } + #[test] + fn test_initialize_with_seed() { + let mut deps = mock_dependencies(); + let r: Result<(), MinterUtilsError> = + initialize_and_shuffle(&mut deps.storage, 10_000, [0; 32]); + assert!(r.is_ok()); + let available_buckets = deps.storage.get(&AVAILABLE_BUCKETS_KEY).unwrap(); + assert_eq!(available_buckets.len(), 40); + assert_ne!( + available_buckets, + (0..40).map(|x| x as u8).collect::>() + ); + assert_eq!( + available_buckets, + [ + 21, 30, 37, 23, 11, 2, 29, 27, 8, 0, 7, 5, 15, 17, 6, 32, 25, 9, 36, 26, 13, 31, + 24, 10, 39, 35, 33, 12, 20, 16, 28, 18, 34, 19, 1, 4, 38, 22, 14, 3 + ] + ); + } + #[test] fn test_shuffle_and_pick_token() { let mut deps = mock_dependencies(); From 7023cb2de8fd8eee297c5dc7c36964e986357b92 Mon Sep 17 00:00:00 2001 From: jhernadnezb Date: Thu, 19 Dec 2024 16:08:36 -0600 Subject: [PATCH 10/10] fix liner --- packages/sg-minter-utils/src/lib.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/sg-minter-utils/src/lib.rs b/packages/sg-minter-utils/src/lib.rs index dfdcb08c3..cbb77ccf8 100644 --- a/packages/sg-minter-utils/src/lib.rs +++ b/packages/sg-minter-utils/src/lib.rs @@ -150,11 +150,11 @@ pub fn purge_buckets(storage: &mut dyn Storage, max_buckets: u32) -> Result= max_buckets { + for (i, bucket) in available_buckets.iter().enumerate() { + if i >= max_buckets as usize { break; } - let bucket_key = bucket_key(available_buckets[i]); + let bucket_key = bucket_key(*bucket); storage.remove(&bucket_key); buckets_to_remove += 1; }