diff --git a/Cargo.lock b/Cargo.lock index 2b4b90c72..15a279129 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -59,6 +59,24 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "claim" +version = "0.1.0" +dependencies = [ + "anyhow", + "cosmwasm-schema", + "cosmwasm-std", + "cosmwasm-storage", + "cw-multi-test", + "cw-utils", + "cw2", + "minter", + "schemars", + "serde", + "sg-std", + "thiserror", +] + [[package]] name = "const-oid" version = "0.6.2" diff --git a/contracts/claim/.cargo/config b/contracts/claim/.cargo/config new file mode 100644 index 000000000..336b618a1 --- /dev/null +++ b/contracts/claim/.cargo/config @@ -0,0 +1,4 @@ +[alias] +wasm = "build --release --target wasm32-unknown-unknown" +unit-test = "test --lib" +schema = "run --example schema" diff --git a/contracts/claim/.editorconfig b/contracts/claim/.editorconfig new file mode 100644 index 000000000..3d36f20b1 --- /dev/null +++ b/contracts/claim/.editorconfig @@ -0,0 +1,11 @@ +root = true + +[*] +indent_style = space +indent_size = 2 +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[*.rs] +indent_size = 4 diff --git a/contracts/claim/.gitignore b/contracts/claim/.gitignore new file mode 100644 index 000000000..dfdaaa6bc --- /dev/null +++ b/contracts/claim/.gitignore @@ -0,0 +1,15 @@ +# Build results +/target + +# Cargo+Git helper file (https://github.com/rust-lang/cargo/blob/0.44.1/src/cargo/sources/git/utils.rs#L320-L327) +.cargo-ok + +# Text file backups +**/*.rs.bk + +# macOS +.DS_Store + +# IDEs +*.iml +.idea diff --git a/contracts/claim/Cargo.lock b/contracts/claim/Cargo.lock new file mode 100644 index 000000000..c9737778e --- /dev/null +++ b/contracts/claim/Cargo.lock @@ -0,0 +1,596 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "base64" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" + +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "generic-array", +] + +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "const-oid" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c32f031ea41b4291d695026c023b95d59db2d8a2c7640800ed56bc8f510f22" + +[[package]] +name = "cosmwasm-crypto" +version = "1.0.0-beta4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f903ebbabc0d4880dbc76148efb8be8fc29fa4bf294c440c3d70da1c8bcafff7" +dependencies = [ + "digest", + "ed25519-zebra", + "k256", + "rand_core 0.5.1", + "thiserror", +] + +[[package]] +name = "cosmwasm-derive" +version = "1.0.0-beta4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "832bebef577ecb394603de8e2bf0de429b74aa364e17dec18e15ce37e71b0cae" +dependencies = [ + "syn", +] + +[[package]] +name = "cosmwasm-schema" +version = "1.0.0-beta" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22e4b3f6933f94acdd3ddb931af4870c2002e3331a4a8b247a4ef070dd31ccb0" +dependencies = [ + "schemars", + "serde_json", +] + +[[package]] +name = "cosmwasm-std" +version = "1.0.0-beta4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6238c45840cc9de5a39f0f619e3a4f7c38c5d2c6ac9e3e4d72751ee045e6d7da" +dependencies = [ + "base64", + "cosmwasm-crypto", + "cosmwasm-derive", + "schemars", + "serde", + "serde-json-wasm", + "thiserror", + "uint", +] + +[[package]] +name = "cosmwasm-storage" +version = "1.0.0-beta" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "665cf97ad42be46936f6e6739711824a9bf21c440a6c98e185a3404aef0c3b81" +dependencies = [ + "cosmwasm-std", + "serde", +] + +[[package]] +name = "cpufeatures" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66c99696f6c9dd7f35d486b9d04d7e6e202aa3e8c40d553f2fdf5e7e0c6a71ef" +dependencies = [ + "libc", +] + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "crypto-bigint" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b32a398eb1ccfbe7e4f452bc749c44d38dd732e9a253f19da224c416f00ee7f4" +dependencies = [ + "generic-array", + "rand_core 0.6.3", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-mac" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714" +dependencies = [ + "generic-array", + "subtle", +] + +[[package]] +name = "curve25519-dalek" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" +dependencies = [ + "byteorder", + "digest", + "rand_core 0.5.1", + "subtle", + "zeroize", +] + +[[package]] +name = "cw-storage-plus" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d7ee1963302b0ac2a9d42fe0faec826209c17452bfd36fbfd9d002a88929261" +dependencies = [ + "cosmwasm-std", + "schemars", + "serde", +] + +[[package]] +name = "cw2" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1d81d7c359d6c1fba3aa83dad7ec6f999e512571380ae62f81257c3db569743" +dependencies = [ + "cosmwasm-std", + "cw-storage-plus", + "schemars", + "serde", +] + +[[package]] +name = "der" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31e21d2d0f22cde6e88694108429775c0219760a07779bf96503b434a03d7412" +dependencies = [ + "const-oid", +] + +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array", +] + +[[package]] +name = "dyn-clone" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee2626afccd7561a06cf1367e2950c4718ea04565e20fb5029b6c7d8ad09abcf" + +[[package]] +name = "ecdsa" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "713c32426287891008edb98f8b5c6abb2130aa043c93a818728fcda78606f274" +dependencies = [ + "der", + "elliptic-curve", + "hmac", + "signature", +] + +[[package]] +name = "ed25519-zebra" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a128b76af6dd4b427e34a6fd43dc78dbfe73672ec41ff615a2414c1a0ad0409" +dependencies = [ + "curve25519-dalek", + "hex", + "rand_core 0.5.1", + "serde", + "sha2", + "thiserror", +] + +[[package]] +name = "elliptic-curve" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "069397e10739989e400628cbc0556a817a8a64119d7a2315767f4456e1332c23" +dependencies = [ + "crypto-bigint", + "ff", + "generic-array", + "group", + "pkcs8", + "rand_core 0.6.3", + "subtle", + "zeroize", +] + +[[package]] +name = "ff" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63eec06c61e487eecf0f7e6e6372e596a81922c28d33e645d6983ca6493a1af0" +dependencies = [ + "rand_core 0.6.3", + "subtle", +] + +[[package]] +name = "generic-array" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.10.2+wasi-snapshot-preview1", +] + +[[package]] +name = "group" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c363a5301b8f153d80747126a04b3c82073b9fe3130571a9d170cacdeaf7912" +dependencies = [ + "ff", + "rand_core 0.6.3", + "subtle", +] + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hmac" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a2a2320eb7ec0ebe8da8f744d7812d9fc4cb4d09344ac01898dbcb6a20ae69b" +dependencies = [ + "crypto-mac", + "digest", +] + +[[package]] +name = "itoa" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" + +[[package]] +name = "k256" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "903ae2481bcdfdb7b68e0a9baa4b7c9aff600b9ae2e8e5bb5833b8c91ab851ea" +dependencies = [ + "cfg-if", + "ecdsa", + "elliptic-curve", + "sha2", +] + +[[package]] +name = "libc" +version = "0.2.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7f823d141fe0a24df1e23b4af4e3c7ba9e5966ec514ea068c93024aa7deb765" + +[[package]] +name = "opaque-debug" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" + +[[package]] +name = "pkcs8" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbee84ed13e44dd82689fa18348a49934fa79cc774a344c42fc9b301c71b140a" +dependencies = [ + "der", + "spki", +] + +[[package]] +name = "proc-macro2" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c7ed8b8c7b886ea3ed7dde405212185f423ab44682667c8c6dd14aa1d9f6612" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "quote" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom 0.1.16", +] + +[[package]] +name = "rand_core" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" +dependencies = [ + "getrandom 0.2.3", +] + +[[package]] +name = "ryu" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" + +[[package]] +name = "schemars" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc6ab463ae35acccb5cba66c0084c985257b797d288b6050cc2f6ac1b266cb78" +dependencies = [ + "dyn-clone", + "schemars_derive", + "serde", + "serde_json", +] + +[[package]] +name = "schemars_derive" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "902fdfbcf871ae8f653bddf4b2c05905ddaabc08f69d32a915787e3be0d31356" +dependencies = [ + "proc-macro2", + "quote", + "serde_derive_internals", + "syn", +] + +[[package]] +name = "serde" +version = "1.0.127" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f03b9878abf6d14e6779d3f24f07b2cfa90352cfec4acc5aab8f1ac7f146fae8" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde-json-wasm" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "042ac496d97e5885149d34139bad1d617192770d7eb8f1866da2317ff4501853" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_derive" +version = "1.0.127" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a024926d3432516606328597e0f224a51355a493b49fdd67e9209187cbe55ecc" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_derive_internals" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dbab34ca63057a1f15280bdf3c39f2b1eb1b54c17e98360e511637aef7418c6" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "336b10da19a12ad094b59d870ebde26a45402e5b470add4b5fd03c5048a32127" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "sha2" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b362ae5752fd2137731f9fa25fd4d9058af34666ca1966fb969119cc35719f12" +dependencies = [ + "block-buffer", + "cfg-if", + "cpufeatures", + "digest", + "opaque-debug", +] + +[[package]] +name = "signature" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c19772be3c4dd2ceaacf03cb41d5885f2a02c4d8804884918e3a258480803335" +dependencies = [ + "digest", + "rand_core 0.6.3", +] + +[[package]] +name = "spki" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "987637c5ae6b3121aba9d513f869bd2bff11c4cc086c22473befd6649c0bd521" +dependencies = [ + "der", +] + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "subtle" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" + +[[package]] +name = "syn" +version = "1.0.74" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1873d832550d4588c3dbc20f01361ab00bfe741048f71e3fecf145a7cc18b29c" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "testgen-local" +version = "0.1.0" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cosmwasm-storage", + "cw-storage-plus", + "cw2", + "schemars", + "serde", + "thiserror", +] + +[[package]] +name = "thiserror" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93119e4feac1cbe6c798c34d3a53ea0026b0b1de6a120deef895137c0529bfe2" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "060d69a0afe7796bf42e9e2ff91f5ee691fb15c53d38b4b62a9a53eb23164745" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "typenum" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06" + +[[package]] +name = "uint" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6470ab50f482bde894a037a57064480a246dbfdd5960bd65a44824693f08da5f" +dependencies = [ + "byteorder", + "crunchy", + "hex", + "static_assertions", +] + +[[package]] +name = "unicode-xid" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" + +[[package]] +name = "version_check" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" + +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + +[[package]] +name = "wasi" +version = "0.10.2+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" + +[[package]] +name = "zeroize" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "377db0846015f7ae377174787dd452e1c5f5a9050bc6f954911d01f116daa0cd" diff --git a/contracts/claim/Cargo.toml b/contracts/claim/Cargo.toml new file mode 100644 index 000000000..6fd2697e3 --- /dev/null +++ b/contracts/claim/Cargo.toml @@ -0,0 +1,56 @@ +[package] +name = "claim" +version = "0.1.0" +authors = ["jhernandezb "] +edition = "2018" + +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"] + +[profile.release] +opt-level = 3 +debug = false +rpath = false +lto = true +debug-assertions = false +codegen-units = 1 +panic = 'abort' +incremental = false +overflow-checks = true + +[features] +# for more explicit tests, cargo test --features=backtraces +backtraces = ["cosmwasm-std/backtraces"] +# use library feature to disable all instantiate/execute/query exports +library = [] + +[package.metadata.scripts] +optimize = """docker run --rm -v "$(pwd)":/code \ + --mount type=volume,source="$(basename "$(pwd)")_cache",target=/code/target \ + --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \ + cosmwasm/rust-optimizer:0.12.5 +""" + +[dependencies] +cosmwasm-std = { version = "1.0.0-beta5" } +cosmwasm-storage = { version = "1.0.0-beta5" } +cw2 = "0.12.1" +cw-utils = "0.12.1" +schemars = "0.8" +serde = { version = "1.0", default-features = false, features = ["derive"] } +minter = { path = "../minter", features = ["library"] } +sg-std = { path = "../../packages/sg-std" } +thiserror = { version = "1.0" } + +[dev-dependencies] +cosmwasm-schema = { version = "1.0.0-beta5" } +cw-multi-test = "0.12.1" +anyhow = "1" diff --git a/contracts/claim/README.md b/contracts/claim/README.md new file mode 100644 index 000000000..69dfd53ca --- /dev/null +++ b/contracts/claim/README.md @@ -0,0 +1 @@ +# Stargaze Airdrop Claim Contract diff --git a/contracts/claim/examples/schema.rs b/contracts/claim/examples/schema.rs new file mode 100644 index 000000000..de44ccf02 --- /dev/null +++ b/contracts/claim/examples/schema.rs @@ -0,0 +1,16 @@ +use std::env::current_dir; +use std::fs::create_dir_all; + +use cosmwasm_schema::{export_schema, remove_schemas, schema_for}; + +use claim::msg::{ExecuteMsg, InstantiateMsg}; + +fn main() { + let mut out_dir = current_dir().unwrap(); + out_dir.push("schema"); + create_dir_all(&out_dir).unwrap(); + remove_schemas(&out_dir).unwrap(); + + export_schema(&schema_for!(InstantiateMsg), &out_dir); + export_schema(&schema_for!(ExecuteMsg), &out_dir); +} diff --git a/contracts/claim/rustfmt.toml b/contracts/claim/rustfmt.toml new file mode 100644 index 000000000..11a85e6a9 --- /dev/null +++ b/contracts/claim/rustfmt.toml @@ -0,0 +1,15 @@ +# stable +newline_style = "unix" +hard_tabs = false +tab_spaces = 4 + +# unstable... should we require `rustup run nightly cargo fmt` ? +# or just update the style guide when they are stable? +#fn_single_line = true +#format_code_in_doc_comments = true +#overflow_delimited_expr = true +#reorder_impl_items = true +#struct_field_align_threshold = 20 +#struct_lit_single_line = true +#report_todo = "Always" + diff --git a/contracts/claim/schema/execute_msg.json b/contracts/claim/schema/execute_msg.json new file mode 100644 index 000000000..94dfd1057 --- /dev/null +++ b/contracts/claim/schema/execute_msg.json @@ -0,0 +1,26 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ExecuteMsg", + "oneOf": [ + { + "type": "object", + "required": [ + "claim_mint_nft" + ], + "properties": { + "claim_mint_nft": { + "type": "object", + "required": [ + "minter_address" + ], + "properties": { + "minter_address": { + "type": "string" + } + } + } + }, + "additionalProperties": false + } + ] +} diff --git a/contracts/claim/schema/instantiate_msg.json b/contracts/claim/schema/instantiate_msg.json new file mode 100644 index 000000000..44588cf22 --- /dev/null +++ b/contracts/claim/schema/instantiate_msg.json @@ -0,0 +1,5 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "InstantiateMsg", + "type": "object" +} diff --git a/contracts/claim/src/contract.rs b/contracts/claim/src/contract.rs new file mode 100644 index 000000000..42dd35856 --- /dev/null +++ b/contracts/claim/src/contract.rs @@ -0,0 +1,64 @@ +#[cfg(not(feature = "library"))] +use cosmwasm_std::entry_point; + +use cosmwasm_std::{Addr, DepsMut, Env, MessageInfo}; +use cw2::set_contract_version; +use minter::msg::{MintCountResponse, QueryMsg}; +use sg_std::{create_claim_for_msg, ClaimAction, StargazeMsgWrapper}; + +use crate::error::ContractError; +use crate::msg::{ExecuteMsg, InstantiateMsg}; +pub type Response = cosmwasm_std::Response; + +// version info for migration info +const CONTRACT_NAME: &str = "crates.io:sg-claim"; +const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn instantiate( + deps: DepsMut, + _env: Env, + _info: MessageInfo, + _msg: InstantiateMsg, +) -> Result { + set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; + Ok(Response::new().add_attribute("action", "instantiate")) +} + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn execute( + deps: DepsMut, + _env: Env, + info: MessageInfo, + msg: ExecuteMsg, +) -> Result { + match msg { + ExecuteMsg::ClaimMintNFT { minter_address } => { + execute_claim_mint_nft(deps, info.sender, minter_address) + } + } +} + +pub fn execute_claim_mint_nft( + deps: DepsMut, + sender: Addr, + minter: String, +) -> Result { + let minter_addr = deps.api.addr_validate(&minter)?; + let count_response: MintCountResponse = deps.querier.query_wasm_smart( + minter_addr, + &QueryMsg::MintCount { + address: sender.to_string(), + }, + )?; + if count_response.count == 0 { + return Err(ContractError::NoMinting {}); + } + + let msg = create_claim_for_msg(sender.to_string(), ClaimAction::MintNFT); + Ok(Response::new() + .add_message(msg) + .add_attribute("action", "claim_mint_nft") + .add_attribute("sender", sender.to_string()) + .add_attribute("minter", minter)) +} diff --git a/contracts/claim/src/error.rs b/contracts/claim/src/error.rs new file mode 100644 index 000000000..287cc381f --- /dev/null +++ b/contracts/claim/src/error.rs @@ -0,0 +1,11 @@ +use cosmwasm_std::StdError; +use thiserror::Error; + +#[derive(Error, Debug)] +pub enum ContractError { + #[error("{0}")] + Std(#[from] StdError), + + #[error("NoMinting")] + NoMinting {}, +} diff --git a/contracts/claim/src/lib.rs b/contracts/claim/src/lib.rs new file mode 100644 index 000000000..3915b791e --- /dev/null +++ b/contracts/claim/src/lib.rs @@ -0,0 +1,5 @@ +pub mod contract; +mod error; +pub mod msg; + +pub use crate::error::ContractError; diff --git a/contracts/claim/src/msg.rs b/contracts/claim/src/msg.rs new file mode 100644 index 000000000..dc0d931b8 --- /dev/null +++ b/contracts/claim/src/msg.rs @@ -0,0 +1,12 @@ +use schemars::JsonSchema; +use serde::{Deserialize, Serialize}; + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +pub struct InstantiateMsg {} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[serde(rename_all = "snake_case")] +pub enum ExecuteMsg { + #[serde(rename = "claim_mint_nft")] + ClaimMintNFT { minter_address: String }, +} diff --git a/contracts/minter/Cargo.toml b/contracts/minter/Cargo.toml index a4e481e80..335a33b8a 100644 --- a/contracts/minter/Cargo.toml +++ b/contracts/minter/Cargo.toml @@ -51,7 +51,7 @@ sg721 = { path = "../sg721", features = ["library"] } thiserror = { version = "1.0" } url = "2.2.0" sg-std = { path = "../../packages/sg-std" } -whitelist = { path = "../whitelist" } +whitelist = { path = "../whitelist", features = ["library"]} cw721 = "0.12.0" cw721-base = { version = "0.12.0", features = ["library"] } diff --git a/e2e/claim_test.go b/e2e/claim_test.go new file mode 100644 index 000000000..ba255b950 --- /dev/null +++ b/e2e/claim_test.go @@ -0,0 +1,256 @@ +package e2e_test + +import ( + "fmt" + "io/ioutil" + "testing" + "time" + + wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" + + wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/public-awesome/stargaze/v3/testutil/simapp" + claimtypes "github.com/public-awesome/stargaze/v3/x/claim/types" + "github.com/stretchr/testify/require" + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" +) + +func TestClaim(t *testing.T) { + accs := GetAccounts() + + genAccs, balances := GetAccountsAndBalances(accs) + + app := simapp.SetupWithGenesisAccounts(t, t.TempDir(), genAccs, balances...) + + startDateTime, err := time.Parse(time.RFC3339Nano, "2022-03-11T20:59:00Z") + require.NoError(t, err) + ctx := app.BaseApp.NewContext(false, tmproto.Header{Height: 1, ChainID: "stargaze-1", Time: startDateTime}) + + app.ClaimKeeper.CreateModuleAccount(ctx, sdk.NewCoin(claimtypes.DefaultClaimDenom, sdk.NewInt(5000_000_000))) + + app.ClaimKeeper.SetParams(ctx, claimtypes.Params{ + AirdropEnabled: true, + AirdropStartTime: startDateTime, + DurationUntilDecay: claimtypes.DefaultDurationUntilDecay, + DurationOfDecay: claimtypes.DefaultDurationOfDecay, + ClaimDenom: claimtypes.DefaultClaimDenom, + }) + + // wasm params + wasmParams := app.WasmKeeper.GetParams(ctx) + wasmParams.CodeUploadAccess = wasmtypes.AllowEverybody + wasmParams.MaxWasmCodeSize = 1000 * 1024 * 4 // 4MB + app.WasmKeeper.SetParams(ctx, wasmParams) + + addr1 := accs[1].Address + + // minter + b, err := ioutil.ReadFile("contracts/minter.wasm") + require.NoError(t, err) + + msgServer := wasmkeeper.NewMsgServerImpl(wasmkeeper.NewDefaultPermissionKeeper(app.WasmKeeper)) + res, err := msgServer.StoreCode(sdk.WrapSDKContext(ctx), &wasmtypes.MsgStoreCode{ + Sender: addr1.String(), + WASMByteCode: b, + }) + require.NoError(t, err) + require.NotNil(t, res) + require.Equal(t, res.CodeID, uint64(1)) + + // claim + b, err = ioutil.ReadFile("contracts/claim.wasm") + require.NoError(t, err) + + res, err = msgServer.StoreCode(sdk.WrapSDKContext(ctx), &wasmtypes.MsgStoreCode{ + Sender: addr1.String(), + WASMByteCode: b, + }) + require.NoError(t, err) + require.NotNil(t, res) + require.Equal(t, res.CodeID, uint64(2)) + + // sg721 + b, err = ioutil.ReadFile("contracts/sg721.wasm") + require.NoError(t, err) + + res, err = msgServer.StoreCode(sdk.WrapSDKContext(ctx), &wasmtypes.MsgStoreCode{ + Sender: addr1.String(), + WASMByteCode: b, + }) + require.NoError(t, err) + require.NotNil(t, res) + require.Equal(t, res.CodeID, uint64(3)) + + creator := accs[0] + + // minter + afterGenesisMint, err := time.Parse(time.RFC3339Nano, "2022-03-11T21:00:01Z") + require.NoError(t, err) + genesisMintDateTime, err := time.Parse(time.RFC3339Nano, "2022-03-11T21:00:00Z") + require.NoError(t, err) + + instantiateMsgRaw := []byte( + fmt.Sprintf(instantiateMinterTemplate, + creator.Address.String(), + creator.Address.String(), + creator.Address.String(), + genesisMintDateTime.UnixNano(), + "null", + 1, // limit 1 + ), + ) + instantiateRes, err := msgServer.InstantiateContract(sdk.WrapSDKContext(ctx), &wasmtypes.MsgInstantiateContract{ + Sender: creator.Address.String(), + Admin: creator.Address.String(), + CodeID: 1, + Label: "Minter", + Msg: instantiateMsgRaw, + Funds: sdk.NewCoins(sdk.NewInt64Coin("ustars", 1_000_000_000)), + }) + require.NoError(t, err) + require.NotNil(t, instantiateRes) + require.NotEmpty(t, instantiateRes.Address) + minterAddress := instantiateRes.Address + ctx = app.BaseApp.NewContext(false, tmproto.Header{Height: 1, ChainID: "stargaze-1", Time: afterGenesisMint}) + + // mint succeeds + _, err = msgServer.ExecuteContract(sdk.WrapSDKContext(ctx), &wasmtypes.MsgExecuteContract{ + Contract: minterAddress, + Sender: accs[1].Address.String(), + Msg: []byte(`{"mint":{}}`), + Funds: sdk.NewCoins(sdk.NewInt64Coin("ustars", 100_000_000)), + }) + require.NoError(t, err) + + // Buyer should have 100STARS less + require.Equal(t, + sdk.NewInt64Coin("ustars", 1_900_000_000).String(), + app.BankKeeper.GetBalance(ctx, accs[1].Address, "ustars").String(), + ) + + claimRecords := []claimtypes.ClaimRecord{ + { + Address: addr1.String(), + InitialClaimableAmount: sdk.NewCoins(sdk.NewInt64Coin(claimtypes.DefaultClaimDenom, 1_000_000_000)), + ActionCompleted: []bool{false, false, false, false, false}, + }, + } + err = app.ClaimKeeper.SetClaimRecords(ctx, claimRecords) + require.NoError(t, err) + + instantiateRes, err = msgServer.InstantiateContract(sdk.WrapSDKContext(ctx), &wasmtypes.MsgInstantiateContract{ + Sender: creator.Address.String(), + Admin: creator.Address.String(), + CodeID: 2, + Label: "Claim", + Msg: []byte("{}"), + }) + require.NoError(t, err) + require.NotNil(t, instantiateRes) + require.NotEmpty(t, instantiateRes.Address) + claimAddress := instantiateRes.Address + require.NotEmpty(t, claimAddress) + + // claim airdrop + claimMsgTemplate := ` + { + "claim_mint_nft" : { + "minter_address":"%s" + } + } + ` + claimMsgRaw := []byte(fmt.Sprintf(claimMsgTemplate, minterAddress)) + _, err = msgServer.ExecuteContract(sdk.WrapSDKContext(ctx), &wasmtypes.MsgExecuteContract{ + Contract: claimAddress, + Sender: accs[1].Address.String(), + Msg: claimMsgRaw, + }) + require.Error(t, err) + require.Contains(t, err.Error(), "address is not allowed to claim") + + // allow contract + + app.ClaimKeeper.SetParams(ctx, claimtypes.Params{ + AirdropEnabled: true, + AirdropStartTime: startDateTime, + DurationUntilDecay: claimtypes.DefaultDurationUntilDecay, + DurationOfDecay: claimtypes.DefaultDurationOfDecay, + ClaimDenom: claimtypes.DefaultClaimDenom, + AllowedClaimers: []claimtypes.ClaimAuthorization{ + { + ContractAddress: claimAddress, + Action: claimtypes.ActionBidNFT, + }, + }, + }) + + claimMsgRaw = []byte(fmt.Sprintf(claimMsgTemplate, minterAddress)) + _, err = msgServer.ExecuteContract(sdk.WrapSDKContext(ctx), &wasmtypes.MsgExecuteContract{ + Contract: claimAddress, + Sender: accs[1].Address.String(), + Msg: claimMsgRaw, + }) + require.Error(t, err) + require.Contains(t, err.Error(), "address is not allowed to claim") + claim, err := app.ClaimKeeper.GetClaimRecord(ctx, addr1) + require.NoError(t, err) + require.False(t, claim.ActionCompleted[claimtypes.ActionMintNFT]) + + app.ClaimKeeper.SetParams(ctx, claimtypes.Params{ + AirdropEnabled: true, + AirdropStartTime: startDateTime, + DurationUntilDecay: claimtypes.DefaultDurationUntilDecay, + DurationOfDecay: claimtypes.DefaultDurationOfDecay, + ClaimDenom: claimtypes.DefaultClaimDenom, + AllowedClaimers: []claimtypes.ClaimAuthorization{ + { + ContractAddress: claimAddress, + Action: claimtypes.ActionMintNFT, + }, + }, + }) + + balance := app.BankKeeper.GetBalance(ctx, accs[1].Address, "ustars") + require.Equal(t, + "1900000000", + balance.Amount.String(), + ) + + claimMsgRaw = []byte(fmt.Sprintf(claimMsgTemplate, minterAddress)) + _, err = msgServer.ExecuteContract(sdk.WrapSDKContext(ctx), &wasmtypes.MsgExecuteContract{ + Contract: claimAddress, + Sender: accs[1].Address.String(), + Msg: claimMsgRaw, + }) + require.NoError(t, err) + balance = app.BankKeeper.GetBalance(ctx, accs[1].Address, "ustars") + perAction := claimRecords[0].InitialClaimableAmount.AmountOf(claimtypes.DefaultClaimDenom).Quo(sdk.NewInt(int64(len(claimRecords[0].ActionCompleted)))) + + require.Equal(t, perAction.Int64(), int64(200_000_000)) + expectedBalance := perAction.Add(sdk.NewInt(1_900_000_000)) // user already had 19000 + require.Equal(t, + expectedBalance.String(), + balance.Amount.String(), + ) + + claim, err = app.ClaimKeeper.GetClaimRecord(ctx, addr1) + require.NoError(t, err) + require.True(t, claim.ActionCompleted[claimtypes.ActionMintNFT]) + + claimMsgRaw = []byte(fmt.Sprintf(claimMsgTemplate, minterAddress)) + _, err = msgServer.ExecuteContract(sdk.WrapSDKContext(ctx), &wasmtypes.MsgExecuteContract{ + Contract: claimAddress, + Sender: accs[1].Address.String(), + Msg: claimMsgRaw, + }) + require.NoError(t, err) + + balance = app.BankKeeper.GetBalance(ctx, accs[1].Address, "ustars") + require.Equal(t, + expectedBalance.String(), + balance.Amount.String(), + "balance should stay the same", + ) + +} diff --git a/e2e/full_test.go b/e2e/full_test.go index c0c2019d7..dafa6e521 100644 --- a/e2e/full_test.go +++ b/e2e/full_test.go @@ -8,7 +8,6 @@ import ( "time" wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" - "github.com/CosmWasm/wasmd/x/wasm/types" wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" sdk "github.com/cosmos/cosmos-sdk/types" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" @@ -132,7 +131,7 @@ func TestMinter(t *testing.T) { require.NoError(t, err) msgServer := wasmkeeper.NewMsgServerImpl(wasmkeeper.NewDefaultPermissionKeeper(app.WasmKeeper)) - res, err := msgServer.StoreCode(sdk.WrapSDKContext(ctx), &types.MsgStoreCode{ + res, err := msgServer.StoreCode(sdk.WrapSDKContext(ctx), &wasmtypes.MsgStoreCode{ Sender: addr1.String(), WASMByteCode: b, }) @@ -144,7 +143,7 @@ func TestMinter(t *testing.T) { b, err = ioutil.ReadFile("contracts/whitelist.wasm") require.NoError(t, err) - res, err = msgServer.StoreCode(sdk.WrapSDKContext(ctx), &types.MsgStoreCode{ + res, err = msgServer.StoreCode(sdk.WrapSDKContext(ctx), &wasmtypes.MsgStoreCode{ Sender: addr1.String(), WASMByteCode: b, }) @@ -156,7 +155,7 @@ func TestMinter(t *testing.T) { b, err = ioutil.ReadFile("contracts/sg721.wasm") require.NoError(t, err) - res, err = msgServer.StoreCode(sdk.WrapSDKContext(ctx), &types.MsgStoreCode{ + res, err = msgServer.StoreCode(sdk.WrapSDKContext(ctx), &wasmtypes.MsgStoreCode{ Sender: addr1.String(), WASMByteCode: b, }) @@ -328,7 +327,7 @@ func TestWhitelistMinter(t *testing.T) { require.NoError(t, err) msgServer := wasmkeeper.NewMsgServerImpl(wasmkeeper.NewDefaultPermissionKeeper(app.WasmKeeper)) - res, err := msgServer.StoreCode(sdk.WrapSDKContext(ctx), &types.MsgStoreCode{ + res, err := msgServer.StoreCode(sdk.WrapSDKContext(ctx), &wasmtypes.MsgStoreCode{ Sender: addr1.String(), WASMByteCode: b, }) @@ -340,7 +339,7 @@ func TestWhitelistMinter(t *testing.T) { b, err = ioutil.ReadFile("contracts/whitelist.wasm") require.NoError(t, err) - res, err = msgServer.StoreCode(sdk.WrapSDKContext(ctx), &types.MsgStoreCode{ + res, err = msgServer.StoreCode(sdk.WrapSDKContext(ctx), &wasmtypes.MsgStoreCode{ Sender: addr1.String(), WASMByteCode: b, }) @@ -352,7 +351,7 @@ func TestWhitelistMinter(t *testing.T) { b, err = ioutil.ReadFile("contracts/sg721.wasm") require.NoError(t, err) - res, err = msgServer.StoreCode(sdk.WrapSDKContext(ctx), &types.MsgStoreCode{ + res, err = msgServer.StoreCode(sdk.WrapSDKContext(ctx), &wasmtypes.MsgStoreCode{ Sender: addr1.String(), WASMByteCode: b, }) diff --git a/go.mod b/go.mod index 12027639e..1f60fed02 100644 --- a/go.mod +++ b/go.mod @@ -2,13 +2,18 @@ module github.com/public-awesome/stargaze-contracts go 1.17 -require github.com/public-awesome/stargaze/v3 v3.0.0 +require ( + github.com/CosmWasm/wasmd v0.23.0 + github.com/cosmos/cosmos-sdk v0.45.1 + github.com/public-awesome/stargaze/v3 v3.0.0 + github.com/stretchr/testify v1.7.0 + github.com/tendermint/tendermint v0.34.15 +) require ( filippo.io/edwards25519 v1.0.0-beta.2 // indirect github.com/99designs/keyring v1.1.6 // indirect github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d // indirect - github.com/CosmWasm/wasmd v0.23.0 // indirect github.com/CosmWasm/wasmvm v1.0.0-beta5 // indirect github.com/DataDog/zstd v1.4.5 // indirect github.com/Workiva/go-datastructures v1.0.53 // indirect @@ -21,7 +26,6 @@ require ( github.com/coinbase/rosetta-sdk-go v0.7.0 // indirect github.com/confio/ics23/go v0.6.6 // indirect github.com/cosmos/btcutil v1.0.4 // indirect - github.com/cosmos/cosmos-sdk v0.45.1 // indirect github.com/cosmos/go-bip39 v1.0.0 // indirect github.com/cosmos/iavl v0.17.3 // indirect github.com/cosmos/ibc-go/v2 v2.0.3 // indirect @@ -94,7 +98,6 @@ require ( github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/spf13/viper v1.10.1 // indirect - github.com/stretchr/testify v1.7.0 // indirect github.com/subosito/gotenv v1.2.0 // indirect github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca // indirect github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c // indirect @@ -102,7 +105,6 @@ require ( github.com/tendermint/crypto v0.0.0-20191022145703-50d29ede1e15 // indirect github.com/tendermint/go-amino v0.16.0 // indirect github.com/tendermint/spm v0.1.9 // indirect - github.com/tendermint/tendermint v0.34.15 // indirect github.com/tendermint/tm-db v0.6.6 // indirect github.com/zondax/hid v0.9.0 // indirect go.etcd.io/bbolt v1.3.6 // indirect diff --git a/types/contracts/claim/execute_msg.d.ts b/types/contracts/claim/execute_msg.d.ts new file mode 100644 index 000000000..a3d7be1c6 --- /dev/null +++ b/types/contracts/claim/execute_msg.d.ts @@ -0,0 +1,6 @@ +export type ExecuteMsg = { +claim_mint_nft: { +minter_address: string +[k: string]: unknown +} +} diff --git a/types/contracts/claim/index.ts b/types/contracts/claim/index.ts new file mode 100644 index 000000000..d06b95c7f --- /dev/null +++ b/types/contracts/claim/index.ts @@ -0,0 +1,2 @@ +export * from './execute_msg' +export * from './instantiate_msg' diff --git a/types/contracts/claim/instantiate_msg.d.ts b/types/contracts/claim/instantiate_msg.d.ts new file mode 100644 index 000000000..fa310209a --- /dev/null +++ b/types/contracts/claim/instantiate_msg.d.ts @@ -0,0 +1,3 @@ +export interface InstantiateMsg { +[k: string]: unknown +} diff --git a/types/contracts/claim/tsconfig.json b/types/contracts/claim/tsconfig.json new file mode 100644 index 000000000..91cd56ea5 --- /dev/null +++ b/types/contracts/claim/tsconfig.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "target": "es2017", + "lib": ["esnext"], + "baseUrl": ".", + "sourceMap": true + }, + "include": ["*.ts"], + "exclude": ["node_modules"] +}