diff --git a/Cargo.lock b/Cargo.lock
index cbfa76190..30e08d09c 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1,19 +1,21 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
+version = 3
+
[[package]]
name = "addr2line"
-version = "0.13.0"
+version = "0.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1b6a2d3371669ab3ca9797670853d61402b03d0b4b9ebf33d677dfa720203072"
+checksum = "3e61f2b7f93d2c7d2b08263acaa4a363b3e276806c68af6134c44f523bf1aacd"
dependencies = [
"gimli",
]
[[package]]
name = "adler"
-version = "0.2.3"
+version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ee2a4ec343196209d6594e19543ae87a39f96d5534d7174822a3ad825dd6ed7e"
+checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
[[package]]
name = "arrayref"
@@ -29,11 +31,12 @@ checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
[[package]]
name = "backtrace"
-version = "0.3.50"
+version = "0.3.61"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "46254cf2fdcdf1badb5934448c1bcbe046a56537b3987d96c51a7afc5d03f293"
+checksum = "e7a905d892734eea339e896738c14b9afce22b5318f64b951e70bf3844419b01"
dependencies = [
"addr2line",
+ "cc",
"cfg-if",
"libc",
"miniz_oxide",
@@ -66,7 +69,7 @@ dependencies = [
"block-padding",
"byte-tools",
"byteorder",
- "generic-array 0.12.3",
+ "generic-array 0.12.4",
]
[[package]]
@@ -95,15 +98,21 @@ checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7"
[[package]]
name = "byteorder"
-version = "1.3.4"
+version = "1.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
+
+[[package]]
+name = "cc"
+version = "1.0.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de"
+checksum = "e70cc2f62c6ce1868963827bd677764c62d07c3d9a3e1fb1177ee1a9ab199eb2"
[[package]]
name = "cfg-if"
-version = "0.1.10"
+version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
+checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "cosmwasm-schema"
@@ -114,18 +123,6 @@ dependencies = [
"serde_json",
]
-[[package]]
-name = "cosmwasm-std"
-version = "0.10.0"
-source = "git+https://github.com/enigmampc/SecretNetwork?tag=v1.0.0#490fba9243e6cb291462e9d3c1bcbd1975c0df1e"
-dependencies = [
- "base64",
- "schemars",
- "serde",
- "serde-json-wasm",
- "snafu",
-]
-
[[package]]
name = "cosmwasm-std"
version = "0.10.0"
@@ -138,53 +135,24 @@ dependencies = [
"snafu",
]
-[[package]]
-name = "cosmwasm-std"
-version = "0.10.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f85908a2696117c8f2c1b3ce201d34a1aa9a6b3c1583a65cfb794ec66e1cfde4"
-dependencies = [
- "base64",
- "schemars",
- "serde",
- "serde-json-wasm",
- "snafu",
-]
-
-[[package]]
-name = "cosmwasm-storage"
-version = "0.10.0"
-source = "git+https://github.com/enigmampc/SecretNetwork?tag=v1.0.0#490fba9243e6cb291462e9d3c1bcbd1975c0df1e"
-dependencies = [
- "cosmwasm-std 0.10.0 (git+https://github.com/enigmampc/SecretNetwork?tag=v1.0.0)",
- "serde",
-]
-
[[package]]
name = "cosmwasm-storage"
version = "0.10.0"
source = "git+https://github.com/enigmampc/SecretNetwork?tag=v1.0.4-debug-print#004c6bca6f2b7f31a6594abe4f44f2e41b1456b3"
dependencies = [
- "cosmwasm-std 0.10.0 (git+https://github.com/enigmampc/SecretNetwork?tag=v1.0.4-debug-print)",
+ "cosmwasm-std",
"serde",
]
[[package]]
-name = "cosmwasm-storage"
-version = "0.10.1"
+name = "cpufeatures"
+version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e103531a2ce636e86b7639cec25d348c4d360832ab8e0e7f9a6e00f08aac1379"
+checksum = "66c99696f6c9dd7f35d486b9d04d7e6e202aa3e8c40d553f2fdf5e7e0c6a71ef"
dependencies = [
- "cosmwasm-std 0.10.1",
- "serde",
+ "libc",
]
-[[package]]
-name = "cpuid-bool"
-version = "0.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8aebca1129a03dc6dc2b127edd729435bbc4a37e1d5f4d7513165089ceb02634"
-
[[package]]
name = "crunchy"
version = "0.2.2"
@@ -197,40 +165,17 @@ version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4434400df11d95d556bac068ddfedd482915eb18fe8bea89bc80b6e4b1c179e5"
dependencies = [
- "generic-array 0.12.3",
+ "generic-array 0.12.4",
"subtle 1.0.0",
]
-[[package]]
-name = "cw0"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "21544b8cbbcbb99dfdf071408288925ebeaf8f633a6138a19bd2156b8ff6ab31"
-dependencies = [
- "cosmwasm-std 0.10.1",
- "schemars",
- "serde",
-]
-
-[[package]]
-name = "cw20"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c68a7162d61e99e7cbdc228025b847506bd8c5501c80494b33c0df6d1628d0f4"
-dependencies = [
- "cosmwasm-std 0.10.1",
- "cw0",
- "schemars",
- "serde",
-]
-
[[package]]
name = "digest"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5"
dependencies = [
- "generic-array 0.12.3",
+ "generic-array 0.12.4",
]
[[package]]
@@ -256,9 +201,9 @@ checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
[[package]]
name = "generic-array"
-version = "0.12.3"
+version = "0.12.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec"
+checksum = "ffdf9f34f1447443d37393cc6c2b8313aebddcd96906caf34e54c68d8e57d7bd"
dependencies = [
"typenum",
]
@@ -275,9 +220,9 @@ dependencies = [
[[package]]
name = "gimli"
-version = "0.22.0"
+version = "0.25.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "aaf91faf136cb47367fa430cd46e37a788775e7fa104f8b4bcb3861dc389b724"
+checksum = "f0a01e0497841a3b2db4f8afa483cce65f7e96a3498bd6c541734792aeac8fe7"
[[package]]
name = "hmac"
@@ -296,21 +241,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c6e570451493f10f6581b48cdd530413b63ea9e780f544bfd3bdcaa0d89d1a7b"
dependencies = [
"digest 0.8.1",
- "generic-array 0.12.3",
+ "generic-array 0.12.4",
"hmac",
]
[[package]]
name = "itoa"
-version = "0.4.6"
+version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dc6f3ad7b9d11a0c00842ff8de1b60ee58661048eb8049ed33c73594f359d7e6"
+checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736"
[[package]]
name = "libc"
-version = "0.2.77"
+version = "0.2.98"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f2f96b10ec2560088a8e76961b00d47107b3a625fecb76dedb29ee7ccbf98235"
+checksum = "320cfe77175da3a483efed4bc0adc1968ca050b098ce4f2f1c13a56626128790"
[[package]]
name = "libsecp256k1"
@@ -324,37 +269,48 @@ dependencies = [
"hmac-drbg",
"rand",
"sha2 0.8.2",
- "subtle 2.3.0",
+ "subtle 2.4.1",
"typenum",
]
+[[package]]
+name = "memchr"
+version = "2.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc"
+
[[package]]
name = "miniz_oxide"
-version = "0.4.2"
+version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c60c0dfe32c10b43a144bad8fc83538c52f58302c92300ea7ec7bf7b38d5a7b9"
+checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b"
dependencies = [
"adler",
"autocfg",
]
[[package]]
-name = "mirror-protocol"
-version = "1.1.0"
+name = "mint"
+version = "0.1.0"
dependencies = [
- "cosmwasm-std 0.10.1",
- "cosmwasm-storage 0.10.1",
- "cw20",
+ "cosmwasm-schema",
+ "cosmwasm-std",
+ "cosmwasm-storage",
"schemars",
+ "secret-toolkit",
"serde",
- "terraswap",
+ "shade-protocol",
+ "snafu",
]
[[package]]
name = "object"
-version = "0.20.0"
+version = "0.26.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1ab52be62400ca80aa00285d25253d7f7c437b7375c4de678f5405d3afe82ca5"
+checksum = "c55827317fb4c08822499848a14237d2874d6f139828893017237e7ab93eb386"
+dependencies = [
+ "memchr",
+]
[[package]]
name = "opaque-debug"
@@ -368,6 +324,20 @@ version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
+[[package]]
+name = "oracle"
+version = "0.1.0"
+dependencies = [
+ "cosmwasm-schema",
+ "cosmwasm-std",
+ "cosmwasm-storage",
+ "schemars",
+ "secret-toolkit",
+ "serde",
+ "shade-protocol",
+ "snafu",
+]
+
[[package]]
name = "ppv-lite86"
version = "0.2.10"
@@ -376,18 +346,18 @@ checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857"
[[package]]
name = "proc-macro2"
-version = "1.0.27"
+version = "1.0.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f0d8caf72986c1a598726adc988bb5984792ef84f5ee5aa50209145ee8077038"
+checksum = "5c7ed8b8c7b886ea3ed7dde405212185f423ab44682667c8c6dd14aa1d9f6612"
dependencies = [
"unicode-xid",
]
[[package]]
name = "quote"
-version = "1.0.7"
+version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37"
+checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7"
dependencies = [
"proc-macro2",
]
@@ -430,9 +400,9 @@ dependencies = [
[[package]]
name = "rustc-demangle"
-version = "0.1.16"
+version = "0.1.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783"
+checksum = "dead70b0b5e03e9c814bcb6b01e03e68f7c57a80aa48c72ec92152ab3e818d49"
[[package]]
name = "ryu"
@@ -466,7 +436,7 @@ dependencies = [
[[package]]
name = "secret-toolkit"
version = "0.1.0"
-source = "git+https://github.com/enigmampc/secret-toolkit?branch=master#87b3a5d721bebbb73a20be56b9f403b4be10eed2"
+source = "git+https://github.com/enigmampc/secret-toolkit?branch=debug-print#f8de2a926fccab9d1f10653bdbc00ea5436df570"
dependencies = [
"secret-toolkit-crypto",
"secret-toolkit-serialization",
@@ -479,31 +449,31 @@ dependencies = [
[[package]]
name = "secret-toolkit-crypto"
version = "0.1.0"
-source = "git+https://github.com/enigmampc/secret-toolkit?branch=master#87b3a5d721bebbb73a20be56b9f403b4be10eed2"
+source = "git+https://github.com/enigmampc/secret-toolkit?branch=debug-print#f8de2a926fccab9d1f10653bdbc00ea5436df570"
dependencies = [
- "cosmwasm-std 0.10.0 (git+https://github.com/enigmampc/SecretNetwork?tag=v1.0.0)",
+ "cosmwasm-std",
"libsecp256k1",
"rand_chacha",
"rand_core",
- "sha2 0.9.1",
+ "sha2 0.9.5",
]
[[package]]
name = "secret-toolkit-serialization"
version = "0.1.0"
-source = "git+https://github.com/enigmampc/secret-toolkit?branch=master#87b3a5d721bebbb73a20be56b9f403b4be10eed2"
+source = "git+https://github.com/enigmampc/secret-toolkit?branch=debug-print#f8de2a926fccab9d1f10653bdbc00ea5436df570"
dependencies = [
"bincode2",
- "cosmwasm-std 0.10.0 (git+https://github.com/enigmampc/SecretNetwork?tag=v1.0.0)",
+ "cosmwasm-std",
"serde",
]
[[package]]
name = "secret-toolkit-snip20"
version = "0.1.0"
-source = "git+https://github.com/enigmampc/secret-toolkit?branch=master#87b3a5d721bebbb73a20be56b9f403b4be10eed2"
+source = "git+https://github.com/enigmampc/secret-toolkit?branch=debug-print#f8de2a926fccab9d1f10653bdbc00ea5436df570"
dependencies = [
- "cosmwasm-std 0.10.0 (git+https://github.com/enigmampc/SecretNetwork?tag=v1.0.0)",
+ "cosmwasm-std",
"schemars",
"secret-toolkit-utils",
"serde",
@@ -512,9 +482,9 @@ dependencies = [
[[package]]
name = "secret-toolkit-snip721"
version = "0.1.0"
-source = "git+https://github.com/enigmampc/secret-toolkit?branch=master#87b3a5d721bebbb73a20be56b9f403b4be10eed2"
+source = "git+https://github.com/enigmampc/secret-toolkit?branch=debug-print#f8de2a926fccab9d1f10653bdbc00ea5436df570"
dependencies = [
- "cosmwasm-std 0.10.0 (git+https://github.com/enigmampc/SecretNetwork?tag=v1.0.0)",
+ "cosmwasm-std",
"schemars",
"secret-toolkit-utils",
"serde",
@@ -523,10 +493,10 @@ dependencies = [
[[package]]
name = "secret-toolkit-storage"
version = "0.1.0"
-source = "git+https://github.com/enigmampc/secret-toolkit?branch=master#87b3a5d721bebbb73a20be56b9f403b4be10eed2"
+source = "git+https://github.com/enigmampc/secret-toolkit?branch=debug-print#f8de2a926fccab9d1f10653bdbc00ea5436df570"
dependencies = [
- "cosmwasm-std 0.10.0 (git+https://github.com/enigmampc/SecretNetwork?tag=v1.0.0)",
- "cosmwasm-storage 0.10.0 (git+https://github.com/enigmampc/SecretNetwork?tag=v1.0.0)",
+ "cosmwasm-std",
+ "cosmwasm-storage",
"secret-toolkit-serialization",
"serde",
]
@@ -534,36 +504,36 @@ dependencies = [
[[package]]
name = "secret-toolkit-utils"
version = "0.1.0"
-source = "git+https://github.com/enigmampc/secret-toolkit?branch=master#87b3a5d721bebbb73a20be56b9f403b4be10eed2"
+source = "git+https://github.com/enigmampc/secret-toolkit?branch=debug-print#f8de2a926fccab9d1f10653bdbc00ea5436df570"
dependencies = [
- "cosmwasm-std 0.10.0 (git+https://github.com/enigmampc/SecretNetwork?tag=v1.0.0)",
+ "cosmwasm-std",
"schemars",
"serde",
]
[[package]]
name = "serde"
-version = "1.0.126"
+version = "1.0.127"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ec7505abeacaec74ae4778d9d9328fe5a5d04253220a85c4ee022239fc996d03"
+checksum = "f03b9878abf6d14e6779d3f24f07b2cfa90352cfec4acc5aab8f1ac7f146fae8"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde-json-wasm"
-version = "0.2.1"
+version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7294d94d390f1d2334697c065ea591d7074c676e2d20aa6f1df752fced29823f"
+checksum = "120bad73306616e91acd7ceed522ba96032a51cffeef3cc813de7f367df71e37"
dependencies = [
"serde",
]
[[package]]
name = "serde_derive"
-version = "1.0.126"
+version = "1.0.127"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "963a7dbc9895aeac7ac90e74f34a5d5261828f79df35cbed41e10189d3804d43"
+checksum = "a024926d3432516606328597e0f224a51355a493b49fdd67e9209187cbe55ecc"
dependencies = [
"proc-macro2",
"quote",
@@ -583,9 +553,9 @@ dependencies = [
[[package]]
name = "serde_json"
-version = "1.0.57"
+version = "1.0.66"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "164eacbdb13512ec2745fb09d51fd5b22b0d65ed294a1dcf7285a360c80a675c"
+checksum = "336b10da19a12ad094b59d870ebde26a45402e5b470add4b5fd03c5048a32127"
dependencies = [
"itoa",
"ryu",
@@ -606,24 +576,24 @@ dependencies = [
[[package]]
name = "sha2"
-version = "0.9.1"
+version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2933378ddfeda7ea26f48c555bdad8bb446bf8a3d17832dc83e380d444cfb8c1"
+checksum = "b362ae5752fd2137731f9fa25fd4d9058af34666ca1966fb969119cc35719f12"
dependencies = [
"block-buffer 0.9.0",
"cfg-if",
- "cpuid-bool",
+ "cpufeatures",
"digest 0.9.0",
"opaque-debug 0.3.0",
]
[[package]]
-name = "shade-mint"
+name = "shade-protocol"
version = "0.1.0"
dependencies = [
"cosmwasm-schema",
- "cosmwasm-std 0.10.0 (git+https://github.com/enigmampc/SecretNetwork?tag=v1.0.4-debug-print)",
- "cosmwasm-storage 0.10.0 (git+https://github.com/enigmampc/SecretNetwork?tag=v1.0.4-debug-print)",
+ "cosmwasm-std",
+ "cosmwasm-storage",
"schemars",
"secret-toolkit",
"serde",
@@ -632,9 +602,9 @@ dependencies = [
[[package]]
name = "snafu"
-version = "0.6.8"
+version = "0.6.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c7f5aed652511f5c9123cf2afbe9c244c29db6effa2abb05c866e965c82405ce"
+checksum = "eab12d3c261b2308b0d80c26fffb58d17eba81a4be97890101f416b478c79ca7"
dependencies = [
"backtrace",
"doc-comment",
@@ -643,9 +613,9 @@ dependencies = [
[[package]]
name = "snafu-derive"
-version = "0.6.8"
+version = "0.6.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ebf8f7d5720104a9df0f7076a8682024e958bba0fe9848767bb44f251f3648e9"
+checksum = "1508efa03c362e23817f96cde18abed596a25219a8b2c66e8db33c03543d315b"
dependencies = [
"proc-macro2",
"quote",
@@ -660,60 +630,35 @@ checksum = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee"
[[package]]
name = "subtle"
-version = "2.3.0"
+version = "2.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "343f3f510c2915908f155e94f17220b19ccfacf2a64a2a5d8004f2c3e311e7fd"
+checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601"
[[package]]
name = "syn"
-version = "1.0.73"
+version = "1.0.74"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f71489ff30030d2ae598524f61326b902466f72a0fb1a8564c001cc63425bcc7"
+checksum = "1873d832550d4588c3dbc20f01361ab00bfe741048f71e3fecf145a7cc18b29c"
dependencies = [
"proc-macro2",
"quote",
"unicode-xid",
]
-[[package]]
-name = "terra-cosmwasm"
-version = "1.2.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4d7275aacd385e4f41647634c35692b1982085917b4dcfc1fdfa3984ee4ce45d"
-dependencies = [
- "cosmwasm-std 0.10.1",
- "schemars",
- "serde",
-]
-
-[[package]]
-name = "terraswap"
-version = "1.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "02334ec5ad280fcc09c86467d40383ea1e4d977103345e53a4f03006c4be51c2"
-dependencies = [
- "cosmwasm-std 0.10.1",
- "cosmwasm-storage 0.10.1",
- "cw20",
- "schemars",
- "serde",
- "terra-cosmwasm",
-]
-
[[package]]
name = "typenum"
-version = "1.12.0"
+version = "1.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33"
+checksum = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06"
[[package]]
name = "unicode-xid"
-version = "0.2.1"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
+checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
[[package]]
name = "version_check"
-version = "0.9.2"
+version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed"
+checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe"
diff --git a/Cargo.toml b/Cargo.toml
index 67d04c481..3c7db5517 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,14 +1,2 @@
[workspace]
-members = ["packages/*", "shade-contracts/*"]
-
-[profile.release.package.mirror-protocol]
-opt-level = 3
-debug = false
-debug-assertions = false
-codegen-units = 1
-incremental = false
-
-[profile.release]
-rpath = false
-lto = true
-overflow-checks = true
+members = ["contracts/mint","contracts/oracle", "packages/shade_protocol"]
diff --git a/LICENSE b/LICENSE
index cd382ffc4..153d416dc 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,52 +1,165 @@
-Apache License
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
-Version 2.0, January 2004
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
-http://www.apache.org/licenses/
-TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+ This version of the GNU Lesser General Public License incorporates
+the terms and conditions of version 3 of the GNU General Public
+License, supplemented by the additional permissions listed below.
-1. Definitions.
+ 0. Additional Definitions.
-"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
+ As used herein, "this License" refers to version 3 of the GNU Lesser
+General Public License, and the "GNU GPL" refers to version 3 of the GNU
+General Public License.
-"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
-
-"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
-
-"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
-
-"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
-
-"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
-
-"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
-
-"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
-
-"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
-
-"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
-
-2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
-
-3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
-
-4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
-
-You must give any other recipients of the Work or Derivative Works a copy of this License; and
-You must cause any modified files to carry prominent notices stating that You changed the files; and
-You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
-If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
-
-You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
-
-6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
-
-7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
-
-8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
-
-9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
-
-END OF TERMS AND CONDITIONS
+ "The Library" refers to a covered work governed by this License,
+other than an Application or a Combined Work as defined below.
+
+ An "Application" is any work that makes use of an interface provided
+by the Library, but which is not otherwise based on the Library.
+Defining a subclass of a class defined by the Library is deemed a mode
+of using an interface provided by the Library.
+
+ A "Combined Work" is a work produced by combining or linking an
+Application with the Library. The particular version of the Library
+with which the Combined Work was made is also called the "Linked
+Version".
+
+ The "Minimal Corresponding Source" for a Combined Work means the
+Corresponding Source for the Combined Work, excluding any source code
+for portions of the Combined Work that, considered in isolation, are
+based on the Application, and not on the Linked Version.
+
+ The "Corresponding Application Code" for a Combined Work means the
+object code and/or source code for the Application, including any data
+and utility programs needed for reproducing the Combined Work from the
+Application, but excluding the System Libraries of the Combined Work.
+
+ 1. Exception to Section 3 of the GNU GPL.
+
+ You may convey a covered work under sections 3 and 4 of this License
+without being bound by section 3 of the GNU GPL.
+
+ 2. Conveying Modified Versions.
+
+ If you modify a copy of the Library, and, in your modifications, a
+facility refers to a function or data to be supplied by an Application
+that uses the facility (other than as an argument passed when the
+facility is invoked), then you may convey a copy of the modified
+version:
+
+ a) under this License, provided that you make a good faith effort to
+ ensure that, in the event an Application does not supply the
+ function or data, the facility still operates, and performs
+ whatever part of its purpose remains meaningful, or
+
+ b) under the GNU GPL, with none of the additional permissions of
+ this License applicable to that copy.
+
+ 3. Object Code Incorporating Material from Library Header Files.
+
+ The object code form of an Application may incorporate material from
+a header file that is part of the Library. You may convey such object
+code under terms of your choice, provided that, if the incorporated
+material is not limited to numerical parameters, data structure
+layouts and accessors, or small macros, inline functions and templates
+(ten or fewer lines in length), you do both of the following:
+
+ a) Give prominent notice with each copy of the object code that the
+ Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the object code with a copy of the GNU GPL and this license
+ document.
+
+ 4. Combined Works.
+
+ You may convey a Combined Work under terms of your choice that,
+taken together, effectively do not restrict modification of the
+portions of the Library contained in the Combined Work and reverse
+engineering for debugging such modifications, if you also do each of
+the following:
+
+ a) Give prominent notice with each copy of the Combined Work that
+ the Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the Combined Work with a copy of the GNU GPL and this license
+ document.
+
+ c) For a Combined Work that displays copyright notices during
+ execution, include the copyright notice for the Library among
+ these notices, as well as a reference directing the user to the
+ copies of the GNU GPL and this license document.
+
+ d) Do one of the following:
+
+ 0) Convey the Minimal Corresponding Source under the terms of this
+ License, and the Corresponding Application Code in a form
+ suitable for, and under terms that permit, the user to
+ recombine or relink the Application with a modified version of
+ the Linked Version to produce a modified Combined Work, in the
+ manner specified by section 6 of the GNU GPL for conveying
+ Corresponding Source.
+
+ 1) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (a) uses at run time
+ a copy of the Library already present on the user's computer
+ system, and (b) will operate properly with a modified version
+ of the Library that is interface-compatible with the Linked
+ Version.
+
+ e) Provide Installation Information, but only if you would otherwise
+ be required to provide such information under section 6 of the
+ GNU GPL, and only to the extent that such information is
+ necessary to install and execute a modified version of the
+ Combined Work produced by recombining or relinking the
+ Application with a modified version of the Linked Version. (If
+ you use option 4d0, the Installation Information must accompany
+ the Minimal Corresponding Source and Corresponding Application
+ Code. If you use option 4d1, you must provide the Installation
+ Information in the manner specified by section 6 of the GNU GPL
+ for conveying Corresponding Source.)
+
+ 5. Combined Libraries.
+
+ You may place library facilities that are a work based on the
+Library side by side in a single library together with other library
+facilities that are not Applications and are not covered by this
+License, and convey such a combined library under terms of your
+choice, if you do both of the following:
+
+ a) Accompany the combined library with a copy of the same work based
+ on the Library, uncombined with any other library facilities,
+ conveyed under the terms of this License.
+
+ b) Give prominent notice with the combined library that part of it
+ is a work based on the Library, and explaining where to find the
+ accompanying uncombined form of the same work.
+
+ 6. Revised Versions of the GNU Lesser General Public License.
+
+ The Free Software Foundation may publish revised and/or new versions
+of the GNU Lesser General Public License from time to time. Such new
+versions will be similar in spirit to the present version, but may
+differ in detail to address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Library as you received it specifies that a certain numbered version
+of the GNU Lesser General Public License "or any later version"
+applies to it, you have the option of following the terms and
+conditions either of that published version or of any later version
+published by the Free Software Foundation. If the Library as you
+received it does not specify a version number of the GNU Lesser
+General Public License, you may choose any version of the GNU Lesser
+General Public License ever published by the Free Software Foundation.
+
+ If the Library as you received it specifies that a proxy can decide
+whether future versions of the GNU Lesser General Public License shall
+apply, that proxy's public statement of acceptance of any version is
+permanent authorization for you to choose that version for the
+Library.
\ No newline at end of file
diff --git a/README.md b/README.md
index 91b44531d..37d618acd 100644
--- a/README.md
+++ b/README.md
@@ -1,45 +1,33 @@
# Shade Protocol Core Contracts
-| Contract | Reference | Description |
-| --------------------------------------------------- | ------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------- |
-| [Placeholder]() | [Placeholder]() | [Placeholder] |
-| [Placeholder]() | [Placeholder]() | [Placeholder] |
-| [Placeholder]() | [Placeholder]() | [Placeholder] |
-| [Placeholder]() | [Placeholder]() | [Placeholder] |
-| [Placeholder]() | [Placeholder]() | [Placeholder] |
-|[Placeholder]() | [Placeholder]() | [Placeholder] |
-| [Placeholder]() | [Placeholder]() |[Placeholder] |
+| Contract | Reference | Description |
+| --------------------------- | --------------------------------- | ------------------------------------- |
+| [`mint`](./contracts/mint) | [doc](./contracts/mint/README.md) | Handles asset burning and silk minting|
+## Development
+## Development Environment
+Instlal docker for local envirnment
-# Mirror Core Contracts
-
-This monorepository contains the source code for the core smart contracts implementing Mirror Protocol on the [Terra](https://terra.money) blockchain.
-
-You can find information about the architecture, usage, and function of the smart contracts on the official Mirror documentation [site](https://docs.mirror.finance/contracts/architecture).
-
-### Dependencies
-
-Mirror depends on [Terraswap](https://terraswap.io) and uses its [implementation](https://github.com/terraswap/terraswap) of the CW20 token specification.
+Source from [testner](https://build.scrt.network/dev/quickstart.html#setup-the-local-developer-testnet)
-## Contracts
+```
+docker run -it --rm -p 26657:26657 -p 26656:26656 -p 1337:1337 -v $(pwd):/root/code --name secretdev enigmampc/secret-network-sw-dev
-| Contract | Reference | Description |
-| --------------------------------------------------- | ------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------- |
-| [`mirror_collector`](./contracts/mirror_collector) | [doc](https://docs.mirror.finance/contracts/collector) | Gathers protocol fees incurred from CDP withdrawals and liquidations and sends to Gov |
-| [`mirror_community`](../contracts/mirror_community) | [doc](https://docs.mirror.finance/contracts/community) | Manages the commuinty pool fund |
-| [`mirror_factory`](./contracts/mirror_factory) | [doc](https://docs.mirror.finance/contracts/factory) | Central directory that organizes the various component contracts of Mirror |
-| [`mirror_gov`](./contracts/mirror_gov) | [doc](https://docs.mirror.finance/contracts/gov) | Allows other Mirror contracts to be controlled by decentralized governance, distributes MIR received from Collector to MIR stakers |
-| [`mirror_mint`](./contracts/mirror_mint) | [doc](https://docs.mirror.finance/contracts/mint) | Handles CDP creation, management and liquidation |
-| [`mirror_oracle`](./contracts/mirror_oracle) | [doc](https://docs.mirror.finance/contracts/oracle) | Provides interface for oracle feeders to post prices for mAssets |
-| [`mirror_staking`](./contracts/mirror_staking) | [doc](https://docs.mirror.finance/contracts/staking) | Distributes MIR rewards from block reward to LP stakers |
+docker exec -it secretdev /bin/bash
-## Development
+```
+#### Testing the environment
+Inside the container:
+```
+run python3 contract_tester.py
+```
### Environment Setup
- Rust v1.44.1+
- `wasm32-unknown-unknown` target
- Docker
+- binaryen
1. Install `rustup` via https://rustup.rs/
@@ -52,6 +40,11 @@ rustup target add wasm32-unknown-unknown
3. Make sure [Docker](https://www.docker.com/) is installed
+4. To compile the contracts install binaryen
+```sh
+apt install binaryen
+```
+
### Unit / Integration Tests
Each contract contains Rust unit and integration tests embedded within the contract source directories. You can run:
@@ -63,32 +56,12 @@ cargo integration-test
### Compiling
-After making sure tests pass, you can compile each contract with the following:
-
-```sh
-RUSTFLAGS='-C link-arg=-s' cargo wasm
-cp ../../target/wasm32-unknown-unknown/release/cw1_subkeys.wasm .
-ls -l cw1_subkeys.wasm
-sha256sum cw1_subkeys.wasm
-```
-
-#### Production
-
-For production builds, run the following:
+Run this script to run all of the contract's unit / integration tests and then prepare the contracts for production in /contracts/compiled:
```sh
-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/workspace-optimizer:0.10.2
+bash ./compile-contracts.sh
```
-This performs several optimizations which can significantly reduce the final size of the contract binaries, which will be available inside the `artifacts/` directory.
-
-## License
-
-Copyright 2020 Mirror Protocol
-
-Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0. Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+### Testing
-See the License for the specific language governing permissions and limitations under the License.
+You can optionally run extended tests inside a private testnet using the [contract tester](./contracts/compiled/contract_tester.py)
\ No newline at end of file
diff --git a/artifacts/checksums.txt b/artifacts/checksums.txt
deleted file mode 100644
index 574a55cc1..000000000
--- a/artifacts/checksums.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-12e7f8dfe7edbe0527b7cd4b51e62281c091ebff7288c2232907af792d8615ab mirror_collateral_oracle.wasm
-209b62233d441bf87f8e8404bcb71e7c51f04e5487bb2944bd94f116881f4e75 mirror_collector.wasm
-a6b7aeff684d79715e3cffda23de2044c0e7b6db9e21fd2f71924d84754928fe mirror_community.wasm
-5d6309d575a4b2a1bdc9ddfde5a1ca4a012dc8ea38f93fcbf11a62fc4e65c668 mirror_factory.wasm
-d3ca1c56db12dea2b8b58b58216500cbc8814a3de346ffdda2697b361f5cbfb8 mirror_gov.wasm
-a4a1793160bc826fd48ab2513ede7a74175796db176a8bf26f19df97f4aebb17 mirror_limit_order.wasm
-db6e6599dde8218e7afe31ec1d6d916246c2b4ab3eb02f4ddf8a19f84d05de27 mirror_lock.wasm
-5719651503503c80369d1ffdbbd9448096f059bbc83be50a9bcddf36b3b16947 mirror_mint.wasm
-c763656f90330870bde049b352a859b43dc461eb04199c9214e3f673eabca460 mirror_oracle.wasm
-de9362bc7dd6b1ffdb64c87165d11117e14cbdb3cb37deefac4e6088e37af432 mirror_staking.wasm
diff --git a/artifacts/mirror_collateral_oracle.wasm b/artifacts/mirror_collateral_oracle.wasm
deleted file mode 100644
index 87da459ca..000000000
Binary files a/artifacts/mirror_collateral_oracle.wasm and /dev/null differ
diff --git a/artifacts/mirror_collector.wasm b/artifacts/mirror_collector.wasm
deleted file mode 100644
index 5d7a9361f..000000000
Binary files a/artifacts/mirror_collector.wasm and /dev/null differ
diff --git a/artifacts/mirror_community.wasm b/artifacts/mirror_community.wasm
deleted file mode 100644
index 23d586e66..000000000
Binary files a/artifacts/mirror_community.wasm and /dev/null differ
diff --git a/artifacts/mirror_factory.wasm b/artifacts/mirror_factory.wasm
deleted file mode 100644
index d18c4e445..000000000
Binary files a/artifacts/mirror_factory.wasm and /dev/null differ
diff --git a/artifacts/mirror_gov.wasm b/artifacts/mirror_gov.wasm
deleted file mode 100644
index 3ed0451a5..000000000
Binary files a/artifacts/mirror_gov.wasm and /dev/null differ
diff --git a/artifacts/mirror_limit_order.wasm b/artifacts/mirror_limit_order.wasm
deleted file mode 100644
index 0e67d073e..000000000
Binary files a/artifacts/mirror_limit_order.wasm and /dev/null differ
diff --git a/artifacts/mirror_lock.wasm b/artifacts/mirror_lock.wasm
deleted file mode 100644
index 023bed012..000000000
Binary files a/artifacts/mirror_lock.wasm and /dev/null differ
diff --git a/artifacts/mirror_mint.wasm b/artifacts/mirror_mint.wasm
deleted file mode 100644
index 5d9b5ff72..000000000
Binary files a/artifacts/mirror_mint.wasm and /dev/null differ
diff --git a/artifacts/mirror_oracle.wasm b/artifacts/mirror_oracle.wasm
deleted file mode 100644
index 9655c0d25..000000000
Binary files a/artifacts/mirror_oracle.wasm and /dev/null differ
diff --git a/artifacts/mirror_staking.wasm b/artifacts/mirror_staking.wasm
deleted file mode 100644
index 95d45e760..000000000
Binary files a/artifacts/mirror_staking.wasm and /dev/null differ
diff --git a/compile-contracts.sh b/compile-contracts.sh
new file mode 100755
index 000000000..6afd0f71e
--- /dev/null
+++ b/compile-contracts.sh
@@ -0,0 +1,19 @@
+#!/bin/bash
+
+root_dir=$(git rev-parse --show-toplevel)
+contracts_dir="${root_dir}/contracts"
+compiled_dir="${contracts_dir}/compiled"
+
+compile_contract() {
+ # Run tests
+ (cd ${contracts_dir}/$1; cargo unit-test)
+ (cd ${contracts_dir}/$1; cargo integration-test)
+ (cd ${compiled_dir}; rm $1.wasm.gz)
+ (cd ${contracts_dir}; cargo build --release --target wasm32-unknown-unknown --locked)
+ wasm-opt -Oz ./target/wasm32-unknown-unknown/release/$1.wasm -o ./$1.wasm
+ cat ./$1.wasm | gzip -n -9 > ${compiled_dir}/$1.wasm.gz
+ rm -f ./$1.wasm
+}
+
+compile_contract "mint"
+compile_contract "oracle"
diff --git a/contracts/compiled/__init__.py b/contracts/compiled/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/contracts/compiled/contract_tester.py b/contracts/compiled/contract_tester.py
new file mode 100644
index 000000000..ecdbed8a0
--- /dev/null
+++ b/contracts/compiled/contract_tester.py
@@ -0,0 +1,63 @@
+import random
+from contractlib.secretlib import secretlib
+from contractlib.snip20lib import SNIP20
+from contractlib.mintlib import Mint
+from contractlib.oraclelib import Oracle
+from contractlib.utils import gen_label
+
+account_key = 'a'
+account = secretlib.run_command(['secretcli', 'keys', 'show', '-a', account_key]).rstrip()
+
+print("Configuring sSCRT")
+sscrt = SNIP20(gen_label(8), decimals=6, public_total_supply=True, enable_deposit=True)
+sscrt_password = sscrt.set_view_key(account_key, "password")
+sscrt.print()
+
+sscrt_mint_amount = '100000000000000'
+print(f"\tDepositing {sscrt_mint_amount} uSCRT")
+sscrt.deposit(account, sscrt_mint_amount + "uscrt")
+sscrt_minted = sscrt.get_balance(account, sscrt_password)
+print(f"\tReceived {sscrt_minted} usSCRT")
+assert sscrt_mint_amount == sscrt_minted, f"Minted {sscrt_minted}; expected {sscrt_mint_amount}"
+
+print("Configuring silk")
+silk = SNIP20(gen_label(8), decimals=6, public_total_supply=True, enable_mint=True)
+silk_password = silk.set_view_key(account_key, "password")
+
+print('Configuring Oracle')
+oracle = Oracle(gen_label(8))
+price = int(oracle.get_silk_price()["price"])
+print(price / (10**18))
+
+print("Configuring Mint contract")
+mint = Mint(gen_label(8), silk, oracle)
+silk.set_minters([mint.address])
+mint.register_asset(sscrt)
+assets = mint.get_supported_assets()['supported_assets']['assets'][0]
+assert sscrt.address == assets, f"Got {assets}; expected {sscrt.address}"
+
+print("Sending to mint contract")
+
+total_amount = int(sscrt_mint_amount)
+minimum_amount = 1000
+total_tests = 5
+
+total_sent = 0
+
+for i in range(total_tests):
+ send_amount = random.randint(minimum_amount, int(total_amount/total_tests)-1)
+ total_sent += send_amount
+
+ print(f"\tSending {send_amount} usSCRT")
+ sscrt.send(account_key, mint.address, send_amount)
+ silk_minted = silk.get_balance(account, silk_password)
+ #assert total_sent == int(silk_minted), f"Total minted {silk_minted}; expected {total_sent}"
+
+ print(f"\tSilk balance: {silk_minted} uSILK")
+ burned_amount = mint.get_asset(sscrt)["asset"]["asset"]["burned_tokens"]
+ print(f"\tTotal burned: {burned_amount} usSCRT\n")
+ #assert total_sent == int(burned_amount), f"Burnt {burned_amount}; expected {total_sent}"
+
+print("Testing migration")
+new_mint = mint.migrate(gen_label(8), int(mint.contract_id), mint.code_hash)
+assert mint.get_supported_assets() == new_mint.get_supported_assets(), "Contracts are not the same"
diff --git a/contracts/compiled/contractlib/__init__.py b/contracts/compiled/contractlib/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/contracts/compiled/contractlib/contractlib.py b/contracts/compiled/contractlib/contractlib.py
new file mode 100644
index 000000000..f1261c61a
--- /dev/null
+++ b/contracts/compiled/contractlib/contractlib.py
@@ -0,0 +1,63 @@
+from .secretlib import secretlib
+
+
+class PreInstantiatedContract:
+ def __init__(self, contract_id, address, code_hash):
+ self.contract_id = contract_id
+ self.address = address
+ self.code_hash = code_hash
+
+
+class Contract:
+ def __init__(self, contract, initMsg, label, admin='a', uploader='a', gas='10000000', backend='test', wait=6,
+ instantiated_contract=None):
+ self.label = label
+ self.admin = admin
+ self.uploader = uploader
+ self.gas = gas
+ self.backend = backend
+ self.wait = wait
+
+ if instantiated_contract is None:
+ self.contract_id = secretlib.store_contract(contract, uploader, gas, backend)
+ initResponse = secretlib.instantiate_contract(str(self.contract_id), initMsg, label, admin, backend)
+ contracts = secretlib.list_code()
+ self.code_hash = contracts[int(self.contract_id) - 1]["data_hash"]
+ for attribute in initResponse["logs"][0]["events"][0]["attributes"]:
+ if attribute["key"] == "contract_address":
+ self.address = attribute["value"]
+ break
+
+ else:
+ self.contract_id = instantiated_contract.contract_id
+ self.code_hash = instantiated_contract.code_hash
+ self.address = instantiated_contract.address
+
+ def execute(self, msg, sender=None, amount=None, compute=True):
+ """
+ Execute said msg
+ :param msg: Execute msg
+ :param sender: Who will be sending the message, defaults to contract admin
+ :param amount: Optional string amount to send along with transaction
+ :return: Result
+ """
+ signer = sender if sender is not None else self.admin
+ return secretlib.execute_contract(self.address, msg, signer, self.backend, amount, compute)
+
+ def query(self, msg):
+ """
+ Query said msg
+ :param msg: Query msg
+ :return: Query
+ """
+ return secretlib.query_contract(self.address, msg)
+
+ def print(self):
+ """
+ Prints the contract info
+ :return:
+ """
+ print(f"Label: {self.label}\n"
+ f"Address: {self.address}\n"
+ f"Id: {self.contract_id}\n"
+ f"Hash: {self.code_hash}")
diff --git a/contracts/compiled/contractlib/mintlib.py b/contracts/compiled/contractlib/mintlib.py
new file mode 100644
index 000000000..5b34ac0b4
--- /dev/null
+++ b/contracts/compiled/contractlib/mintlib.py
@@ -0,0 +1,117 @@
+import copy
+
+from .contractlib import Contract
+from .secretlib import secretlib
+import json
+
+
+class Mint(Contract):
+ def __init__(self, label, silk, oracle, contract='mint.wasm.gz', admin='a', uploader='a', gas='10000000',
+ backend='test', instantiated_contract=None):
+ init_msg = json.dumps(
+ {"silk": {"address": silk.address, "code_hash": silk.code_hash},
+ "oracle": {"address": oracle.address, "code_hash": oracle.code_hash}})
+ super().__init__(contract, init_msg, label, admin, uploader, gas, backend,
+ instantiated_contract=instantiated_contract)
+
+ def migrate(self, label, code_id, code_hash):
+ """
+ Instantiate another mint contract and migrate this contracts info into that one
+ :param label: Label name of the contract
+ :param code_id: Code id of the contract
+ :param code_hash: Code hash
+ :return: new Mint
+ """
+ msg = json.dumps(
+ {"migrate": {"label": label, "code_id": code_id, "code_hash": code_hash}})
+
+ new_mint = copy.deepcopy(self)
+ for attribute in self.execute(msg, compute=False)["logs"][0]["events"][0]["attributes"]:
+ if attribute["key"] == "contract_address":
+ new_mint.address = attribute["value"]
+ break
+ new_mint.contract_id = code_id
+ new_mint.code_hash = code_hash
+ return new_mint
+
+ def update_config(self, owner=None, silk=None, oracle=None):
+ """
+ Updates the minting contract's config
+ :param owner: New admin
+ :param silk: Silk contract
+ :param oracle: Oracle contract
+ :return: Result
+ """
+ raw_msg = {"update_config": {}}
+ if owner is not None:
+ raw_msg["update_config"]["owner"] = owner
+ if silk is not None:
+ contract = {
+ "address": silk.address,
+ "code_hash": silk.code_hash
+ }
+ raw_msg["update_config"]["silk"] = contract
+ if oracle is not None:
+ contract = {
+ "address": oracle.address,
+ "code_hash": oracle.code_hash
+ }
+ raw_msg["update_config"]["oracle"] = contract
+
+ msg = json.dumps(raw_msg)
+ return self.execute(msg)
+
+ def register_asset(self, snip20):
+ """
+ Registers a SNIP20 asset
+ :param snip20: SNIP20 object to add
+ :return: Result
+ """
+ msg = json.dumps(
+ {"register_asset": {"contract": {"address": snip20.address, "code_hash": snip20.code_hash}}})
+
+ return self.execute(msg)
+
+ def update_asset(self, old_snip20, snip20):
+ """
+ Updates a SNIP20 asset's info
+ :param old_snip20: The registered snip20
+ :param snip20: New snip20 to replace with
+ :return: Result
+ """
+ msg = json.dumps(
+ {"update_asset": {"asset": old_snip20.address, "contract": {"address": snip20.address,
+ "code_hash": snip20.code_hash}}})
+
+ return self.execute(msg)
+
+ def get_supported_assets(self):
+ """
+ Get all supported asset addressed
+ :return: Supported assets info
+ """
+ msg = json.dumps(
+ {"get_supported_assets": {}})
+
+ return self.query(msg)
+
+ def get_config(self):
+ """
+ Get the contracts config information
+ :return: Contract config info
+ """
+ msg = json.dumps(
+ {"get_config": {}})
+
+ return self.query(msg)
+
+ def get_asset(self, snip20):
+ """
+ Returns that assets info
+ :param snip20: SNIP20 object to query
+ :return: Asset info
+ """
+ msg = json.dumps(
+ {"get_asset": {"contract": snip20.address}})
+
+ return self.query(msg)
diff --git a/contracts/compiled/contractlib/oraclelib.py b/contracts/compiled/contractlib/oraclelib.py
new file mode 100644
index 000000000..c8b4c6050
--- /dev/null
+++ b/contracts/compiled/contractlib/oraclelib.py
@@ -0,0 +1,23 @@
+import copy
+
+from .contractlib import Contract
+from .secretlib import secretlib
+import json
+
+
+class Oracle(Contract):
+ def __init__(self, label, contract='oracle.wasm.gz', admin='a', uploader='a', gas='10000000', backend='test',
+ instantiated_contract=None):
+ init_msg = json.dumps({})
+ super().__init__(contract, init_msg, label, admin, uploader, gas, backend,
+ instantiated_contract=instantiated_contract)
+
+ def get_silk_price(self):
+ """
+ Get current silk price
+ :return:
+ """
+ msg = json.dumps(
+ {"get_scrt_price": {}})
+
+ return self.query(msg)
\ No newline at end of file
diff --git a/contracts/compiled/contractlib/secretlib/__init__.py b/contracts/compiled/contractlib/secretlib/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/contracts/compiled/contractlib/secretlib/secretlib.py b/contracts/compiled/contractlib/secretlib/secretlib.py
new file mode 100644
index 000000000..b6737c860
--- /dev/null
+++ b/contracts/compiled/contractlib/secretlib/secretlib.py
@@ -0,0 +1,107 @@
+import subprocess
+import json
+import time
+
+# Presetup some commands
+query_list_code = ['secretcli', 'query', 'compute', 'list-code']
+
+
+def run_command(command, wait=6):
+ """
+ Will run any cli command and return its output after waiting a set amount
+ :param command: Array of command to run
+ :param wait: Time to wait for command
+ :return: Output string
+ """
+
+ result = subprocess.run(command, stdout=subprocess.PIPE, text=True)
+ time.sleep(wait)
+ return result.stdout
+
+
+def store_contract(contract, user='a', gas='10000000', backend='test', wait=15):
+ """
+ Store contract and return its ID
+ :param contract: Contract name
+ :param user: User to upload with
+ :param gas: Gas to use
+ :param backend: Keyring backend
+ :return: Contract ID
+ """
+
+ command = ['secretcli', 'tx', 'compute', 'store', contract,
+ '--from', user, '--gas', gas, '-y']
+
+ if backend is not None:
+ command += ['--keyring-backend', backend]
+
+ for attribute in run_command_query_hash(command, wait)['logs'][0]['events'][0]['attributes']:
+ if attribute["key"] == "code_id":
+ return attribute['value']
+
+
+def instantiate_contract(contract, msg, label, user='a', backend='test', wait=6):
+ """
+ Instantiates a contract
+ :param contract: Contract name
+ :param msg: Init msg
+ :param label: Name to give to the contract
+ :param user: User to instantiate with
+ :param backend: Keyring backend
+ :return:
+ """
+
+ command = ['secretcli', 'tx', 'compute', 'instantiate', contract, msg, '--from',
+ user, '--label', label, '-y']
+
+ if backend is not None:
+ command += ['--keyring-backend', backend]
+
+ return run_command_query_hash(command, wait)
+
+
+def list_code():
+ command = ['secretcli', 'query', 'compute', 'list-code']
+
+ return json.loads(run_command(command, 3))
+
+
+def execute_contract(contract, msg, user='a', backend='test', amount=None, compute=True, wait=6):
+ command = ['secretcli', 'tx', 'compute', 'execute', contract, msg, '--from', user, '--gas', '10000000', '-y']
+
+ if backend is not None:
+ command += ['--keyring-backend', backend]
+
+ if amount is not None:
+ command.append("--amount")
+ command.append(amount)
+
+ if compute:
+ return run_command_compute_hash(command, wait)
+ return run_command_query_hash(command, wait)
+
+
+def query_hash(hash):
+ return run_command(['secretcli', 'q', 'tx', hash], 3)
+
+
+def compute_hash(hash):
+ return run_command(['secretcli', 'q', 'compute', 'tx', hash])
+
+
+def query_contract(contract, msg):
+ command = ['secretcli', 'query', 'compute', 'query', contract, msg]
+
+ return json.loads(run_command(command))
+
+
+def run_command_compute_hash(command, wait=6):
+ out = run_command(command, wait)
+ txhash = json.loads(out)["txhash"]
+ return json.loads(compute_hash(txhash))
+
+
+def run_command_query_hash(command, wait=6):
+ out = run_command(command, wait)
+ txhash = json.loads(out)["txhash"]
+ return json.loads(query_hash(txhash))
diff --git a/contracts/compiled/contractlib/snip20lib.py b/contracts/compiled/contractlib/snip20lib.py
new file mode 100644
index 000000000..388b1893b
--- /dev/null
+++ b/contracts/compiled/contractlib/snip20lib.py
@@ -0,0 +1,90 @@
+from .contractlib import Contract
+from .secretlib import secretlib
+import json
+
+
+class SNIP20(Contract):
+ def __init__(self, label, name="token", symbol="TKN", decimals=3, seed="cGFzc3dvcmQ=", public_total_supply=False,
+ enable_deposit=False, enable_redeem=False, enable_mint=False, enable_burn=False,
+ contract='snip20.wasm.gz', admin='a', uploader='a', gas='10000000', backend='test',
+ instantiated_contract=None):
+ self.view_key = ""
+ initMsg = json.dumps(
+ {"name": name, "symbol": symbol, "decimals": decimals, "prng_seed": seed, "config": {
+ "public_total_supply": public_total_supply, "enable_deposit": enable_deposit,
+ "enable_redeem": enable_redeem, "enable_mint": enable_mint, "enable_burn": enable_burn
+ }})
+ super().__init__(contract, initMsg, label, admin, uploader, gas, backend,
+ instantiated_contract=instantiated_contract)
+
+ def set_minters(self, accounts):
+ """
+ Sets minters
+ :param accounts: Accounts list
+ :return: Response
+ """
+ msg = json.dumps(
+ {"set_minters": {"minters": accounts}})
+
+ return self.execute(msg)
+
+ def deposit(self, account, amount):
+ """
+ Deposit a specified amount to contract
+ :param account: User which will deposit
+ :param amount: uSCRT
+ :return: Response
+ """
+ msg = json.dumps(
+ {"deposit": {}})
+
+ return self.execute(msg, account, amount)
+
+ def mint(self, recipient, amount):
+ """
+ Mint an amount into the recipients wallet
+ :param recipient: Address to be minted in
+ :param amount: Amount to mint
+ :return: Response
+ """
+ msg = json.dumps(
+ {"mint": {"recipient": recipient, "amount": str(amount)}})
+
+ return self.execute(msg)
+
+ def send(self, account, recipient, amount):
+ """
+ Send amount from an account to a recipient
+ :param account: User to generate the key for
+ :param recipient: Address to be minted in
+ :param amount: Amount to mint
+ :return: Response
+ """
+ msg = json.dumps(
+ {"send": {"recipient": recipient, "amount": str(amount)}})
+
+ return self.execute(msg, account)
+
+ def set_view_key(self, account, entropy):
+ """
+ Generate view key to query balance
+ :param account: User to generate the key for
+ :param entropy: Password generation entropy
+ :return: Password
+ """
+ msg = json.dumps(
+ {"create_viewing_key": {"entropy": entropy}})
+
+ return json.loads(self.execute(msg, account)["output_data_as_string"])["create_viewing_key"]["key"]
+
+ def get_balance(self, address, password):
+ """
+ Gets amount of coins in wallet
+ :param address: Account to access
+ :param password: View key
+ :return: Response
+ """
+ msg = json.dumps(
+ {"balance": {"key": password, "address": address}})
+
+ return self.query(msg)["balance"]["amount"]
diff --git a/contracts/compiled/contractlib/utils.py b/contracts/compiled/contractlib/utils.py
new file mode 100644
index 000000000..58decdd74
--- /dev/null
+++ b/contracts/compiled/contractlib/utils.py
@@ -0,0 +1,7 @@
+import string
+import random
+
+
+def gen_label(length):
+ # With combination of lower and upper case
+ return ''.join(random.choice(string.ascii_letters) for i in range(length))
diff --git a/contracts/compiled/mint.wasm.gz b/contracts/compiled/mint.wasm.gz
new file mode 100644
index 000000000..1f0cf4c54
Binary files /dev/null and b/contracts/compiled/mint.wasm.gz differ
diff --git a/contracts/compiled/oracle.wasm.gz b/contracts/compiled/oracle.wasm.gz
new file mode 100644
index 000000000..1337a1103
Binary files /dev/null and b/contracts/compiled/oracle.wasm.gz differ
diff --git a/contracts/compiled/snip20.wasm.gz b/contracts/compiled/snip20.wasm.gz
new file mode 100644
index 000000000..be54f8913
Binary files /dev/null and b/contracts/compiled/snip20.wasm.gz differ
diff --git a/contracts/mirror_gov/.cargo/config b/contracts/mint/.cargo/config
similarity index 100%
rename from contracts/mirror_gov/.cargo/config
rename to contracts/mint/.cargo/config
diff --git a/contracts/mint/.circleci/config.yml b/contracts/mint/.circleci/config.yml
new file mode 100644
index 000000000..127e1ae7d
--- /dev/null
+++ b/contracts/mint/.circleci/config.yml
@@ -0,0 +1,52 @@
+version: 2.1
+
+jobs:
+ build:
+ docker:
+ - image: rust:1.43.1
+ steps:
+ - checkout
+ - run:
+ name: Version information
+ command: rustc --version; cargo --version; rustup --version
+ - restore_cache:
+ keys:
+ - v4-cargo-cache-{{ arch }}-{{ checksum "Cargo.lock" }}
+ - run:
+ name: Add wasm32 target
+ command: rustup target add wasm32-unknown-unknown
+ - run:
+ name: Build
+ command: cargo wasm --locked
+ - run:
+ name: Unit tests
+ env: RUST_BACKTRACE=1
+ command: cargo unit-test --locked
+ - run:
+ name: Integration tests
+ command: cargo integration-test --locked
+ - run:
+ name: Format source code
+ command: cargo fmt
+ - run:
+ name: Build and run schema generator
+ command: cargo schema --locked
+ - run:
+ name: Ensure checked-in source code and schemas are up-to-date
+ command: |
+ CHANGES_IN_REPO=$(git status --porcelain)
+ if [[ -n "$CHANGES_IN_REPO" ]]; then
+ echo "Repository is dirty. Showing 'git status' and 'git --no-pager diff' for debugging now:"
+ git status && git --no-pager diff
+ exit 1
+ fi
+ - save_cache:
+ paths:
+ - /usr/local/cargo/registry
+ - target/debug/.fingerprint
+ - target/debug/build
+ - target/debug/deps
+ - target/wasm32-unknown-unknown/release/.fingerprint
+ - target/wasm32-unknown-unknown/release/build
+ - target/wasm32-unknown-unknown/release/deps
+ key: v4-cargo-cache-{{ arch }}-{{ checksum "Cargo.lock" }}
diff --git a/contracts/mirror_collateral_oracle/Cargo.toml b/contracts/mint/Cargo.toml
similarity index 55%
rename from contracts/mirror_collateral_oracle/Cargo.toml
rename to contracts/mint/Cargo.toml
index 5975759e7..b72f053da 100644
--- a/contracts/mirror_collateral_oracle/Cargo.toml
+++ b/contracts/mint/Cargo.toml
@@ -1,10 +1,8 @@
[package]
-name = "mirror-collateral-oracle"
-version = "1.1.0"
-authors = ["Terraform Labs, PTE."]
+name = "mint"
+version = "0.1.0"
+authors = ["Guy Garcia "]
edition = "2018"
-description = "A proxy oracle for collaterals in Mirror Protocol"
-license = "Apache-2.0"
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,19 +27,18 @@ incremental = false
overflow-checks = true
[features]
+default = []
# for quicker tests, cargo test --lib
# for more explicit tests, cargo test --features=backtraces
backtraces = ["cosmwasm-std/backtraces"]
+debug-print = ["cosmwasm-std/debug-print"]
[dependencies]
-cosmwasm-std = { version = "0.10.1", features = ["iterator"] }
-cosmwasm-storage = { version = "0.10.1", features = ["iterator"] }
-mirror-protocol = { version = "1.1.0", path = "../../packages/mirror_protocol" }
+cosmwasm-schema = { git = "https://github.com/enigmampc/SecretNetwork", tag = "v1.0.4-debug-print" }
+cosmwasm-std = { git = "https://github.com/enigmampc/SecretNetwork", tag = "v1.0.4-debug-print" }
+cosmwasm-storage = { git = "https://github.com/enigmampc/SecretNetwork", tag = "v1.0.4-debug-print" }
+secret-toolkit = { git = "https://github.com/enigmampc/secret-toolkit", branch = "debug-print"}
+shade-protocol = { version = "0.1.0", path = "../../packages/shade_protocol" }
schemars = "0.7"
serde = { version = "1.0.103", default-features = false, features = ["derive"] }
-terraswap = "1.1.0"
-cosmwasm-bignumber = "1.0"
-terra-cosmwasm = "1.2.4"
-
-[dev-dependencies]
-cosmwasm-schema = "0.10.1"
\ No newline at end of file
+snafu = { version = "0.6.3" }
diff --git a/contracts/mint/Makefile b/contracts/mint/Makefile
new file mode 100644
index 000000000..2493c22f4
--- /dev/null
+++ b/contracts/mint/Makefile
@@ -0,0 +1,68 @@
+.PHONY: check
+check:
+ cargo check
+
+.PHONY: clippy
+clippy:
+ cargo clippy
+
+PHONY: test
+test: unit-test
+
+.PHONY: unit-test
+unit-test:
+ cargo test
+
+# This is a local build with debug-prints activated. Debug prints only show up
+# in the local development chain (see the `start-server` command below)
+# and mainnet won't accept contracts built with the feature enabled.
+.PHONY: build _build
+build: _build compress-wasm
+_build:
+ RUSTFLAGS='-C link-arg=-s' cargo build --release --target wasm32-unknown-unknown --features="debug-print"
+
+# This is a build suitable for uploading to mainnet.
+# Calls to `debug_print` get removed by the compiler.
+.PHONY: build-mainnet _build-mainnet
+build-mainnet: _build-mainnet compress-wasm
+_build-mainnet:
+ RUSTFLAGS='-C link-arg=-s' cargo build --release --target wasm32-unknown-unknown
+
+# like build-mainnet, but slower and more deterministic
+.PHONY: build-mainnet-reproducible
+build-mainnet-reproducible:
+ docker run --rm -v "$$(pwd)":/contract \
+ --mount type=volume,source="$$(basename "$$(pwd)")_cache",target=/contract/target \
+ --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \
+ enigmampc/secret-contract-optimizer:1.0.3
+
+.PHONY: compress-wasm
+compress-wasm:
+ cp ./target/wasm32-unknown-unknown/release/*.wasm ./contract.wasm
+ @## The following line is not necessary, may work only on linux (extra size optimization)
+ @# wasm-opt -Os ./contract.wasm -o ./contract.wasm
+ cat ./contract.wasm | gzip -9 > ./contract.wasm.gz
+
+.PHONY: schema
+schema:
+ cargo run --example schema
+
+# Run local development chain with four funded accounts (named a, b, c, and d)
+.PHONY: start-server
+start-server: # CTRL+C to stop
+ docker run -it --rm \
+ -p 26657:26657 -p 26656:26656 -p 1317:1317 \
+ -v $$(pwd):/root/code \
+ --name secretdev enigmampc/secret-network-sw-dev:v1.0.4-3
+
+# This relies on running `start-server` in another console
+# You can run other commands on the secretcli inside the dev image
+# by using `docker exec secretdev secretcli`.
+.PHONY: store-contract-local
+store-contract-local:
+ docker exec secretdev secretcli tx compute store -y --from a --gas 1000000 /root/code/contract.wasm.gz
+
+.PHONY: clean
+clean:
+ cargo clean
+ -rm -f ./contract.wasm ./contract.wasm.gz
diff --git a/contracts/mint/README.md b/contracts/mint/README.md
new file mode 100644
index 000000000..79290095c
--- /dev/null
+++ b/contracts/mint/README.md
@@ -0,0 +1,175 @@
+# Mint Contract
+* [Introduction](#Introduction)
+* [Sections](#Sections)
+ * [Init](#Init)
+ * [Admin](#Admin)
+ * Messages
+ * [Migrate](#Migrate)
+ * [UpdateConfig](#UpdateConfig)
+ * [RegisterAsset](#RegisterAsset)
+ * [UpdateAsset](#UpdateAsset)
+ * Queries
+ * [GetConfig](#GetConfig)
+ * [SupportedAssets](#SupportedAssets)
+ * [GetAsset](#getAsset)
+ * [User](#User)
+ * Messages
+ * [Receive](#Receive)
+# Introduction
+The minting contract is used as a way to acquire newly minted Silk, sending a set amount from any supported contract will result in receiving x amount of silk.
+
+# Sections
+
+## Init
+##### Request
+|Name |Type |Description | optional |
+|----------|----------|-------------------------------------------------------------------------------------------------------------------|----------|
+|owner | string | New contract owner; SHOULD be a valid bech32 address, but contracts may use a different naming scheme as well | yes |
+|silk | Contract | Silk contract | no |
+|oracle | Contract | Oracle contract | no |
+
+## Admin
+
+### Messages
+### Migrate
+Migrates all the contracts state and data into a new contract
+#### Request
+| Name | Type | Description | optional |
+|----------| -------|---------------------|----------|
+|label | String | Contract label name | no |
+|code_id | u64 | Contract ID | no |
+|code_hash | String | Contract code hash | no |
+##### Response
+```json
+{
+ "update_config": {
+ "status": "success"
+ }
+}
+```
+
+#### UpdateConfig
+Updates the given values
+##### Request
+|Name |Type |Description | optional |
+|----------|----------|-------------------------------------------------------------------------------------------------------------------|----------|
+|owner | string | New contract owner; SHOULD be a valid bech32 address, but contracts may use a different naming scheme as well | yes |
+|silk | Contract | Silk contract | no |
+|oracle | Contract | Oracle contract | no |
+##### Response
+```json
+{
+ "update_config": {
+ "status": "success"
+ }
+}
+```
+
+#### RegisterAsset
+Registers a supported asset. The asset must be SNIP-20 compliant since [RegisterReceive](https://github.com/SecretFoundation/SNIPs/blob/master/SNIP-20.md#RegisterReceive) is called.
+
+Note: Will return an error if there's an asset with that address already registered.
+##### Request
+|Name |Type |Description | optional |
+|------------|--------|-----------------------------------------------------------------------------------------------------------------------|----------|
+|contract | Contract | Type explained [here](#Contract) | no |
+##### Response
+```json
+{
+ "register_asset": {
+ "status": "success"
+ }
+}
+```
+
+#### UpdateAsset
+Updates a supported asset. The asset must be SNIP-20 compliant since [RegisterReceive](https://github.com/SecretFoundation/SNIPs/blob/master/SNIP-20.md#RegisterReceive) is called.
+
+Note: Will return an error if no asset exists already with that address.
+##### Request
+|Name |Type |Description | optional |
+|------------|----------|-----------------------------------------------------------------------------------------------------------------------|----------|
+|asset | string | Asset to update; SHOULD be a valid bech32 address, but contracts may use a different naming scheme as well | no |
+|contract | Contract | Type explained [here](#Contract) | no |
+##### Response
+```json
+{
+ "update_asset": {
+ "status": "success"
+ }
+}
+```
+
+### Queries
+
+#### GetConfig
+Gets the contract's configuration variables
+##### Response
+```json
+{
+ "config": {
+ "config": {
+ "owner": "Owner address",
+ "silk": {
+ "address": "Asset contract address",
+ "code_hash": "Asset callback code hash"
+ },
+ "oracle": {
+ "address": "Asset contract address",
+ "code_hash": "Asset callback code hash"
+ },
+ "activated": "Boolean of contract's actviation status"
+ }
+ }
+}
+```
+
+#### SupportedAssets
+Get all the contract's supported assets.
+##### Response
+```json
+{
+ "supported_assets": {
+ "assets": ["asset address"]
+ }
+}
+```
+
+#### GetAsset
+Get specific information on a supported asset.
+##### Request
+|Name |Type |Description | optional |
+|------------|--------|-----------------------------------------------------------------------------------------------------------------------|----------|
+|contract | string | Snip20 contract address; SHOULD be a valid bech32 address, but contracts may use a different naming scheme as well | no |
+##### Response
+```json
+{
+ "asset": {
+ "asset": {
+ "contract": {
+ "address": "Asset contract address",
+ "code_hash": "Asset callback code hash"
+ },
+ "burned_tokens": "Total burned on this contract"
+ }
+ }
+}
+```
+
+##User
+
+### Messages
+
+#### Receive
+To mint the user must use a supported asset's send function and send the amount over to the contract's address. The contract will take care of the rest.
+
+## Contract
+Type used in many of the admin commands
+```json
+{
+ "config": {
+ "address": "Asset contract address",
+ "code_hash": "Asset callback code hash"
+ }
+}
+```
\ No newline at end of file
diff --git a/contracts/mirror_lock/examples/schema.rs b/contracts/mint/examples/schema.rs
similarity index 54%
rename from contracts/mirror_lock/examples/schema.rs
rename to contracts/mint/examples/schema.rs
index f9a4fe207..54d7d06fb 100644
--- a/contracts/mirror_lock/examples/schema.rs
+++ b/contracts/mint/examples/schema.rs
@@ -3,9 +3,8 @@ use std::fs::create_dir_all;
use cosmwasm_schema::{export_schema, remove_schemas, schema_for};
-use mirror_protocol::lock::{
- ConfigResponse, HandleMsg, InitMsg, PositionLockInfoResponse, QueryMsg,
-};
+use mint::msg::{SupportedAssetsResponse, AssetResponse, HandleMsg, InitMsg, QueryMsg};
+use mint::state::{MintConfig, BurnableAsset};
fn main() {
let mut out_dir = current_dir().unwrap();
@@ -16,6 +15,8 @@ fn main() {
export_schema(&schema_for!(InitMsg), &out_dir);
export_schema(&schema_for!(HandleMsg), &out_dir);
export_schema(&schema_for!(QueryMsg), &out_dir);
- export_schema(&schema_for!(ConfigResponse), &out_dir);
- export_schema(&schema_for!(PositionLockInfoResponse), &out_dir);
+ export_schema(&schema_for!(MintConfig), &out_dir);
+ export_schema(&schema_for!(BurnableAsset), &out_dir);
+ export_schema(&schema_for!(SupportedAssetsResponse), &out_dir);
+ export_schema(&schema_for!(AssetResponse), &out_dir);
}
diff --git a/contracts/mirror_collateral_oracle/rustfmt.toml b/contracts/mint/rustfmt.toml
similarity index 100%
rename from contracts/mirror_collateral_oracle/rustfmt.toml
rename to contracts/mint/rustfmt.toml
diff --git a/contracts/mirror_community/schema/init_msg.json b/contracts/mint/schema/asset.json
similarity index 66%
rename from contracts/mirror_community/schema/init_msg.json
rename to contracts/mint/schema/asset.json
index 1fa2f91af..cf4d9b949 100644
--- a/contracts/mirror_community/schema/init_msg.json
+++ b/contracts/mint/schema/asset.json
@@ -1,21 +1,21 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
- "title": "InitMsg",
+ "title": "Asset",
"type": "object",
"required": [
- "mirror_token",
- "owner",
- "spend_limit"
+ "burned_tokens",
+ "code_hash",
+ "contract"
],
"properties": {
- "mirror_token": {
- "$ref": "#/definitions/HumanAddr"
+ "burned_tokens": {
+ "$ref": "#/definitions/Uint128"
},
- "owner": {
- "$ref": "#/definitions/HumanAddr"
+ "code_hash": {
+ "type": "string"
},
- "spend_limit": {
- "$ref": "#/definitions/Uint128"
+ "contract": {
+ "$ref": "#/definitions/HumanAddr"
}
},
"definitions": {
diff --git a/contracts/mint/schema/asset_response.json b/contracts/mint/schema/asset_response.json
new file mode 100644
index 000000000..f74a6b34d
--- /dev/null
+++ b/contracts/mint/schema/asset_response.json
@@ -0,0 +1,40 @@
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "title": "AssetResponse",
+ "type": "object",
+ "required": [
+ "asset"
+ ],
+ "properties": {
+ "asset": {
+ "$ref": "#/definitions/Asset"
+ }
+ },
+ "definitions": {
+ "Asset": {
+ "type": "object",
+ "required": [
+ "burned_tokens",
+ "code_hash",
+ "contract"
+ ],
+ "properties": {
+ "burned_tokens": {
+ "$ref": "#/definitions/Uint128"
+ },
+ "code_hash": {
+ "type": "string"
+ },
+ "contract": {
+ "$ref": "#/definitions/HumanAddr"
+ }
+ }
+ },
+ "HumanAddr": {
+ "type": "string"
+ },
+ "Uint128": {
+ "type": "string"
+ }
+ }
+}
diff --git a/contracts/mirror_collector/schema/init_msg.json b/contracts/mint/schema/config.json
similarity index 54%
rename from contracts/mirror_collector/schema/init_msg.json
rename to contracts/mint/schema/config.json
index 3bb10c0cf..a39eab5f0 100644
--- a/contracts/mirror_collector/schema/init_msg.json
+++ b/contracts/mint/schema/config.json
@@ -1,25 +1,29 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
- "title": "InitMsg",
+ "title": "Config",
"type": "object",
"required": [
- "base_denom",
- "distribution_contract",
- "mirror_token",
- "terraswap_factory"
+ "oracle_contract",
+ "oracle_contract_code_hash",
+ "owner",
+ "silk_contract",
+ "silk_contract_code_hash"
],
"properties": {
- "base_denom": {
+ "oracle_contract": {
+ "$ref": "#/definitions/HumanAddr"
+ },
+ "oracle_contract_code_hash": {
"type": "string"
},
- "distribution_contract": {
+ "owner": {
"$ref": "#/definitions/HumanAddr"
},
- "mirror_token": {
+ "silk_contract": {
"$ref": "#/definitions/HumanAddr"
},
- "terraswap_factory": {
- "$ref": "#/definitions/HumanAddr"
+ "silk_contract_code_hash": {
+ "type": "string"
}
},
"definitions": {
diff --git a/contracts/mirror_mint/schema/handle_response_for__empty.json b/contracts/mint/schema/handle_msg.json
similarity index 64%
rename from contracts/mirror_mint/schema/handle_response_for__empty.json
rename to contracts/mint/schema/handle_msg.json
index 9e41be313..07181e1e3 100644
--- a/contracts/mirror_mint/schema/handle_response_for__empty.json
+++ b/contracts/mint/schema/handle_msg.json
@@ -1,35 +1,130 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
- "title": "HandleResponse_for_Empty",
- "type": "object",
- "required": [
- "log",
- "messages"
- ],
- "properties": {
- "data": {
- "anyOf": [
- {
- "$ref": "#/definitions/Binary"
- },
- {
- "type": "null"
+ "title": "HandleMsg",
+ "anyOf": [
+ {
+ "type": "object",
+ "required": [
+ "update_config"
+ ],
+ "properties": {
+ "update_config": {
+ "type": "object",
+ "required": [
+ "oracle_contract",
+ "oracle_contract_code_hash",
+ "owner",
+ "silk_contract",
+ "silk_contract_code_hash"
+ ],
+ "properties": {
+ "oracle_contract": {
+ "$ref": "#/definitions/HumanAddr"
+ },
+ "oracle_contract_code_hash": {
+ "type": "string"
+ },
+ "owner": {
+ "$ref": "#/definitions/HumanAddr"
+ },
+ "silk_contract": {
+ "$ref": "#/definitions/HumanAddr"
+ },
+ "silk_contract_code_hash": {
+ "type": "string"
+ }
+ }
}
- ]
+ }
},
- "log": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/LogAttribute"
+ {
+ "type": "object",
+ "required": [
+ "register_asset"
+ ],
+ "properties": {
+ "register_asset": {
+ "type": "object",
+ "required": [
+ "code_hash",
+ "contract"
+ ],
+ "properties": {
+ "code_hash": {
+ "type": "string"
+ },
+ "contract": {
+ "$ref": "#/definitions/HumanAddr"
+ }
+ }
+ }
}
},
- "messages": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/CosmosMsg_for_Empty"
+ {
+ "type": "object",
+ "required": [
+ "update_asset"
+ ],
+ "properties": {
+ "update_asset": {
+ "type": "object",
+ "required": [
+ "asset",
+ "code_hash",
+ "contract"
+ ],
+ "properties": {
+ "asset": {
+ "$ref": "#/definitions/HumanAddr"
+ },
+ "code_hash": {
+ "type": "string"
+ },
+ "contract": {
+ "$ref": "#/definitions/HumanAddr"
+ }
+ }
+ }
+ }
+ },
+ {
+ "type": "object",
+ "required": [
+ "receive"
+ ],
+ "properties": {
+ "receive": {
+ "type": "object",
+ "required": [
+ "amount",
+ "from",
+ "sender"
+ ],
+ "properties": {
+ "amount": {
+ "$ref": "#/definitions/Uint128"
+ },
+ "from": {
+ "$ref": "#/definitions/HumanAddr"
+ },
+ "msg": {
+ "anyOf": [
+ {
+ "$ref": "#/definitions/CosmosMsg_for_Empty"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ },
+ "sender": {
+ "$ref": "#/definitions/HumanAddr"
+ }
+ }
+ }
}
}
- },
+ ],
"definitions": {
"BankMsg": {
"anyOf": [
@@ -129,6 +224,17 @@
"$ref": "#/definitions/WasmMsg"
}
}
+ },
+ {
+ "type": "object",
+ "required": [
+ "gov"
+ ],
+ "properties": {
+ "gov": {
+ "$ref": "#/definitions/GovMsg"
+ }
+ }
}
]
},
@@ -136,24 +242,38 @@
"description": "An empty struct that serves as a placeholder in different places, such as contracts that don't set a custom message.\n\nIt is designed to be expressable in correct JSON and JSON Schema but contains no meaningful data. Previously we used enums without cases, but those cannot represented as valid JSON Schema (https://github.com/CosmWasm/cosmwasm/issues/451)",
"type": "object"
},
+ "GovMsg": {
+ "anyOf": [
+ {
+ "type": "object",
+ "required": [
+ "vote"
+ ],
+ "properties": {
+ "vote": {
+ "type": "object",
+ "required": [
+ "proposal",
+ "vote_option"
+ ],
+ "properties": {
+ "proposal": {
+ "type": "integer",
+ "format": "uint64",
+ "minimum": 0.0
+ },
+ "vote_option": {
+ "$ref": "#/definitions/VoteOption"
+ }
+ }
+ }
+ }
+ }
+ ]
+ },
"HumanAddr": {
"type": "string"
},
- "LogAttribute": {
- "type": "object",
- "required": [
- "key",
- "value"
- ],
- "properties": {
- "key": {
- "type": "string"
- },
- "value": {
- "type": "string"
- }
- }
- },
"StakingMsg": {
"anyOf": [
{
@@ -264,6 +384,15 @@
"Uint128": {
"type": "string"
},
+ "VoteOption": {
+ "type": "string",
+ "enum": [
+ "Yes",
+ "No",
+ "Abstain",
+ "NoWithVeto"
+ ]
+ },
"WasmMsg": {
"anyOf": [
{
@@ -276,11 +405,16 @@
"execute": {
"type": "object",
"required": [
+ "callback_code_hash",
"contract_addr",
"msg",
"send"
],
"properties": {
+ "callback_code_hash": {
+ "description": "callback_code_hash is the hex encoded hash of the code. This is used by Secret Network to harden against replaying the contract It is used to bind the request to a destination contract in a stronger way than just the contract address which can be faked",
+ "type": "string"
+ },
"contract_addr": {
"$ref": "#/definitions/HumanAddr"
},
@@ -312,22 +446,25 @@
"instantiate": {
"type": "object",
"required": [
+ "callback_code_hash",
"code_id",
+ "label",
"msg",
"send"
],
"properties": {
+ "callback_code_hash": {
+ "description": "callback_code_hash is the hex encoded hash of the code. This is used by Secret Network to harden against replaying the contract It is used to bind the request to a destination contract in a stronger way than just the contract address which can be faked",
+ "type": "string"
+ },
"code_id": {
"type": "integer",
"format": "uint64",
"minimum": 0.0
},
"label": {
- "description": "optional human-readbale label for the contract",
- "type": [
- "string",
- "null"
- ]
+ "description": "mandatory human-readbale label for the contract",
+ "type": "string"
},
"msg": {
"description": "msg is the json-encoded InitMsg struct (as raw Binary)",
diff --git a/contracts/mirror_lock/schema/init_msg.json b/contracts/mint/schema/init_msg.json
similarity index 58%
rename from contracts/mirror_lock/schema/init_msg.json
rename to contracts/mint/schema/init_msg.json
index 2606bf3ee..7a9f29da9 100644
--- a/contracts/mirror_lock/schema/init_msg.json
+++ b/contracts/mint/schema/init_msg.json
@@ -3,25 +3,23 @@
"title": "InitMsg",
"type": "object",
"required": [
- "base_denom",
- "lockup_period",
- "mint_contract",
- "owner"
+ "oracle_contract",
+ "oracle_contract_code_hash",
+ "silk_contract",
+ "silk_contract_code_hash"
],
"properties": {
- "base_denom": {
- "type": "string"
+ "oracle_contract": {
+ "$ref": "#/definitions/HumanAddr"
},
- "lockup_period": {
- "type": "integer",
- "format": "uint64",
- "minimum": 0.0
+ "oracle_contract_code_hash": {
+ "type": "string"
},
- "mint_contract": {
+ "silk_contract": {
"$ref": "#/definitions/HumanAddr"
},
- "owner": {
- "$ref": "#/definitions/HumanAddr"
+ "silk_contract_code_hash": {
+ "type": "string"
}
},
"definitions": {
diff --git a/contracts/mirror_lock/schema/query_msg.json b/contracts/mint/schema/query_msg.json
similarity index 62%
rename from contracts/mirror_lock/schema/query_msg.json
rename to contracts/mint/schema/query_msg.json
index b32e33d52..73e8d9378 100644
--- a/contracts/mirror_lock/schema/query_msg.json
+++ b/contracts/mint/schema/query_msg.json
@@ -5,10 +5,10 @@
{
"type": "object",
"required": [
- "config"
+ "get_supported_assets"
],
"properties": {
- "config": {
+ "get_supported_assets": {
"type": "object"
}
}
@@ -16,26 +16,21 @@
{
"type": "object",
"required": [
- "position_lock_info"
+ "get_asset"
],
"properties": {
- "position_lock_info": {
+ "get_asset": {
"type": "object",
"required": [
- "position_idx"
+ "contract"
],
"properties": {
- "position_idx": {
- "$ref": "#/definitions/Uint128"
+ "contract": {
+ "type": "string"
}
}
}
}
}
- ],
- "definitions": {
- "Uint128": {
- "type": "string"
- }
- }
+ ]
}
diff --git a/contracts/mint/schema/supported_assets_response.json b/contracts/mint/schema/supported_assets_response.json
new file mode 100644
index 000000000..dd63512ae
--- /dev/null
+++ b/contracts/mint/schema/supported_assets_response.json
@@ -0,0 +1,16 @@
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "title": "SupportedAssetsResponse",
+ "type": "object",
+ "required": [
+ "assets"
+ ],
+ "properties": {
+ "assets": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+}
diff --git a/contracts/mint/src/contract.rs b/contracts/mint/src/contract.rs
new file mode 100644
index 000000000..7b4937921
--- /dev/null
+++ b/contracts/mint/src/contract.rs
@@ -0,0 +1,791 @@
+use cosmwasm_std::{debug_print, to_binary, Api, Binary, Env, Extern, HandleResponse, InitResponse, Querier, StdError, StdResult, Storage, CosmosMsg, HumanAddr, Uint128};
+use crate::state::{config, config_read, assets_w, assets_r, asset_list, asset_list_read};
+use secret_toolkit::{
+ snip20::{mint_msg, register_receive_msg, token_info_query},
+};
+use shade_protocol::{
+ mint::{InitMsg, HandleMsg, HandleAnswer, QueryMsg, QueryAnswer, AssetMsg, MintConfig, BurnableAsset},
+ asset::{Contract},
+ msg_traits::{Init, Query},
+};
+use shade_protocol::generic_response::ResponseStatus;
+
+// TODO: tester that tests for contract availability
+// TODO: add remove asset
+// TODO: add spacepad padding
+// TODO: father contract must be snip20 contract owner
+// TODO: father contract must change minters when migrating
+pub fn init(
+ deps: &mut Extern,
+ env: Env,
+ msg: InitMsg,
+) -> StdResult {
+ let state = MintConfig {
+ owner: match msg.admin {
+ None => { env.message.sender.clone() }
+ Some(admin) => { admin }
+ },
+ silk: msg.silk,
+ oracle: msg.oracle,
+ activated: true,
+ };
+
+ config(&mut deps.storage).save(&state)?;
+
+ let empty_assets_list: Vec = Vec::new();
+ asset_list(&mut deps.storage).save(&empty_assets_list)?;
+
+ if let Some(assets) = msg.initial_assets {
+ for asset in assets {
+ let _response = try_register_asset(deps, &env, asset.contract, asset.burned_tokens);
+ }
+ }
+ debug_print!("Contract was initialized by {}", env.message.sender);
+
+ Ok(InitResponse {
+ messages: vec![],
+ log: vec![]
+ })
+}
+
+pub fn handle(
+ deps: &mut Extern,
+ env: Env,
+ msg: HandleMsg,
+) -> StdResult {
+ match msg {
+ HandleMsg::Migrate {
+ code_id,
+ code_hash,
+ label
+ } => try_migrate(deps, env, label, code_id, code_hash),
+ HandleMsg::UpdateConfig {
+ owner,
+ silk,
+ oracle
+ } => try_update_config(deps, env, owner, silk, oracle),
+ HandleMsg::RegisterAsset {
+ contract,
+ } => try_register_asset(deps, &env, contract, None),
+ HandleMsg::UpdateAsset {
+ asset,
+ contract,
+ } => try_update_asset(deps, env, asset, contract),
+ HandleMsg::Receive {
+ sender,
+ from,
+ amount,
+ msg,
+ ..} => try_burn(deps, env, sender, from, amount, msg),
+ }
+}
+
+pub fn try_migrate(
+ deps: &mut Extern,
+ env: Env,
+ label: String,
+ code_id: u64,
+ code_hash: String,
+) -> StdResult {
+ if !authorized(deps, &env, AllowedAccess::Admin)? {
+ return Err(StdError::Unauthorized { backtrace: None });
+ }
+
+ let mut config = config(&mut deps.storage);
+ config.update(|mut state| {
+ state.activated = false;
+ Ok(state)
+ })?;
+
+ let config_read = config.load()?;
+ let mut initial_assets: Vec = vec![];
+ let assets = assets_r(&deps.storage);
+
+ for asset_addr in asset_list_read(&deps.storage).load()? {
+ if let Some(item) = assets.may_load(asset_addr.as_bytes())? {
+ initial_assets.push(AssetMsg {
+ contract: item.contract,
+ burned_tokens: Some(item.burned_tokens),
+ })
+ }
+ };
+
+ let init_msg = InitMsg {
+ admin: Option::from(config_read.owner),
+ silk: config_read.silk,
+ oracle: config_read.oracle,
+ initial_assets: Some(initial_assets)
+ };
+
+ Ok(HandleResponse {
+ messages: vec![init_msg.to_cosmos_msg(1, code_id, code_hash, label)?],
+ log: vec![],
+ data: Some( to_binary( &HandleAnswer::Migrate {
+ status: ResponseStatus::Success } )? )
+ })
+}
+
+pub fn try_update_config(
+ deps: &mut Extern,
+ env: Env,
+ owner: Option,
+ silk: Option,
+ oracle: Option,
+) -> StdResult {
+ if !authorized(deps, &env, AllowedAccess::Admin)? {
+ return Err(StdError::Unauthorized { backtrace: None });
+ }
+
+ // Save new info
+ let mut config = config(&mut deps.storage);
+ config.update(|mut state| {
+ if let Some(owner) = owner {
+ state.owner = owner;
+ }
+ if let Some(silk) = silk {
+ state.silk = silk;
+ }
+ if let Some(oracle) = oracle {
+ state.oracle = oracle;
+ }
+ Ok(state)
+ })?;
+
+ Ok(HandleResponse {
+ messages: vec![],
+ log: vec![],
+ data: Some( to_binary( &HandleAnswer::UpdateAsset {
+ status: ResponseStatus::Success } )? )
+ })
+}
+
+pub fn try_register_asset(
+ deps: &mut Extern,
+ env: &Env,
+ contract: Contract,
+ burned_amount: Option
+) -> StdResult {
+ if !authorized(deps, &env, AllowedAccess::Admin)? {
+ return Err(StdError::Unauthorized { backtrace: None });
+ }
+
+ let contract_str = contract.address.to_string();
+ let mut assets = assets_w(&mut deps.storage);
+ let mut messages = vec![];
+
+ // Check if asset already exists
+ match assets.may_load(contract_str.as_bytes())? {
+ Some(_) => return Err(StdError::generic_err("Asset already exists")),
+
+ None => {
+ // Add the new asset
+ assets.save(contract_str.as_bytes(), &BurnableAsset {
+ contract: contract.clone(),
+ burned_tokens: match burned_amount {
+ None => { Uint128(0) }
+ Some(amount) => { amount }
+ },
+ })?;
+ // Add asset to list
+ asset_list(&mut deps.storage).update(|mut state| {
+ state.push(contract_str);
+ Ok(state)
+ })?;
+ // Register contract in asset
+ let register_msg = register_receive(env, contract.address, contract.code_hash)?;
+ messages.push(register_msg);
+ }
+ }
+
+ Ok(HandleResponse {
+ messages,
+ log: vec![],
+ data: Some( to_binary( &HandleAnswer::RegisterAsset {
+ status: ResponseStatus::Success } )? )
+ })
+}
+
+pub fn try_update_asset(
+ deps: &mut Extern,
+ env: Env,
+ asset: HumanAddr,
+ contract: Contract,
+) -> StdResult {
+ if !authorized(deps, &env, AllowedAccess::Admin)? {
+ return Err(StdError::Unauthorized { backtrace: None });
+ }
+
+ let asset_str = asset.to_string();
+ let mut assets = assets_w(&mut deps.storage);
+ let mut messages = vec![];
+
+ // Check if asset already exists
+ match assets.may_load(asset_str.as_bytes())? {
+ Some(loaded_asset) => {
+ // Remove the old asset
+ assets.remove(asset_str.as_bytes());
+ // Add the new asset
+ assets.save(contract.address.to_string().as_bytes(), &BurnableAsset {
+ contract: contract.clone(),
+ burned_tokens: loaded_asset.burned_tokens
+ })?;
+ // Remove old asset from list
+ asset_list(&mut deps.storage).update(|mut state| {
+ for (i, asset) in state.iter().enumerate() {
+ if asset == &asset_str {
+ state.remove(i);
+ state.push(asset_str.clone());
+ break;
+ }
+ }
+ Ok(state)
+ })?;
+ // Register contract in asset
+ let register_msg = register_receive(&env, contract.address, contract.code_hash)?;
+ messages.push(register_msg)
+ },
+
+ None => return Err(StdError::NotFound { kind: asset_str, backtrace: None }),
+ }
+
+ Ok(HandleResponse {
+ messages,
+ log: vec![],
+ data: Some( to_binary( &HandleAnswer::UpdateAsset {
+ status: ResponseStatus::Success } )? )
+ })
+}
+
+pub fn try_burn(
+ deps: &mut Extern,
+ env: Env,
+ _sender: HumanAddr,
+ from: HumanAddr,
+ amount: Uint128,
+ _msg: Option
+) -> StdResult {
+ if !authorized(deps, &env, AllowedAccess::User)? {
+ return Err(StdError::Unauthorized { backtrace: None });
+ }
+
+ // Check that the asset is supported
+ let mut assets = assets_w(&mut deps.storage);
+ let mut callback_code_hash: String = "".to_string();
+
+ // Check if asset already exists
+ match assets.may_load(env.message.sender.to_string().as_bytes())? {
+ Some(_) => {
+ assets.update(env.message.sender.to_string().as_bytes(), |item| {
+ let mut asset: BurnableAsset = item.unwrap();
+ callback_code_hash = asset.contract.code_hash.clone();
+ asset.burned_tokens += amount;
+ Ok(asset)
+ })?;
+ },
+
+ None => return Err(StdError::NotFound { kind: env.message.sender.to_string(), backtrace: None }),
+ }
+
+ // 1.6 = 1_600_000_000_000_000_000
+ // 1.6 SCRT = 1_600_000 uSCRT = 1_600_000_000_000_000_000
+ // 1.6 * 1.6 = 2.56
+ // 2_560_000_000_000_000_000_00
+
+ // TODO: make this a function that way it can be tested
+
+ // Returned value is x * 10**18
+ let token_value = Uint128(call_oracle(deps)?.into());
+
+ // Load the decimal information for both coins
+ let config = config_read(&deps.storage).load()?;
+ let send_decimals = token_info_query(&deps.querier, 1, callback_code_hash,
+ env.message.sender)?.decimals as u32;
+ let silk_decimals = token_info_query(&deps.querier, 1,
+ config.silk.code_hash,
+ config.silk.address)?.decimals as u32;
+
+ // ( ( token_value * 10**18 ) * ( amount * 10**send_decimals ) ) / ( 10**(18 - ( send_decimals - silk-decimals ) ) )
+ // This will calculate the total mind value
+ let value_to_mint = calculate_mint(token_value, amount, send_decimals, silk_decimals);
+ let mut messages = vec![];
+
+ let mint_msg = mint_silk(deps, from, value_to_mint)?;
+ messages.push(mint_msg);
+
+ Ok(HandleResponse {
+ messages,
+ log: vec![],
+ data: Some( to_binary( &HandleAnswer::Burn {
+ status: ResponseStatus::Success,
+ mint_amount: value_to_mint
+ } )? ),
+ })
+}
+
+// Helper functions
+
+#[derive(PartialEq)]
+pub enum AllowedAccess{
+ Admin,
+ User,
+}
+
+fn authorized(
+ deps: &Extern,
+ env: &Env,
+ access: AllowedAccess,
+) -> StdResult {
+ let config = config_read(&deps.storage).load()?;
+ // Check if contract is still activated
+ if !config.activated {
+ return Ok(false)
+ }
+
+ if access == AllowedAccess::Admin {
+ // Check if admin
+ if env.message.sender != config.owner {
+ return Ok(false)
+ }
+ }
+ return Ok(true)
+}
+
+fn calculate_mint(x: Uint128, y: Uint128, a: u32, b: u32) -> Uint128 {
+ // x = value * 10**18
+ // y = value * 10**a
+ // ( x * y ) / ( 10**(18 - ( a - b ) ) )
+ let exponent = (18 as i32 + a as i32 - b as i32) as u32;
+ x.multiply_ratio(y, 10u128.pow(exponent))
+}
+
+fn register_receive (
+ env: &Env,
+ contract: HumanAddr,
+ code_hash: String,
+) -> StdResult {
+ let cosmos_msg = register_receive_msg(
+ env.contract_code_hash.clone(),
+ None,
+ 256,
+ code_hash,
+ contract,
+ );
+
+ cosmos_msg
+}
+
+fn mint_silk(
+ deps: &Extern,
+ sender: HumanAddr,
+ amount: Uint128,
+) -> StdResult {
+ let config = config_read(&deps.storage).load()?;
+
+ let cosmos_msg = mint_msg(
+ sender,
+ amount,
+ None,
+ 256,
+ config.silk.code_hash,
+ config.silk.address,
+ );
+
+ cosmos_msg
+}
+
+fn call_oracle(
+ deps: &mut Extern,
+) -> StdResult {
+ let block_size = 1; //update this later
+ let config = config_read(&deps.storage).load()?;
+ let query_msg = shade_protocol::oracle::QueryMsg::GetScrtPrice {};
+ let answer: shade_protocol::oracle::PriceResponse = query_msg.query(&deps.querier, block_size,
+ config.oracle.code_hash,
+ config.oracle.address)?;
+
+ let value = answer.price;
+ Ok(value)
+}
+
+pub fn query(
+ deps: &Extern,
+ msg: QueryMsg,
+) -> StdResult {
+ match msg {
+ QueryMsg::GetSupportedAssets {} => to_binary(&query_supported_assets(deps)?),
+ QueryMsg::GetAsset { contract } => to_binary(&query_asset(deps, contract)?),
+ QueryMsg::GetConfig {} => to_binary(&query_config(deps)?),
+ }
+}
+
+fn query_supported_assets(deps: &Extern) -> StdResult {
+ Ok(QueryAnswer::SupportedAssets { assets: asset_list_read(&deps.storage).load()? })
+}
+
+fn query_asset(deps: &Extern, contract: String) -> StdResult {
+ let assets = assets_r(&deps.storage);
+
+ return match assets.may_load(contract.as_bytes())? {
+ Some(asset) => Ok(QueryAnswer::Asset { asset }),
+ None => Err(StdError::NotFound { kind: contract, backtrace: None }),
+ };
+}
+
+fn query_config(deps: &Extern) -> StdResult {
+ Ok(QueryAnswer::Config { config: config_read(&deps.storage).load()? })
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use cosmwasm_std::testing::{mock_dependencies, mock_env, MockStorage, MockApi, MockQuerier};
+ use cosmwasm_std::{coins, from_binary, StdError};
+ use shade_protocol::mint::QueryAnswer;
+
+ fn create_contract(address: &str, code_hash: &str) -> Contract {
+ let env = mock_env(address.to_string(), &[]);
+ return Contract{
+ address: env.message.sender,
+ code_hash: code_hash.to_string()
+ }
+ }
+
+ fn dummy_init(admin: String, silk: Contract, oracle: Contract) -> Extern {
+ let mut deps = mock_dependencies(20, &[]);
+ let msg = InitMsg {
+ admin: None,
+ silk,
+ oracle,
+ initial_assets: None
+ };
+ let env = mock_env(admin, &coins(1000, "earth"));
+ let _res = init(&mut deps, env, msg).unwrap();
+
+ return deps
+ }
+
+ #[test]
+ fn proper_initialization() {
+ let mut deps = mock_dependencies(20, &[]);
+ let msg = InitMsg {
+ admin: None,
+ silk: create_contract("", ""),
+ oracle: create_contract("", ""),
+ initial_assets: None
+ };
+ let env = mock_env("creator", &coins(1000, "earth"));
+
+ // we can just call .unwrap() to assert this was a success
+ let res = init(&mut deps, env, msg).unwrap();
+ assert_eq!(0, res.messages.len());
+ }
+
+ #[test]
+ fn config_update() {
+ let silk_contract = create_contract("silk_contract", "silk_hash");
+ let oracle_contract = create_contract("oracle_contract", "oracle_hash");
+ let mut deps = dummy_init("admin".to_string(), silk_contract, oracle_contract);
+
+ // Check config is properly updated
+ let res = query(&deps, QueryMsg::GetConfig {}).unwrap();
+ let value: QueryAnswer = from_binary(&res).unwrap();
+ let silk_contract = create_contract("silk_contract", "silk_hash");
+ let oracle_contract = create_contract("oracle_contract", "oracle_hash");
+ match value {
+ QueryAnswer::Config { config } => {
+ assert_eq!(config.silk, silk_contract);
+ assert_eq!(config.oracle, oracle_contract);
+
+ }
+ _ => { panic!("Received wrong answer") }
+ }
+
+ // Update config
+ let user_env = mock_env("admin", &coins(1000, "earth"));
+ let new_silk_contract = create_contract("new_silk_contract", "silk_hash");
+ let new_oracle_contract = create_contract("new_oracle_contract", "oracle_hash");
+ let msg = HandleMsg::UpdateConfig {
+ owner: None,
+ silk: Option::from(new_silk_contract),
+ oracle: Option::from(new_oracle_contract),
+ };
+ let _res = handle(&mut deps, user_env, msg);
+
+ // Check config is properly updated
+ let res = query(&deps, QueryMsg::GetConfig {}).unwrap();
+ let value: QueryAnswer = from_binary(&res).unwrap();
+ let new_silk_contract = create_contract("new_silk_contract", "silk_hash");
+ let new_oracle_contract = create_contract("new_oracle_contract", "oracle_hash");
+ match value {
+ QueryAnswer::Config { config } => {
+ assert_eq!(config.silk, new_silk_contract);
+ assert_eq!(config.oracle, new_oracle_contract);
+
+ }
+ _ => { panic!("Received wrong answer") }
+ }
+
+ }
+
+ #[test]
+ fn user_register_asset() {
+ let mut deps = dummy_init("admin".to_string(),
+ create_contract("", ""),
+ create_contract("", ""));
+
+ // User should not be allowed to add an item
+ let user_env = mock_env("user", &coins(1000, "earth"));
+ let dummy_contract = create_contract("some_contract", "some_hash");
+ let msg = HandleMsg::RegisterAsset {
+ contract: dummy_contract,
+ };
+ let res = handle(&mut deps, user_env, msg);
+ match res {
+ Err(StdError::Unauthorized { .. }) => {}
+ _ => panic!("Must return unauthorized error"),
+ }
+
+ // Response should be an empty array
+ let res = query(&deps, QueryMsg::GetSupportedAssets {}).unwrap();
+ let value: QueryAnswer = from_binary(&res).unwrap();
+ match value {
+ QueryAnswer::SupportedAssets { assets } => { assert_eq!(0, assets.len()) }
+ _ => { panic!("Received wrong answer") }
+ }
+ }
+
+ #[test]
+ fn admin_register_asset() {
+ let mut deps = dummy_init("admin".to_string(),
+ create_contract("", ""),
+ create_contract("", ""));
+
+ // Admin should be allowed to add an item
+ let env = mock_env("admin", &coins(1000, "earth"));
+ let dummy_contract = create_contract("some_contract", "some_hash");
+ let msg = HandleMsg::RegisterAsset {
+ contract: dummy_contract,
+ };
+ let _res = handle(&mut deps, env, msg).unwrap();
+
+ // Response should be an array of size 1
+ let res = query(&deps, QueryMsg::GetSupportedAssets {}).unwrap();
+ let value: QueryAnswer = from_binary(&res).unwrap();
+ match value {
+ QueryAnswer::SupportedAssets { assets } => { assert_eq!(1, assets.len()) }
+ _ => { panic!("Received wrong answer") }
+ }
+ }
+
+ #[test]
+ fn duplicate_register_asset() {
+ let mut deps = dummy_init("admin".to_string(),
+ create_contract("", ""),
+ create_contract("", ""));
+
+ let env = mock_env("admin", &coins(1000, "earth"));
+ let dummy_contract = create_contract("some_contract", "some_hash");
+ let msg = HandleMsg::RegisterAsset {
+ contract: dummy_contract,
+ };
+ let _res = handle(&mut deps, env, msg).unwrap();
+
+ // Should not be allowed to add an existing asset
+ let env = mock_env("admin", &coins(1000, "earth"));
+ let dummy_contract = create_contract("some_contract", "other_hash");
+ let msg = HandleMsg::RegisterAsset {
+ contract: dummy_contract,
+ };
+ let res = handle(&mut deps, env, msg);
+ match res {
+ Err(StdError::GenericErr { .. }) => {}
+ _ => panic!("Must return not found error"),
+ };
+ }
+
+ #[test]
+ fn user_update_asset() {
+ let mut deps = dummy_init("admin".to_string(),
+ create_contract("", ""),
+ create_contract("", ""));
+
+ // Add a supported asset
+ let env = mock_env("admin", &coins(1000, "earth"));
+ let dummy_contract = create_contract("some_contract", "some_hash");
+ let msg = HandleMsg::RegisterAsset {
+ contract: dummy_contract,
+ };
+ let _res = handle(&mut deps, env, msg).unwrap();
+
+ // users should not be allowed to update assets
+ let user_env = mock_env("user", &coins(1000, "earth"));
+ let dummy_contract = create_contract("some_contract", "some_hash");
+ let new_dummy_contract = create_contract("some_other_contract", "some_hash");
+ let msg = HandleMsg::UpdateAsset {
+ asset: dummy_contract.address,
+ contract: new_dummy_contract,
+ };
+ let res = handle(&mut deps, user_env, msg);
+ match res {
+ Err(StdError::Unauthorized { .. }) => {}
+ _ => panic!("Must return unauthorized error"),
+ };
+ }
+
+ #[test]
+ fn admin_update_asset() {
+ let mut deps = dummy_init("admin".to_string(),
+ create_contract("", ""),
+ create_contract("", ""));
+
+ // Add a supported asset
+ let env = mock_env("admin", &coins(1000, "earth"));
+ let dummy_contract = create_contract("some_contract", "some_hash");
+ let msg = HandleMsg::RegisterAsset {
+ contract: dummy_contract,
+ };
+ let _res = handle(&mut deps, env, msg).unwrap();
+
+ // admins can update assets
+ let env = mock_env("admin", &coins(1000, "earth"));
+ let dummy_contract = create_contract("some_contract", "some_hash");
+ let new_dummy_contract = create_contract("some_other_contract", "some_hash");
+ let msg = HandleMsg::UpdateAsset {
+ asset: dummy_contract.address,
+ contract: new_dummy_contract,
+ };
+ let _res = handle(&mut deps, env, msg).unwrap();
+
+ // Response should be new dummy contract
+ let res = query(&deps, QueryMsg::GetAsset { contract: "some_other_contract".to_string() }).unwrap();
+ let value: QueryAnswer = from_binary(&res).unwrap();
+ match value {
+ QueryAnswer::Asset { asset } => { assert_eq!("some_other_contract".to_string(), asset.contract.address.to_string()) }
+ _ => { panic!("Received wrong answer") }
+ };
+ }
+
+ #[test]
+ fn nonexisting_update_asset() {
+ let mut deps = dummy_init("admin".to_string(),
+ create_contract("", ""),
+ create_contract("", ""));
+
+ // Add a supported asset
+ let env = mock_env("admin", &coins(1000, "earth"));
+ let dummy_contract = create_contract("some_contract", "some_hash");
+ let msg = HandleMsg::RegisterAsset {
+ contract: dummy_contract,
+ };
+ let _res = handle(&mut deps, env, msg).unwrap();
+
+ // Should now be able to update non existing asset
+ let env = mock_env("admin", &coins(1000, "earth"));
+ let bad_dummy_contract = create_contract("some_non_existing_contract", "some_hash");
+ let new_dummy_contract = create_contract("some_other_contract", "some_hash");
+ let msg = HandleMsg::UpdateAsset {
+ asset: bad_dummy_contract.address,
+ contract: new_dummy_contract,
+ };
+ let res = handle(&mut deps, env, msg);
+ match res {
+ Err(StdError::NotFound { .. }) => {}
+ _ => panic!("Must return not found error"),
+ }
+ }
+
+ #[test]
+ fn receiving_an_asset() {
+ let mut deps = dummy_init("admin".to_string(),
+ create_contract("", ""),
+ create_contract("", ""));
+
+ // Add a supported asset
+ let env = mock_env("admin", &coins(1000, "earth"));
+ let dummy_contract = create_contract("some_contract", "some_hash");
+ let msg = HandleMsg::RegisterAsset {
+ contract: dummy_contract,
+ };
+ let _res = handle(&mut deps, env, msg).unwrap();
+
+ // Contract tries to send funds
+ let env = mock_env("some_contract", &coins(1000, "earth"));
+ let dummy_contract = create_contract("some_owner", "some_hash");
+
+ let msg = HandleMsg::Receive {
+ sender: dummy_contract.address,
+ from: Default::default(),
+ amount: Uint128(100),
+ msg: None,
+ memo: None
+ };
+
+ let res = handle(&mut deps, env, msg);
+ match res {
+ Err(err) => {
+ match err {
+ StdError::NotFound { .. } => {panic!("Not found");}
+ StdError::Unauthorized { .. } => {panic!("Unauthorized");}
+ _ => {//panic!("Must not return error");
+ }
+ }
+ }
+ _ => {}
+ }
+ }
+
+ #[test]
+ fn receiving_an_asset_from_non_supported_asset() {
+ let mut deps = dummy_init("admin".to_string(),
+ create_contract("", ""),
+ create_contract("", ""));
+
+ // Add a supported asset
+ let env = mock_env("admin", &coins(1000, "earth"));
+ let dummy_contract = create_contract("some_contract", "some_hash");
+ let msg = HandleMsg::RegisterAsset {
+ contract: dummy_contract,
+ };
+ let _res = handle(&mut deps, env, msg).unwrap();
+
+ // Contract tries to send funds
+ let env = mock_env("some_other_contract", &coins(1000, "earth"));
+ let dummy_contract = create_contract("some_owner", "some_hash");
+ let msg = HandleMsg::Receive {
+ sender: dummy_contract.address,
+ from: Default::default(),
+ amount: Uint128(100),
+ msg: None,
+ memo: None
+ };
+ let res = handle(&mut deps, env, msg);
+ match res {
+ Err(StdError::NotFound { .. }) => {}
+ _ => {panic!("Must return not found error")},
+ }
+ }
+
+ #[test]
+ fn mint_algorithm_simple() {
+ // In this example the "sent" value is 1 with 6 decimal places
+ // The mint value will be 1 with 3 decimal places
+ let price = Uint128(1_000_000_000_000_000_000);
+ let sent_value = Uint128(1_000_000);
+ let expected_value = Uint128(1_000);
+ let value = calculate_mint(price, sent_value, 6, 3);
+
+ assert_eq!(value, expected_value);
+ }
+
+ #[test]
+ fn mint_algorithm_complex() {
+ // In this example the "sent" value is 1.8 with 6 decimal places
+ // The mint value will be 3.6 with 12 decimal places
+ let price = Uint128(2_000_000_000_000_000_000);
+ let sent_value = Uint128(1_800_000);
+ let expected_value = Uint128(3_600_000_000_000);
+ let value = calculate_mint(price, sent_value, 6, 12);
+
+ assert_eq!(value, expected_value);
+ }
+}
diff --git a/contracts/mint/src/lib.rs b/contracts/mint/src/lib.rs
new file mode 100644
index 000000000..18d548e3f
--- /dev/null
+++ b/contracts/mint/src/lib.rs
@@ -0,0 +1,39 @@
+pub mod contract;
+pub mod state;
+
+#[cfg(target_arch = "wasm32")]
+mod wasm {
+ use super::contract;
+ use cosmwasm_std::{
+ do_handle, do_init, do_query, ExternalApi, ExternalQuerier, ExternalStorage,
+ };
+
+ #[no_mangle]
+ extern "C" fn init(env_ptr: u32, msg_ptr: u32) -> u32 {
+ do_init(
+ &contract::init::,
+ env_ptr,
+ msg_ptr,
+ )
+ }
+
+ #[no_mangle]
+ extern "C" fn handle(env_ptr: u32, msg_ptr: u32) -> u32 {
+ do_handle(
+ &contract::handle::,
+ env_ptr,
+ msg_ptr,
+ )
+ }
+
+ #[no_mangle]
+ extern "C" fn query(msg_ptr: u32) -> u32 {
+ do_query(
+ &contract::query::,
+ msg_ptr,
+ )
+ }
+
+ // Other C externs like cosmwasm_vm_version_1, allocate, deallocate are available
+ // automatically because we `use cosmwasm_std`.
+}
diff --git a/contracts/mint/src/state.rs b/contracts/mint/src/state.rs
new file mode 100644
index 000000000..c00b9cd48
--- /dev/null
+++ b/contracts/mint/src/state.rs
@@ -0,0 +1,34 @@
+use cosmwasm_std::{Storage};
+use cosmwasm_storage::{singleton, singleton_read, ReadonlySingleton, Singleton, bucket, Bucket, bucket_read, ReadonlyBucket};
+use shade_protocol::{
+ mint::{MintConfig, BurnableAsset},
+};
+
+pub static CONFIG_KEY: &[u8] = b"config";
+pub static NATIVE_COIN_KEY: &[u8] = b"native_coin";
+pub static ASSET_KEY: &[u8] = b"assets";
+pub static ASSET_LIST_KEY: &[u8] = b"asset_list";
+
+pub fn config(storage: &mut S) -> Singleton {
+ singleton(storage, CONFIG_KEY)
+}
+
+pub fn config_read(storage: &S) -> ReadonlySingleton {
+ singleton_read(storage, CONFIG_KEY)
+}
+
+pub fn asset_list(storage: &mut S) -> Singleton> {
+ singleton(storage, ASSET_LIST_KEY)
+}
+
+pub fn asset_list_read(storage: &S) -> ReadonlySingleton> {
+ singleton_read(storage, ASSET_LIST_KEY)
+}
+
+pub fn assets_r(storage: & S) -> ReadonlyBucket {
+ bucket_read(ASSET_KEY, storage)
+}
+
+pub fn assets_w(storage: &mut S) -> Bucket {
+ bucket(ASSET_KEY, storage)
+}
\ No newline at end of file
diff --git a/contracts/mint/tests/integration.rs b/contracts/mint/tests/integration.rs
new file mode 100644
index 000000000..6c26b034f
--- /dev/null
+++ b/contracts/mint/tests/integration.rs
@@ -0,0 +1,18 @@
+//! This integration test tries to run and call the generated wasm.
+//! It depends on a Wasm build being available, which you can create with `cargo wasm`.
+//! Then running `cargo integration-test` will validate we can properly call into that generated Wasm.
+//!
+//! You can easily convert unit tests to integration tests.
+//! 1. First copy them over verbatum,
+//! 2. Then change
+//! let mut deps = mock_dependencies(20, &[]);
+//! to
+//! let mut deps = mock_instance(WASM, &[]);
+//! 3. If you access raw storage, where ever you see something like:
+//! deps.storage.get(CONFIG_KEY).expect("no data stored");
+//! replace it with:
+//! deps.with_storage(|store| {
+//! let data = store.get(CONFIG_KEY).expect("no data stored");
+//! //...
+//! });
+//! 4. Anywhere you see query(&deps, ...) you must replace it with query(&mut deps, ...)
diff --git a/contracts/mirror_collateral_oracle/.editorconfig b/contracts/mirror_collateral_oracle/.editorconfig
deleted file mode 100644
index 3d36f20b1..000000000
--- a/contracts/mirror_collateral_oracle/.editorconfig
+++ /dev/null
@@ -1,11 +0,0 @@
-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/mirror_collateral_oracle/.gitignore b/contracts/mirror_collateral_oracle/.gitignore
deleted file mode 100644
index 10fe5d615..000000000
--- a/contracts/mirror_collateral_oracle/.gitignore
+++ /dev/null
@@ -1,12 +0,0 @@
-# Build results
-/target
-
-# Text file backups
-**/*.rs.bk
-
-# macOS
-.DS_Store
-
-# IDEs
-*.iml
-.idea
diff --git a/contracts/mirror_collateral_oracle/README.md b/contracts/mirror_collateral_oracle/README.md
deleted file mode 100644
index 9b442f635..000000000
--- a/contracts/mirror_collateral_oracle/README.md
+++ /dev/null
@@ -1 +0,0 @@
-# Mirror Collateral Oracle
diff --git a/contracts/mirror_collateral_oracle/examples/schema.rs b/contracts/mirror_collateral_oracle/examples/schema.rs
deleted file mode 100644
index 43a96679f..000000000
--- a/contracts/mirror_collateral_oracle/examples/schema.rs
+++ /dev/null
@@ -1,24 +0,0 @@
-use std::env::current_dir;
-use std::fs::create_dir_all;
-
-use cosmwasm_schema::{export_schema, remove_schemas, schema_for};
-use mirror_protocol::collateral_oracle::{
- CollateralInfoResponse, CollateralInfosResponse, CollateralPriceResponse, ConfigResponse,
- HandleMsg, InitMsg, MigrateMsg, QueryMsg,
-};
-
-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!(InitMsg), &out_dir);
- export_schema(&schema_for!(HandleMsg), &out_dir);
- export_schema(&schema_for!(QueryMsg), &out_dir);
- export_schema(&schema_for!(MigrateMsg), &out_dir);
- export_schema(&schema_for!(CollateralInfoResponse), &out_dir);
- export_schema(&schema_for!(ConfigResponse), &out_dir);
- export_schema(&schema_for!(CollateralInfosResponse), &out_dir);
- export_schema(&schema_for!(CollateralPriceResponse), &out_dir);
-}
diff --git a/contracts/mirror_collateral_oracle/schema/collateral_info_response.json b/contracts/mirror_collateral_oracle/schema/collateral_info_response.json
deleted file mode 100644
index e8f0aab19..000000000
--- a/contracts/mirror_collateral_oracle/schema/collateral_info_response.json
+++ /dev/null
@@ -1,31 +0,0 @@
-{
- "$schema": "http://json-schema.org/draft-07/schema#",
- "title": "CollateralInfoResponse",
- "type": "object",
- "required": [
- "asset",
- "is_revoked",
- "multiplier",
- "source_type"
- ],
- "properties": {
- "asset": {
- "type": "string"
- },
- "is_revoked": {
- "type": "boolean"
- },
- "multiplier": {
- "$ref": "#/definitions/Decimal"
- },
- "source_type": {
- "type": "string"
- }
- },
- "definitions": {
- "Decimal": {
- "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)",
- "type": "string"
- }
- }
-}
diff --git a/contracts/mirror_collateral_oracle/schema/collateral_infos_response.json b/contracts/mirror_collateral_oracle/schema/collateral_infos_response.json
deleted file mode 100644
index 6d2b20d68..000000000
--- a/contracts/mirror_collateral_oracle/schema/collateral_infos_response.json
+++ /dev/null
@@ -1,45 +0,0 @@
-{
- "$schema": "http://json-schema.org/draft-07/schema#",
- "title": "CollateralInfosResponse",
- "type": "object",
- "required": [
- "collaterals"
- ],
- "properties": {
- "collaterals": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/CollateralInfoResponse"
- }
- }
- },
- "definitions": {
- "CollateralInfoResponse": {
- "type": "object",
- "required": [
- "asset",
- "is_revoked",
- "multiplier",
- "source_type"
- ],
- "properties": {
- "asset": {
- "type": "string"
- },
- "is_revoked": {
- "type": "boolean"
- },
- "multiplier": {
- "$ref": "#/definitions/Decimal"
- },
- "source_type": {
- "type": "string"
- }
- }
- },
- "Decimal": {
- "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)",
- "type": "string"
- }
- }
-}
diff --git a/contracts/mirror_collateral_oracle/schema/collateral_price_response.json b/contracts/mirror_collateral_oracle/schema/collateral_price_response.json
deleted file mode 100644
index 44c9eaccf..000000000
--- a/contracts/mirror_collateral_oracle/schema/collateral_price_response.json
+++ /dev/null
@@ -1,37 +0,0 @@
-{
- "$schema": "http://json-schema.org/draft-07/schema#",
- "title": "CollateralPriceResponse",
- "type": "object",
- "required": [
- "asset",
- "is_revoked",
- "last_updated",
- "multiplier",
- "rate"
- ],
- "properties": {
- "asset": {
- "type": "string"
- },
- "is_revoked": {
- "type": "boolean"
- },
- "last_updated": {
- "type": "integer",
- "format": "uint64",
- "minimum": 0.0
- },
- "multiplier": {
- "$ref": "#/definitions/Decimal"
- },
- "rate": {
- "$ref": "#/definitions/Decimal"
- }
- },
- "definitions": {
- "Decimal": {
- "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)",
- "type": "string"
- }
- }
-}
diff --git a/contracts/mirror_collateral_oracle/schema/config_response.json b/contracts/mirror_collateral_oracle/schema/config_response.json
deleted file mode 100644
index ccb201f63..000000000
--- a/contracts/mirror_collateral_oracle/schema/config_response.json
+++ /dev/null
@@ -1,42 +0,0 @@
-{
- "$schema": "http://json-schema.org/draft-07/schema#",
- "title": "ConfigResponse",
- "type": "object",
- "required": [
- "anchor_oracle",
- "band_oracle",
- "base_denom",
- "factory_contract",
- "mint_contract",
- "mirror_oracle",
- "owner"
- ],
- "properties": {
- "anchor_oracle": {
- "$ref": "#/definitions/HumanAddr"
- },
- "band_oracle": {
- "$ref": "#/definitions/HumanAddr"
- },
- "base_denom": {
- "type": "string"
- },
- "factory_contract": {
- "$ref": "#/definitions/HumanAddr"
- },
- "mint_contract": {
- "$ref": "#/definitions/HumanAddr"
- },
- "mirror_oracle": {
- "$ref": "#/definitions/HumanAddr"
- },
- "owner": {
- "$ref": "#/definitions/HumanAddr"
- }
- },
- "definitions": {
- "HumanAddr": {
- "type": "string"
- }
- }
-}
diff --git a/contracts/mirror_collateral_oracle/schema/handle_msg.json b/contracts/mirror_collateral_oracle/schema/handle_msg.json
deleted file mode 100644
index 62a0c30c0..000000000
--- a/contracts/mirror_collateral_oracle/schema/handle_msg.json
+++ /dev/null
@@ -1,347 +0,0 @@
-{
- "$schema": "http://json-schema.org/draft-07/schema#",
- "title": "HandleMsg",
- "anyOf": [
- {
- "type": "object",
- "required": [
- "update_config"
- ],
- "properties": {
- "update_config": {
- "type": "object",
- "properties": {
- "anchor_oracle": {
- "anyOf": [
- {
- "$ref": "#/definitions/HumanAddr"
- },
- {
- "type": "null"
- }
- ]
- },
- "band_oracle": {
- "anyOf": [
- {
- "$ref": "#/definitions/HumanAddr"
- },
- {
- "type": "null"
- }
- ]
- },
- "base_denom": {
- "type": [
- "string",
- "null"
- ]
- },
- "factory_contract": {
- "anyOf": [
- {
- "$ref": "#/definitions/HumanAddr"
- },
- {
- "type": "null"
- }
- ]
- },
- "mint_contract": {
- "anyOf": [
- {
- "$ref": "#/definitions/HumanAddr"
- },
- {
- "type": "null"
- }
- ]
- },
- "mirror_oracle": {
- "anyOf": [
- {
- "$ref": "#/definitions/HumanAddr"
- },
- {
- "type": "null"
- }
- ]
- },
- "owner": {
- "anyOf": [
- {
- "$ref": "#/definitions/HumanAddr"
- },
- {
- "type": "null"
- }
- ]
- }
- }
- }
- }
- },
- {
- "type": "object",
- "required": [
- "register_collateral_asset"
- ],
- "properties": {
- "register_collateral_asset": {
- "type": "object",
- "required": [
- "asset",
- "multiplier",
- "price_source"
- ],
- "properties": {
- "asset": {
- "$ref": "#/definitions/AssetInfo"
- },
- "multiplier": {
- "$ref": "#/definitions/Decimal"
- },
- "price_source": {
- "$ref": "#/definitions/SourceType"
- }
- }
- }
- }
- },
- {
- "type": "object",
- "required": [
- "revoke_collateral_asset"
- ],
- "properties": {
- "revoke_collateral_asset": {
- "type": "object",
- "required": [
- "asset"
- ],
- "properties": {
- "asset": {
- "$ref": "#/definitions/AssetInfo"
- }
- }
- }
- }
- },
- {
- "type": "object",
- "required": [
- "update_collateral_price_source"
- ],
- "properties": {
- "update_collateral_price_source": {
- "type": "object",
- "required": [
- "asset",
- "price_source"
- ],
- "properties": {
- "asset": {
- "$ref": "#/definitions/AssetInfo"
- },
- "price_source": {
- "$ref": "#/definitions/SourceType"
- }
- }
- }
- }
- },
- {
- "type": "object",
- "required": [
- "update_collateral_multiplier"
- ],
- "properties": {
- "update_collateral_multiplier": {
- "type": "object",
- "required": [
- "asset",
- "multiplier"
- ],
- "properties": {
- "asset": {
- "$ref": "#/definitions/AssetInfo"
- },
- "multiplier": {
- "$ref": "#/definitions/Decimal"
- }
- }
- }
- }
- }
- ],
- "definitions": {
- "AssetInfo": {
- "anyOf": [
- {
- "type": "object",
- "required": [
- "token"
- ],
- "properties": {
- "token": {
- "type": "object",
- "required": [
- "contract_addr"
- ],
- "properties": {
- "contract_addr": {
- "$ref": "#/definitions/HumanAddr"
- }
- }
- }
- }
- },
- {
- "type": "object",
- "required": [
- "native_token"
- ],
- "properties": {
- "native_token": {
- "type": "object",
- "required": [
- "denom"
- ],
- "properties": {
- "denom": {
- "type": "string"
- }
- }
- }
- }
- }
- ]
- },
- "Decimal": {
- "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)",
- "type": "string"
- },
- "HumanAddr": {
- "type": "string"
- },
- "SourceType": {
- "anyOf": [
- {
- "type": "object",
- "required": [
- "mirror_oracle"
- ],
- "properties": {
- "mirror_oracle": {
- "type": "object"
- }
- }
- },
- {
- "type": "object",
- "required": [
- "anchor_oracle"
- ],
- "properties": {
- "anchor_oracle": {
- "type": "object"
- }
- }
- },
- {
- "type": "object",
- "required": [
- "band_oracle"
- ],
- "properties": {
- "band_oracle": {
- "type": "object"
- }
- }
- },
- {
- "type": "object",
- "required": [
- "fixed_price"
- ],
- "properties": {
- "fixed_price": {
- "type": "object",
- "required": [
- "price"
- ],
- "properties": {
- "price": {
- "$ref": "#/definitions/Decimal"
- }
- }
- }
- }
- },
- {
- "type": "object",
- "required": [
- "terraswap"
- ],
- "properties": {
- "terraswap": {
- "type": "object",
- "required": [
- "terraswap_pair_addr"
- ],
- "properties": {
- "intermediate_denom": {
- "type": [
- "string",
- "null"
- ]
- },
- "terraswap_pair_addr": {
- "$ref": "#/definitions/HumanAddr"
- }
- }
- }
- }
- },
- {
- "type": "object",
- "required": [
- "anchor_market"
- ],
- "properties": {
- "anchor_market": {
- "type": "object",
- "required": [
- "anchor_market_addr"
- ],
- "properties": {
- "anchor_market_addr": {
- "$ref": "#/definitions/HumanAddr"
- }
- }
- }
- }
- },
- {
- "type": "object",
- "required": [
- "native"
- ],
- "properties": {
- "native": {
- "type": "object",
- "required": [
- "native_denom"
- ],
- "properties": {
- "native_denom": {
- "type": "string"
- }
- }
- }
- }
- }
- ]
- }
- }
-}
diff --git a/contracts/mirror_collateral_oracle/schema/init_msg.json b/contracts/mirror_collateral_oracle/schema/init_msg.json
deleted file mode 100644
index 992250af5..000000000
--- a/contracts/mirror_collateral_oracle/schema/init_msg.json
+++ /dev/null
@@ -1,42 +0,0 @@
-{
- "$schema": "http://json-schema.org/draft-07/schema#",
- "title": "InitMsg",
- "type": "object",
- "required": [
- "anchor_oracle",
- "band_oracle",
- "base_denom",
- "factory_contract",
- "mint_contract",
- "mirror_oracle",
- "owner"
- ],
- "properties": {
- "anchor_oracle": {
- "$ref": "#/definitions/HumanAddr"
- },
- "band_oracle": {
- "$ref": "#/definitions/HumanAddr"
- },
- "base_denom": {
- "type": "string"
- },
- "factory_contract": {
- "$ref": "#/definitions/HumanAddr"
- },
- "mint_contract": {
- "$ref": "#/definitions/HumanAddr"
- },
- "mirror_oracle": {
- "$ref": "#/definitions/HumanAddr"
- },
- "owner": {
- "$ref": "#/definitions/HumanAddr"
- }
- },
- "definitions": {
- "HumanAddr": {
- "type": "string"
- }
- }
-}
diff --git a/contracts/mirror_collateral_oracle/schema/migrate_msg.json b/contracts/mirror_collateral_oracle/schema/migrate_msg.json
deleted file mode 100644
index 666fb7e9f..000000000
--- a/contracts/mirror_collateral_oracle/schema/migrate_msg.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "$schema": "http://json-schema.org/draft-07/schema#",
- "title": "MigrateMsg",
- "description": "We currently take no arguments for migrations",
- "type": "object"
-}
diff --git a/contracts/mirror_collateral_oracle/schema/query_msg.json b/contracts/mirror_collateral_oracle/schema/query_msg.json
deleted file mode 100644
index 0bc4ceeeb..000000000
--- a/contracts/mirror_collateral_oracle/schema/query_msg.json
+++ /dev/null
@@ -1,66 +0,0 @@
-{
- "$schema": "http://json-schema.org/draft-07/schema#",
- "title": "QueryMsg",
- "anyOf": [
- {
- "type": "object",
- "required": [
- "config"
- ],
- "properties": {
- "config": {
- "type": "object"
- }
- }
- },
- {
- "type": "object",
- "required": [
- "collateral_price"
- ],
- "properties": {
- "collateral_price": {
- "type": "object",
- "required": [
- "asset"
- ],
- "properties": {
- "asset": {
- "type": "string"
- }
- }
- }
- }
- },
- {
- "type": "object",
- "required": [
- "collateral_asset_info"
- ],
- "properties": {
- "collateral_asset_info": {
- "type": "object",
- "required": [
- "asset"
- ],
- "properties": {
- "asset": {
- "type": "string"
- }
- }
- }
- }
- },
- {
- "type": "object",
- "required": [
- "collateral_asset_infos"
- ],
- "properties": {
- "collateral_asset_infos": {
- "type": "object"
- }
- }
- }
- ]
-}
diff --git a/contracts/mirror_collateral_oracle/src/contract.rs b/contracts/mirror_collateral_oracle/src/contract.rs
deleted file mode 100644
index 1a746f05d..000000000
--- a/contracts/mirror_collateral_oracle/src/contract.rs
+++ /dev/null
@@ -1,333 +0,0 @@
-use crate::querier::query_price;
-use crate::state::{
- read_collateral_info, read_collateral_infos, read_config, store_collateral_info, store_config,
- CollateralAssetInfo, Config,
-};
-use cosmwasm_std::{
- to_binary, Api, Binary, CanonicalAddr, Decimal, Env, Extern, HandleResponse, HandleResult,
- HumanAddr, InitResponse, MigrateResponse, MigrateResult, Querier, StdError, StdResult, Storage,
-};
-
-use mirror_protocol::collateral_oracle::{
- CollateralInfoResponse, CollateralInfosResponse, CollateralPriceResponse, ConfigResponse,
- HandleMsg, InitMsg, MigrateMsg, QueryMsg, SourceType,
-};
-
-use terraswap::asset::AssetInfo;
-
-pub fn init(
- deps: &mut Extern,
- _env: Env,
- msg: InitMsg,
-) -> StdResult {
- store_config(
- &mut deps.storage,
- &Config {
- owner: deps.api.canonical_address(&msg.owner)?,
- mint_contract: deps.api.canonical_address(&msg.mint_contract)?,
- factory_contract: deps.api.canonical_address(&msg.factory_contract)?,
- base_denom: msg.base_denom,
- mirror_oracle: deps.api.canonical_address(&msg.mirror_oracle)?,
- anchor_oracle: deps.api.canonical_address(&msg.anchor_oracle)?,
- band_oracle: deps.api.canonical_address(&msg.band_oracle)?,
- },
- )?;
-
- Ok(InitResponse::default())
-}
-
-pub fn handle(
- deps: &mut Extern,
- env: Env,
- msg: HandleMsg,
-) -> HandleResult {
- match msg {
- HandleMsg::UpdateConfig {
- owner,
- mint_contract,
- factory_contract,
- base_denom,
- mirror_oracle,
- anchor_oracle,
- band_oracle,
- } => update_config(
- deps,
- env,
- owner,
- mint_contract,
- factory_contract,
- base_denom,
- mirror_oracle,
- anchor_oracle,
- band_oracle,
- ),
- HandleMsg::RegisterCollateralAsset {
- asset,
- price_source,
- multiplier,
- } => register_collateral(deps, env, asset, price_source, multiplier),
- HandleMsg::RevokeCollateralAsset { asset } => revoke_collateral(deps, env, asset),
- HandleMsg::UpdateCollateralPriceSource {
- asset,
- price_source,
- } => update_collateral_source(deps, env, asset, price_source),
- HandleMsg::UpdateCollateralMultiplier { asset, multiplier } => {
- update_collateral_multiplier(deps, env, asset, multiplier)
- }
- }
-}
-
-pub fn update_config(
- deps: &mut Extern,
- env: Env,
- owner: Option,
- mint_contract: Option,
- factory_contract: Option,
- base_denom: Option,
- mirror_oracle: Option,
- anchor_oracle: Option,
- band_oracle: Option,
-) -> HandleResult {
- let mut config: Config = read_config(&deps.storage)?;
- if deps.api.canonical_address(&env.message.sender)? != config.owner {
- return Err(StdError::unauthorized());
- }
-
- if let Some(owner) = owner {
- config.owner = deps.api.canonical_address(&owner)?;
- }
-
- if let Some(mint_contract) = mint_contract {
- config.mint_contract = deps.api.canonical_address(&mint_contract)?;
- }
-
- if let Some(factory_contract) = factory_contract {
- config.factory_contract = deps.api.canonical_address(&factory_contract)?;
- }
-
- if let Some(base_denom) = base_denom {
- config.base_denom = base_denom;
- }
-
- if let Some(mirror_oracle) = mirror_oracle {
- config.mirror_oracle = deps.api.canonical_address(&mirror_oracle)?;
- }
-
- if let Some(anchor_oracle) = anchor_oracle {
- config.anchor_oracle = deps.api.canonical_address(&anchor_oracle)?;
- }
-
- if let Some(band_oracle) = band_oracle {
- config.band_oracle = deps.api.canonical_address(&band_oracle)?;
- }
-
- store_config(&mut deps.storage, &config)?;
- Ok(HandleResponse::default())
-}
-
-pub fn register_collateral(
- deps: &mut Extern,
- env: Env,
- asset: AssetInfo,
- price_source: SourceType,
- multiplier: Decimal,
-) -> HandleResult {
- let config: Config = read_config(&deps.storage)?;
- let sender_address_raw: CanonicalAddr = deps.api.canonical_address(&env.message.sender)?;
- // only contract onwner and mint contract can register a new collateral
- if config.owner != sender_address_raw && config.mint_contract != sender_address_raw {
- return Err(StdError::unauthorized());
- }
-
- if read_collateral_info(&deps.storage, &asset.to_string()).is_ok() {
- return Err(StdError::generic_err("Collateral was already registered"));
- }
-
- if multiplier.is_zero() {
- return Err(StdError::generic_err("Multiplier must be bigger than 0"));
- }
-
- store_collateral_info(
- &mut deps.storage,
- &CollateralAssetInfo {
- asset: asset.to_string(),
- multiplier,
- price_source,
- is_revoked: false,
- },
- )?;
-
- Ok(HandleResponse::default())
-}
-
-pub fn revoke_collateral(
- deps: &mut Extern,
- env: Env,
- asset: AssetInfo,
-) -> HandleResult {
- let config: Config = read_config(&deps.storage)?;
- let sender_address_raw: CanonicalAddr = deps.api.canonical_address(&env.message.sender)?;
- // only owner and mint contract can revoke a collateral assets
- if config.owner != sender_address_raw && config.mint_contract != sender_address_raw {
- return Err(StdError::unauthorized());
- }
-
- let mut collateral_info: CollateralAssetInfo =
- if let Ok(collateral) = read_collateral_info(&deps.storage, &asset.to_string()) {
- collateral
- } else {
- return Err(StdError::generic_err("Collateral not found"));
- };
-
- collateral_info.is_revoked = true;
-
- store_collateral_info(&mut deps.storage, &collateral_info)?;
-
- Ok(HandleResponse::default())
-}
-
-pub fn update_collateral_source(
- deps: &mut Extern,
- env: Env,
- asset: AssetInfo,
- price_source: SourceType,
-) -> HandleResult {
- let config: Config = read_config(&deps.storage)?;
- let sender_address_raw: CanonicalAddr = deps.api.canonical_address(&env.message.sender)?;
- // only contract onwner can update collateral query
- if config.owner != sender_address_raw {
- return Err(StdError::unauthorized());
- }
-
- let mut collateral_info: CollateralAssetInfo =
- if let Ok(collateral) = read_collateral_info(&deps.storage, &asset.to_string()) {
- collateral
- } else {
- return Err(StdError::generic_err("Collateral not found"));
- };
-
- collateral_info.price_source = price_source;
-
- store_collateral_info(&mut deps.storage, &collateral_info)?;
-
- Ok(HandleResponse::default())
-}
-
-pub fn update_collateral_multiplier(
- deps: &mut Extern,
- env: Env,
- asset: AssetInfo,
- multiplier: Decimal,
-) -> HandleResult {
- let config: Config = read_config(&deps.storage)?;
- let sender_address_raw: CanonicalAddr = deps.api.canonical_address(&env.message.sender)?;
- // only factory contract can update collateral premium
- if config.factory_contract != sender_address_raw {
- return Err(StdError::unauthorized());
- }
-
- let mut collateral_info: CollateralAssetInfo =
- if let Ok(collateral) = read_collateral_info(&deps.storage, &asset.to_string()) {
- collateral
- } else {
- return Err(StdError::generic_err("Collateral not found"));
- };
-
- if multiplier.is_zero() {
- return Err(StdError::generic_err("Multiplier must be bigger than 0"));
- }
-
- collateral_info.multiplier = multiplier;
- store_collateral_info(&mut deps.storage, &collateral_info)?;
-
- Ok(HandleResponse::default())
-}
-
-pub fn query(
- deps: &Extern,
- msg: QueryMsg,
-) -> StdResult {
- match msg {
- QueryMsg::Config {} => to_binary(&query_config(deps)?),
- QueryMsg::CollateralPrice { asset } => to_binary(&query_collateral_price(deps, asset)?),
- QueryMsg::CollateralAssetInfo { asset } => to_binary(&query_collateral_info(deps, asset)?),
- QueryMsg::CollateralAssetInfos {} => to_binary(&query_collateral_infos(deps)?),
- }
-}
-
-pub fn query_config(
- deps: &Extern,
-) -> StdResult {
- let config = read_config(&deps.storage)?;
- let resp = ConfigResponse {
- owner: deps.api.human_address(&config.owner)?,
- mint_contract: deps.api.human_address(&config.mint_contract)?,
- factory_contract: deps.api.human_address(&config.factory_contract)?,
- base_denom: config.base_denom,
- mirror_oracle: deps.api.human_address(&config.mirror_oracle)?,
- anchor_oracle: deps.api.human_address(&config.anchor_oracle)?,
- band_oracle: deps.api.human_address(&config.band_oracle)?,
- };
-
- Ok(resp)
-}
-
-pub fn query_collateral_price(
- deps: &Extern,
- quote_asset: String,
-) -> StdResult {
- let config: Config = read_config(&deps.storage)?;
-
- let collateral: CollateralAssetInfo =
- if let Ok(res) = read_collateral_info(&deps.storage, "e_asset) {
- res
- } else {
- return Err(StdError::generic_err("Collateral asset not found"));
- };
-
- let (price, last_updated): (Decimal, u64) =
- query_price(deps, &config, "e_asset, &collateral.price_source)?;
-
- Ok(CollateralPriceResponse {
- asset: collateral.asset,
- rate: price,
- last_updated,
- multiplier: collateral.multiplier,
- is_revoked: collateral.is_revoked,
- })
-}
-
-pub fn query_collateral_info(
- deps: &Extern,
- quote_asset: String,
-) -> StdResult {
- let collateral: CollateralAssetInfo =
- if let Ok(res) = read_collateral_info(&deps.storage, "e_asset) {
- res
- } else {
- return Err(StdError::generic_err("Collateral asset not found"));
- };
-
- Ok(CollateralInfoResponse {
- asset: collateral.asset,
- source_type: collateral.price_source.to_string(),
- multiplier: collateral.multiplier,
- is_revoked: collateral.is_revoked,
- })
-}
-
-pub fn query_collateral_infos(
- deps: &Extern,
-) -> StdResult {
- let infos: Vec = read_collateral_infos(&deps.storage)?;
-
- Ok(CollateralInfosResponse { collaterals: infos })
-}
-
-pub fn migrate(
- _deps: &mut Extern,
- _env: Env,
- _msg: MigrateMsg,
-) -> MigrateResult {
- Ok(MigrateResponse::default())
-}
diff --git a/contracts/mirror_collateral_oracle/src/lib.rs b/contracts/mirror_collateral_oracle/src/lib.rs
deleted file mode 100644
index 6b2695c89..000000000
--- a/contracts/mirror_collateral_oracle/src/lib.rs
+++ /dev/null
@@ -1,13 +0,0 @@
-pub mod contract;
-pub mod math;
-pub mod querier;
-pub mod state;
-
-#[cfg(test)]
-mod testing;
-
-#[cfg(test)]
-mod mock_querier;
-
-#[cfg(target_arch = "wasm32")]
-cosmwasm_std::create_entry_points_with_migration!(contract);
diff --git a/contracts/mirror_collateral_oracle/src/math.rs b/contracts/mirror_collateral_oracle/src/math.rs
deleted file mode 100644
index 7cafbb1bf..000000000
--- a/contracts/mirror_collateral_oracle/src/math.rs
+++ /dev/null
@@ -1,12 +0,0 @@
-use cosmwasm_std::{Decimal, Uint128};
-
-const DECIMAL_FRACTIONAL: Uint128 = Uint128(1_000_000_000u128);
-
-/// return a / b
-pub fn decimal_division(a: Decimal, b: Decimal) -> Decimal {
- Decimal::from_ratio(DECIMAL_FRACTIONAL * a, b * DECIMAL_FRACTIONAL)
-}
-
-pub fn decimal_multiplication(a: Decimal, b: Decimal) -> Decimal {
- Decimal::from_ratio(a * DECIMAL_FRACTIONAL * b, DECIMAL_FRACTIONAL)
-}
diff --git a/contracts/mirror_collateral_oracle/src/mock_querier.rs b/contracts/mirror_collateral_oracle/src/mock_querier.rs
deleted file mode 100644
index 6f3ddc1be..000000000
--- a/contracts/mirror_collateral_oracle/src/mock_querier.rs
+++ /dev/null
@@ -1,249 +0,0 @@
-use cosmwasm_std::testing::{MockApi, MockQuerier, MockStorage, MOCK_CONTRACT_ADDR};
-use cosmwasm_std::{
- from_binary, from_slice, to_binary, Coin, Decimal, Extern, HumanAddr, Querier, QuerierResult,
- QueryRequest, SystemError, Uint128, WasmQuery,
-};
-use schemars::JsonSchema;
-use serde::{Deserialize, Serialize};
-use std::collections::HashMap;
-use std::str::FromStr;
-
-use crate::math::decimal_division;
-use cosmwasm_bignumber::{Decimal256, Uint256};
-use mirror_protocol::oracle::PriceResponse;
-use terra_cosmwasm::{
- ExchangeRateItem, ExchangeRatesResponse, TerraQuery, TerraQueryWrapper, TerraRoute,
-};
-use terraswap::asset::{Asset, AssetInfo};
-use terraswap::pair::PoolResponse;
-
-/// mock_dependencies is a drop-in replacement for cosmwasm_std::testing::mock_dependencies
-/// this uses our CustomQuerier.
-pub fn mock_dependencies(
- canonical_length: usize,
- contract_balance: &[Coin],
-) -> Extern {
- let contract_addr = HumanAddr::from(MOCK_CONTRACT_ADDR);
- let custom_querier: WasmMockQuerier =
- WasmMockQuerier::new(MockQuerier::new(&[(&contract_addr, contract_balance)]));
-
- Extern {
- storage: MockStorage::default(),
- api: MockApi::new(canonical_length),
- querier: custom_querier,
- }
-}
-
-pub struct WasmMockQuerier {
- base: MockQuerier,
- oracle_price_querier: OraclePriceQuerier,
- terraswap_pools_querier: TerraswapPoolsQuerier,
-}
-
-#[derive(Clone, Default)]
-pub struct OraclePriceQuerier {
- // this lets us iterate over all pairs that match the first string
- oracle_price: HashMap,
-}
-
-impl OraclePriceQuerier {
- pub fn new(oracle_price: &[(&String, &Decimal)]) -> Self {
- OraclePriceQuerier {
- oracle_price: oracle_price_to_map(oracle_price),
- }
- }
-}
-
-pub(crate) fn oracle_price_to_map(
- oracle_price: &[(&String, &Decimal)],
-) -> HashMap {
- let mut oracle_price_map: HashMap = HashMap::new();
- for (base_quote, oracle_price) in oracle_price.iter() {
- oracle_price_map.insert((*base_quote).clone(), **oracle_price);
- }
-
- oracle_price_map
-}
-
-#[derive(Clone, Default)]
-pub struct TerraswapPoolsQuerier {
- pools: HashMap,
-}
-
-impl TerraswapPoolsQuerier {
- pub fn new(pools: &[(&HumanAddr, (&String, &Uint128, &String, &Uint128))]) -> Self {
- TerraswapPoolsQuerier {
- pools: pools_to_map(pools),
- }
- }
-}
-
-pub(crate) fn pools_to_map(
- pools: &[(&HumanAddr, (&String, &Uint128, &String, &Uint128))],
-) -> HashMap {
- let mut pools_map: HashMap = HashMap::new();
- for (key, pool) in pools.into_iter() {
- pools_map.insert(
- HumanAddr::from(key),
- (pool.0.clone(), *pool.1, pool.2.clone(), *pool.3),
- );
- }
- pools_map
-}
-
-impl Querier for WasmMockQuerier {
- fn raw_query(&self, bin_request: &[u8]) -> QuerierResult {
- // MockQuerier doesn't support Custom, so we ignore it completely here
- let request: QueryRequest = match from_slice(bin_request) {
- Ok(v) => v,
- Err(e) => {
- return Err(SystemError::InvalidRequest {
- error: format!("Parsing query request: {}", e),
- request: bin_request.into(),
- })
- }
- };
- self.handle_query(&request)
- }
-}
-
-#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
-#[serde(rename_all = "snake_case")]
-pub struct ReferenceData {
- rate: Uint128,
- last_updated_base: u64,
- last_updated_quote: u64,
-}
-
-#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
-#[serde(rename_all = "snake_case")]
-pub struct EpochStateResponse {
- exchange_rate: Decimal256,
- aterra_supply: Uint256,
-}
-
-#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
-#[serde(rename_all = "snake_case")]
-pub enum QueryMsg {
- Price {
- base_asset: String,
- quote_asset: String,
- },
- Pool {},
- GetReferenceData {
- base_symbol: String,
- quote_symbol: String,
- },
- EpochState {
- block_heigth: Option,
- distributed_interest: Option,
- },
-}
-
-impl WasmMockQuerier {
- pub fn handle_query(&self, request: &QueryRequest) -> QuerierResult {
- match &request {
- QueryRequest::Custom(TerraQueryWrapper { route, query_data }) => {
- if &TerraRoute::Oracle == route {
- match query_data {
- TerraQuery::ExchangeRates {
- base_denom: _,
- quote_denoms: _,
- } => {
- let res = ExchangeRatesResponse {
- exchange_rates: vec![ExchangeRateItem {
- quote_denom: "uusd".to_string(),
- exchange_rate: Decimal::from_ratio(5u128, 1u128),
- }],
- base_denom: "uluna".to_string(),
- };
- Ok(to_binary(&res))
- }
- _ => panic!("DO NOT ENTER HERE"),
- }
- } else {
- panic!("DO NOT ENTER HERE")
- }
- }
- QueryRequest::Wasm(WasmQuery::Smart { contract_addr, msg }) => match from_binary(&msg)
- .unwrap()
- {
- QueryMsg::Price {
- base_asset,
- quote_asset,
- } => match self.oracle_price_querier.oracle_price.get(&base_asset) {
- Some(base_price) => {
- match self.oracle_price_querier.oracle_price.get("e_asset) {
- Some(quote_price) => Ok(to_binary(&PriceResponse {
- rate: decimal_division(*base_price, *quote_price),
- last_updated_base: 1000u64,
- last_updated_quote: 1000u64,
- })),
- None => Err(SystemError::InvalidRequest {
- error: "No oracle price exists".to_string(),
- request: msg.as_slice().into(),
- }),
- }
- }
- None => Err(SystemError::InvalidRequest {
- error: "No oracle price exists".to_string(),
- request: msg.as_slice().into(),
- }),
- },
- QueryMsg::Pool {} => match self.terraswap_pools_querier.pools.get(&contract_addr) {
- Some(v) => Ok(to_binary(&PoolResponse {
- assets: [
- Asset {
- amount: v.1,
- info: AssetInfo::NativeToken { denom: v.0.clone() },
- },
- Asset {
- amount: v.3,
- info: AssetInfo::Token {
- contract_addr: HumanAddr::from(v.2.clone()),
- },
- },
- ],
- total_share: Uint128::zero(),
- })),
- None => Err(SystemError::InvalidRequest {
- error: "No pair info exists".to_string(),
- request: msg.as_slice().into(),
- }),
- },
- QueryMsg::GetReferenceData { .. } => Ok(to_binary(&ReferenceData {
- rate: Uint128(3465211050000000000000),
- last_updated_base: 100u64,
- last_updated_quote: 100u64,
- })),
- QueryMsg::EpochState { .. } => Ok(to_binary(&EpochStateResponse {
- exchange_rate: Decimal256::from_ratio(10, 3),
- aterra_supply: Uint256::from_str("123123123").unwrap(),
- })),
- },
- _ => self.base.handle_query(request),
- }
- }
-}
-
-impl WasmMockQuerier {
- pub fn new(base: MockQuerier) -> Self {
- WasmMockQuerier {
- base,
- oracle_price_querier: OraclePriceQuerier::default(),
- terraswap_pools_querier: TerraswapPoolsQuerier::default(),
- }
- }
-
- // configure the oracle price mock querier
- pub fn with_oracle_price(&mut self, oracle_price: &[(&String, &Decimal)]) {
- self.oracle_price_querier = OraclePriceQuerier::new(oracle_price);
- }
-
- pub fn with_terraswap_pools(
- &mut self,
- pairs: &[(&HumanAddr, (&String, &Uint128, &String, &Uint128))],
- ) {
- self.terraswap_pools_querier = TerraswapPoolsQuerier::new(pairs);
- }
-}
diff --git a/contracts/mirror_collateral_oracle/src/querier.rs b/contracts/mirror_collateral_oracle/src/querier.rs
deleted file mode 100644
index 82e121063..000000000
--- a/contracts/mirror_collateral_oracle/src/querier.rs
+++ /dev/null
@@ -1,230 +0,0 @@
-use cosmwasm_std::{
- to_binary, Api, Decimal, Extern, HumanAddr, Querier, QueryRequest, StdError, StdResult,
- Storage, Uint128, WasmQuery,
-};
-use std::str::FromStr;
-
-use crate::math::decimal_multiplication;
-use crate::state::Config;
-use cosmwasm_bignumber::Decimal256;
-use cosmwasm_bignumber::Uint256;
-use mirror_protocol::collateral_oracle::SourceType;
-use serde::{Deserialize, Serialize};
-use terra_cosmwasm::{ExchangeRatesResponse, TerraQuerier};
-use terraswap::asset::{Asset, AssetInfo};
-use terraswap::pair::QueryMsg as TerraswapPairQueryMsg;
-
-#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
-#[serde(rename_all = "snake_case")]
-pub enum SourceQueryMsg {
- Price {
- base_asset: String,
- quote_asset: String,
- },
- Pool {},
- GetReferenceData {
- base_symbol: String,
- quote_symbol: String,
- },
- EpochState {
- block_heigth: Option,
- distributed_interest: Option,
- },
-}
-
-#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
-pub struct TerraOracleResponse {
- // oracle queries returns rate
- pub rate: Decimal,
- pub last_updated_base: u64,
-}
-#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
-pub struct TerraswapResponse {
- // terraswap queries return pool assets
- pub assets: [Asset; 2],
-}
-#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
-pub struct BandOracleResponse {
- // band oracle queries returns rate (uint128)
- pub rate: Uint128,
- pub last_updated_base: u64,
-}
-#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
-pub struct AnchorMarketResponse {
- // anchor market queries return exchange rate in Decimal256
- pub exchange_rate: Decimal256,
-}
-
-pub fn query_price(
- deps: &Extern,
- config: &Config,
- asset: &String,
- price_source: &SourceType,
-) -> StdResult<(Decimal, u64)> {
- match price_source {
- SourceType::BandOracle {} => {
- let res: BandOracleResponse =
- deps.querier.query(&QueryRequest::Wasm(WasmQuery::Smart {
- contract_addr: deps.api.human_address(&config.band_oracle)?,
- msg: to_binary(&SourceQueryMsg::GetReferenceData {
- base_symbol: asset.to_string(),
- quote_symbol: config.base_denom.clone(),
- })
- .unwrap(),
- }))?;
- let rate: Decimal = parse_band_rate(res.rate)?;
-
- Ok((rate, res.last_updated_base))
- }
- SourceType::FixedPrice { price } => return Ok((*price, u64::MAX)),
- SourceType::MirrorOracle {} => {
- let res: TerraOracleResponse =
- deps.querier.query(&QueryRequest::Wasm(WasmQuery::Smart {
- contract_addr: deps.api.human_address(&config.mirror_oracle)?,
- msg: to_binary(&SourceQueryMsg::Price {
- base_asset: asset.to_string(),
- quote_asset: config.base_denom.clone(),
- })
- .unwrap(),
- }))?;
-
- Ok((res.rate, res.last_updated_base))
- }
- SourceType::AnchorOracle {} => {
- let res: TerraOracleResponse =
- deps.querier.query(&QueryRequest::Wasm(WasmQuery::Smart {
- contract_addr: deps.api.human_address(&config.anchor_oracle)?,
- msg: to_binary(&SourceQueryMsg::Price {
- base_asset: asset.to_string(),
- quote_asset: config.base_denom.clone(),
- })
- .unwrap(),
- }))?;
-
- Ok((res.rate, res.last_updated_base))
- }
- SourceType::Terraswap {
- terraswap_pair_addr,
- intermediate_denom,
- } => {
- let res: TerraswapResponse =
- deps.querier.query(&QueryRequest::Wasm(WasmQuery::Smart {
- contract_addr: HumanAddr::from(terraswap_pair_addr),
- msg: to_binary(&TerraswapPairQueryMsg::Pool {}).unwrap(),
- }))?;
- let assets: [Asset; 2] = res.assets;
-
- // query intermediate denom if it exists
- let query_denom: String = match intermediate_denom.clone() {
- Some(v) => v,
- None => config.base_denom.clone(),
- };
-
- let queried_rate: Decimal = if assets[0].info.equal(&AssetInfo::NativeToken {
- denom: query_denom.clone(),
- }) {
- Decimal::from_ratio(assets[0].amount, assets[1].amount)
- } else if assets[1].info.equal(&AssetInfo::NativeToken {
- denom: query_denom.clone(),
- }) {
- Decimal::from_ratio(assets[1].amount, assets[0].amount)
- } else {
- return Err(StdError::generic_err("Invalid pool"));
- };
-
- // if intermediate denom exists, calculate final rate
- let rate: Decimal = if intermediate_denom.is_some() {
- // (query_denom / intermediate_denom) * (intermedaite_denom / base_denom) = (query_denom / base_denom)
- let native_rate: Decimal =
- query_native_rate(&deps.querier, query_denom, config.base_denom.clone())?;
- decimal_multiplication(queried_rate, native_rate)
- } else {
- queried_rate
- };
-
- Ok((rate, u64::MAX))
- }
- SourceType::AnchorMarket { anchor_market_addr } => {
- let res: AnchorMarketResponse =
- deps.querier.query(&QueryRequest::Wasm(WasmQuery::Smart {
- contract_addr: HumanAddr::from(anchor_market_addr),
- msg: to_binary(&SourceQueryMsg::EpochState {
- block_heigth: None,
- distributed_interest: None,
- })
- .unwrap(),
- }))?;
- let rate: Decimal = res.exchange_rate.into();
-
- Ok((rate, u64::MAX))
- }
- SourceType::Native { native_denom } => {
- let rate: Decimal = query_native_rate(
- &deps.querier,
- native_denom.clone(),
- config.base_denom.clone(),
- )?;
-
- Ok((rate, u64::MAX))
- }
- }
-}
-
-/// Parses a uint that contains the price multiplied by 1e18
-fn parse_band_rate(uint_rate: Uint128) -> StdResult {
- // manipulate the uint as a string to prevent overflow
- let mut rate_uint_string: String = uint_rate.to_string();
-
- let uint_len = rate_uint_string.len();
- if uint_len > 18 {
- let dec_point = rate_uint_string.len() - 18;
- rate_uint_string.insert(dec_point, '.');
- } else {
- let mut prefix: String = "0.".to_owned();
- let dec_zeros = 18 - uint_len;
- for _ in 0..dec_zeros {
- prefix.push('0');
- }
- rate_uint_string = prefix + rate_uint_string.as_str();
- }
-
- Decimal::from_str(rate_uint_string.as_str())
-}
-
-fn query_native_rate(
- querier: &Q,
- base_denom: String,
- quote_denom: String,
-) -> StdResult {
- let terra_querier = TerraQuerier::new(querier);
- let res: ExchangeRatesResponse =
- terra_querier.query_exchange_rates(base_denom, vec![quote_denom])?;
-
- Ok(res.exchange_rates[0].exchange_rate)
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
-
- #[test]
- fn test_parse_band_rate() {
- let rate_dec_1: Decimal = parse_band_rate(Uint128(3493968700000000000000u128)).unwrap();
- assert_eq!(
- rate_dec_1,
- Decimal::from_str("3493.968700000000000000").unwrap()
- );
-
- let rate_dec_2: Decimal = parse_band_rate(Uint128(1234u128)).unwrap();
- assert_eq!(
- rate_dec_2,
- Decimal::from_str("0.000000000000001234").unwrap()
- );
-
- let rate_dec_3: Decimal = parse_band_rate(Uint128(100000000000000001u128)).unwrap();
- assert_eq!(
- rate_dec_3,
- Decimal::from_str("0.100000000000000001").unwrap()
- );
- }
-}
diff --git a/contracts/mirror_collateral_oracle/src/state.rs b/contracts/mirror_collateral_oracle/src/state.rs
deleted file mode 100644
index 7628ec5cd..000000000
--- a/contracts/mirror_collateral_oracle/src/state.rs
+++ /dev/null
@@ -1,73 +0,0 @@
-use schemars::JsonSchema;
-use serde::{Deserialize, Serialize};
-
-use cosmwasm_std::{CanonicalAddr, Decimal, Order, StdResult, Storage};
-use cosmwasm_storage::{singleton, singleton_read, Bucket, ReadonlyBucket};
-
-use mirror_protocol::collateral_oracle::{CollateralInfoResponse, SourceType};
-
-static PREFIX_COLLATERAL_ASSET_INFO: &[u8] = b"collateral_asset_info";
-static KEY_CONFIG: &[u8] = b"config";
-
-#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
-pub struct Config {
- pub owner: CanonicalAddr,
- pub mint_contract: CanonicalAddr,
- pub factory_contract: CanonicalAddr,
- pub base_denom: String,
- pub mirror_oracle: CanonicalAddr,
- pub anchor_oracle: CanonicalAddr,
- pub band_oracle: CanonicalAddr,
-}
-
-pub fn store_config(storage: &mut S, config: &Config) -> StdResult<()> {
- singleton(storage, KEY_CONFIG).save(config)
-}
-
-pub fn read_config(storage: &S) -> StdResult {
- singleton_read(storage, KEY_CONFIG).load()
-}
-
-#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
-pub struct CollateralAssetInfo {
- pub asset: String,
- pub price_source: SourceType,
- pub multiplier: Decimal,
- pub is_revoked: bool,
-}
-
-pub fn store_collateral_info(
- storage: &mut S,
- collateral: &CollateralAssetInfo,
-) -> StdResult<()> {
- let mut collaterals_bucket: Bucket =
- Bucket::new(PREFIX_COLLATERAL_ASSET_INFO, storage);
- collaterals_bucket.save(collateral.asset.as_bytes(), collateral)
-}
-
-pub fn read_collateral_info(
- storage: &S,
- id: &String,
-) -> StdResult {
- let price_bucket: ReadonlyBucket =
- ReadonlyBucket::new(PREFIX_COLLATERAL_ASSET_INFO, storage);
- price_bucket.load(id.as_bytes())
-}
-
-pub fn read_collateral_infos(storage: &S) -> StdResult> {
- let price_bucket: ReadonlyBucket =
- ReadonlyBucket::new(PREFIX_COLLATERAL_ASSET_INFO, storage);
-
- price_bucket
- .range(None, None, Order::Ascending)
- .map(|item| {
- let (_, v) = item?;
- Ok(CollateralInfoResponse {
- asset: v.asset,
- source_type: v.price_source.to_string(),
- multiplier: v.multiplier,
- is_revoked: v.is_revoked,
- })
- })
- .collect()
-}
diff --git a/contracts/mirror_collateral_oracle/src/testing.rs b/contracts/mirror_collateral_oracle/src/testing.rs
deleted file mode 100644
index 229fed156..000000000
--- a/contracts/mirror_collateral_oracle/src/testing.rs
+++ /dev/null
@@ -1,674 +0,0 @@
-use crate::contract::{handle, init, query_collateral_info, query_collateral_price, query_config};
-use crate::mock_querier::mock_dependencies;
-use cosmwasm_std::testing::mock_env;
-use cosmwasm_std::{Decimal, HumanAddr, StdError, Uint128};
-use mirror_protocol::collateral_oracle::{
- CollateralInfoResponse, CollateralPriceResponse, HandleMsg, InitMsg, SourceType,
-};
-use std::str::FromStr;
-use terraswap::asset::AssetInfo;
-
-#[test]
-fn proper_initialization() {
- let mut deps = mock_dependencies(20, &[]);
-
- let msg = InitMsg {
- owner: HumanAddr("owner0000".to_string()),
- mint_contract: HumanAddr("mint0000".to_string()),
- factory_contract: HumanAddr("factory0000".to_string()),
- base_denom: "uusd".to_string(),
- mirror_oracle: HumanAddr("mirrororacle0000".to_string()),
- anchor_oracle: HumanAddr("anchororacle0000".to_string()),
- band_oracle: HumanAddr("bandoracle0000".to_string()),
- };
-
- let env = mock_env("addr0000", &[]);
-
- // we can just call .unwrap() to assert this was a success
- let res = init(&mut deps, env, msg).unwrap();
- assert_eq!(0, res.messages.len());
-
- // it worked, let's query the state
- let value = query_config(&deps).unwrap();
- assert_eq!("owner0000", value.owner.as_str());
- assert_eq!("mint0000", value.mint_contract.as_str());
- assert_eq!("factory0000", value.factory_contract.as_str());
- assert_eq!("uusd", value.base_denom.as_str());
-}
-
-#[test]
-fn update_config() {
- let mut deps = mock_dependencies(20, &[]);
-
- let msg = InitMsg {
- owner: HumanAddr("owner0000".to_string()),
- mint_contract: HumanAddr("mint0000".to_string()),
- factory_contract: HumanAddr("factory0000".to_string()),
- base_denom: "uusd".to_string(),
- mirror_oracle: HumanAddr("mirrororacle0000".to_string()),
- anchor_oracle: HumanAddr("anchororacle0000".to_string()),
- band_oracle: HumanAddr("bandoracle0000".to_string()),
- };
-
- let env = mock_env("addr0000", &[]);
- let _res = init(&mut deps, env, msg).unwrap();
-
- // update owner
- let env = mock_env("owner0000", &[]);
- let msg = HandleMsg::UpdateConfig {
- owner: Some(HumanAddr("owner0001".to_string())),
- mint_contract: Some(HumanAddr("mint0001".to_string())),
- factory_contract: Some(HumanAddr("factory0001".to_string())),
- base_denom: Some("uluna".to_string()),
- mirror_oracle: Some(HumanAddr("mirrororacle0001".to_string())),
- anchor_oracle: Some(HumanAddr("anchororacle0001".to_string())),
- band_oracle: Some(HumanAddr("bandoracle0001".to_string())),
- };
-
- let res = handle(&mut deps, env, msg).unwrap();
- assert_eq!(0, res.messages.len());
-
- // it worked, let's query the state
- let value = query_config(&deps).unwrap();
- assert_eq!("owner0001", value.owner.as_str());
- assert_eq!("mint0001", value.mint_contract.as_str());
- assert_eq!("factory0001", value.factory_contract.as_str());
- assert_eq!("uluna", value.base_denom.as_str());
- assert_eq!("mirrororacle0001", value.mirror_oracle.as_str());
- assert_eq!("anchororacle0001", value.anchor_oracle.as_str());
- assert_eq!("bandoracle0001", value.band_oracle.as_str());
-
- // Unauthorized err
- let env = mock_env("owner0000", &[]);
- let msg = HandleMsg::UpdateConfig {
- owner: None,
- mint_contract: None,
- factory_contract: None,
- base_denom: None,
- mirror_oracle: None,
- anchor_oracle: None,
- band_oracle: None,
- };
-
- let res = handle(&mut deps, env, msg);
- match res {
- Err(StdError::Unauthorized { .. }) => {}
- _ => panic!("Must return unauthorized error"),
- }
-}
-
-#[test]
-fn register_collateral() {
- let mut deps = mock_dependencies(20, &[]);
- deps.querier.with_oracle_price(&[
- (&"uusd".to_string(), &Decimal::one()),
- (&"mTSLA".to_string(), &Decimal::percent(100)),
- ]);
-
- let msg = InitMsg {
- owner: HumanAddr("owner0000".to_string()),
- mint_contract: HumanAddr("mint0000".to_string()),
- factory_contract: HumanAddr("factory0000".to_string()),
- base_denom: "uusd".to_string(),
- mirror_oracle: HumanAddr("mirrororacle0000".to_string()),
- anchor_oracle: HumanAddr("anchororacle0000".to_string()),
- band_oracle: HumanAddr("bandoracle0000".to_string()),
- };
-
- let env = mock_env("addr0000", &[]);
- let _res = init(&mut deps, env, msg).unwrap();
-
- let msg = HandleMsg::RegisterCollateralAsset {
- asset: AssetInfo::Token {
- contract_addr: HumanAddr::from("mTSLA"),
- },
- multiplier: Decimal::percent(100),
- price_source: SourceType::MirrorOracle {},
- };
-
- // unauthorized attempt
- let env = mock_env("addr0000", &[]);
- let res = handle(&mut deps, env, msg.clone()).unwrap_err();
- assert_eq!(res, StdError::unauthorized());
-
- // successfull attempt
- let env = mock_env("owner0000", &[]);
- let res = handle(&mut deps, env, msg).unwrap();
- assert_eq!(0, res.messages.len());
-
- // query collateral info
- let query_res = query_collateral_info(&deps, "mTSLA".to_string()).unwrap();
- assert_eq!(
- query_res,
- CollateralInfoResponse {
- asset: "mTSLA".to_string(),
- source_type: "mirror_oracle".to_string(),
- multiplier: Decimal::percent(100),
- is_revoked: false,
- }
- )
-}
-
-#[test]
-fn update_collateral() {
- let mut deps = mock_dependencies(20, &[]);
- deps.querier.with_oracle_price(&[
- (&"uusd".to_string(), &Decimal::one()),
- (&"mTSLA".to_string(), &Decimal::percent(100)),
- ]);
-
- let msg = InitMsg {
- owner: HumanAddr("owner0000".to_string()),
- mint_contract: HumanAddr("mint0000".to_string()),
- factory_contract: HumanAddr("factory0000".to_string()),
- base_denom: "uusd".to_string(),
- mirror_oracle: HumanAddr("mirrororacle0000".to_string()),
- anchor_oracle: HumanAddr("anchororacle0000".to_string()),
- band_oracle: HumanAddr("bandoracle0000".to_string()),
- };
-
- let env = mock_env("addr0000", &[]);
- let _res = init(&mut deps, env, msg).unwrap();
-
- let msg = HandleMsg::RegisterCollateralAsset {
- asset: AssetInfo::Token {
- contract_addr: HumanAddr::from("mTSLA"),
- },
- multiplier: Decimal::percent(100),
- price_source: SourceType::MirrorOracle {},
- };
-
- // successfull attempt
- let env = mock_env("owner0000", &[]);
- let res = handle(&mut deps, env, msg).unwrap();
- assert_eq!(0, res.messages.len());
-
- // query collateral info
- let query_res = query_collateral_info(&deps, "mTSLA".to_string()).unwrap();
- assert_eq!(
- query_res,
- CollateralInfoResponse {
- asset: "mTSLA".to_string(),
- source_type: "mirror_oracle".to_string(),
- multiplier: Decimal::percent(100),
- is_revoked: false,
- }
- );
-
- // update collateral query
- let msg = HandleMsg::UpdateCollateralPriceSource {
- asset: AssetInfo::Token {
- contract_addr: HumanAddr::from("mTSLA"),
- },
- price_source: SourceType::FixedPrice {
- price: Decimal::zero(),
- },
- };
-
- // unauthorized attempt
- let env = mock_env("factory0000", &[]);
- let res = handle(&mut deps, env, msg.clone()).unwrap_err();
- assert_eq!(res, StdError::unauthorized());
-
- // successfull attempt
- let env = mock_env("owner0000", &[]);
- let res = handle(&mut deps, env, msg).unwrap();
- assert_eq!(0, res.messages.len());
-
- // query the updated collateral
- let query_res = query_collateral_info(&deps, "mTSLA".to_string()).unwrap();
- assert_eq!(
- query_res,
- CollateralInfoResponse {
- asset: "mTSLA".to_string(),
- source_type: "fixed_price".to_string(),
- multiplier: Decimal::percent(100),
- is_revoked: false,
- }
- );
-
- // update collateral premium - invalid msg
- let msg = HandleMsg::UpdateCollateralMultiplier {
- asset: AssetInfo::Token {
- contract_addr: HumanAddr::from("mTSLA"),
- },
- multiplier: Decimal::zero(),
- };
-
- // invalid multiplier
- let env = mock_env("factory0000", &[]);
- let res = handle(&mut deps, env, msg).unwrap_err();
- assert_eq!(
- res,
- StdError::generic_err("Multiplier must be bigger than 0")
- );
-
- // update collateral premium - valid msg
- let msg = HandleMsg::UpdateCollateralMultiplier {
- asset: AssetInfo::Token {
- contract_addr: HumanAddr::from("mTSLA"),
- },
- multiplier: Decimal::percent(120),
- };
-
- // unauthorized attempt
- let env = mock_env("owner0000", &[]);
- let res = handle(&mut deps, env, msg.clone()).unwrap_err();
- assert_eq!(res, StdError::unauthorized());
-
- // successfull attempt
- let env = mock_env("factory0000", &[]);
- let res = handle(&mut deps, env, msg).unwrap();
- assert_eq!(0, res.messages.len());
-
- // query the updated collateral
- let query_res = query_collateral_info(&deps, "mTSLA".to_string()).unwrap();
- assert_eq!(
- query_res,
- CollateralInfoResponse {
- asset: "mTSLA".to_string(),
- source_type: "fixed_price".to_string(),
- multiplier: Decimal::percent(120),
- is_revoked: false,
- }
- )
-}
-
-#[test]
-fn get_oracle_price() {
- let mut deps = mock_dependencies(20, &[]);
- deps.querier.with_oracle_price(&[
- (&"uusd".to_string(), &Decimal::one()),
- (&"mTSLA".to_string(), &Decimal::percent(100)),
- ]);
-
- let msg = InitMsg {
- owner: HumanAddr("owner0000".to_string()),
- mint_contract: HumanAddr("mint0000".to_string()),
- factory_contract: HumanAddr("factory0000".to_string()),
- base_denom: "uusd".to_string(),
- mirror_oracle: HumanAddr("mirrororacle0000".to_string()),
- anchor_oracle: HumanAddr("anchororacle0000".to_string()),
- band_oracle: HumanAddr("bandoracle0000".to_string()),
- };
-
- let env = mock_env("addr0000", &[]);
- let _res = init(&mut deps, env, msg).unwrap();
-
- let msg = HandleMsg::RegisterCollateralAsset {
- asset: AssetInfo::Token {
- contract_addr: HumanAddr::from("mTSLA"),
- },
- multiplier: Decimal::percent(100),
- price_source: SourceType::MirrorOracle {},
- };
-
- let env = mock_env("owner0000", &[]);
- let _res = handle(&mut deps, env, msg).unwrap();
-
- // attempt to query price
- let query_res = query_collateral_price(&deps, "mTSLA".to_string()).unwrap();
- assert_eq!(
- query_res,
- CollateralPriceResponse {
- asset: "mTSLA".to_string(),
- rate: Decimal::percent(100),
- last_updated: 1000u64,
- multiplier: Decimal::percent(100),
- is_revoked: false,
- }
- );
-}
-
-#[test]
-fn get_terraswap_price() {
- let mut deps = mock_dependencies(20, &[]);
- deps.querier.with_terraswap_pools(&[
- (
- &HumanAddr::from("ustancpair0000"),
- (
- &"uusd".to_string(),
- &Uint128(1u128),
- &"anc0000".to_string(),
- &Uint128(100u128),
- ),
- ),
- (
- &HumanAddr::from("lunablunapair0000"),
- (
- &"uluna".to_string(),
- &Uint128(18u128),
- &"bluna0000".to_string(),
- &Uint128(2u128),
- ),
- ),
- ]);
-
- let msg = InitMsg {
- owner: HumanAddr("owner0000".to_string()),
- mint_contract: HumanAddr("mint0000".to_string()),
- factory_contract: HumanAddr("factory0000".to_string()),
- base_denom: "uusd".to_string(),
- mirror_oracle: HumanAddr("mirrororacle0000".to_string()),
- anchor_oracle: HumanAddr("anchororacle0000".to_string()),
- band_oracle: HumanAddr("bandoracle0000".to_string()),
- };
-
- let env = mock_env("addr0000", &[]);
- let _res = init(&mut deps, env, msg).unwrap();
-
- let msg = HandleMsg::RegisterCollateralAsset {
- asset: AssetInfo::Token {
- contract_addr: HumanAddr::from("anc0000"),
- },
- multiplier: Decimal::percent(100),
- price_source: SourceType::Terraswap {
- terraswap_pair_addr: HumanAddr::from("ustancpair0000"),
- intermediate_denom: None,
- },
- };
-
- let env = mock_env("owner0000", &[]);
- let _res = handle(&mut deps, env, msg).unwrap();
-
- // attempt to query price
- let query_res = query_collateral_price(&deps, "anc0000".to_string()).unwrap();
- assert_eq!(
- query_res,
- CollateralPriceResponse {
- asset: "anc0000".to_string(),
- rate: Decimal::from_ratio(1u128, 100u128),
- last_updated: u64::MAX,
- multiplier: Decimal::percent(100),
- is_revoked: false,
- }
- );
-
- // register collateral with intermediate denom
- let msg = HandleMsg::RegisterCollateralAsset {
- asset: AssetInfo::Token {
- contract_addr: HumanAddr::from("bluna0000"),
- },
- multiplier: Decimal::percent(100),
- price_source: SourceType::Terraswap {
- terraswap_pair_addr: HumanAddr::from("lunablunapair0000"),
- intermediate_denom: Some("uluna".to_string()),
- },
- };
-
- let env = mock_env("owner0000", &[]);
- let _res = handle(&mut deps, env, msg).unwrap();
-
- // attempt to query price
- let query_res = query_collateral_price(&deps, "bluna0000".to_string()).unwrap();
- assert_eq!(
- query_res,
- CollateralPriceResponse {
- asset: "bluna0000".to_string(),
- rate: Decimal::from_ratio(45u128, 1u128), // 9 / 1 * 5 / 1
- last_updated: u64::MAX,
- multiplier: Decimal::percent(100),
- is_revoked: false,
- }
- );
-}
-
-#[test]
-fn get_fixed_price() {
- let mut deps = mock_dependencies(20, &[]);
-
- let msg = InitMsg {
- owner: HumanAddr("owner0000".to_string()),
- mint_contract: HumanAddr("mint0000".to_string()),
- factory_contract: HumanAddr("factory0000".to_string()),
- base_denom: "uusd".to_string(),
- mirror_oracle: HumanAddr("mirrororacle0000".to_string()),
- anchor_oracle: HumanAddr("anchororacle0000".to_string()),
- band_oracle: HumanAddr("bandoracle0000".to_string()),
- };
-
- let env = mock_env("addr0000", &[]);
- let _res = init(&mut deps, env, msg).unwrap();
-
- let msg = HandleMsg::RegisterCollateralAsset {
- asset: AssetInfo::Token {
- contract_addr: HumanAddr::from("aUST"),
- },
- multiplier: Decimal::percent(100),
- price_source: SourceType::FixedPrice {
- price: Decimal::from_ratio(1u128, 2u128),
- },
- };
-
- let env = mock_env("owner0000", &[]);
- let _res = handle(&mut deps, env, msg).unwrap();
-
- // attempt to query price
- let query_res = query_collateral_price(&deps, "aUST".to_string()).unwrap();
- assert_eq!(
- query_res,
- CollateralPriceResponse {
- asset: "aUST".to_string(),
- rate: Decimal::from_ratio(1u128, 2u128),
- last_updated: u64::MAX,
- multiplier: Decimal::percent(100),
- is_revoked: false,
- }
- );
-}
-
-#[test]
-fn get_band_oracle_price() {
- let mut deps = mock_dependencies(20, &[]);
-
- let msg = InitMsg {
- owner: HumanAddr("owner0000".to_string()),
- mint_contract: HumanAddr("mint0000".to_string()),
- factory_contract: HumanAddr("factory0000".to_string()),
- base_denom: "uusd".to_string(),
- mirror_oracle: HumanAddr("mirrororacle0000".to_string()),
- anchor_oracle: HumanAddr("anchororacle0000".to_string()),
- band_oracle: HumanAddr("bandoracle0000".to_string()),
- };
-
- let env = mock_env("addr0000", &[]);
- let _res = init(&mut deps, env, msg).unwrap();
-
- let msg = HandleMsg::RegisterCollateralAsset {
- asset: AssetInfo::NativeToken {
- denom: "uluna".to_string(),
- },
- multiplier: Decimal::percent(100),
- price_source: SourceType::BandOracle {},
- };
-
- let env = mock_env("owner0000", &[]);
- let _res = handle(&mut deps, env, msg).unwrap();
-
- // attempt to query price
- let query_res = query_collateral_price(&deps, "uluna".to_string()).unwrap();
- assert_eq!(
- query_res,
- CollateralPriceResponse {
- asset: "uluna".to_string(),
- rate: Decimal::from_str("3465.211050000000000000").unwrap(),
- last_updated: 100u64,
- multiplier: Decimal::percent(100),
- is_revoked: false,
- }
- );
-}
-
-#[test]
-fn get_anchor_market_price() {
- let mut deps = mock_dependencies(20, &[]);
-
- let msg = InitMsg {
- owner: HumanAddr("owner0000".to_string()),
- mint_contract: HumanAddr("mint0000".to_string()),
- factory_contract: HumanAddr("factory0000".to_string()),
- base_denom: "uusd".to_string(),
- mirror_oracle: HumanAddr("mirrororacle0000".to_string()),
- anchor_oracle: HumanAddr("anchororacle0000".to_string()),
- band_oracle: HumanAddr("bandoracle0000".to_string()),
- };
-
- let env = mock_env("addr0000", &[]);
- let _res = init(&mut deps, env, msg).unwrap();
-
- let msg = HandleMsg::RegisterCollateralAsset {
- asset: AssetInfo::Token {
- contract_addr: HumanAddr::from("aust0000"),
- },
- multiplier: Decimal::percent(100),
- price_source: SourceType::AnchorMarket {
- anchor_market_addr: HumanAddr::from("anchormarket0000"),
- },
- };
-
- let env = mock_env("owner0000", &[]);
- let _res = handle(&mut deps, env, msg).unwrap();
-
- // attempt to query price
- let query_res = query_collateral_price(&deps, "aust0000".to_string()).unwrap();
- assert_eq!(
- query_res,
- CollateralPriceResponse {
- asset: "aust0000".to_string(),
- rate: Decimal::from_ratio(10u128, 3u128),
- last_updated: u64::MAX,
- multiplier: Decimal::percent(100),
- is_revoked: false,
- }
- );
-}
-
-#[test]
-fn get_native_price() {
- let mut deps = mock_dependencies(20, &[]);
-
- let msg = InitMsg {
- owner: HumanAddr("owner0000".to_string()),
- mint_contract: HumanAddr("mint0000".to_string()),
- factory_contract: HumanAddr("factory0000".to_string()),
- base_denom: "uusd".to_string(),
- mirror_oracle: HumanAddr("mirrororacle0000".to_string()),
- anchor_oracle: HumanAddr("anchororacle0000".to_string()),
- band_oracle: HumanAddr("bandoracle0000".to_string()),
- };
-
- let env = mock_env("addr0000", &[]);
- let _res = init(&mut deps, env, msg).unwrap();
-
- let msg = HandleMsg::RegisterCollateralAsset {
- asset: AssetInfo::NativeToken {
- denom: "uluna".to_string(),
- },
- multiplier: Decimal::percent(100),
- price_source: SourceType::Native {
- native_denom: "uluna".to_string(),
- },
- };
-
- let env = mock_env("owner0000", &[]);
- let _res = handle(&mut deps, env, msg).unwrap();
-
- // attempt to query price
- let query_res = query_collateral_price(&deps, "uluna".to_string()).unwrap();
- assert_eq!(
- query_res,
- CollateralPriceResponse {
- asset: "uluna".to_string(),
- rate: Decimal::from_ratio(5u128, 1u128),
- last_updated: u64::MAX,
- multiplier: Decimal::percent(100),
- is_revoked: false,
- }
- );
-}
-
-#[test]
-fn revoke_collateral() {
- let mut deps = mock_dependencies(20, &[]);
-
- let msg = InitMsg {
- owner: HumanAddr("owner0000".to_string()),
- mint_contract: HumanAddr("mint0000".to_string()),
- factory_contract: HumanAddr("factory0000".to_string()),
- base_denom: "uusd".to_string(),
- mirror_oracle: HumanAddr("mirrororacle0000".to_string()),
- anchor_oracle: HumanAddr("anchororacle0000".to_string()),
- band_oracle: HumanAddr("bandoracle0000".to_string()),
- };
-
- let env = mock_env("addr0000", &[]);
- let _res = init(&mut deps, env, msg).unwrap();
-
- let msg = HandleMsg::RegisterCollateralAsset {
- asset: AssetInfo::Token {
- contract_addr: HumanAddr::from("aUST"),
- },
- multiplier: Decimal::percent(100),
- price_source: SourceType::FixedPrice {
- price: Decimal::one(),
- },
- };
-
- let env = mock_env("owner0000", &[]);
- let _res = handle(&mut deps, env, msg).unwrap();
-
- // attempt to query price
- let query_res = query_collateral_price(&deps, "aUST".to_string()).unwrap();
- assert_eq!(
- query_res,
- CollateralPriceResponse {
- asset: "aUST".to_string(),
- rate: Decimal::one(),
- last_updated: u64::MAX,
- multiplier: Decimal::percent(100),
- is_revoked: false,
- }
- );
-
- // revoke the asset
- let msg = HandleMsg::RevokeCollateralAsset {
- asset: AssetInfo::Token {
- contract_addr: HumanAddr::from("aUST"),
- },
- };
-
- // unauthorized attempt
- let env = mock_env("factory0000", &[]);
- let res = handle(&mut deps, env, msg.clone()).unwrap_err();
- assert_eq!(res, StdError::unauthorized());
-
- // successfull attempt
- let env = mock_env("owner0000", &[]);
- let res = handle(&mut deps, env, msg).unwrap();
- assert_eq!(0, res.messages.len());
-
- // query the revoked collateral
- let query_res = query_collateral_info(&deps, "aUST".to_string()).unwrap();
- assert_eq!(
- query_res,
- CollateralInfoResponse {
- asset: "aUST".to_string(),
- source_type: "fixed_price".to_string(),
- multiplier: Decimal::percent(100),
- is_revoked: true,
- }
- );
-
- // attempt to query price of revoked asset
- let query_res = query_collateral_price(&deps, "aUST".to_string()).unwrap();
- assert_eq!(
- query_res,
- CollateralPriceResponse {
- asset: "aUST".to_string(),
- rate: Decimal::one(),
- last_updated: u64::MAX,
- multiplier: Decimal::percent(100),
- is_revoked: true,
- }
- );
-}
diff --git a/contracts/mirror_collector/.editorconfig b/contracts/mirror_collector/.editorconfig
deleted file mode 100644
index 3d36f20b1..000000000
--- a/contracts/mirror_collector/.editorconfig
+++ /dev/null
@@ -1,11 +0,0 @@
-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/mirror_collector/.gitignore b/contracts/mirror_collector/.gitignore
deleted file mode 100644
index 10fe5d615..000000000
--- a/contracts/mirror_collector/.gitignore
+++ /dev/null
@@ -1,12 +0,0 @@
-# Build results
-/target
-
-# Text file backups
-**/*.rs.bk
-
-# macOS
-.DS_Store
-
-# IDEs
-*.iml
-.idea
diff --git a/contracts/mirror_collector/Cargo.toml b/contracts/mirror_collector/Cargo.toml
deleted file mode 100644
index 9c4127c5b..000000000
--- a/contracts/mirror_collector/Cargo.toml
+++ /dev/null
@@ -1,51 +0,0 @@
-[package]
-name = "mirror-collector"
-version = "1.1.0"
-authors = ["Terraform Labs, PTE."]
-edition = "2018"
-description = "A Collector contract for Mirror Protocol - collect all swap rewards and send it to staking contract"
-license = "Apache-2.0"
-
-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]
-default = ["cranelift"]
-# for quicker tests, cargo test --lib
-# for more explicit tests, cargo test --features=backtraces
-backtraces = ["cosmwasm-std/backtraces", "cosmwasm-vm/backtraces"]
-cranelift = ["cosmwasm-vm/default-cranelift"]
-singlepass = ["cosmwasm-vm/default-singlepass"]
-
-[dependencies]
-cw20 = "0.2"
-cosmwasm-std = { version = "0.10.1" }
-cosmwasm-storage = { version = "0.10.1" }
-mirror-protocol = { version = "1.1.0", path = "../../packages/mirror_protocol" }
-terraswap = "1.1.0"
-schemars = "0.7"
-serde = { version = "1.0.103", default-features = false, features = ["derive"] }
-
-[dev-dependencies]
-cosmwasm-vm = { version = "0.10.1", default-features = false }
-cosmwasm-schema = "0.10.1"
-terra-cosmwasm = "1.2.2"
diff --git a/contracts/mirror_collector/README.md b/contracts/mirror_collector/README.md
deleted file mode 100644
index f9b0b8ac2..000000000
--- a/contracts/mirror_collector/README.md
+++ /dev/null
@@ -1,5 +0,0 @@
-# Mirror Collector
-
-**NOTE**: Reference documentation for this contract is available [here](https://docs.mirror.finance/contracts/collector).
-
-The Collector accumulates fee rewards generated from CDP withdrawal within the protocol, and converts them into UST in order to purchase MIR from the MIR-UST Terraswap pool. The MIR is then sent to the Gov Contract to supply trading fee rewards for MIR stakers.
diff --git a/contracts/mirror_collector/schema/config_response.json b/contracts/mirror_collector/schema/config_response.json
deleted file mode 100644
index 002b34aca..000000000
--- a/contracts/mirror_collector/schema/config_response.json
+++ /dev/null
@@ -1,30 +0,0 @@
-{
- "$schema": "http://json-schema.org/draft-07/schema#",
- "title": "ConfigResponse",
- "type": "object",
- "required": [
- "base_denom",
- "distribution_contract",
- "mirror_token",
- "terraswap_factory"
- ],
- "properties": {
- "base_denom": {
- "type": "string"
- },
- "distribution_contract": {
- "$ref": "#/definitions/HumanAddr"
- },
- "mirror_token": {
- "$ref": "#/definitions/HumanAddr"
- },
- "terraswap_factory": {
- "$ref": "#/definitions/HumanAddr"
- }
- },
- "definitions": {
- "HumanAddr": {
- "type": "string"
- }
- }
-}
diff --git a/contracts/mirror_collector/schema/query_msg.json b/contracts/mirror_collector/schema/query_msg.json
deleted file mode 100644
index 8af77727d..000000000
--- a/contracts/mirror_collector/schema/query_msg.json
+++ /dev/null
@@ -1,17 +0,0 @@
-{
- "$schema": "http://json-schema.org/draft-07/schema#",
- "title": "QueryMsg",
- "anyOf": [
- {
- "type": "object",
- "required": [
- "config"
- ],
- "properties": {
- "config": {
- "type": "object"
- }
- }
- }
- ]
-}
diff --git a/contracts/mirror_collector/src/contract.rs b/contracts/mirror_collector/src/contract.rs
deleted file mode 100644
index 96a1aaa33..000000000
--- a/contracts/mirror_collector/src/contract.rs
+++ /dev/null
@@ -1,187 +0,0 @@
-use cosmwasm_std::{
- log, to_binary, Api, Binary, Coin, CosmosMsg, Env, Extern, HandleResponse, HandleResult,
- HumanAddr, InitResponse, MigrateResponse, MigrateResult, Querier, StdResult, Storage, WasmMsg,
-};
-
-use crate::state::{read_config, store_config, Config};
-
-use cw20::Cw20HandleMsg;
-use mirror_protocol::collector::{ConfigResponse, HandleMsg, InitMsg, MigrateMsg, QueryMsg};
-use mirror_protocol::gov::Cw20HookMsg::DepositReward;
-use terraswap::asset::{Asset, AssetInfo, PairInfo};
-use terraswap::pair::{Cw20HookMsg as TerraswapCw20HookMsg, HandleMsg as TerraswapHandleMsg};
-use terraswap::querier::{query_balance, query_pair_info, query_token_balance};
-
-pub fn init(
- deps: &mut Extern,
- _env: Env,
- msg: InitMsg,
-) -> StdResult {
- store_config(
- &mut deps.storage,
- &Config {
- distribution_contract: deps.api.canonical_address(&msg.distribution_contract)?,
- terraswap_factory: deps.api.canonical_address(&msg.terraswap_factory)?,
- mirror_token: deps.api.canonical_address(&msg.mirror_token)?,
- base_denom: msg.base_denom,
- },
- )?;
-
- Ok(InitResponse::default())
-}
-
-pub fn handle(
- deps: &mut Extern,
- env: Env,
- msg: HandleMsg,
-) -> StdResult {
- match msg {
- HandleMsg::Convert { asset_token } => convert(deps, env, asset_token),
- HandleMsg::Distribute {} => distribute(deps, env),
- }
-}
-
-/// Convert
-/// Anyone can execute convert function to swap
-/// asset token => collateral token
-/// collateral token => MIR token
-pub fn convert(
- deps: &mut Extern,
- env: Env,
- asset_token: HumanAddr,
-) -> HandleResult {
- let config: Config = read_config(&deps.storage)?;
- let asset_token_raw = deps.api.canonical_address(&asset_token)?;
- let terraswap_factory_raw = deps.api.human_address(&config.terraswap_factory)?;
-
- let pair_info: PairInfo = query_pair_info(
- &deps,
- &terraswap_factory_raw,
- &[
- AssetInfo::NativeToken {
- denom: config.base_denom.to_string(),
- },
- AssetInfo::Token {
- contract_addr: asset_token.clone(),
- },
- ],
- )?;
-
- let messages: Vec;
- if config.mirror_token == asset_token_raw {
- // collateral token => MIR token
- let amount = query_balance(&deps, &env.contract.address, config.base_denom.to_string())?;
- let swap_asset = Asset {
- info: AssetInfo::NativeToken {
- denom: config.base_denom.clone(),
- },
- amount,
- };
-
- // deduct tax first
- let amount = (swap_asset.deduct_tax(&deps)?).amount;
- messages = vec![CosmosMsg::Wasm(WasmMsg::Execute {
- contract_addr: pair_info.contract_addr,
- msg: to_binary(&TerraswapHandleMsg::Swap {
- offer_asset: Asset {
- amount,
- ..swap_asset
- },
- max_spread: None,
- belief_price: None,
- to: None,
- })?,
- send: vec![Coin {
- denom: config.base_denom,
- amount,
- }],
- })];
- } else {
- // asset token => collateral token
- let amount = query_token_balance(&deps, &asset_token, &env.contract.address)?;
-
- messages = vec![CosmosMsg::Wasm(WasmMsg::Execute {
- contract_addr: asset_token.clone(),
- msg: to_binary(&Cw20HandleMsg::Send {
- contract: pair_info.contract_addr,
- amount,
- msg: Some(to_binary(&TerraswapCw20HookMsg::Swap {
- max_spread: None,
- belief_price: None,
- to: None,
- })?),
- })?,
- send: vec![],
- })];
- }
-
- Ok(HandleResponse {
- messages,
- log: vec![
- log("action", "convert"),
- log("asset_token", asset_token.as_str()),
- ],
- data: None,
- })
-}
-
-// Anyone can execute send function to receive staking token rewards
-pub fn distribute(
- deps: &mut Extern,
- env: Env,
-) -> HandleResult {
- let config: Config = read_config(&deps.storage)?;
- let amount = query_token_balance(
- &deps,
- &deps.api.human_address(&config.mirror_token)?,
- &env.contract.address,
- )?;
-
- Ok(HandleResponse {
- messages: vec![CosmosMsg::Wasm(WasmMsg::Execute {
- contract_addr: deps.api.human_address(&config.mirror_token)?,
- msg: to_binary(&Cw20HandleMsg::Send {
- contract: deps.api.human_address(&config.distribution_contract)?,
- amount,
- msg: Some(to_binary(&DepositReward {})?),
- })?,
- send: vec![],
- })],
- log: vec![
- log("action", "distribute"),
- log("amount", amount.to_string()),
- ],
- data: None,
- })
-}
-
-pub fn query(
- deps: &Extern,
- msg: QueryMsg,
-) -> StdResult {
- match msg {
- QueryMsg::Config {} => to_binary(&query_config(deps)?),
- }
-}
-
-pub fn query_config(
- deps: &Extern,
-) -> StdResult {
- let state = read_config(&deps.storage)?;
- let resp = ConfigResponse {
- distribution_contract: deps.api.human_address(&state.distribution_contract)?,
- terraswap_factory: deps.api.human_address(&state.terraswap_factory)?,
- mirror_token: deps.api.human_address(&state.mirror_token)?,
- base_denom: state.base_denom,
- };
-
- Ok(resp)
-}
-
-pub fn migrate(
- _deps: &mut Extern,
- _env: Env,
- _msg: MigrateMsg,
-) -> MigrateResult {
- Ok(MigrateResponse::default())
-}
diff --git a/contracts/mirror_collector/src/lib.rs b/contracts/mirror_collector/src/lib.rs
deleted file mode 100644
index 750eebc46..000000000
--- a/contracts/mirror_collector/src/lib.rs
+++ /dev/null
@@ -1,11 +0,0 @@
-pub mod contract;
-pub mod state;
-
-#[cfg(test)]
-mod testing;
-
-#[cfg(test)]
-mod mock_querier;
-
-#[cfg(target_arch = "wasm32")]
-cosmwasm_std::create_entry_points_with_migration!(contract);
diff --git a/contracts/mirror_collector/src/mock_querier.rs b/contracts/mirror_collector/src/mock_querier.rs
deleted file mode 100644
index 5f30697fd..000000000
--- a/contracts/mirror_collector/src/mock_querier.rs
+++ /dev/null
@@ -1,276 +0,0 @@
-use schemars::JsonSchema;
-use serde::{Deserialize, Serialize};
-
-use cosmwasm_std::testing::{MockApi, MockQuerier, MockStorage, MOCK_CONTRACT_ADDR};
-use cosmwasm_std::{
- from_binary, from_slice, to_binary, Api, CanonicalAddr, Coin, Decimal, Extern, HumanAddr,
- Querier, QuerierResult, QueryRequest, SystemError, Uint128, WasmQuery,
-};
-use cosmwasm_storage::to_length_prefixed;
-
-use std::collections::HashMap;
-
-use terra_cosmwasm::{TaxCapResponse, TaxRateResponse, TerraQuery, TerraQueryWrapper, TerraRoute};
-use terraswap::asset::{AssetInfo, PairInfo};
-
-/// mock_dependencies is a drop-in replacement for cosmwasm_std::testing::mock_dependencies
-/// this uses our CustomQuerier.
-pub fn mock_dependencies(
- canonical_length: usize,
- contract_balance: &[Coin],
-) -> Extern {
- let contract_addr = HumanAddr::from(MOCK_CONTRACT_ADDR);
- let custom_querier: WasmMockQuerier = WasmMockQuerier::new(
- MockQuerier::new(&[(&contract_addr, contract_balance)]),
- MockApi::new(canonical_length),
- canonical_length,
- );
-
- Extern {
- storage: MockStorage::default(),
- api: MockApi::new(canonical_length),
- querier: custom_querier,
- }
-}
-
-pub struct WasmMockQuerier {
- base: MockQuerier,
- token_querier: TokenQuerier,
- tax_querier: TaxQuerier,
- terraswap_factory_querier: TerraswapFactoryQuerier,
- canonical_length: usize,
-}
-
-#[derive(Clone, Default)]
-pub struct TokenQuerier {
- // this lets us iterate over all pairs that match the first string
- balances: HashMap>,
-}
-
-impl TokenQuerier {
- pub fn new(balances: &[(&HumanAddr, &[(&HumanAddr, &Uint128)])]) -> Self {
- TokenQuerier {
- balances: balances_to_map(balances),
- }
- }
-}
-
-pub(crate) fn balances_to_map(
- balances: &[(&HumanAddr, &[(&HumanAddr, &Uint128)])],
-) -> HashMap> {
- let mut balances_map: HashMap> = HashMap::new();
- for (contract_addr, balances) in balances.iter() {
- let mut contract_balances_map: HashMap = HashMap::new();
- for (addr, balance) in balances.iter() {
- contract_balances_map.insert(HumanAddr::from(addr), **balance);
- }
-
- balances_map.insert(HumanAddr::from(contract_addr), contract_balances_map);
- }
- balances_map
-}
-
-#[derive(Clone, Default)]
-pub struct TaxQuerier {
- rate: Decimal,
- // this lets us iterate over all pairs that match the first string
- caps: HashMap,
-}
-
-impl TaxQuerier {
- pub fn new(rate: Decimal, caps: &[(&String, &Uint128)]) -> Self {
- TaxQuerier {
- rate,
- caps: caps_to_map(caps),
- }
- }
-}
-
-pub(crate) fn caps_to_map(caps: &[(&String, &Uint128)]) -> HashMap {
- let mut owner_map: HashMap = HashMap::new();
- for (denom, cap) in caps.iter() {
- owner_map.insert(denom.to_string(), **cap);
- }
- owner_map
-}
-
-#[derive(Clone, Default)]
-pub struct TerraswapFactoryQuerier {
- pairs: HashMap,
-}
-
-impl TerraswapFactoryQuerier {
- pub fn new(pairs: &[(&String, &HumanAddr)]) -> Self {
- TerraswapFactoryQuerier {
- pairs: pairs_to_map(pairs),
- }
- }
-}
-
-pub(crate) fn pairs_to_map(pairs: &[(&String, &HumanAddr)]) -> HashMap {
- let mut pairs_map: HashMap = HashMap::new();
- for (key, pair) in pairs.iter() {
- pairs_map.insert(key.to_string(), HumanAddr::from(pair));
- }
- pairs_map
-}
-
-impl Querier for WasmMockQuerier {
- fn raw_query(&self, bin_request: &[u8]) -> QuerierResult {
- // MockQuerier doesn't support Custom, so we ignore it completely here
- let request: QueryRequest = match from_slice(bin_request) {
- Ok(v) => v,
- Err(e) => {
- return Err(SystemError::InvalidRequest {
- error: format!("Parsing query request: {}", e),
- request: bin_request.into(),
- })
- }
- };
- self.handle_query(&request)
- }
-}
-
-#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
-#[serde(rename_all = "snake_case")]
-pub enum QueryMsg {
- Pair { asset_infos: [AssetInfo; 2] },
-}
-
-impl WasmMockQuerier {
- pub fn handle_query(&self, request: &QueryRequest) -> QuerierResult {
- match &request {
- QueryRequest::Custom(TerraQueryWrapper { route, query_data }) => {
- if route == &TerraRoute::Treasury {
- match query_data {
- TerraQuery::TaxRate {} => {
- let res = TaxRateResponse {
- rate: self.tax_querier.rate,
- };
- Ok(to_binary(&res))
- }
- TerraQuery::TaxCap { denom } => {
- let cap = self
- .tax_querier
- .caps
- .get(denom)
- .copied()
- .unwrap_or_default();
- let res = TaxCapResponse { cap };
- Ok(to_binary(&res))
- }
- _ => panic!("DO NOT ENTER HERE"),
- }
- } else {
- panic!("DO NOT ENTER HERE")
- }
- }
- QueryRequest::Wasm(WasmQuery::Smart {
- contract_addr: _,
- msg,
- }) => match from_binary(&msg).unwrap() {
- QueryMsg::Pair { asset_infos } => {
- let key = asset_infos[0].to_string() + asset_infos[1].to_string().as_str();
- match self.terraswap_factory_querier.pairs.get(&key) {
- Some(v) => Ok(to_binary(&PairInfo {
- contract_addr: v.clone(),
- liquidity_token: HumanAddr::from("liquidity"),
- asset_infos: [
- AssetInfo::NativeToken {
- denom: "uusd".to_string(),
- },
- AssetInfo::NativeToken {
- denom: "uusd".to_string(),
- },
- ],
- })),
- None => Err(SystemError::InvalidRequest {
- error: "No pair info exists".to_string(),
- request: msg.as_slice().into(),
- }),
- }
- }
- },
- QueryRequest::Wasm(WasmQuery::Raw { contract_addr, key }) => {
- let key: &[u8] = key.as_slice();
- let prefix_balance = to_length_prefixed(b"balance").to_vec();
-
- let balances: &HashMap =
- match self.token_querier.balances.get(contract_addr) {
- Some(balances) => balances,
- None => {
- return Err(SystemError::InvalidRequest {
- error: format!(
- "No balance info exists for the contract {}",
- contract_addr
- ),
- request: key.into(),
- })
- }
- };
-
- if key[..prefix_balance.len()].to_vec() == prefix_balance {
- let key_address: &[u8] = &key[prefix_balance.len()..];
- let address_raw: CanonicalAddr = CanonicalAddr::from(key_address);
-
- let api: MockApi = MockApi::new(self.canonical_length);
- let address: HumanAddr = match api.human_address(&address_raw) {
- Ok(v) => v,
- Err(e) => {
- return Err(SystemError::InvalidRequest {
- error: format!("Parsing query request: {}", e),
- request: key.into(),
- })
- }
- };
-
- let balance = match balances.get(&address) {
- Some(v) => v,
- None => {
- return Err(SystemError::InvalidRequest {
- error: "Balance not found".to_string(),
- request: key.into(),
- })
- }
- };
-
- Ok(to_binary(&to_binary(&balance).unwrap()))
- } else {
- panic!("DO NOT ENTER HERE")
- }
- }
- _ => self.base.handle_query(request),
- }
- }
-}
-
-impl WasmMockQuerier {
- pub fn new(
- base: MockQuerier,
- _api: A,
- canonical_length: usize,
- ) -> Self {
- WasmMockQuerier {
- base,
- token_querier: TokenQuerier::default(),
- tax_querier: TaxQuerier::default(),
- terraswap_factory_querier: TerraswapFactoryQuerier::default(),
- canonical_length,
- }
- }
-
- // configure the mint whitelist mock querier
- pub fn with_token_balances(&mut self, balances: &[(&HumanAddr, &[(&HumanAddr, &Uint128)])]) {
- self.token_querier = TokenQuerier::new(balances);
- }
-
- // configure the token owner mock querier
- pub fn with_tax(&mut self, rate: Decimal, caps: &[(&String, &Uint128)]) {
- self.tax_querier = TaxQuerier::new(rate, caps);
- }
-
- // configure the terraswap pair
- pub fn with_terraswap_pairs(&mut self, pairs: &[(&String, &HumanAddr)]) {
- self.terraswap_factory_querier = TerraswapFactoryQuerier::new(pairs);
- }
-}
diff --git a/contracts/mirror_collector/src/state.rs b/contracts/mirror_collector/src/state.rs
deleted file mode 100644
index 0bc00bd5e..000000000
--- a/contracts/mirror_collector/src/state.rs
+++ /dev/null
@@ -1,23 +0,0 @@
-use schemars::JsonSchema;
-use serde::{Deserialize, Serialize};
-
-use cosmwasm_std::{CanonicalAddr, StdResult, Storage};
-use cosmwasm_storage::{singleton, singleton_read};
-
-static KEY_CONFIG: &[u8] = b"config";
-
-#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
-pub struct Config {
- pub distribution_contract: CanonicalAddr, // collected rewards receiver
- pub terraswap_factory: CanonicalAddr, // terraswap factory contract
- pub mirror_token: CanonicalAddr,
- pub base_denom: String,
-}
-
-pub fn store_config(storage: &mut S, config: &Config) -> StdResult<()> {
- singleton(storage, KEY_CONFIG).save(config)
-}
-
-pub fn read_config(storage: &S) -> StdResult {
- singleton_read(storage, KEY_CONFIG).load()
-}
diff --git a/contracts/mirror_collector/src/testing.rs b/contracts/mirror_collector/src/testing.rs
deleted file mode 100644
index 00dffe073..000000000
--- a/contracts/mirror_collector/src/testing.rs
+++ /dev/null
@@ -1,164 +0,0 @@
-use crate::contract::{handle, init, query_config};
-use crate::mock_querier::mock_dependencies;
-use cosmwasm_std::testing::{mock_env, MOCK_CONTRACT_ADDR};
-use cosmwasm_std::{to_binary, Coin, CosmosMsg, Decimal, HumanAddr, Uint128, WasmMsg};
-use cw20::Cw20HandleMsg;
-use mirror_protocol::collector::{ConfigResponse, HandleMsg, InitMsg};
-use mirror_protocol::gov::Cw20HookMsg::DepositReward;
-use terraswap::asset::{Asset, AssetInfo};
-use terraswap::pair::{Cw20HookMsg as TerraswapCw20HookMsg, HandleMsg as TerraswapHandleMsg};
-
-#[test]
-fn proper_initialization() {
- let mut deps = mock_dependencies(20, &[]);
-
- let msg = InitMsg {
- terraswap_factory: HumanAddr("terraswapfactory".to_string()),
- distribution_contract: HumanAddr("gov0000".to_string()),
- mirror_token: HumanAddr("mirror0000".to_string()),
- base_denom: "uusd".to_string(),
- };
-
- let env = mock_env("addr0000", &[]);
-
- // we can just call .unwrap() to assert this was a success
- let _res = init(&mut deps, env, msg).unwrap();
-
- // it worked, let's query the state
- let config: ConfigResponse = query_config(&deps).unwrap();
- assert_eq!("terraswapfactory", config.terraswap_factory.as_str());
- assert_eq!("uusd", config.base_denom.as_str());
-}
-
-#[test]
-fn test_convert() {
- let mut deps = mock_dependencies(
- 20,
- &[Coin {
- denom: "uusd".to_string(),
- amount: Uint128(100u128),
- }],
- );
- deps.querier.with_token_balances(&[(
- &HumanAddr::from("tokenAPPL"),
- &[(&HumanAddr::from(MOCK_CONTRACT_ADDR), &Uint128(100u128))],
- )]);
-
- deps.querier.with_tax(
- Decimal::percent(1),
- &[(&"uusd".to_string(), &Uint128(1000000u128))],
- );
-
- deps.querier.with_terraswap_pairs(&[
- (&"uusdtokenAPPL".to_string(), &HumanAddr::from("pairAPPL")),
- (
- &"uusdtokenMIRROR".to_string(),
- &HumanAddr::from("pairMIRROR"),
- ),
- ]);
-
- let msg = InitMsg {
- terraswap_factory: HumanAddr("terraswapfactory".to_string()),
- distribution_contract: HumanAddr("gov0000".to_string()),
- mirror_token: HumanAddr("tokenMIRROR".to_string()),
- base_denom: "uusd".to_string(),
- };
-
- let env = mock_env("addr0000", &[]);
- let _res = init(&mut deps, env, msg).unwrap();
-
- let msg = HandleMsg::Convert {
- asset_token: HumanAddr::from("tokenAPPL"),
- };
-
- let env = mock_env("addr0000", &[]);
- let res = handle(&mut deps, env, msg).unwrap();
- assert_eq!(
- res.messages,
- vec![CosmosMsg::Wasm(WasmMsg::Execute {
- contract_addr: HumanAddr::from("tokenAPPL"),
- msg: to_binary(&Cw20HandleMsg::Send {
- contract: HumanAddr::from("pairAPPL"),
- amount: Uint128(100u128),
- msg: Some(
- to_binary(&TerraswapCw20HookMsg::Swap {
- max_spread: None,
- belief_price: None,
- to: None,
- })
- .unwrap()
- ),
- })
- .unwrap(),
- send: vec![],
- })]
- );
-
- let msg = HandleMsg::Convert {
- asset_token: HumanAddr::from("tokenMIRROR"),
- };
-
- let env = mock_env("addr0000", &[]);
- let res = handle(&mut deps, env, msg).unwrap();
-
- // tax deduct 100 => 99
- assert_eq!(
- res.messages,
- vec![CosmosMsg::Wasm(WasmMsg::Execute {
- contract_addr: HumanAddr::from("pairMIRROR"),
- msg: to_binary(&TerraswapHandleMsg::Swap {
- offer_asset: Asset {
- info: AssetInfo::NativeToken {
- denom: "uusd".to_string()
- },
- amount: Uint128(99u128),
- },
- max_spread: None,
- belief_price: None,
- to: None,
- })
- .unwrap(),
- send: vec![Coin {
- amount: Uint128(99u128),
- denom: "uusd".to_string(),
- }],
- })]
- );
-}
-
-#[test]
-fn test_send() {
- let mut deps = mock_dependencies(20, &[]);
- deps.querier.with_token_balances(&[(
- &HumanAddr::from("mirror0000"),
- &[(&HumanAddr::from(MOCK_CONTRACT_ADDR), &Uint128(100u128))],
- )]);
-
- let msg = InitMsg {
- terraswap_factory: HumanAddr("terraswapfactory".to_string()),
- distribution_contract: HumanAddr("gov0000".to_string()),
- mirror_token: HumanAddr("mirror0000".to_string()),
- base_denom: "uusd".to_string(),
- };
-
- let env = mock_env("addr0000", &[]);
- let _res = init(&mut deps, env, msg).unwrap();
- let msg = HandleMsg::Distribute {};
-
- let env = mock_env("addr0000", &[]);
- let res = handle(&mut deps, env, msg).unwrap();
-
- assert_eq!(
- res.messages,
- vec![CosmosMsg::Wasm(WasmMsg::Execute {
- contract_addr: HumanAddr::from("mirror0000"),
- msg: to_binary(&Cw20HandleMsg::Send {
- contract: HumanAddr::from("gov0000"),
- amount: Uint128(100u128),
- msg: Some(to_binary(&DepositReward {}).unwrap()),
- })
- .unwrap(),
- send: vec![],
- })]
- )
-}
diff --git a/contracts/mirror_collector/tests/integration.rs b/contracts/mirror_collector/tests/integration.rs
deleted file mode 100644
index 2470aa18f..000000000
--- a/contracts/mirror_collector/tests/integration.rs
+++ /dev/null
@@ -1,66 +0,0 @@
-//! This integration test tries to run and call the generated wasm.
-//! It depends on a Wasm build being available, which you can create with `cargo wasm`.
-//! Then running `cargo integration-test` will validate we can properly call into that generated Wasm.
-//!
-//! You can easily convert unit tests to integration tests as follows:
-//! 1. Copy them over verbatim
-//! 2. Then change
-//! let mut deps = mock_dependencies(20, &[]);
-//! to
-//! let mut deps = mock_instance(WASM, &[]);
-//! 3. If you access raw storage, where ever you see something like:
-//! deps.storage.get(CONFIG_KEY).expect("no data stored");
-//! replace it with:
-//! deps.with_storage(|store| {
-//! let data = store.get(CONFIG_KEY).expect("no data stored");
-//! //...
-//! });
-//! 4. Anywhere you see query(&deps, ...) you must replace it with query(&mut deps, ...)
-use cosmwasm_std::{from_binary, Coin, HumanAddr, InitResponse};
-use cosmwasm_vm::testing::{
- init, mock_dependencies, mock_env, query, MockApi, MockQuerier, MockStorage,
-};
-use cosmwasm_vm::Instance;
-use mirror_protocol::collector::{ConfigResponse, InitMsg, QueryMsg};
-
-// This line will test the output of cargo wasm
-static WASM: &[u8] =
- include_bytes!("../../../target/wasm32-unknown-unknown/release/mirror_collector.wasm");
-// You can uncomment this line instead to test productionified build from rust-optimizer
-// static WASM: &[u8] = include_bytes!("../contract.wasm");
-
-const DEFAULT_GAS_LIMIT: u64 = 500_000;
-
-pub fn mock_instance(
- wasm: &[u8],
- contract_balance: &[Coin],
-) -> Instance {
- // TODO: check_wasm is not exported from cosmwasm_vm
- // let terra_features = features_from_csv("staking,terra");
- // check_wasm(wasm, &terra_features).unwrap();
- let deps = mock_dependencies(20, contract_balance);
- Instance::from_code(wasm, deps, DEFAULT_GAS_LIMIT).unwrap()
-}
-
-#[test]
-fn proper_initialization() {
- let mut deps = mock_instance(WASM, &[]);
-
- let msg = InitMsg {
- terraswap_factory: HumanAddr("terraswapfactory".to_string()),
- distribution_contract: HumanAddr("gov0000".to_string()),
- mirror_token: HumanAddr("mirror0000".to_string()),
- base_denom: "uusd".to_string(),
- };
-
- let env = mock_env("addr0000", &[]);
- let _res: InitResponse = init(&mut deps, env, msg).unwrap();
-
- // it worked, let's query the state
- let res = query(&mut deps, QueryMsg::Config {}).unwrap();
- let config: ConfigResponse = from_binary(&res).unwrap();
- assert_eq!("terraswapfactory", config.terraswap_factory.as_str());
- assert_eq!("gov0000", config.distribution_contract.as_str());
- assert_eq!("mirror0000", config.mirror_token.as_str());
- assert_eq!("uusd", config.base_denom.as_str());
-}
diff --git a/contracts/mirror_community/.cargo/config b/contracts/mirror_community/.cargo/config
deleted file mode 100644
index 7c115322a..000000000
--- a/contracts/mirror_community/.cargo/config
+++ /dev/null
@@ -1,6 +0,0 @@
-[alias]
-wasm = "build --release --target wasm32-unknown-unknown"
-wasm-debug = "build --target wasm32-unknown-unknown"
-unit-test = "test --lib --features backtraces"
-integration-test = "test --test integration"
-schema = "run --example schema"
diff --git a/contracts/mirror_community/.editorconfig b/contracts/mirror_community/.editorconfig
deleted file mode 100644
index 3d36f20b1..000000000
--- a/contracts/mirror_community/.editorconfig
+++ /dev/null
@@ -1,11 +0,0 @@
-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/mirror_community/.gitignore b/contracts/mirror_community/.gitignore
deleted file mode 100644
index 10fe5d615..000000000
--- a/contracts/mirror_community/.gitignore
+++ /dev/null
@@ -1,12 +0,0 @@
-# Build results
-/target
-
-# Text file backups
-**/*.rs.bk
-
-# macOS
-.DS_Store
-
-# IDEs
-*.iml
-.idea
diff --git a/contracts/mirror_community/Cargo.toml b/contracts/mirror_community/Cargo.toml
deleted file mode 100644
index 371799e2b..000000000
--- a/contracts/mirror_community/Cargo.toml
+++ /dev/null
@@ -1,49 +0,0 @@
-[package]
-name = "mirror-community"
-version = "1.1.0"
-authors = ["Terraform Labs, PTE."]
-edition = "2018"
-description = "A Community contract for Mirror Protocol - Keeps premined MIR token which can be used through Gov proposal"
-license = "Apache-2.0"
-
-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]
-default = ["cranelift"]
-# for quicker tests, cargo test --lib
-# for more explicit tests, cargo test --features=backtraces
-backtraces = ["cosmwasm-std/backtraces", "cosmwasm-vm/backtraces"]
-cranelift = ["cosmwasm-vm/default-cranelift"]
-singlepass = ["cosmwasm-vm/default-singlepass"]
-
-[dependencies]
-cw20 = "0.2"
-cosmwasm-std = { version = "0.10.1" }
-cosmwasm-storage = { version = "0.10.1" }
-mirror-protocol = { version = "1.1.0", path = "../../packages/mirror_protocol" }
-schemars = "0.7"
-serde = { version = "1.0.103", default-features = false, features = ["derive"] }
-
-[dev-dependencies]
-cosmwasm-vm = { version = "0.10.1", default-features = false }
-cosmwasm-schema = "0.10.1"
diff --git a/contracts/mirror_community/README.md b/contracts/mirror_community/README.md
deleted file mode 100644
index 4040d8d68..000000000
--- a/contracts/mirror_community/README.md
+++ /dev/null
@@ -1,5 +0,0 @@
-# Mirror Community
-
-**NOTE**: Reference documentation for this contract is available [here](https://docs.mirror.finance/contracts/community).
-
-The Community Contract holds the funds of the Community Pool, which can be spent through a governance poll.
diff --git a/contracts/mirror_community/examples/schema.rs b/contracts/mirror_community/examples/schema.rs
deleted file mode 100644
index cadca0610..000000000
--- a/contracts/mirror_community/examples/schema.rs
+++ /dev/null
@@ -1,17 +0,0 @@
-use std::env::current_dir;
-use std::fs::create_dir_all;
-
-use cosmwasm_schema::{export_schema, remove_schemas, schema_for};
-use mirror_protocol::community::{ConfigResponse, HandleMsg, InitMsg, QueryMsg};
-
-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!(InitMsg), &out_dir);
- export_schema(&schema_for!(HandleMsg), &out_dir);
- export_schema(&schema_for!(QueryMsg), &out_dir);
- export_schema(&schema_for!(ConfigResponse), &out_dir);
-}
diff --git a/contracts/mirror_community/rustfmt.toml b/contracts/mirror_community/rustfmt.toml
deleted file mode 100644
index 11a85e6a9..000000000
--- a/contracts/mirror_community/rustfmt.toml
+++ /dev/null
@@ -1,15 +0,0 @@
-# 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/mirror_community/schema/config_response.json b/contracts/mirror_community/schema/config_response.json
deleted file mode 100644
index a22a2a192..000000000
--- a/contracts/mirror_community/schema/config_response.json
+++ /dev/null
@@ -1,29 +0,0 @@
-{
- "$schema": "http://json-schema.org/draft-07/schema#",
- "title": "ConfigResponse",
- "type": "object",
- "required": [
- "mirror_token",
- "owner",
- "spend_limit"
- ],
- "properties": {
- "mirror_token": {
- "$ref": "#/definitions/HumanAddr"
- },
- "owner": {
- "$ref": "#/definitions/HumanAddr"
- },
- "spend_limit": {
- "$ref": "#/definitions/Uint128"
- }
- },
- "definitions": {
- "HumanAddr": {
- "type": "string"
- },
- "Uint128": {
- "type": "string"
- }
- }
-}
diff --git a/contracts/mirror_community/schema/handle_msg.json b/contracts/mirror_community/schema/handle_msg.json
deleted file mode 100644
index 4cffb8a89..000000000
--- a/contracts/mirror_community/schema/handle_msg.json
+++ /dev/null
@@ -1,70 +0,0 @@
-{
- "$schema": "http://json-schema.org/draft-07/schema#",
- "title": "HandleMsg",
- "anyOf": [
- {
- "type": "object",
- "required": [
- "update_config"
- ],
- "properties": {
- "update_config": {
- "type": "object",
- "properties": {
- "owner": {
- "anyOf": [
- {
- "$ref": "#/definitions/HumanAddr"
- },
- {
- "type": "null"
- }
- ]
- },
- "spend_limit": {
- "anyOf": [
- {
- "$ref": "#/definitions/Uint128"
- },
- {
- "type": "null"
- }
- ]
- }
- }
- }
- }
- },
- {
- "type": "object",
- "required": [
- "spend"
- ],
- "properties": {
- "spend": {
- "type": "object",
- "required": [
- "amount",
- "recipient"
- ],
- "properties": {
- "amount": {
- "$ref": "#/definitions/Uint128"
- },
- "recipient": {
- "$ref": "#/definitions/HumanAddr"
- }
- }
- }
- }
- }
- ],
- "definitions": {
- "HumanAddr": {
- "type": "string"
- },
- "Uint128": {
- "type": "string"
- }
- }
-}
diff --git a/contracts/mirror_community/src/contract.rs b/contracts/mirror_community/src/contract.rs
deleted file mode 100644
index cecf7199e..000000000
--- a/contracts/mirror_community/src/contract.rs
+++ /dev/null
@@ -1,136 +0,0 @@
-use crate::state::{read_config, store_config, Config};
-
-use cosmwasm_std::{
- log, to_binary, Api, Binary, CosmosMsg, Env, Extern, HandleResponse, HandleResult, HumanAddr,
- InitResponse, MigrateResponse, MigrateResult, Querier, StdError, StdResult, Storage, Uint128,
- WasmMsg,
-};
-
-use mirror_protocol::community::{ConfigResponse, HandleMsg, InitMsg, MigrateMsg, QueryMsg};
-
-use cw20::Cw20HandleMsg;
-
-pub fn init(
- deps: &mut Extern,
- _env: Env,
- msg: InitMsg,
-) -> StdResult {
- store_config(
- &mut deps.storage,
- &Config {
- owner: deps.api.canonical_address(&msg.owner)?,
- mirror_token: deps.api.canonical_address(&msg.mirror_token)?,
- spend_limit: msg.spend_limit,
- },
- )?;
-
- Ok(InitResponse::default())
-}
-
-pub fn handle(
- deps: &mut Extern,
- env: Env,
- msg: HandleMsg,
-) -> StdResult {
- match msg {
- HandleMsg::UpdateConfig { owner, spend_limit } => {
- udpate_config(deps, env, owner, spend_limit)
- }
- HandleMsg::Spend { recipient, amount } => spend(deps, env, recipient, amount),
- }
-}
-
-pub fn udpate_config(
- deps: &mut Extern,
- env: Env,
- owner: Option,
- spend_limit: Option,
-) -> HandleResult {
- let mut config: Config = read_config(&deps.storage)?;
- if config.owner != deps.api.canonical_address(&env.message.sender)? {
- return Err(StdError::unauthorized());
- }
-
- if let Some(owner) = owner {
- config.owner = deps.api.canonical_address(&owner)?;
- }
-
- if let Some(spend_limit) = spend_limit {
- config.spend_limit = spend_limit;
- }
-
- store_config(&mut deps.storage, &config)?;
-
- Ok(HandleResponse {
- messages: vec![],
- log: vec![log("action", "update_config")],
- data: None,
- })
-}
-
-/// Spend
-/// Owner can execute spend operation to send
-/// `amount` of MIR token to `recipient` for community purpose
-pub fn spend(
- deps: &mut Extern,
- env: Env,
- recipient: HumanAddr,
- amount: Uint128,
-) -> HandleResult {
- let config: Config = read_config(&deps.storage)?;
- if config.owner != deps.api.canonical_address(&env.message.sender)? {
- return Err(StdError::unauthorized());
- }
-
- if config.spend_limit < amount {
- return Err(StdError::generic_err("Cannot spend more than spend_limit"));
- }
-
- let mirror_token = deps.api.human_address(&config.mirror_token)?;
- Ok(HandleResponse {
- messages: vec![CosmosMsg::Wasm(WasmMsg::Execute {
- contract_addr: mirror_token,
- send: vec![],
- msg: to_binary(&Cw20HandleMsg::Transfer {
- recipient: recipient.clone(),
- amount,
- })?,
- })],
- log: vec![
- log("action", "spend"),
- log("recipient", recipient),
- log("amount", amount),
- ],
- data: None,
- })
-}
-
-pub fn query(
- deps: &Extern,
- msg: QueryMsg,
-) -> StdResult {
- match msg {
- QueryMsg::Config {} => to_binary(&query_config(deps)?),
- }
-}
-
-pub fn query_config(
- deps: &Extern,
-) -> StdResult {
- let state = read_config(&deps.storage)?;
- let resp = ConfigResponse {
- owner: deps.api.human_address(&state.owner)?,
- mirror_token: deps.api.human_address(&state.mirror_token)?,
- spend_limit: state.spend_limit,
- };
-
- Ok(resp)
-}
-
-pub fn migrate(
- _deps: &mut Extern,
- _env: Env,
- _msg: MigrateMsg,
-) -> MigrateResult {
- Ok(MigrateResponse::default())
-}
diff --git a/contracts/mirror_community/src/lib.rs b/contracts/mirror_community/src/lib.rs
deleted file mode 100644
index 3f8a0889c..000000000
--- a/contracts/mirror_community/src/lib.rs
+++ /dev/null
@@ -1,8 +0,0 @@
-pub mod contract;
-pub mod state;
-
-#[cfg(test)]
-mod testing;
-
-#[cfg(target_arch = "wasm32")]
-cosmwasm_std::create_entry_points_with_migration!(contract);
diff --git a/contracts/mirror_community/src/state.rs b/contracts/mirror_community/src/state.rs
deleted file mode 100644
index 58a96c52a..000000000
--- a/contracts/mirror_community/src/state.rs
+++ /dev/null
@@ -1,22 +0,0 @@
-use schemars::JsonSchema;
-use serde::{Deserialize, Serialize};
-
-use cosmwasm_std::{CanonicalAddr, StdResult, Storage, Uint128};
-use cosmwasm_storage::{singleton, singleton_read};
-
-static KEY_CONFIG: &[u8] = b"config";
-
-#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
-pub struct Config {
- pub owner: CanonicalAddr, // mirror gov address
- pub mirror_token: CanonicalAddr, // mirror token address
- pub spend_limit: Uint128, // spend limit per each `spend` request
-}
-
-pub fn store_config(storage: &mut S, config: &Config) -> StdResult<()> {
- singleton(storage, KEY_CONFIG).save(config)
-}
-
-pub fn read_config(storage: &S) -> StdResult {
- singleton_read(storage, KEY_CONFIG).load()
-}
diff --git a/contracts/mirror_community/src/testing.rs b/contracts/mirror_community/src/testing.rs
deleted file mode 100644
index 7f67870ea..000000000
--- a/contracts/mirror_community/src/testing.rs
+++ /dev/null
@@ -1,155 +0,0 @@
-use crate::contract::{handle, init, query};
-
-use cosmwasm_std::testing::{mock_dependencies, mock_env};
-use cosmwasm_std::{from_binary, to_binary, CosmosMsg, HumanAddr, StdError, Uint128, WasmMsg};
-use cw20::Cw20HandleMsg;
-use mirror_protocol::community::{ConfigResponse, HandleMsg, InitMsg, QueryMsg};
-
-#[test]
-fn proper_initialization() {
- let mut deps = mock_dependencies(20, &[]);
-
- let msg = InitMsg {
- owner: HumanAddr("owner0000".to_string()),
- mirror_token: HumanAddr("mirror0000".to_string()),
- spend_limit: Uint128::from(1000000u128),
- };
-
- let env = mock_env("addr0000", &[]);
-
- // we can just call .unwrap() to assert this was a success
- let _res = init(&mut deps, env, msg).unwrap();
-
- // it worked, let's query the state
- let config: ConfigResponse = from_binary(&query(&deps, QueryMsg::Config {}).unwrap()).unwrap();
- assert_eq!("owner0000", config.owner.as_str());
- assert_eq!("mirror0000", config.mirror_token.as_str());
- assert_eq!(Uint128::from(1000000u128), config.spend_limit);
-}
-
-#[test]
-fn update_config() {
- let mut deps = mock_dependencies(20, &[]);
-
- let msg = InitMsg {
- owner: HumanAddr("owner0000".to_string()),
- mirror_token: HumanAddr("mirror0000".to_string()),
- spend_limit: Uint128::from(1000000u128),
- };
-
- let env = mock_env("addr0000", &[]);
-
- // we can just call .unwrap() to assert this was a success
- let _res = init(&mut deps, env, msg).unwrap();
-
- // it worked, let's query the state
- let config: ConfigResponse = from_binary(&query(&deps, QueryMsg::Config {}).unwrap()).unwrap();
- assert_eq!("owner0000", config.owner.as_str());
- assert_eq!("mirror0000", config.mirror_token.as_str());
- assert_eq!(Uint128::from(1000000u128), config.spend_limit);
-
- let msg = HandleMsg::UpdateConfig {
- owner: Some(HumanAddr::from("owner0001")),
- spend_limit: None,
- };
- let env = mock_env("addr0000", &[]);
- let res = handle(&mut deps, env, msg.clone());
-
- match res {
- Err(StdError::Unauthorized { .. }) => {}
- _ => panic!("DO NOT ENTER HERE"),
- }
-
- let env = mock_env("owner0000", &[]);
- let _res = handle(&mut deps, env, msg).unwrap();
- let config: ConfigResponse = from_binary(&query(&deps, QueryMsg::Config {}).unwrap()).unwrap();
- assert_eq!(
- config,
- ConfigResponse {
- owner: HumanAddr::from("owner0001"),
- mirror_token: HumanAddr::from("mirror0000"),
- spend_limit: Uint128::from(1000000u128),
- }
- );
-
- // Update spend_limit
- let msg = HandleMsg::UpdateConfig {
- owner: None,
- spend_limit: Some(Uint128::from(2000000u128)),
- };
- let env = mock_env("owner0001", &[]);
- let _res = handle(&mut deps, env, msg);
- let config: ConfigResponse = from_binary(&query(&deps, QueryMsg::Config {}).unwrap()).unwrap();
- assert_eq!(
- config,
- ConfigResponse {
- owner: HumanAddr::from("owner0001"),
- mirror_token: HumanAddr::from("mirror0000"),
- spend_limit: Uint128::from(2000000u128),
- }
- );
-}
-
-#[test]
-fn test_spend() {
- let mut deps = mock_dependencies(20, &[]);
-
- let msg = InitMsg {
- owner: HumanAddr("owner0000".to_string()),
- mirror_token: HumanAddr("mirror0000".to_string()),
- spend_limit: Uint128::from(1000000u128),
- };
-
- let env = mock_env("addr0000", &[]);
-
- // we can just call .unwrap() to assert this was a success
- let _res = init(&mut deps, env, msg).unwrap();
-
- // permission failed
- let msg = HandleMsg::Spend {
- recipient: HumanAddr::from("addr0000"),
- amount: Uint128::from(1000000u128),
- };
-
- let env = mock_env("addr0000", &[]);
- let res = handle(&mut deps, env, msg);
- match res {
- Err(StdError::Unauthorized { .. }) => {}
- _ => panic!("DO NOT ENTER HERE"),
- }
-
- // failed due to spend limit
- let msg = HandleMsg::Spend {
- recipient: HumanAddr::from("addr0000"),
- amount: Uint128::from(2000000u128),
- };
-
- let env = mock_env("owner0000", &[]);
- let res = handle(&mut deps, env, msg);
- match res {
- Err(StdError::GenericErr { msg, .. }) => {
- assert_eq!(msg, "Cannot spend more than spend_limit")
- }
- _ => panic!("DO NOT ENTER HERE"),
- }
-
- let msg = HandleMsg::Spend {
- recipient: HumanAddr::from("addr0000"),
- amount: Uint128::from(1000000u128),
- };
-
- let env = mock_env("owner0000", &[]);
- let res = handle(&mut deps, env, msg).unwrap();
- assert_eq!(
- res.messages,
- vec![CosmosMsg::Wasm(WasmMsg::Execute {
- contract_addr: HumanAddr::from("mirror0000"),
- send: vec![],
- msg: to_binary(&Cw20HandleMsg::Transfer {
- recipient: HumanAddr::from("addr0000"),
- amount: Uint128::from(1000000u128),
- })
- .unwrap(),
- })]
- );
-}
diff --git a/contracts/mirror_community/tests/integration.rs b/contracts/mirror_community/tests/integration.rs
deleted file mode 100644
index a82321b4c..000000000
--- a/contracts/mirror_community/tests/integration.rs
+++ /dev/null
@@ -1,66 +0,0 @@
-//! This integration test tries to run and call the generated wasm.
-//! It depends on a Wasm build being available, which you can create with `cargo wasm`.
-//! Then running `cargo integration-test` will validate we can properly call into that generated Wasm.
-//!
-//! You can easily convert unit tests to integration tests as follows:
-//! 1. Copy them over verbatim
-//! 2. Then change
-//! let mut deps = mock_dependencies(20, &[]);
-//! to
-//! let mut deps = mock_instance(WASM, &[]);
-//! 3. If you access raw storage, where ever you see something like:
-//! deps.storage.get(CONFIG_KEY).expect("no data stored");
-//! replace it with:
-//! deps.with_storage(|store| {
-//! let data = store.get(CONFIG_KEY).expect("no data stored");
-//! //...
-//! });
-//! 4. Anywhere you see query(&deps, ...) you must replace it with query(&mut deps, ...)
-use cosmwasm_std::{from_binary, Coin, HumanAddr, InitResponse, Uint128};
-use cosmwasm_vm::testing::{
- init, mock_dependencies, mock_env, query, MockApi, MockQuerier, MockStorage,
-};
-use cosmwasm_vm::Instance;
-use mirror_protocol::community::{ConfigResponse, InitMsg, QueryMsg};
-
-// This line will test the output of cargo wasm
-static WASM: &[u8] =
- include_bytes!("../../../target/wasm32-unknown-unknown/release/mirror_community.wasm");
-// You can uncomment this line instead to test productionified build from rust-optimizer
-// static WASM: &[u8] = include_bytes!("../contract.wasm");
-
-const DEFAULT_GAS_LIMIT: u64 = 500_000;
-
-pub fn mock_instance(
- wasm: &[u8],
- contract_balance: &[Coin],
-) -> Instance {
- // TODO: check_wasm is not exported from cosmwasm_vm
- // let terra_features = features_from_csv("staking,terra");
- // check_wasm(wasm, &terra_features).unwrap();
- let deps = mock_dependencies(20, contract_balance);
- Instance::from_code(wasm, deps, DEFAULT_GAS_LIMIT).unwrap()
-}
-
-#[test]
-fn proper_initialization() {
- let mut deps = mock_instance(WASM, &[]);
-
- let msg = InitMsg {
- owner: HumanAddr("owner0000".to_string()),
- mirror_token: HumanAddr("mirror0000".to_string()),
- spend_limit: Uint128::from(1000000u128),
- };
-
- let env = mock_env("addr0000", &[]);
-
- // we can just call .unwrap() to assert this was a success
- let _res: InitResponse = init(&mut deps, env, msg).unwrap();
-
- // it worked, let's query the state
- let config: ConfigResponse =
- from_binary(&query(&mut deps, QueryMsg::Config {}).unwrap()).unwrap();
- assert_eq!("owner0000", config.owner.as_str());
- assert_eq!("mirror0000", config.mirror_token.as_str());
- assert_eq!(Uint128::from(1000000u128), config.spend_limit);
-}
diff --git a/contracts/mirror_factory/.cargo/config b/contracts/mirror_factory/.cargo/config
deleted file mode 100644
index 7c115322a..000000000
--- a/contracts/mirror_factory/.cargo/config
+++ /dev/null
@@ -1,6 +0,0 @@
-[alias]
-wasm = "build --release --target wasm32-unknown-unknown"
-wasm-debug = "build --target wasm32-unknown-unknown"
-unit-test = "test --lib --features backtraces"
-integration-test = "test --test integration"
-schema = "run --example schema"
diff --git a/contracts/mirror_factory/.editorconfig b/contracts/mirror_factory/.editorconfig
deleted file mode 100644
index 3d36f20b1..000000000
--- a/contracts/mirror_factory/.editorconfig
+++ /dev/null
@@ -1,11 +0,0 @@
-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/mirror_factory/.gitignore b/contracts/mirror_factory/.gitignore
deleted file mode 100644
index 10fe5d615..000000000
--- a/contracts/mirror_factory/.gitignore
+++ /dev/null
@@ -1,12 +0,0 @@
-# Build results
-/target
-
-# Text file backups
-**/*.rs.bk
-
-# macOS
-.DS_Store
-
-# IDEs
-*.iml
-.idea
diff --git a/contracts/mirror_factory/Cargo.toml b/contracts/mirror_factory/Cargo.toml
deleted file mode 100644
index 3c00d7e29..000000000
--- a/contracts/mirror_factory/Cargo.toml
+++ /dev/null
@@ -1,50 +0,0 @@
-[package]
-name = "mirror-factory"
-version = "1.1.0"
-authors = ["Terraform Labs, PTE."]
-edition = "2018"
-description = "A Factory contract for Mirror Protocol - mint mirror token and distribute it to registered staking contracts"
-license = "Apache-2.0"
-
-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]
-default = ["cranelift"]
-# for quicker tests, cargo test --lib
-# for more explicit tests, cargo test --features=backtraces
-backtraces = ["cosmwasm-std/backtraces", "cosmwasm-vm/backtraces"]
-cranelift = ["cosmwasm-vm/default-cranelift"]
-singlepass = ["cosmwasm-vm/default-singlepass"]
-
-[dependencies]
-cw20 = "0.2"
-cosmwasm-std = { version = "0.10.1", features = ["iterator"] }
-cosmwasm-storage = { version = "0.10.1", features = ["iterator"] }
-mirror-protocol = { version = "1.1.0", path = "../../packages/mirror_protocol" }
-terraswap = "1.1.0"
-schemars = "0.7"
-serde = { version = "1.0.103", default-features = false, features = ["derive"] }
-
-[dev-dependencies]
-cosmwasm-vm = { version = "0.10.1", default-features = false, features = ["iterator"] }
-cosmwasm-schema = "0.10.1"
diff --git a/contracts/mirror_factory/README.md b/contracts/mirror_factory/README.md
deleted file mode 100644
index 49238db60..000000000
--- a/contracts/mirror_factory/README.md
+++ /dev/null
@@ -1,7 +0,0 @@
-# Mirror Factory
-
-**NOTE**: Reference documentation for this contract is available [here](https://docs.mirror.finance/contracts/factory).
-
-The Factory contract is Mirror Protocol's central directory and organizes information related to mAssets and the Mirror Token (MIR). It is also responsible for minting new MIR tokens each block and distributing them to the Staking Contract for rewarding LP Token stakers.
-
-After the initial bootstrapping of Mirror Protocol contracts, the Factory is assigned to be the owner for the Mint, Oracle, Staking, and Collector contracts. The Factory is owned by the Gov Contract.
diff --git a/contracts/mirror_factory/examples/schema.rs b/contracts/mirror_factory/examples/schema.rs
deleted file mode 100644
index b0a47e164..000000000
--- a/contracts/mirror_factory/examples/schema.rs
+++ /dev/null
@@ -1,21 +0,0 @@
-use std::env::current_dir;
-use std::fs::create_dir_all;
-
-use cosmwasm_schema::{export_schema, remove_schemas, schema_for};
-use mirror_protocol::factory::{
- ConfigResponse, DistributionInfoResponse, HandleMsg, InitMsg, MigrateMsg, QueryMsg,
-};
-
-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!(InitMsg), &out_dir);
- export_schema(&schema_for!(HandleMsg), &out_dir);
- export_schema(&schema_for!(QueryMsg), &out_dir);
- export_schema(&schema_for!(MigrateMsg), &out_dir);
- export_schema(&schema_for!(ConfigResponse), &out_dir);
- export_schema(&schema_for!(DistributionInfoResponse), &out_dir);
-}
diff --git a/contracts/mirror_factory/rustfmt.toml b/contracts/mirror_factory/rustfmt.toml
deleted file mode 100644
index 11a85e6a9..000000000
--- a/contracts/mirror_factory/rustfmt.toml
+++ /dev/null
@@ -1,15 +0,0 @@
-# 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/mirror_factory/schema/config_response.json b/contracts/mirror_factory/schema/config_response.json
deleted file mode 100644
index e62b81c10..000000000
--- a/contracts/mirror_factory/schema/config_response.json
+++ /dev/null
@@ -1,85 +0,0 @@
-{
- "$schema": "http://json-schema.org/draft-07/schema#",
- "title": "ConfigResponse",
- "type": "object",
- "required": [
- "base_denom",
- "commission_collector",
- "distribution_schedule",
- "genesis_time",
- "mint_contract",
- "mirror_token",
- "oracle_contract",
- "owner",
- "staking_contract",
- "terraswap_factory",
- "token_code_id"
- ],
- "properties": {
- "base_denom": {
- "type": "string"
- },
- "commission_collector": {
- "$ref": "#/definitions/HumanAddr"
- },
- "distribution_schedule": {
- "type": "array",
- "items": {
- "type": "array",
- "items": [
- {
- "type": "integer",
- "format": "uint64",
- "minimum": 0.0
- },
- {
- "type": "integer",
- "format": "uint64",
- "minimum": 0.0
- },
- {
- "$ref": "#/definitions/Uint128"
- }
- ],
- "maxItems": 3,
- "minItems": 3
- }
- },
- "genesis_time": {
- "type": "integer",
- "format": "uint64",
- "minimum": 0.0
- },
- "mint_contract": {
- "$ref": "#/definitions/HumanAddr"
- },
- "mirror_token": {
- "$ref": "#/definitions/HumanAddr"
- },
- "oracle_contract": {
- "$ref": "#/definitions/HumanAddr"
- },
- "owner": {
- "$ref": "#/definitions/HumanAddr"
- },
- "staking_contract": {
- "$ref": "#/definitions/HumanAddr"
- },
- "terraswap_factory": {
- "$ref": "#/definitions/HumanAddr"
- },
- "token_code_id": {
- "type": "integer",
- "format": "uint64",
- "minimum": 0.0
- }
- },
- "definitions": {
- "HumanAddr": {
- "type": "string"
- },
- "Uint128": {
- "type": "string"
- }
- }
-}
diff --git a/contracts/mirror_factory/schema/distribution_info_response.json b/contracts/mirror_factory/schema/distribution_info_response.json
deleted file mode 100644
index 01dfeb45c..000000000
--- a/contracts/mirror_factory/schema/distribution_info_response.json
+++ /dev/null
@@ -1,39 +0,0 @@
-{
- "$schema": "http://json-schema.org/draft-07/schema#",
- "title": "DistributionInfoResponse",
- "type": "object",
- "required": [
- "last_distributed",
- "weights"
- ],
- "properties": {
- "last_distributed": {
- "type": "integer",
- "format": "uint64",
- "minimum": 0.0
- },
- "weights": {
- "type": "array",
- "items": {
- "type": "array",
- "items": [
- {
- "$ref": "#/definitions/HumanAddr"
- },
- {
- "type": "integer",
- "format": "uint32",
- "minimum": 0.0
- }
- ],
- "maxItems": 2,
- "minItems": 2
- }
- }
- },
- "definitions": {
- "HumanAddr": {
- "type": "string"
- }
- }
-}
diff --git a/contracts/mirror_factory/schema/handle_msg.json b/contracts/mirror_factory/schema/handle_msg.json
deleted file mode 100644
index 21e837134..000000000
--- a/contracts/mirror_factory/schema/handle_msg.json
+++ /dev/null
@@ -1,387 +0,0 @@
-{
- "$schema": "http://json-schema.org/draft-07/schema#",
- "title": "HandleMsg",
- "anyOf": [
- {
- "description": "Owner Operations",
- "type": "object",
- "required": [
- "post_initialize"
- ],
- "properties": {
- "post_initialize": {
- "type": "object",
- "required": [
- "commission_collector",
- "mint_contract",
- "mirror_token",
- "oracle_contract",
- "owner",
- "staking_contract",
- "terraswap_factory"
- ],
- "properties": {
- "commission_collector": {
- "$ref": "#/definitions/HumanAddr"
- },
- "mint_contract": {
- "$ref": "#/definitions/HumanAddr"
- },
- "mirror_token": {
- "$ref": "#/definitions/HumanAddr"
- },
- "oracle_contract": {
- "$ref": "#/definitions/HumanAddr"
- },
- "owner": {
- "$ref": "#/definitions/HumanAddr"
- },
- "staking_contract": {
- "$ref": "#/definitions/HumanAddr"
- },
- "terraswap_factory": {
- "$ref": "#/definitions/HumanAddr"
- }
- }
- }
- }
- },
- {
- "type": "object",
- "required": [
- "update_config"
- ],
- "properties": {
- "update_config": {
- "type": "object",
- "properties": {
- "distribution_schedule": {
- "type": [
- "array",
- "null"
- ],
- "items": {
- "type": "array",
- "items": [
- {
- "type": "integer",
- "format": "uint64",
- "minimum": 0.0
- },
- {
- "type": "integer",
- "format": "uint64",
- "minimum": 0.0
- },
- {
- "$ref": "#/definitions/Uint128"
- }
- ],
- "maxItems": 3,
- "minItems": 3
- }
- },
- "owner": {
- "anyOf": [
- {
- "$ref": "#/definitions/HumanAddr"
- },
- {
- "type": "null"
- }
- ]
- },
- "token_code_id": {
- "type": [
- "integer",
- "null"
- ],
- "format": "uint64",
- "minimum": 0.0
- }
- }
- }
- }
- },
- {
- "type": "object",
- "required": [
- "update_weight"
- ],
- "properties": {
- "update_weight": {
- "type": "object",
- "required": [
- "asset_token",
- "weight"
- ],
- "properties": {
- "asset_token": {
- "$ref": "#/definitions/HumanAddr"
- },
- "weight": {
- "type": "integer",
- "format": "uint32",
- "minimum": 0.0
- }
- }
- }
- }
- },
- {
- "type": "object",
- "required": [
- "whitelist"
- ],
- "properties": {
- "whitelist": {
- "type": "object",
- "required": [
- "name",
- "oracle_feeder",
- "params",
- "symbol"
- ],
- "properties": {
- "name": {
- "description": "asset name used to create token contract",
- "type": "string"
- },
- "oracle_feeder": {
- "description": "authorized asset oracle feeder",
- "allOf": [
- {
- "$ref": "#/definitions/HumanAddr"
- }
- ]
- },
- "params": {
- "description": "used to create all necessary contract or register asset",
- "allOf": [
- {
- "$ref": "#/definitions/Params"
- }
- ]
- },
- "symbol": {
- "description": "asset symbol used to create token contract",
- "type": "string"
- }
- }
- }
- }
- },
- {
- "description": "Internal use",
- "type": "object",
- "required": [
- "token_creation_hook"
- ],
- "properties": {
- "token_creation_hook": {
- "type": "object",
- "required": [
- "oracle_feeder"
- ],
- "properties": {
- "oracle_feeder": {
- "$ref": "#/definitions/HumanAddr"
- }
- }
- }
- }
- },
- {
- "description": "Internal use except MIR registration",
- "type": "object",
- "required": [
- "terraswap_creation_hook"
- ],
- "properties": {
- "terraswap_creation_hook": {
- "type": "object",
- "required": [
- "asset_token"
- ],
- "properties": {
- "asset_token": {
- "$ref": "#/definitions/HumanAddr"
- }
- }
- }
- }
- },
- {
- "type": "object",
- "required": [
- "pass_command"
- ],
- "properties": {
- "pass_command": {
- "type": "object",
- "required": [
- "contract_addr",
- "msg"
- ],
- "properties": {
- "contract_addr": {
- "$ref": "#/definitions/HumanAddr"
- },
- "msg": {
- "$ref": "#/definitions/Binary"
- }
- }
- }
- }
- },
- {
- "description": "Feeder Operations ////////////////// Revoke asset from MIR rewards pool and register end_price to mint contract",
- "type": "object",
- "required": [
- "revoke_asset"
- ],
- "properties": {
- "revoke_asset": {
- "type": "object",
- "required": [
- "asset_token",
- "end_price"
- ],
- "properties": {
- "asset_token": {
- "$ref": "#/definitions/HumanAddr"
- },
- "end_price": {
- "$ref": "#/definitions/Decimal"
- }
- }
- }
- }
- },
- {
- "description": "Migrate asset to new asset by registering end_price to mint contract and add the new asset to MIR rewards pool",
- "type": "object",
- "required": [
- "migrate_asset"
- ],
- "properties": {
- "migrate_asset": {
- "type": "object",
- "required": [
- "end_price",
- "from_token",
- "name",
- "symbol"
- ],
- "properties": {
- "end_price": {
- "$ref": "#/definitions/Decimal"
- },
- "from_token": {
- "$ref": "#/definitions/HumanAddr"
- },
- "name": {
- "type": "string"
- },
- "symbol": {
- "type": "string"
- }
- }
- }
- }
- },
- {
- "description": "User Operations",
- "type": "object",
- "required": [
- "distribute"
- ],
- "properties": {
- "distribute": {
- "type": "object"
- }
- }
- }
- ],
- "definitions": {
- "Binary": {
- "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec",
- "type": "string"
- },
- "Decimal": {
- "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)",
- "type": "string"
- },
- "HumanAddr": {
- "type": "string"
- },
- "Params": {
- "type": "object",
- "required": [
- "auction_discount",
- "min_collateral_ratio"
- ],
- "properties": {
- "auction_discount": {
- "description": "Auction discount rate applied to asset mint",
- "allOf": [
- {
- "$ref": "#/definitions/Decimal"
- }
- ]
- },
- "min_collateral_ratio": {
- "description": "Minium collateral ratio applied to asset mint",
- "allOf": [
- {
- "$ref": "#/definitions/Decimal"
- }
- ]
- },
- "min_collateral_ratio_after_ipo": {
- "description": "For pre-IPO assets, collateral ratio for the asset after ipo",
- "anyOf": [
- {
- "$ref": "#/definitions/Decimal"
- },
- {
- "type": "null"
- }
- ]
- },
- "mint_period": {
- "description": "For pre-IPO assets, time period after asset creation in which minting is enabled",
- "type": [
- "integer",
- "null"
- ],
- "format": "uint64",
- "minimum": 0.0
- },
- "pre_ipo_price": {
- "description": "For pre-IPO assets, fixed price during minting period",
- "anyOf": [
- {
- "$ref": "#/definitions/Decimal"
- },
- {
- "type": "null"
- }
- ]
- },
- "weight": {
- "description": "Distribution weight (default is 30, which is 1/10 of MIR distribution weight)",
- "type": [
- "integer",
- "null"
- ],
- "format": "uint32",
- "minimum": 0.0
- }
- }
- },
- "Uint128": {
- "type": "string"
- }
- }
-}
diff --git a/contracts/mirror_factory/schema/init_msg.json b/contracts/mirror_factory/schema/init_msg.json
deleted file mode 100644
index 02e44d578..000000000
--- a/contracts/mirror_factory/schema/init_msg.json
+++ /dev/null
@@ -1,48 +0,0 @@
-{
- "$schema": "http://json-schema.org/draft-07/schema#",
- "title": "InitMsg",
- "type": "object",
- "required": [
- "base_denom",
- "distribution_schedule",
- "token_code_id"
- ],
- "properties": {
- "base_denom": {
- "type": "string"
- },
- "distribution_schedule": {
- "type": "array",
- "items": {
- "type": "array",
- "items": [
- {
- "type": "integer",
- "format": "uint64",
- "minimum": 0.0
- },
- {
- "type": "integer",
- "format": "uint64",
- "minimum": 0.0
- },
- {
- "$ref": "#/definitions/Uint128"
- }
- ],
- "maxItems": 3,
- "minItems": 3
- }
- },
- "token_code_id": {
- "type": "integer",
- "format": "uint64",
- "minimum": 0.0
- }
- },
- "definitions": {
- "Uint128": {
- "type": "string"
- }
- }
-}
diff --git a/contracts/mirror_factory/schema/migrate_msg.json b/contracts/mirror_factory/schema/migrate_msg.json
deleted file mode 100644
index 666fb7e9f..000000000
--- a/contracts/mirror_factory/schema/migrate_msg.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "$schema": "http://json-schema.org/draft-07/schema#",
- "title": "MigrateMsg",
- "description": "We currently take no arguments for migrations",
- "type": "object"
-}
diff --git a/contracts/mirror_factory/schema/query_msg.json b/contracts/mirror_factory/schema/query_msg.json
deleted file mode 100644
index 8139c2619..000000000
--- a/contracts/mirror_factory/schema/query_msg.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
- "$schema": "http://json-schema.org/draft-07/schema#",
- "title": "QueryMsg",
- "anyOf": [
- {
- "type": "object",
- "required": [
- "config"
- ],
- "properties": {
- "config": {
- "type": "object"
- }
- }
- },
- {
- "type": "object",
- "required": [
- "distribution_info"
- ],
- "properties": {
- "distribution_info": {
- "type": "object"
- }
- }
- }
- ]
-}
diff --git a/contracts/mirror_factory/src/contract.rs b/contracts/mirror_factory/src/contract.rs
deleted file mode 100644
index 0631da2dd..000000000
--- a/contracts/mirror_factory/src/contract.rs
+++ /dev/null
@@ -1,721 +0,0 @@
-use cosmwasm_std::{
- log, to_binary, Api, Binary, CanonicalAddr, CosmosMsg, Decimal, Env, Extern, HandleResponse,
- HandleResult, HumanAddr, InitResponse, LogAttribute, MigrateResponse, MigrateResult, Querier,
- StdError, StdResult, Storage, Uint128, WasmMsg,
-};
-
-use crate::querier::{load_mint_asset_config, load_oracle_feeder};
-use crate::state::{
- decrease_total_weight, increase_total_weight, read_all_weight, read_config,
- read_last_distributed, read_params, read_total_weight, read_weight, remove_params,
- remove_weight, store_config, store_last_distributed, store_params, store_total_weight,
- store_weight, Config,
-};
-
-use mirror_protocol::factory::{
- ConfigResponse, DistributionInfoResponse, HandleMsg, InitMsg, MigrateMsg, Params, QueryMsg,
-};
-use mirror_protocol::mint::{HandleMsg as MintHandleMsg, IPOParams};
-use mirror_protocol::oracle::HandleMsg as OracleHandleMsg;
-use mirror_protocol::staking::Cw20HookMsg as StakingCw20HookMsg;
-use mirror_protocol::staking::HandleMsg as StakingHandleMsg;
-
-use cw20::{Cw20HandleMsg, MinterResponse};
-use terraswap::asset::{AssetInfo, PairInfo};
-use terraswap::factory::HandleMsg as TerraswapFactoryHandleMsg;
-use terraswap::hook::InitHook;
-use terraswap::querier::query_pair_info;
-use terraswap::token::InitMsg as TokenInitMsg;
-
-const MIRROR_TOKEN_WEIGHT: u32 = 300u32;
-const NORMAL_TOKEN_WEIGHT: u32 = 30u32;
-const DISTRIBUTION_INTERVAL: u64 = 60u64;
-
-pub fn init(
- deps: &mut Extern,
- env: Env,
- msg: InitMsg,
-) -> StdResult {
- store_config(
- &mut deps.storage,
- &Config {
- owner: CanonicalAddr::default(),
- mirror_token: CanonicalAddr::default(),
- mint_contract: CanonicalAddr::default(),
- oracle_contract: CanonicalAddr::default(),
- terraswap_factory: CanonicalAddr::default(),
- staking_contract: CanonicalAddr::default(),
- commission_collector: CanonicalAddr::default(),
- token_code_id: msg.token_code_id,
- base_denom: msg.base_denom,
- genesis_time: env.block.time,
- distribution_schedule: msg.distribution_schedule,
- },
- )?;
-
- store_total_weight(&mut deps.storage, 0u32)?;
- store_last_distributed(&mut deps.storage, env.block.time)?;
- Ok(InitResponse::default())
-}
-
-pub fn handle(
- deps: &mut Extern,
- env: Env,
- msg: HandleMsg,
-) -> StdResult {
- match msg {
- HandleMsg::PostInitialize {
- owner,
- mirror_token,
- mint_contract,
- oracle_contract,
- terraswap_factory,
- staking_contract,
- commission_collector,
- } => post_initialize(
- deps,
- env,
- owner,
- mirror_token,
- mint_contract,
- oracle_contract,
- terraswap_factory,
- staking_contract,
- commission_collector,
- ),
- HandleMsg::UpdateConfig {
- owner,
- token_code_id,
- distribution_schedule,
- } => update_config(deps, env, owner, token_code_id, distribution_schedule),
- HandleMsg::UpdateWeight {
- asset_token,
- weight,
- } => update_weight(deps, env, asset_token, weight),
- HandleMsg::Whitelist {
- name,
- symbol,
- oracle_feeder,
- params,
- } => whitelist(deps, env, name, symbol, oracle_feeder, params),
- HandleMsg::TokenCreationHook { oracle_feeder } => {
- token_creation_hook(deps, env, oracle_feeder)
- }
- HandleMsg::TerraswapCreationHook { asset_token } => {
- terraswap_creation_hook(deps, env, asset_token)
- }
- HandleMsg::Distribute {} => distribute(deps, env),
- HandleMsg::PassCommand { contract_addr, msg } => {
- pass_command(deps, env, contract_addr, msg)
- }
- HandleMsg::RevokeAsset {
- asset_token,
- end_price,
- } => revoke_asset(deps, env, asset_token, end_price),
- HandleMsg::MigrateAsset {
- name,
- symbol,
- from_token,
- end_price,
- } => migrate_asset(deps, env, name, symbol, from_token, end_price),
- }
-}
-
-#[allow(clippy::too_many_arguments)]
-pub fn post_initialize(
- deps: &mut Extern,
- _env: Env,
- owner: HumanAddr,
- mirror_token: HumanAddr,
- mint_contract: HumanAddr,
- oracle_contract: HumanAddr,
- terraswap_factory: HumanAddr,
- staking_contract: HumanAddr,
- commission_collector: HumanAddr,
-) -> HandleResult {
- let mut config: Config = read_config(&deps.storage)?;
- if config.owner != CanonicalAddr::default() {
- return Err(StdError::unauthorized());
- }
-
- config.owner = deps.api.canonical_address(&owner)?;
- config.mirror_token = deps.api.canonical_address(&mirror_token)?;
- config.mint_contract = deps.api.canonical_address(&mint_contract)?;
- config.oracle_contract = deps.api.canonical_address(&oracle_contract)?;
- config.terraswap_factory = deps.api.canonical_address(&terraswap_factory)?;
- config.staking_contract = deps.api.canonical_address(&staking_contract)?;
- config.commission_collector = deps.api.canonical_address(&commission_collector)?;
- store_config(&mut deps.storage, &config)?;
-
- Ok(HandleResponse::default())
-}
-
-pub fn update_config(
- deps: &mut Extern,
- env: Env,
- owner: Option,
- token_code_id: Option,
- distribution_schedule: Option>,
-) -> HandleResult {
- let mut config: Config = read_config(&deps.storage)?;
- if config.owner != deps.api.canonical_address(&env.message.sender)? {
- return Err(StdError::unauthorized());
- }
-
- if let Some(owner) = owner {
- config.owner = deps.api.canonical_address(&owner)?;
- }
-
- if let Some(distribution_schedule) = distribution_schedule {
- config.distribution_schedule = distribution_schedule;
- }
-
- if let Some(token_code_id) = token_code_id {
- config.token_code_id = token_code_id;
- }
-
- store_config(&mut deps.storage, &config)?;
-
- Ok(HandleResponse {
- messages: vec![],
- log: vec![log("action", "update_config")],
- data: None,
- })
-}
-
-pub fn update_weight(
- deps: &mut Extern,
- env: Env,
- asset_token: HumanAddr,
- weight: u32,
-) -> HandleResult {
- let config: Config = read_config(&deps.storage)?;
- if config.owner != deps.api.canonical_address(&env.message.sender)? {
- return Err(StdError::unauthorized());
- }
-
- let asset_token_raw = deps.api.canonical_address(&asset_token)?;
- let origin_weight = read_weight(&deps.storage, &asset_token_raw)?;
- store_weight(&mut deps.storage, &asset_token_raw, weight)?;
-
- let origin_total_weight = read_total_weight(&deps.storage)?;
- store_total_weight(
- &mut deps.storage,
- origin_total_weight + weight - origin_weight,
- )?;
-
- Ok(HandleResponse {
- messages: vec![],
- log: vec![
- log("action", "update_weight"),
- log("asset_token", asset_token),
- log("weight", weight),
- ],
- data: None,
- })
-}
-
-// just for by passing command to other contract like update config
-pub fn pass_command(
- deps: &mut Extern,
- env: Env,
- contract_addr: HumanAddr,
- msg: Binary,
-) -> HandleResult {
- let config: Config = read_config(&deps.storage)?;
- if config.owner != deps.api.canonical_address(&env.message.sender)? {
- return Err(StdError::unauthorized());
- }
-
- Ok(HandleResponse {
- messages: vec![CosmosMsg::Wasm(WasmMsg::Execute {
- contract_addr,
- msg,
- send: vec![],
- })],
- log: vec![],
- data: None,
- })
-}
-
-/// Whitelisting process
-/// 1. Create asset token contract with `config.token_code_id` with `minter` argument
-/// 2. Call `TokenCreationHook`
-/// 2-1. Initialize distribution info
-/// 2-2. Register asset to mint contract
-/// 2-3. Register asset and oracle feeder to oracle contract
-/// 2-4. Create terraswap pair through terraswap factory
-/// 3. Call `TerraswapCreationHook`
-/// 3-1. Register asset to staking contract
-pub fn whitelist(
- deps: &mut Extern,
- env: Env,
- name: String,
- symbol: String,
- oracle_feeder: HumanAddr,
- params: Params,
-) -> HandleResult {
- let config: Config = read_config(&deps.storage)?;
- if config.owner != deps.api.canonical_address(&env.message.sender)? {
- return Err(StdError::unauthorized());
- }
-
- if read_params(&deps.storage).is_ok() {
- return Err(StdError::generic_err("A whitelist process is in progress"));
- }
-
- store_params(&mut deps.storage, ¶ms)?;
-
- Ok(HandleResponse {
- messages: vec![CosmosMsg::Wasm(WasmMsg::Instantiate {
- code_id: config.token_code_id,
- send: vec![],
- label: None,
- msg: to_binary(&TokenInitMsg {
- name: name.clone(),
- symbol: symbol.to_string(),
- decimals: 6u8,
- initial_balances: vec![],
- mint: Some(MinterResponse {
- minter: deps.api.human_address(&config.mint_contract)?,
- cap: None,
- }),
- init_hook: Some(InitHook {
- contract_addr: env.contract.address,
- msg: to_binary(&HandleMsg::TokenCreationHook { oracle_feeder })?,
- }),
- })?,
- })],
- log: vec![
- log("action", "whitelist"),
- log("symbol", symbol),
- log("name", name),
- ],
- data: None,
- })
-}
-
-/// TokenCreationHook
-/// 1. Initialize distribution info
-/// 2. Register asset to mint contract
-/// 3. Register asset and oracle feeder to oracle contract
-/// 4. Create terraswap pair through terraswap factory with `TerraswapCreationHook`
-pub fn token_creation_hook(
- deps: &mut Extern,
- env: Env,
- oracle_feeder: HumanAddr,
-) -> HandleResult {
- let config: Config = read_config(&deps.storage)?;
-
- // If the param is not exists, it means there is no whitelist process in progress
- let params: Params = match read_params(&deps.storage) {
- Ok(v) => v,
- Err(_) => return Err(StdError::generic_err("No whitelist process in progress")),
- };
-
- let asset_token = env.message.sender;
- let asset_token_raw = deps.api.canonical_address(&asset_token)?;
-
- // If weight is given as params, we use that or just use default
- let weight = if let Some(weight) = params.weight {
- weight
- } else {
- NORMAL_TOKEN_WEIGHT
- };
-
- // Increase total weight
- store_weight(&mut deps.storage, &asset_token_raw, weight)?;
- increase_total_weight(&mut deps.storage, weight)?;
-
- // Remove params == clear flag
- remove_params(&mut deps.storage);
-
- let mut logs: Vec = vec![];
-
- // Check if all IPO params exist
- let ipo_params: Option =
- if let (Some(mint_period), Some(min_collateral_ratio_after_ipo), Some(pre_ipo_price)) = (
- params.mint_period,
- params.min_collateral_ratio_after_ipo,
- params.pre_ipo_price,
- ) {
- let mint_end: u64 = env.block.time + mint_period;
- logs = vec![
- log("is_pre_ipo", true),
- log("mint_end", mint_end.to_string()),
- log(
- "min_collateral_ratio_after_ipo",
- min_collateral_ratio_after_ipo.to_string(),
- ),
- log("pre_ipo_price", pre_ipo_price.to_string()),
- ];
- Some(IPOParams {
- mint_end: mint_end,
- min_collateral_ratio_after_ipo,
- pre_ipo_price,
- })
- } else {
- logs.push(log("is_pre_ipo", false));
- None
- };
-
- // Register asset to mint contract
- // Register asset to oracle contract
- // Create terraswap pair
- Ok(HandleResponse {
- messages: vec![
- CosmosMsg::Wasm(WasmMsg::Execute {
- contract_addr: deps.api.human_address(&config.mint_contract)?,
- send: vec![],
- msg: to_binary(&MintHandleMsg::RegisterAsset {
- asset_token: asset_token.clone(),
- auction_discount: params.auction_discount,
- min_collateral_ratio: params.min_collateral_ratio,
- ipo_params,
- })?,
- }),
- CosmosMsg::Wasm(WasmMsg::Execute {
- contract_addr: deps.api.human_address(&config.oracle_contract)?,
- send: vec![],
- msg: to_binary(&OracleHandleMsg::RegisterAsset {
- asset_token: asset_token.clone(),
- feeder: oracle_feeder,
- })?,
- }),
- CosmosMsg::Wasm(WasmMsg::Execute {
- contract_addr: deps.api.human_address(&config.terraswap_factory)?,
- send: vec![],
- msg: to_binary(&TerraswapFactoryHandleMsg::CreatePair {
- asset_infos: [
- AssetInfo::NativeToken {
- denom: config.base_denom,
- },
- AssetInfo::Token {
- contract_addr: asset_token.clone(),
- },
- ],
- init_hook: Some(InitHook {
- msg: to_binary(&HandleMsg::TerraswapCreationHook {
- asset_token: asset_token.clone(),
- })?,
- contract_addr: env.contract.address,
- }),
- })?,
- }),
- ],
- log: vec![vec![log("asset_token_addr", asset_token.as_str())], logs].concat(),
- data: None,
- })
-}
-
-/// TerraswapCreationHook
-/// 1. Register asset and liquidity(LP) token to staking contract
-pub fn terraswap_creation_hook(
- deps: &mut Extern,
- env: Env,
- asset_token: HumanAddr,
-) -> HandleResult {
- // Now terraswap contract is already created,
- // and liquidity token also created
- let config: Config = read_config(&deps.storage)?;
- let asset_token_raw = deps.api.canonical_address(&asset_token)?;
- let sender_raw = deps.api.canonical_address(&env.message.sender)?;
-
- if config.mirror_token == asset_token_raw {
- store_weight(&mut deps.storage, &asset_token_raw, MIRROR_TOKEN_WEIGHT)?;
- increase_total_weight(&mut deps.storage, MIRROR_TOKEN_WEIGHT)?;
- } else if config.terraswap_factory != sender_raw {
- return Err(StdError::unauthorized());
- }
-
- let asset_infos = [
- AssetInfo::NativeToken {
- denom: config.base_denom,
- },
- AssetInfo::Token {
- contract_addr: asset_token.clone(),
- },
- ];
-
- // Load terraswap pair info
- let pair_info: PairInfo = query_pair_info(
- &deps,
- &deps.api.human_address(&config.terraswap_factory)?,
- &asset_infos,
- )?;
-
- // Execute staking contract to register staking token of newly created asset
- Ok(HandleResponse {
- messages: vec![CosmosMsg::Wasm(WasmMsg::Execute {
- contract_addr: deps.api.human_address(&config.staking_contract)?,
- send: vec![],
- msg: to_binary(&StakingHandleMsg::RegisterAsset {
- asset_token,
- staking_token: pair_info.liquidity_token,
- })?,
- })],
- log: vec![],
- data: None,
- })
-}
-
-/// Distribute
-/// Anyone can execute distribute operation to distribute
-/// mirror inflation rewards on the staking pool
-pub fn distribute(
- deps: &mut Extern,
- env: Env,
-) -> HandleResult {
- let last_distributed = read_last_distributed(&deps.storage)?;
- if last_distributed + DISTRIBUTION_INTERVAL > env.block.time {
- return Err(StdError::generic_err(
- "Cannot distribute mirror token before interval",
- ));
- }
-
- let config: Config = read_config(&deps.storage)?;
- let time_elapsed = env.block.time - config.genesis_time;
- let last_time_elapsed = last_distributed - config.genesis_time;
- let mut target_distribution_amount: Uint128 = Uint128::zero();
- for s in config.distribution_schedule.iter() {
- if s.0 > time_elapsed || s.1 < last_time_elapsed {
- continue;
- }
-
- // min(s.1, time_elapsed) - max(s.0, last_time_elapsed)
- let time_duration =
- std::cmp::min(s.1, time_elapsed) - std::cmp::max(s.0, last_time_elapsed);
-
- let time_slot = s.1 - s.0;
- let distribution_amount_per_sec: Decimal = Decimal::from_ratio(s.2, time_slot);
- target_distribution_amount += distribution_amount_per_sec * Uint128(time_duration as u128);
- }
-
- let staking_contract = deps.api.human_address(&config.staking_contract)?;
- let mirror_token = deps.api.human_address(&config.mirror_token)?;
-
- let total_weight: u32 = read_total_weight(&deps.storage)?;
- let mut distribution_amount: Uint128 = Uint128::zero();
- let weights: Vec<(CanonicalAddr, u32)> = read_all_weight(&deps.storage)?;
- let rewards: Vec<(HumanAddr, Uint128)> = weights
- .iter()
- .map(|w| {
- let amount = Uint128::from(
- target_distribution_amount.u128() * (w.1 as u128) / (total_weight as u128),
- );
-
- if amount.is_zero() {
- return Err(StdError::generic_err("cannot distribute zero amount"));
- }
-
- distribution_amount += amount;
- Ok((deps.api.human_address(&w.0)?, amount))
- })
- .filter(|m| m.is_ok())
- .collect::>>()?;
-
- // store last distributed
- store_last_distributed(&mut deps.storage, env.block.time)?;
-
- const SPLIT_UNIT: usize = 10;
- let rewards_vec: Vec> =
- rewards.chunks(SPLIT_UNIT).map(|v| v.to_vec()).collect();
-
- // mint token to self and try send minted tokens to staking contract
- Ok(HandleResponse {
- messages: rewards_vec
- .into_iter()
- .map(|rewards| {
- Ok(CosmosMsg::Wasm(WasmMsg::Execute {
- contract_addr: mirror_token.clone(),
- msg: to_binary(&Cw20HandleMsg::Send {
- contract: staking_contract.clone(),
- amount: rewards.iter().map(|v| v.1.u128()).sum::().into(),
- msg: Some(to_binary(&StakingCw20HookMsg::DepositReward { rewards })?),
- })?,
- send: vec![],
- }))
- })
- .collect::>>()?,
- log: vec![
- log("action", "distribute"),
- log("distribution_amount", distribution_amount.to_string()),
- ],
- data: None,
- })
-}
-
-pub fn revoke_asset(
- deps: &mut Extern,
- env: Env,
- asset_token: HumanAddr,
- end_price: Decimal,
-) -> HandleResult {
- let config: Config = read_config(&deps.storage)?;
- let asset_token_raw: CanonicalAddr = deps.api.canonical_address(&asset_token)?;
- let oracle_feeder: HumanAddr = deps.api.human_address(&load_oracle_feeder(
- &deps,
- &deps.api.human_address(&config.oracle_contract)?,
- &asset_token_raw,
- )?)?;
- let sender_raw = deps.api.canonical_address(&env.message.sender)?;
-
- // revoke asset can only be executed by the feeder or the owner (gov contract)
- if oracle_feeder != env.message.sender && config.owner != sender_raw {
- return Err(StdError::unauthorized());
- }
-
- remove_weight(&mut deps.storage, &asset_token_raw);
- decrease_total_weight(&mut deps.storage, NORMAL_TOKEN_WEIGHT)?;
-
- Ok(HandleResponse {
- messages: vec![CosmosMsg::Wasm(WasmMsg::Execute {
- contract_addr: deps.api.human_address(&config.mint_contract)?,
- send: vec![],
- msg: to_binary(&MintHandleMsg::RegisterMigration {
- asset_token: asset_token.clone(),
- end_price,
- })?,
- })],
- log: vec![
- log("action", "revoke_asset"),
- log("end_price", end_price.to_string()),
- log("asset_token", asset_token.to_string()),
- ],
- data: None,
- })
-}
-
-pub fn migrate_asset(
- deps: &mut Extern,
- env: Env,
- name: String,
- symbol: String,
- asset_token: HumanAddr,
- end_price: Decimal,
-) -> HandleResult {
- let config: Config = read_config(&deps.storage)?;
- let asset_token_raw: CanonicalAddr = deps.api.canonical_address(&asset_token)?;
- let oracle_feeder: HumanAddr = deps.api.human_address(&load_oracle_feeder(
- &deps,
- &deps.api.human_address(&config.oracle_contract)?,
- &asset_token_raw,
- )?)?;
-
- if oracle_feeder != env.message.sender {
- return Err(StdError::unauthorized());
- }
-
- let weight = read_weight(&deps.storage, &asset_token_raw)?;
- remove_weight(&mut deps.storage, &asset_token_raw);
- decrease_total_weight(&mut deps.storage, NORMAL_TOKEN_WEIGHT)?;
-
- let mint_contract = deps.api.human_address(&config.mint_contract)?;
- let mint_config: (Decimal, Decimal) =
- load_mint_asset_config(&deps, &mint_contract, &asset_token_raw)?;
-
- store_params(
- &mut deps.storage,
- &Params {
- auction_discount: mint_config.0,
- min_collateral_ratio: mint_config.1,
- weight: Some(weight),
- mint_period: None,
- min_collateral_ratio_after_ipo: None,
- pre_ipo_price: None,
- },
- )?;
-
- Ok(HandleResponse {
- messages: vec![
- CosmosMsg::Wasm(WasmMsg::Execute {
- contract_addr: mint_contract,
- send: vec![],
- msg: to_binary(&MintHandleMsg::RegisterMigration {
- asset_token: asset_token.clone(),
- end_price,
- })?,
- }),
- CosmosMsg::Wasm(WasmMsg::Instantiate {
- code_id: config.token_code_id,
- send: vec![],
- label: None,
- msg: to_binary(&TokenInitMsg {
- name,
- symbol,
- decimals: 6u8,
- initial_balances: vec![],
- mint: Some(MinterResponse {
- minter: deps.api.human_address(&config.mint_contract)?,
- cap: None,
- }),
- init_hook: Some(InitHook {
- contract_addr: env.contract.address,
- msg: to_binary(&HandleMsg::TokenCreationHook { oracle_feeder })?,
- }),
- })?,
- }),
- ],
- log: vec![
- log("action", "migration"),
- log("end_price", end_price.to_string()),
- log("asset_token", asset_token.to_string()),
- ],
- data: None,
- })
-}
-
-pub fn query(
- deps: &Extern,
- msg: QueryMsg,
-) -> StdResult {
- match msg {
- QueryMsg::Config {} => to_binary(&query_config(deps)?),
- QueryMsg::DistributionInfo {} => to_binary(&query_distribution_info(deps)?),
- }
-}
-
-pub fn query_config(
- deps: &Extern,
-) -> StdResult {
- let state = read_config(&deps.storage)?;
- let resp = ConfigResponse {
- owner: deps.api.human_address(&state.owner)?,
- mirror_token: deps.api.human_address(&state.mirror_token)?,
- mint_contract: deps.api.human_address(&state.mint_contract)?,
- oracle_contract: deps.api.human_address(&state.oracle_contract)?,
- terraswap_factory: deps.api.human_address(&state.terraswap_factory)?,
- staking_contract: deps.api.human_address(&state.staking_contract)?,
- commission_collector: deps.api.human_address(&state.commission_collector)?,
- token_code_id: state.token_code_id,
- base_denom: state.base_denom,
- genesis_time: state.genesis_time,
- distribution_schedule: state.distribution_schedule,
- };
-
- Ok(resp)
-}
-
-pub fn query_distribution_info(
- deps: &Extern,
-) -> StdResult {
- let weights: Vec<(CanonicalAddr, u32)> = read_all_weight(&deps.storage)?;
- let last_distributed = read_last_distributed(&deps.storage)?;
- let resp = DistributionInfoResponse {
- last_distributed,
- weights: weights
- .iter()
- .map(|w| Ok((deps.api.human_address(&w.0)?, w.1)))
- .collect::>>()?,
- };
-
- Ok(resp)
-}
-
-pub fn migrate(
- _deps: &mut Extern,
- _env: Env,
- _msg: MigrateMsg,
-) -> MigrateResult {
- Ok(MigrateResponse::default())
-}
diff --git a/contracts/mirror_factory/src/lib.rs b/contracts/mirror_factory/src/lib.rs
deleted file mode 100644
index 6b2695c89..000000000
--- a/contracts/mirror_factory/src/lib.rs
+++ /dev/null
@@ -1,13 +0,0 @@
-pub mod contract;
-pub mod math;
-pub mod querier;
-pub mod state;
-
-#[cfg(test)]
-mod testing;
-
-#[cfg(test)]
-mod mock_querier;
-
-#[cfg(target_arch = "wasm32")]
-cosmwasm_std::create_entry_points_with_migration!(contract);
diff --git a/contracts/mirror_factory/src/math.rs b/contracts/mirror_factory/src/math.rs
deleted file mode 100644
index ce7bb0c0e..000000000
--- a/contracts/mirror_factory/src/math.rs
+++ /dev/null
@@ -1,18 +0,0 @@
-use cosmwasm_std::{Decimal, Uint128};
-
-const DECIMAL_FRACTIONAL: Uint128 = Uint128(1_000_000_000u128);
-
-pub fn reverse_decimal(decimal: Decimal) -> Decimal {
- Decimal::from_ratio(DECIMAL_FRACTIONAL, decimal * DECIMAL_FRACTIONAL)
-}
-
-pub fn decimal_multiplication(a: Decimal, b: Decimal) -> Decimal {
- Decimal::from_ratio(a * DECIMAL_FRACTIONAL * b, DECIMAL_FRACTIONAL)
-}
-
-pub fn decimal_subtraction(a: Decimal, b: Decimal) -> Decimal {
- Decimal::from_ratio(
- (DECIMAL_FRACTIONAL * a - DECIMAL_FRACTIONAL * b).unwrap(),
- DECIMAL_FRACTIONAL,
- )
-}
diff --git a/contracts/mirror_factory/src/mock_querier.rs b/contracts/mirror_factory/src/mock_querier.rs
deleted file mode 100644
index 19d2039ad..000000000
--- a/contracts/mirror_factory/src/mock_querier.rs
+++ /dev/null
@@ -1,255 +0,0 @@
-use schemars::JsonSchema;
-use serde::{Deserialize, Serialize};
-
-use cosmwasm_std::testing::{MockApi, MockQuerier, MockStorage, MOCK_CONTRACT_ADDR};
-use cosmwasm_std::{
- from_binary, from_slice, to_binary, Api, CanonicalAddr, Coin, Decimal, Empty, Extern,
- HumanAddr, Querier, QuerierResult, QueryRequest, SystemError, WasmQuery,
-};
-use cosmwasm_storage::to_length_prefixed;
-
-use crate::querier::MintAssetConfig;
-use std::collections::HashMap;
-use terraswap::asset::{AssetInfo, PairInfo};
-
-/// mock_dependencies is a drop-in replacement for cosmwasm_std::testing::mock_dependencies
-/// this uses our CustomQuerier.
-pub fn mock_dependencies(
- canonical_length: usize,
- contract_balance: &[Coin],
-) -> Extern {
- let contract_addr = HumanAddr::from(MOCK_CONTRACT_ADDR);
- let custom_querier: WasmMockQuerier = WasmMockQuerier::new(
- MockQuerier::new(&[(&contract_addr, contract_balance)]),
- MockApi::new(canonical_length),
- canonical_length,
- );
-
- Extern {
- storage: MockStorage::default(),
- api: MockApi::new(canonical_length),
- querier: custom_querier,
- }
-}
-
-pub struct WasmMockQuerier {
- base: MockQuerier,
- terraswap_factory_querier: TerraswapFactoryQuerier,
- oracle_querier: OracleQuerier,
- mint_querier: MintQuerier,
- canonical_length: usize,
-}
-
-#[derive(Clone, Default)]
-pub struct TerraswapFactoryQuerier {
- pairs: HashMap,
-}
-
-impl TerraswapFactoryQuerier {
- pub fn new(pairs: &[(&String, &HumanAddr)]) -> Self {
- TerraswapFactoryQuerier {
- pairs: pairs_to_map(pairs),
- }
- }
-}
-
-pub(crate) fn pairs_to_map(pairs: &[(&String, &HumanAddr)]) -> HashMap