diff --git a/Anchor.toml b/Anchor.toml index 1a6d7b5..6a5d73e 100644 --- a/Anchor.toml +++ b/Anchor.toml @@ -5,7 +5,7 @@ seeds = false skip-lint = false [programs.localnet] -core_sol_bond_stake_sc = "2gxhxhiRqQazdyniirt9QHhJk9aguG1RgtAhfo5B4yDY" +core_sol_bond_stake_sc = "4V8Luy9PjMdzF5VzNLGKH5uxXUXeBFooayEHXBGpXnxo" [registry] url = "https://api.apr.dev" @@ -15,7 +15,7 @@ cluster = "Localnet" wallet = "/Users/bucurdavid/.config/solana/id.json" [scripts] -test = "yarn run ts-mocha -p ./tsconfig.json -t 1000000 tests/**/*.ts" +test = "yarn run ts-mocha --runInBand -p ./tsconfig.json -t 1000000 tests/**/*.ts" [test.validator] diff --git a/Cargo.lock b/Cargo.lock index 77bd7a1..a950df5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -72,9 +72,9 @@ dependencies = [ [[package]] name = "anchor-attribute-access-control" -version = "0.30.1" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47fe28365b33e8334dd70ae2f34a43892363012fe239cf37d2ee91693575b1f8" +checksum = "e5f619f1d04f53621925ba8a2e633ba5a6081f2ae14758cbb67f38fd823e0a3e" dependencies = [ "anchor-syn", "proc-macro2", @@ -84,9 +84,9 @@ dependencies = [ [[package]] name = "anchor-attribute-account" -version = "0.30.1" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c288d496168268d198d9b53ee9f4f9d260a55ba4df9877ea1d4486ad6109e0f" +checksum = "e7f2a3e1df4685f18d12a943a9f2a7456305401af21a07c9fe076ef9ecd6e400" dependencies = [ "anchor-syn", "bs58 0.5.1", @@ -97,9 +97,9 @@ dependencies = [ [[package]] name = "anchor-attribute-constant" -version = "0.30.1" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49b77b6948d0eeaaa129ce79eea5bbbb9937375a9241d909ca8fb9e006bb6e90" +checksum = "9423945cb55627f0b30903288e78baf6f62c6c8ab28fb344b6b25f1ffee3dca7" dependencies = [ "anchor-syn", "quote", @@ -108,9 +108,9 @@ dependencies = [ [[package]] name = "anchor-attribute-error" -version = "0.30.1" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d20bb569c5a557c86101b944721d865e1fd0a4c67c381d31a44a84f07f84828" +checksum = "93ed12720033cc3c3bf3cfa293349c2275cd5ab99936e33dd4bf283aaad3e241" dependencies = [ "anchor-syn", "quote", @@ -119,9 +119,9 @@ dependencies = [ [[package]] name = "anchor-attribute-event" -version = "0.30.1" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cebd8d0671a3a9dc3160c48598d652c34c77de6be4d44345b8b514323284d57" +checksum = "eef4dc0371eba2d8c8b54794b0b0eb786a234a559b77593d6f80825b6d2c77a2" dependencies = [ "anchor-syn", "proc-macro2", @@ -131,26 +131,20 @@ dependencies = [ [[package]] name = "anchor-attribute-program" -version = "0.30.1" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efb2a5eb0860e661ab31aff7bb5e0288357b176380e985bade4ccb395981b42d" +checksum = "b18c4f191331e078d4a6a080954d1576241c29c56638783322a18d308ab27e4f" dependencies = [ - "anchor-lang-idl", "anchor-syn", - "anyhow", - "bs58 0.5.1", - "heck", - "proc-macro2", "quote", - "serde_json", "syn 1.0.109", ] [[package]] name = "anchor-derive-accounts" -version = "0.30.1" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04368b5abef4266250ca8d1d12f4dff860242681e4ec22b885dcfe354fd35aa1" +checksum = "5de10d6e9620d3bcea56c56151cad83c5992f50d5960b3a9bebc4a50390ddc3c" dependencies = [ "anchor-syn", "quote", @@ -159,9 +153,9 @@ dependencies = [ [[package]] name = "anchor-derive-serde" -version = "0.30.1" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0bb0e0911ad4a70cab880cdd6287fe1e880a1a9d8e4e6defa8e9044b9796a6c" +checksum = "f4e2e5be518ec6053d90a2a7f26843dbee607583c779e6c8395951b9739bdfbe" dependencies = [ "anchor-syn", "borsh-derive-internal 0.10.3", @@ -172,9 +166,9 @@ dependencies = [ [[package]] name = "anchor-derive-space" -version = "0.30.1" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ef415ff156dc82e9ecb943189b0cb241b3a6bfc26a180234dc21bd3ef3ce0cb" +checksum = "1ecc31d19fa54840e74b7a979d44bcea49d70459de846088a1d71e87ba53c419" dependencies = [ "proc-macro2", "quote", @@ -183,9 +177,9 @@ dependencies = [ [[package]] name = "anchor-lang" -version = "0.30.1" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6620c9486d9d36a4389cab5e37dc34a42ed0bfaa62e6a75a2999ce98f8f2e373" +checksum = "35da4785497388af0553586d55ebdc08054a8b1724720ef2749d313494f2b8ad" dependencies = [ "anchor-attribute-access-control", "anchor-attribute-account", @@ -196,66 +190,37 @@ dependencies = [ "anchor-derive-accounts", "anchor-derive-serde", "anchor-derive-space", - "anchor-lang-idl", "arrayref", - "base64 0.21.7", + "base64 0.13.1", "bincode", "borsh 0.10.3", "bytemuck", "getrandom 0.2.15", - "solana-program", + "solana-program 1.18.23", "thiserror", ] -[[package]] -name = "anchor-lang-idl" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31cf97b4e6f7d6144a05e435660fcf757dbc3446d38d0e2b851d11ed13625bba" -dependencies = [ - "anchor-lang-idl-spec", - "anyhow", - "heck", - "regex", - "serde", - "serde_json", - "sha2 0.10.8", -] - -[[package]] -name = "anchor-lang-idl-spec" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bdf143115440fe621bdac3a29a1f7472e09f6cd82b2aa569429a0c13f103838" -dependencies = [ - "anyhow", - "serde", -] - [[package]] name = "anchor-spl" -version = "0.30.1" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04bd077c34449319a1e4e0bc21cea572960c9ae0d0fefda0dd7c52fcc3c647a3" +checksum = "6c4fd6e43b2ca6220d2ef1641539e678bfc31b6cc393cf892b373b5997b6a39a" dependencies = [ "anchor-lang", + "solana-program 1.18.23", "spl-associated-token-account", - "spl-pod", "spl-token", - "spl-token-2022", - "spl-token-group-interface", - "spl-token-metadata-interface", + "spl-token-2022 0.9.0", ] [[package]] name = "anchor-syn" -version = "0.30.1" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f99daacb53b55cfd37ce14d6c9905929721137fd4c67bbab44a19802aecb622f" +checksum = "d9101b84702fed2ea57bd22992f75065da5648017135b844283a2f6d74f27825" dependencies = [ "anyhow", "bs58 0.5.1", - "cargo_toml", "heck", "proc-macro2", "quote", @@ -268,9 +233,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.86" +version = "1.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" +checksum = "10f00e1f6e58a40e807377c75c6a7f97bf9044fab57816f2414e6f5f4499d7b8" [[package]] name = "ark-bn254" @@ -430,12 +395,24 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff" +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + [[package]] name = "base64" version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + [[package]] name = "bincode" version = "1.3.3" @@ -565,10 +542,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3ef8005764f53cd4dca619f5bf64cafd4664dada50ece25e4d81de54c80cc0b" dependencies = [ "once_cell", - "proc-macro-crate 3.1.0", + "proc-macro-crate 3.2.0", "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.77", "syn_derive", ] @@ -649,9 +626,9 @@ dependencies = [ [[package]] name = "bytemuck" -version = "1.17.0" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fd4c6dcc3b0aea2f5c0b4b82c2b15fe39ddbc76041a310848f4706edf76bb31" +checksum = "94bbb0ad554ad961ddc5da507a12a29b14e4ae5bda06b19f575a3e6079d2e2ae" dependencies = [ "bytemuck_derive", ] @@ -664,7 +641,7 @@ checksum = "0cc8b54b395f2fcfbb3d90c47b01c7f444d94d05bdeb775811dec868ac3bbc26" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.77", ] [[package]] @@ -673,21 +650,11 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" -[[package]] -name = "cargo_toml" -version = "0.19.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a98356df42a2eb1bd8f1793ae4ee4de48e384dd974ce5eac8eee802edb7492be" -dependencies = [ - "serde", - "toml 0.8.19", -] - [[package]] name = "cc" -version = "1.1.13" +version = "1.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72db2f7947ecee9b03b510377e8bb9077afa27176fdbff55c51027e976fdcc48" +checksum = "b62ac837cdb5cb22e10a256099b4fc502b1dfe560cb282963a974d7abd80e476" dependencies = [ "jobserver", "libc", @@ -746,9 +713,9 @@ dependencies = [ [[package]] name = "constant_time_eq" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7144d30dcf0fafbce74250a3963025d8d52177934239851c917d29f1df280c2" +checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" [[package]] name = "core-sol-bond-stake-sc" @@ -756,19 +723,20 @@ version = "0.1.0" dependencies = [ "anchor-lang", "anchor-spl", - "mpl-token-metadata", + "mpl-bubblegum", "quickcheck", - "solana-program", + "solana-program 1.18.23", "solana-security-txt", + "spl-account-compression", "spl-token", "uint", ] [[package]] name = "cpufeatures" -version = "0.2.13" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51e852e6dc9a5bed1fae92dd2375037bf2b768725bf3be87811edee3249d09ad" +checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" dependencies = [ "libc", ] @@ -868,7 +836,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.75", + "syn 2.0.77", ] [[package]] @@ -879,7 +847,7 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ "darling_core", "quote", - "syn 2.0.75", + "syn 2.0.77", ] [[package]] @@ -1146,9 +1114,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93ead53efc7ea8ed3cfb0c79fc8023fbb782a5432b52830b6518941cebe6505c" +checksum = "68b900aa2f7301e21c36462b170ee99994de34dff39a4a6a528e80e7376d07e5" dependencies = [ "equivalent", "hashbrown 0.14.5", @@ -1187,6 +1155,15 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "kaigan" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6dd100976df9dd59d0c3fecf6f9ad3f161a087374d1b2a77ebb4ad8920f11bb" +dependencies = [ + "borsh 0.10.3", +] + [[package]] name = "keccak" version = "0.1.5" @@ -1321,15 +1298,16 @@ dependencies = [ ] [[package]] -name = "mpl-token-metadata" -version = "4.1.2" +name = "mpl-bubblegum" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "caf0f61b553e424a6234af1268456972ee66c2222e1da89079242251fa7479e5" +checksum = "a9eff5ae5cafd1acdf7e7c93359da1eec91dcaede318470d9f68b78e8b7469f4" dependencies = [ "borsh 0.10.3", + "kaigan", "num-derive 0.3.3", "num-traits", - "solana-program", + "solana-program 1.18.23", "thiserror", ] @@ -1362,7 +1340,7 @@ checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.77", ] [[package]] @@ -1398,10 +1376,10 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56" dependencies = [ - "proc-macro-crate 3.1.0", + "proc-macro-crate 3.2.0", "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.77", ] [[package]] @@ -1496,16 +1474,16 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" dependencies = [ - "toml 0.5.11", + "toml", ] [[package]] name = "proc-macro-crate" -version = "3.1.0" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" +checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b" dependencies = [ - "toml_edit 0.21.1", + "toml_edit", ] [[package]] @@ -1557,7 +1535,7 @@ checksum = "9e2e25ee72f5b24d773cae88422baddefff7714f97aab68d96fe2b6fc4a28fb2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.77", ] [[package]] @@ -1574,9 +1552,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.36" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -1727,9 +1705,9 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" [[package]] name = "rustc_version" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" dependencies = [ "semver", ] @@ -1760,9 +1738,9 @@ checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" [[package]] name = "serde" -version = "1.0.208" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cff085d2cb684faa248efb494c39b68e522822ac0de72ccf08109abde717cfb2" +checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" dependencies = [ "serde_derive", ] @@ -1778,20 +1756,20 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.208" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24008e81ff7613ed8e5ba0cfaf24e2c2f1e5b8a0495711e44fcd4882fca62bcf" +checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.77", ] [[package]] name = "serde_json" -version = "1.0.125" +version = "1.0.128" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83c8e735a073ccf5be70aa8066aa984eaf2fa000db6c8d0100ae605b366d31ed" +checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" dependencies = [ "itoa", "memchr", @@ -1799,15 +1777,6 @@ dependencies = [ "serde", ] -[[package]] -name = "serde_spanned" -version = "0.6.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb5b1b31579f3811bf615c144393417496f152e12ac8b7663bf664f4a815306d" -dependencies = [ - "serde", -] - [[package]] name = "serde_with" version = "2.3.3" @@ -1827,7 +1796,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.77", ] [[package]] @@ -1912,9 +1881,9 @@ checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "solana-frozen-abi" -version = "1.18.22" +version = "1.18.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20a6ef2db80dceb124b7bf81cca3300804bf427d2711973fc3df450ed7dfb26d" +checksum = "4bfcde2fc6946c99c7e3400fadd04d1628d675bfd66cb34d461c0f3224bd27d1" dependencies = [ "block-buffer 0.10.4", "bs58 0.4.0", @@ -1937,21 +1906,21 @@ dependencies = [ [[package]] name = "solana-frozen-abi-macro" -version = "1.18.22" +version = "1.18.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70088de7d4067d19a7455609e2b393e6086bd847bb39c4d2bf234fc14827ef9e" +checksum = "d5024d241425f4e99f112ee03bfa89e526c86c7ca9bd7e13448a7f2dffb7e060" dependencies = [ "proc-macro2", "quote", "rustc_version", - "syn 2.0.75", + "syn 2.0.77", ] [[package]] name = "solana-logger" -version = "1.18.22" +version = "1.18.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b129da15193f26db62d62ae6bb9f72361f361bcdc36054be3ab8bc04cc7a4f31" +checksum = "10948c30d138d6fbfc2ae78a4882be5a9ebffa4bb1239c4efc386104ebc35b7f" dependencies = [ "env_logger 0.9.3", "lazy_static", @@ -1960,9 +1929,9 @@ dependencies = [ [[package]] name = "solana-program" -version = "1.18.22" +version = "1.18.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb2b2c8babfae4cace1a25b6efa00418f3acd852cf55d7cecc0360d3c5050479" +checksum = "76056fecde0fe0ece8b457b719729c17173333471c72ad41969982975a10d6e0" dependencies = [ "ark-bn254", "ark-ec", @@ -2006,18 +1975,64 @@ dependencies = [ "sha3 0.10.8", "solana-frozen-abi", "solana-frozen-abi-macro", - "solana-sdk-macro", + "solana-sdk-macro 1.18.23", "thiserror", "tiny-bip39", "wasm-bindgen", "zeroize", ] +[[package]] +name = "solana-program" +version = "2.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51237f3618428e8b9dd1e5c3d89b8f44f00dbcb88a7ad577ebdfdfac51501c61" +dependencies = [ + "ark-bn254", + "ark-ec", + "ark-ff", + "ark-serialize", + "base64 0.22.1", + "bincode", + "bitflags", + "blake3", + "borsh 0.10.3", + "borsh 1.5.1", + "bs58 0.5.1", + "bv", + "bytemuck", + "bytemuck_derive", + "console_error_panic_hook", + "console_log", + "curve25519-dalek", + "getrandom 0.2.15", + "js-sys", + "lazy_static", + "libsecp256k1", + "log", + "memoffset", + "num-bigint", + "num-derive 0.4.2", + "num-traits", + "parking_lot", + "rand 0.8.5", + "rustc_version", + "rustversion", + "serde", + "serde_bytes", + "serde_derive", + "sha2 0.10.8", + "sha3 0.10.8", + "solana-sdk-macro 2.0.9", + "thiserror", + "wasm-bindgen", +] + [[package]] name = "solana-sdk" -version = "1.18.22" +version = "1.18.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e0f0def5c5af07f53d321cea7b104487b522cfff77c3cae3da361bfe956e9e" +checksum = "b4b3f2080eddef6552fde7f149c429cf05b9bb0605a068b0d28e19d793e24df4" dependencies = [ "assert_matches", "base64 0.21.7", @@ -2061,8 +2076,8 @@ dependencies = [ "solana-frozen-abi", "solana-frozen-abi-macro", "solana-logger", - "solana-program", - "solana-sdk-macro", + "solana-program 1.18.23", + "solana-sdk-macro 1.18.23", "thiserror", "uriparse", "wasm-bindgen", @@ -2070,15 +2085,28 @@ dependencies = [ [[package]] name = "solana-sdk-macro" -version = "1.18.22" +version = "1.18.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c55c196c8050834c391a34b58e3c9fd86b15452ef1feeeafa1dbeb9d2291dfec" +checksum = "2a8613ca80150f7e277e773620ba65d2c5fcc3a08eb8026627d601421ab43aef" dependencies = [ "bs58 0.4.0", "proc-macro2", "quote", "rustversion", - "syn 2.0.75", + "syn 2.0.77", +] + +[[package]] +name = "solana-sdk-macro" +version = "2.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45b6e930455ef68cf15e5a22a0e0c207e67c3d70978a565e0a64f568c8a24129" +dependencies = [ + "bs58 0.5.1", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.77", ] [[package]] @@ -2089,9 +2117,9 @@ checksum = "468aa43b7edb1f9b7b7b686d5c3aeb6630dc1708e86e31343499dd5c4d775183" [[package]] name = "solana-zk-token-sdk" -version = "1.18.22" +version = "1.18.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57ee07fa523b4cfcff68de774db7aa87d2da2c4357155a90bacd9a0a0af70a99" +checksum = "39a57b2f269f24088b6b8e426de05e5c1faa6b5d6f26175c06eb80df96ec685e" dependencies = [ "aes-gcm-siv", "base64 0.21.7", @@ -2109,61 +2137,85 @@ dependencies = [ "serde", "serde_json", "sha3 0.9.1", - "solana-program", + "solana-program 1.18.23", "solana-sdk", "subtle", "thiserror", "zeroize", ] +[[package]] +name = "spl-account-compression" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "602499d5fe3b60280239c4656a361b283c8c5f73f769c6cf41d2e8a151ce72db" +dependencies = [ + "anchor-lang", + "bytemuck", + "solana-program 2.0.9", + "spl-concurrent-merkle-tree", + "spl-noop", +] + [[package]] name = "spl-associated-token-account" -version = "3.0.4" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "143109d789171379e6143ef23191786dfaac54289ad6e7917cfb26b36c432b10" +checksum = "992d9c64c2564cc8f63a4b508bf3ebcdf2254b0429b13cd1d31adb6162432a5f" dependencies = [ "assert_matches", - "borsh 1.5.1", + "borsh 0.10.3", "num-derive 0.4.2", "num-traits", - "solana-program", + "solana-program 1.18.23", "spl-token", - "spl-token-2022", + "spl-token-2022 1.0.0", + "thiserror", +] + +[[package]] +name = "spl-concurrent-merkle-tree" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7f5f45b971d82cbb0416fdffad3c9098f259545d54072e83a0a482f60f8f689" +dependencies = [ + "bytemuck", + "solana-program 2.0.9", "thiserror", ] [[package]] name = "spl-discriminator" -version = "0.2.5" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "210101376962bb22bb13be6daea34656ea1cbc248fce2164b146e39203b55e03" +checksum = "cce5d563b58ef1bb2cdbbfe0dfb9ffdc24903b10ae6a4df2d8f425ece375033f" dependencies = [ "bytemuck", - "solana-program", + "solana-program 1.18.23", "spl-discriminator-derive", ] [[package]] name = "spl-discriminator-derive" -version = "0.2.0" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9e8418ea6269dcfb01c712f0444d2c75542c04448b480e87de59d2865edc750" +checksum = "07fd7858fc4ff8fb0e34090e41d7eb06a823e1057945c26d480bfc21d2338a93" dependencies = [ "quote", "spl-discriminator-syn", - "syn 2.0.75", + "syn 2.0.77", ] [[package]] name = "spl-discriminator-syn" -version = "0.2.0" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c1f05593b7ca9eac7caca309720f2eafb96355e037e6d373b909a80fe7b69b9" +checksum = "18fea7be851bd98d10721782ea958097c03a0c2a07d8d4997041d0ece6319a63" dependencies = [ "proc-macro2", "quote", "sha2 0.10.8", - "syn 2.0.75", + "syn 2.0.77", "thiserror", ] @@ -2173,55 +2225,78 @@ version = "4.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a49f49f95f2d02111ded31696ab38a081fab623d4c76bd4cb074286db4560836" dependencies = [ - "solana-program", + "solana-program 1.18.23", +] + +[[package]] +name = "spl-noop" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dd67ea3d0070a12ff141f5da46f9695f49384a03bce1203a5608f5739437950" +dependencies = [ + "solana-program 1.18.23", ] [[package]] name = "spl-pod" -version = "0.2.5" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c52d84c55efeef8edcc226743dc089d7e3888b8e3474569aa3eff152b37b9996" +checksum = "2881dddfca792737c0706fa0175345ab282b1b0879c7d877bad129645737c079" dependencies = [ - "borsh 1.5.1", + "borsh 0.10.3", "bytemuck", - "solana-program", + "solana-program 1.18.23", "solana-zk-token-sdk", "spl-program-error", ] [[package]] name = "spl-program-error" -version = "0.4.4" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e45a49acb925db68aa501b926096b2164adbdcade7a0c24152af9f0742d0a602" +checksum = "249e0318493b6bcf27ae9902600566c689b7dfba9f1bdff5893e92253374e78c" dependencies = [ "num-derive 0.4.2", "num-traits", - "solana-program", + "solana-program 1.18.23", "spl-program-error-derive", "thiserror", ] [[package]] name = "spl-program-error-derive" -version = "0.4.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6d375dd76c517836353e093c2dbb490938ff72821ab568b545fd30ab3256b3e" +checksum = "1845dfe71fd68f70382232742e758557afe973ae19e6c06807b2c30f5d5cb474" dependencies = [ "proc-macro2", "quote", "sha2 0.10.8", - "syn 2.0.75", + "syn 2.0.77", ] [[package]] name = "spl-tlv-account-resolution" -version = "0.6.5" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fab8edfd37be5fa17c9e42c1bff86abbbaf0494b031b37957f2728ad2ff842ba" +checksum = "062e148d3eab7b165582757453632ffeef490c02c86a48bfdb4988f63eefb3b9" dependencies = [ "bytemuck", - "solana-program", + "solana-program 1.18.23", + "spl-discriminator", + "spl-pod", + "spl-program-error", + "spl-type-length-value", +] + +[[package]] +name = "spl-tlv-account-resolution" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "615d381f48ddd2bb3c57c7f7fb207591a2a05054639b18a62e785117dd7a8683" +dependencies = [ + "bytemuck", + "solana-program 1.18.23", "spl-discriminator", "spl-pod", "spl-program-error", @@ -2239,22 +2314,44 @@ dependencies = [ "num-derive 0.4.2", "num-traits", "num_enum", - "solana-program", + "solana-program 1.18.23", + "thiserror", +] + +[[package]] +name = "spl-token-2022" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4abf34a65ba420584a0c35f3903f8d727d1f13ababbdc3f714c6b065a686e86" +dependencies = [ + "arrayref", + "bytemuck", + "num-derive 0.4.2", + "num-traits", + "num_enum", + "solana-program 1.18.23", + "solana-zk-token-sdk", + "spl-memo", + "spl-pod", + "spl-token", + "spl-token-metadata-interface", + "spl-transfer-hook-interface 0.3.0", + "spl-type-length-value", "thiserror", ] [[package]] name = "spl-token-2022" -version = "3.0.4" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b01d1b2851964e257187c0bca43a0de38d0af59192479ca01ac3e2b58b1bd95a" +checksum = "d697fac19fd74ff472dfcc13f0b442dd71403178ce1de7b5d16f83a33561c059" dependencies = [ "arrayref", "bytemuck", "num-derive 0.4.2", "num-traits", "num_enum", - "solana-program", + "solana-program 1.18.23", "solana-security-txt", "solana-zk-token-sdk", "spl-memo", @@ -2262,19 +2359,19 @@ dependencies = [ "spl-token", "spl-token-group-interface", "spl-token-metadata-interface", - "spl-transfer-hook-interface", + "spl-transfer-hook-interface 0.4.1", "spl-type-length-value", "thiserror", ] [[package]] name = "spl-token-group-interface" -version = "0.2.5" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "014817d6324b1e20c4bbc883e8ee30a5faa13e59d91d1b2b95df98b920150c17" +checksum = "b889509d49fa74a4a033ca5dae6c2307e9e918122d97e58562f5c4ffa795c75d" dependencies = [ "bytemuck", - "solana-program", + "solana-program 1.18.23", "spl-discriminator", "spl-pod", "spl-program-error", @@ -2282,12 +2379,12 @@ dependencies = [ [[package]] name = "spl-token-metadata-interface" -version = "0.3.5" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3da00495b602ebcf5d8ba8b3ecff1ee454ce4c125c9077747be49c2d62335ba" +checksum = "4c16ce3ba6979645fb7627aa1e435576172dd63088dc7848cb09aa331fa1fe4f" dependencies = [ - "borsh 1.5.1", - "solana-program", + "borsh 0.10.3", + "solana-program 1.18.23", "spl-discriminator", "spl-pod", "spl-program-error", @@ -2296,28 +2393,44 @@ dependencies = [ [[package]] name = "spl-transfer-hook-interface" -version = "0.6.5" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "051d31803f873cabe71aec3c1b849f35248beae5d19a347d93a5c9cccc5d5a9b" +dependencies = [ + "arrayref", + "bytemuck", + "solana-program 1.18.23", + "spl-discriminator", + "spl-pod", + "spl-program-error", + "spl-tlv-account-resolution 0.4.0", + "spl-type-length-value", +] + +[[package]] +name = "spl-transfer-hook-interface" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9b5c08a89838e5a2931f79b17f611857f281a14a2100968a3ccef352cb7414b" +checksum = "7aabdb7c471566f6ddcee724beb8618449ea24b399e58d464d6b5bc7db550259" dependencies = [ "arrayref", "bytemuck", - "solana-program", + "solana-program 1.18.23", "spl-discriminator", "spl-pod", "spl-program-error", - "spl-tlv-account-resolution", + "spl-tlv-account-resolution 0.5.1", "spl-type-length-value", ] [[package]] name = "spl-type-length-value" -version = "0.4.6" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c872f93d0600e743116501eba2d53460e73a12c9a496875a42a7d70e034fe06d" +checksum = "a468e6f6371f9c69aae760186ea9f1a01c2908351b06a5e0026d21cfc4d7ecac" dependencies = [ "bytemuck", - "solana-program", + "solana-program 1.18.23", "spl-discriminator", "spl-pod", "spl-program-error", @@ -2354,9 +2467,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.75" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6af063034fc1935ede7be0122941bafa9bacb949334d090b77ca98b5817c7d9" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -2372,7 +2485,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.77", ] [[package]] @@ -2401,7 +2514,7 @@ checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.77", ] [[package]] @@ -2447,37 +2560,11 @@ dependencies = [ "serde", ] -[[package]] -name = "toml" -version = "0.8.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" -dependencies = [ - "serde", - "serde_spanned", - "toml_datetime", - "toml_edit 0.22.20", -] - [[package]] name = "toml_datetime" version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" -dependencies = [ - "serde", -] - -[[package]] -name = "toml_edit" -version = "0.21.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" -dependencies = [ - "indexmap", - "toml_datetime", - "winnow 0.5.40", -] [[package]] name = "toml_edit" @@ -2486,10 +2573,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "583c44c02ad26b0c3f3066fe629275e50627026c51ac2e595cca4c230ce1ce1d" dependencies = [ "indexmap", - "serde", - "serde_spanned", "toml_datetime", - "winnow 0.6.18", + "winnow", ] [[package]] @@ -2591,7 +2676,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.77", "wasm-bindgen-shared", ] @@ -2613,7 +2698,7 @@ checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.77", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -2738,15 +2823,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" -[[package]] -name = "winnow" -version = "0.5.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" -dependencies = [ - "memchr", -] - [[package]] name = "winnow" version = "0.6.18" @@ -2774,7 +2850,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.77", ] [[package]] @@ -2794,5 +2870,5 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.77", ] diff --git a/README.md b/README.md new file mode 100644 index 0000000..6d10b04 --- /dev/null +++ b/README.md @@ -0,0 +1,193 @@ +# Itheum Core Solana - Itheum Life Bonding Contract V1 (cNFTs) + +## Abstract + +The Itheum Life bonding contract coordinates data creator $ITHEUM token bonding actions and "Liveliness" reputation scores for data creators. + +## Install, Build, Deploy and Test + +Let's run the test once to see what happens. + +### Install `anchor` + +First, make sure that `anchor` and the `solana-cli` is installed: + +Install `avm`: + +```bash +$ cargo install --git https://github.com/coral-xyz/anchor avm --locked --force +... +``` + +Install latest `anchor` version: + +```bash +$ avm install 0.29.0 +... +$ avm use 0.29.0 +... +``` + +install Solana CLI as per here: https://docs.solanalabs.com/cli/install + +#### Verify the Installation + +Check if Anchor is successfully installed: + +```bash +$ anchor --version +anchor-cli 0.29.0 + +$ solana --version +solana-cli 1.18.15 (src:767d24e5; feat:4215500110, client:SolanaLabs) +``` + +### Install Dependencies + +Next, install dependencies: + +``` +$ yarn +``` + +### Build `core-sol-bond-stake-sc` + +Remove any `target` folder if needed or rename if you want to keep it (i.e. version upgrade). You also need to delete it the first time you deploy this program, as only doing this will generate a new program_id needed for next step. For upgrades and followups, you don't need to delete the folder. + +```bash +$ anchor build +``` + +#### Update `program_id` + +Get the public key of the deploy key. This keypair is generated automatically so a different key is expected: + +```bash +$ anchor keys list +core-sol-bond-stake-sc: 4wDs9FnvdksFXy69UKVgi7WWqtYJmbM6TiMCEWY9wJz9 +``` + +Replace the default value of `program_id` with this new value: + +```toml +# Anchor.toml + +[programs.localnet] +core-sol-bond-stake-sc = "DRxp3EJv4hGQDze6Evf515KE1YwVgYNv6PiDp1dqF4pK" + +... +``` + +```rust +// lib.rs + +... + +declare_id!("DRxp3EJv4hGQDze6Evf515KE1YwVgYNv6PiDp1dqF4pK"); + +... +``` + +ALSO, note that you need to "hardcode" the General Admin wallet in constants.rs. This general admin is the one that can call initializeContract. + +``` +pub const ADMIN_PUBKEY: Pubkey = pubkey!("AxDG4CDKrn8s3a1caY69nQYCjR8YnxqjhMPwhUGFKL2Q"); +``` + +We we re-Build the program: (DO NOT delete the target folder this time before running) + +``` +$ anchor build +``` + +### Deploy `core-sol-bond-stake-sc` + +Let's deploy the program using anchor... + +``` +$ solana config set --url localhost +``` + +or else, you can update Anchor.toml `cluster = "devnet"` or `mainnet` (mainnet-beta?) + +you can also toggle deploying wallet by `wallet = "usb://ledger?key=1"` or `wallet = "~/.config/solana/id.json"` + +NOTE: that we can't deploy via Anchor as we found it not too stable, so we used the Solana CLI. + +- First, let's generate a new key pair that we will use to deploy the "buffer", once you have it, save it somewhere safe. You will also need a decent amount of SOL in this account (around 3 should do for this program), as it will be used as "rent" for the code. then we set this as the default solana cli wallet for now (or else it will use our standard id.json wallet). Note that on top of setting the custom wallet, you also need to confirm the RPC and config is correct for the mainnet deployment as it defaults to devnet. + +Update RPC for devnet/testnet/mainnet by editing the config file here: +`vi /Users/markpaul/.config/solana/cli/config.yml` (and then check via `solana config get`) + +Set the default wallet like so: +`solana config set -k /location_of/custom_wallet.json` + +The below keys have been backed-up in storage. + +[devnet] +`solana config set -k /Users/markpaul/Documents/Source/Software/core-sol-bond-stake-sc/devnet_interim_first_deployer_wallet_9tSsTbCZEGMgZYALathtBbqmELY7BefFbQQ4gasXGBAo.json` + +[mainnet] +`solana config set -k /Users/markpaul/Documents/Source/Software/core-sol-bond-stake-sc/interim_buffer_deployer_mainnet_FVnq4TFB39W8xEY36rhwFnScpkGzc59jhL3EuFi6K8Nb.json` + +- Next, we use this key pair to generate the buffer + `solana program write-buffer "./target/deploy/core-sol-bond-stake-sc.so"` + +Note that if you don't have enough SOL, then you will see some error like `Error: Account XXX has insufficient funds for spend (2.80402392 SOL) + fee (0.002 SOL)` + +In this situation, you need to get more SOL.. but you don't lose what you used, you can do this to close the buffer (note that this closes ALL buffers on this authority -- so if this is not the plan, then you can try and recover the buffer after increasing your SOL. The console should give you tips on how to recover the buffer when the error is hit) +`solana program close --buffers` + +if it's a success, the console will give us the buffer like so as an e.g. `Buffer: 85me4UW2ytQmUnzTAHtFvLoZf85D6qhzwgcvUusAByb2` + +[devnet] +https://explorer.solana.com/address/85me4UW2ytQmUnzTAHtFvLoZf85D6qhzwgcvUusAByb2?cluster=devnet + +[testnet] +`Buffer: 4c5UDi4inDoauN9HShH4CrF5SfEmXxnPAZguKvMK4ocd` +https://explorer.solana.com/address/4c5UDi4inDoauN9HShH4CrF5SfEmXxnPAZguKvMK4ocd?cluster=testnet + +[mainnet] +`Buffer: GohVs4cC1WMtTjBgvKA7byWpWsyd9zHy85Z21JtuDPm` +https://explorer.solana.com/address/GohVs4cC1WMtTjBgvKA7byWpWsyd9zHy85Z21JtuDPm + +if you notice, the Deploy Authority, is our custom new HOT wallet. Maybe we want to move this to a Cold wallet for security? if so we can do this: + +[devnet] +`solana program set-buffer-authority 85me4UW2ytQmUnzTAHtFvLoZf85D6qhzwgcvUusAByb2 --new-buffer-authority 4FeJ53a5QZQFroVgQ5pKFNsu7BEV5AoxHMGhsNKhETYt` + +[mainnet] +`solana program set-buffer-authority GohVs4cC1WMtTjBgvKA7byWpWsyd9zHy85Z21JtuDPm --new-buffer-authority 4FeJ53a5QZQFroVgQ5pKFNsu7BEV5AoxHMGhsNKhETYt` + +- And finally, we deploy the program from the buffer: + [devnet] + `solana program deploy --program-id "./target/deploy/core-sol-bond-stake-sc-keypair.json" --buffer 85me4UW2ytQmUnzTAHtFvLoZf85D6qhzwgcvUusAByb2 --upgrade-authority "usb://ledger?key=2"` + +[mainnet] +`solana program deploy --program-id "./target/deploy/core-sol-bond-stake-sc-keypair.json" --buffer GohVs4cC1WMtTjBgvKA7byWpWsyd9zHy85Z21JtuDPm --upgrade-authority "usb://ledger?key=2"` + +You should finally get the program deployed and see something like: + +``` +✅ Approved +Program Id: 4wDs9FnvdksFXy69UKVgi7WWqtYJmbM6TiMCEWY9wJz9 +``` + +### Test `core-sol-bond-stake-sc` + +To test against localnet, update the `cluster` section in `Anchor.toml`: + +```toml +[provider] +cluster = "localnet" +``` + +Because the program needs a constant admin address, the tests will use the `UNIT_TEST_PRIVATE_KEY` stored in the `.env` file. This key is used to sign transactions in the tests. +Copy the content from `env.copy` to `.env`. Copy the `UNIT_TEST_PUBLIC_KEY` from the `env.copy` to the `constants.rs` file where the `ADMIN_PUBKEY` constant is defined. + +> [!WARNING] +> In order to run the tests, you need to comment out the cNFT leaf owner check in bond endpoint at `src/bond.rs` line `185` - `201`. This check can be tested separately on devnet. + +``` +$ anchor test +``` diff --git a/env.copy b/env.copy new file mode 100644 index 0000000..f08f1cd --- /dev/null +++ b/env.copy @@ -0,0 +1,2 @@ +UNIT_TEST_PRIVATE_KEY="65,173,180,18,162,174,69,191,200,220,10,70,138,19,244,181,144,100,7,190,30,72,103,181,16,103,198,82,154,74,30,78,221,109,141,227,162,187,63,92,28,188,75,184,3,68,173,194,80,181,59,58,154,160,111,196,193,133,82,55,54,43,94,122" +UNIT_TEST_PUBLIC_KEY="FuMzWZ2bi7QmquTzCrjvsEbmyCt1tF78idxGJQhjTiWu" \ No newline at end of file diff --git a/interactions/index.ts b/interactions/index.ts new file mode 100644 index 0000000..d2d885e --- /dev/null +++ b/interactions/index.ts @@ -0,0 +1,308 @@ +import { + AccountMeta, + Connection, + Keypair, + PublicKey, + Transaction, + clusterApiUrl, + sendAndConfirmTransaction, +} from '@solana/web3.js' +import * as anchor from '@coral-xyz/anchor' +import {CoreSolBondStakeSc, IDL} from '../target/types/core_sol_bond_stake_sc' +import { + ASSOCIATED_TOKEN_PROGRAM_ID, + createAssociatedTokenAccountInstruction, + getAssociatedTokenAddress, + getOrCreateAssociatedTokenAccount, + TOKEN_PROGRAM_ID, +} from '@solana/spl-token' +import {bs58} from '@coral-xyz/anchor/dist/cjs/utils/bytes' +import {SPL_ACCOUNT_COMPRESSION_PROGRAM_ID} from '@metaplex-foundation/mpl-bubblegum' + +require('dotenv').config() + +function decode(stuff: string) { + return bufferToArray(bs58.decode(stuff)) +} +function bufferToArray(buffer: Buffer): number[] { + const nums: number[] = [] + for (let i = 0; i < buffer.length; i++) { + nums.push(buffer[i]) + } + return nums +} +const mapProof = (proof: string[]): AccountMeta[] => { + return proof.map((node) => ({ + pubkey: new PublicKey(node), + isSigner: false, + isWritable: false, + })) +} + +const ITHEUM_TOKEN_DEVNET = 'iTH89rapYE2GG4B77UjoEqnY7bRAPQrUs6LRAXQEHUo' + +const programId = new PublicKey('4V8Luy9PjMdzF5VzNLGKH5uxXUXeBFooayEHXBGpXnxo') +const connection = new Connection(clusterApiUrl('devnet'), 'confirmed') + +const program = new anchor.Program(IDL, programId, { + connection, +}) + +const bondConfigPda1 = PublicKey.findProgramAddressSync( + [Buffer.from('bond_config'), Buffer.from([1])], + programId +)[0] + +const rewardsConfigPda = PublicKey.findProgramAddressSync( + [Buffer.from('rewards_config')], + programId +)[0] + +const vaultConfig = PublicKey.findProgramAddressSync( + [Buffer.from('vault_config')], + programId +)[0] + +// Extract the private key from the environment variable +const PRIVATE_KEY_STR = process.env.ANCHOR_WALLET +const privateKeys = PRIVATE_KEY_STR.split(',').map(Number) +const admin = Keypair.fromSecretKey(Uint8Array.from(privateKeys)) +// Create the transaction using Anchor's methods API +const initializeContract = async () => { + const transaction = await program.methods + .initializeContract( + 1, + new anchor.BN(43200), // Lock period (half a day) + new anchor.BN(1000e9), // Example parameter + new anchor.BN(1e4), // Example parameter + new anchor.BN(8000), // Max APR + new anchor.BN(8000) // Withdraw penalty + ) + .signers([admin]) + .accounts({ + bondConfig: bondConfigPda1, + rewardsConfig: rewardsConfigPda, + merkleTree: new PublicKey('GpseMQCGcVHt2QxhieSGiEsuS6G5sKpEHeAWYwUx5z5c'), // Replace with your actual merkle tree address + authority: admin.publicKey, // The admin will act as the authority + }) + .transaction() + + const transactionSignature = await connection.sendTransaction(transaction, [ + admin, + ]) + + console.log(transactionSignature) +} + +// initializeContract() + +const initializeVault = async () => { + const vault_ata = await getOrCreateAssociatedTokenAccount( + connection, + admin, + new PublicKey(ITHEUM_TOKEN_DEVNET), + vaultConfig, + true, + 'finalized' + ) + + const tx = await program.methods + .initializeVault() + .signers([admin]) + .accounts({ + vaultConfig: vaultConfig, + vault: vault_ata.address, + mintOfToken: new PublicKey(ITHEUM_TOKEN_DEVNET), + authority: admin.publicKey, + }) + .transaction() + + const transactionSignature = await connection.sendTransaction(tx, [admin]) + + console.log(transactionSignature) +} + +// initializeVault() + +const setBondStateActive = async () => { + const tx = await program.methods + .setBondStateActive(1) + .signers([admin]) + .accounts({ + bondConfig: bondConfigPda1, + authority: admin.publicKey, + }) + .transaction() + + const transactionSignature = await connection.sendTransaction(tx, [admin]) + + console.log(transactionSignature) +} + +// setBondStateActive() + +const addRewards = async (amount: anchor.BN) => { + const vault_ata = await getAssociatedTokenAddress( + new PublicKey(ITHEUM_TOKEN_DEVNET), + vaultConfig, + true + ) + + const admin_ata = await getAssociatedTokenAddress( + new PublicKey(ITHEUM_TOKEN_DEVNET), + admin.publicKey, + true + ) + + const tx = await program.methods + .addRewards(amount) + .signers([admin]) + .accounts({ + rewardsConfig: rewardsConfigPda, + vaultConfig: vaultConfig, + vault: vault_ata, + mintOfToken: new PublicKey(ITHEUM_TOKEN_DEVNET), + authority: admin.publicKey, + authorityTokenAccount: admin_ata, + }) + .transaction() + + const transactionSignature = await connection.sendTransaction(tx, [admin]) + + console.log(transactionSignature) +} + +// addRewards(new anchor.BN(5000000e9)) + +const object_response = + '{"assetId":"F1h2kBVpb3bPeNYiMAQxUBrURxNXtjV25B6He9S63Xre","leafSchema":{"__kind":"V1","id":"F1h2kBVpb3bPeNYiMAQxUBrURxNXtjV25B6He9S63Xre","owner":"7jwJ1V27b91GoeWNuNcjVVZy2kv4PUab6MyZoKcwZy5o","delegate":"7jwJ1V27b91GoeWNuNcjVVZy2kv4PUab6MyZoKcwZy5o","nonce":28,"dataHash":{"0":69,"1":204,"2":218,"3":52,"4":77,"5":10,"6":199,"7":233,"8":245,"9":87,"10":127,"11":45,"12":212,"13":64,"14":124,"15":209,"16":147,"17":64,"18":243,"19":252,"20":90,"21":115,"22":189,"23":33,"24":9,"25":156,"26":190,"27":136,"28":242,"29":182,"30":253,"31":37},"creatorHash":{"0":77,"1":213,"2":154,"3":225,"4":97,"5":203,"6":74,"7":63,"8":198,"9":140,"10":244,"11":87,"12":144,"13":15,"14":74,"15":46,"16":161,"17":9,"18":203,"19":202,"20":242,"21":175,"22":172,"23":151,"24":43,"25":195,"26":151,"27":143,"28":107,"29":138,"30":102,"31":27}},"index":28,"root":[153,5,27,166,131,202,163,237,254,166,244,131,17,183,239,54,26,192,126,177,64,187,189,26,220,44,163,70,99,162,241,134],"proof":{"root":"BJKtvp9MjxNT7M5cpJ5vsEwP9i6qupkThTUWZHEk8ni1","proof":["11111111111111111111111111111111","Cf5tmmFZ4D31tviuJezHdFLf5WF7yFvzfxNyftKsqTwr","DJ1kkERH23xtXVC5w4JM8VuLaGBFMSzjnEhu8ds6BiWR","7kieKvZEkYzsP2KFniw1R94R5xLtxiQEfn1jJY9qrb6a","CX6YjLNphY2mUgDCt2MSWGUWmDB8aoJEoRiabxFgjQDb","zLUDhASAn7WA1Aqc724azRpZjKCjMQNATApe74JMg8C","ABnEXHmveD6iuMwfw2po7t6TPjn5kYMVwYJMi3fa9K91","JDh7eiWiUWtiWn623iybHqjQ6AQ6c2Czz8m6ZxwSCkta","BFvmeiEuzAYcMR8YxcuCMGYPDpjcmP5hsNbcswgQ8pMc","EvxphsdRErrDMs9nhFfF4nzq8i1C2KSogA7uB96TPpPR","HpMJWAzQv9HFgHBqY1o8V1B27sCYPFHJdGivDA658jEL","HjnrJn5vBUUzpCxzjjM9ZnCPuXei2cXKJjX468B9yWD7","4YCF1CSyTXm1Yi9W9JeYevawupkomdgy2dLxEBHL9euq","E3oMtCuPEauftdZLX8EZ8YX7BbFzpBCVRYEiLxwPJLY2"],"node_index":16412,"leaf":"BTVmcRPBuutDxfGhxcCXGHdgHCEhZrvdxj36CFG7arzt","tree_id":"GpseMQCGcVHt2QxhieSGiEsuS6G5sKpEHeAWYwUx5z5c"}}' + +const object2_response = + '{"assetId":"AEdTGc4kWLco9vkWQrAUKbtzzPva9QmWYJMxHeBvjJtq","leafSchema":{"__kind":"V1","id":"AEdTGc4kWLco9vkWQrAUKbtzzPva9QmWYJMxHeBvjJtq","owner":"BAC786427LZg4iK2TaLaHVStYhcwHxWingCUGqzMatei","delegate":"BAC786427LZg4iK2TaLaHVStYhcwHxWingCUGqzMatei","nonce":32,"dataHash":{"0":69,"1":204,"2":218,"3":52,"4":77,"5":10,"6":199,"7":233,"8":245,"9":87,"10":127,"11":45,"12":212,"13":64,"14":124,"15":209,"16":147,"17":64,"18":243,"19":252,"20":90,"21":115,"22":189,"23":33,"24":9,"25":156,"26":190,"27":136,"28":242,"29":182,"30":253,"31":37},"creatorHash":{"0":77,"1":213,"2":154,"3":225,"4":97,"5":203,"6":74,"7":63,"8":198,"9":140,"10":244,"11":87,"12":144,"13":15,"14":74,"15":46,"16":161,"17":9,"18":203,"19":202,"20":242,"21":175,"22":172,"23":151,"24":43,"25":195,"26":151,"27":143,"28":107,"29":138,"30":102,"31":27}},"index":32,"root":[95,115,57,29,46,187,206,174,111,140,123,137,116,223,51,146,251,0,162,65,128,1,165,7,4,218,168,48,18,247,192,201],"proof":{"root":"7RbdqkiSF4QmMr65we9QPgPA5i49CeiDhoMHBphaFm84","proof":["11111111111111111111111111111111","Cf5tmmFZ4D31tviuJezHdFLf5WF7yFvzfxNyftKsqTwr","DAbAU9srHpEUogXWuhy5VZ7g8UX9STymELtndcx1xgP1","3HCYqQRcQSChEuAw1ybNYHibrTNNjzbYzm56cmEmivB6","GSz87YKd3YoZWcEKhnjSsYJwv8o5aWGdBdGGYUphRfTh","4K6tKnbfNar36yQDrWvb2KSjm4y6C8aUAAcXq94BoxkG","ABnEXHmveD6iuMwfw2po7t6TPjn5kYMVwYJMi3fa9K91","JDh7eiWiUWtiWn623iybHqjQ6AQ6c2Czz8m6ZxwSCkta","BFvmeiEuzAYcMR8YxcuCMGYPDpjcmP5hsNbcswgQ8pMc","EvxphsdRErrDMs9nhFfF4nzq8i1C2KSogA7uB96TPpPR","HpMJWAzQv9HFgHBqY1o8V1B27sCYPFHJdGivDA658jEL","HjnrJn5vBUUzpCxzjjM9ZnCPuXei2cXKJjX468B9yWD7","4YCF1CSyTXm1Yi9W9JeYevawupkomdgy2dLxEBHL9euq","E3oMtCuPEauftdZLX8EZ8YX7BbFzpBCVRYEiLxwPJLY2"],"node_index":16416,"leaf":"BJ4wXh1HvjmJV8cCuQn5PuFxcL7TyJHnPCKRZwGHVV7A","tree_id":"GpseMQCGcVHt2QxhieSGiEsuS6G5sKpEHeAWYwUx5z5c"}}' + +const cnft_data = JSON.parse(object2_response) + +const initializeAddress = async () => { + const pk = + 'rDQ9vxwjaqrXQZk6Y6CXTAsoVMd2C33VLejE8p1Gd3Xgobyk5RKrGWXZ9H6CsZsNCVxStBMVXV9nKByKTcEKCUD' + + const user = Keypair.fromSecretKey(Uint8Array.from(bs58.decode(pk))) + + const addressBondsRewards = PublicKey.findProgramAddressSync( + [Buffer.from('address_bonds_rewards'), user.publicKey.toBuffer()], + program.programId + )[0] + + const transaction = await program.methods + .initializeAddress() + .signers([user]) + .accounts({ + addressBondsRewards: addressBondsRewards, + rewardsConfig: rewardsConfigPda, + authority: user.publicKey, + }) + .transaction() + + const transactionSignature = await connection.sendTransaction(transaction, [ + user, + ]) + + console.log(transactionSignature) +} + +// initializeAddress() + +const bond = async () => { + const asset_id = cnft_data.assetId + + const proofPathAsAccounts = mapProof(cnft_data.proof.proof) + + const root = decode(cnft_data.proof.root) + + const dataHash = Object.values(cnft_data.leafSchema.dataHash) as number[] + + const creatorHash = Object.values( + cnft_data.leafSchema.creatorHash as number[] + ) + + const nonce = cnft_data.leafSchema.nonce + const index = cnft_data.index + + const pk = + 'rDQ9vxwjaqrXQZk6Y6CXTAsoVMd2C33VLejE8p1Gd3Xgobyk5RKrGWXZ9H6CsZsNCVxStBMVXV9nKByKTcEKCUD' + + const user = Keypair.fromSecretKey(Uint8Array.from(bs58.decode(pk))) + + console.log(user.publicKey.toBase58()) + + const userBondsRewards = PublicKey.findProgramAddressSync( + [Buffer.from('address_bonds_rewards'), user.publicKey.toBuffer()], + program.programId + )[0] + + const bond1 = PublicKey.findProgramAddressSync( + [Buffer.from('bond'), user.publicKey.toBuffer(), Buffer.from([2])], + program.programId + )[0] + + const assetUsage = PublicKey.findProgramAddressSync( + [new PublicKey(asset_id).toBuffer()], + program.programId + )[0] + + const vault_ata = await getAssociatedTokenAddress( + new PublicKey(ITHEUM_TOKEN_DEVNET), + vaultConfig, + true + ) + + const user_itheum_ata = await getAssociatedTokenAddress( + new PublicKey(ITHEUM_TOKEN_DEVNET), + user.publicKey, + true + ) + + const transaction = await program.methods + .bond( + 1, + 2, + new anchor.BN(1000e9), + new PublicKey(asset_id), + true, + root, + dataHash, + creatorHash, + new anchor.BN(nonce), + index + ) + .signers([user]) + .accounts({ + addressBondsRewards: userBondsRewards, + assetUsage: assetUsage, + bond: bond1, + bondConfig: bondConfigPda1, + rewardsConfig: rewardsConfigPda, + vaultConfig: vaultConfig, + vault: vault_ata, + mintOfTokenSent: new PublicKey(ITHEUM_TOKEN_DEVNET), + authority: user.publicKey, + merkleTree: new PublicKey('GpseMQCGcVHt2QxhieSGiEsuS6G5sKpEHeAWYwUx5z5c'), + authorityTokenAccount: user_itheum_ata, + systemProgram: anchor.web3.SystemProgram.programId, + tokenProgram: TOKEN_PROGRAM_ID, + associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ID, + compressionProgram: SPL_ACCOUNT_COMPRESSION_PROGRAM_ID, + }) + .remainingAccounts(proofPathAsAccounts) + .transaction() + + const transactionSignature = await connection.sendTransaction( + transaction, + [user], + {skipPreflight: true} + ) + + console.log(transactionSignature) +} + +bond() diff --git a/package-lock.json b/package-lock.json index e9d9a46..0bb9f9d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,17 +5,18 @@ "packages": { "": { "dependencies": { - "@coral-xyz/anchor": "^0.30.1", - "@metaplex-foundation/mpl-bubblegum": "^4.1.0", + "@coral-xyz/anchor": "^0.29.0", "@metaplex-foundation/mpl-token-metadata": "^3.2.1", "@metaplex-foundation/umi": "^0.8.10", - "@metaplex-foundation/umi-bundle-defaults": "^0.8.10", "@metaplex-foundation/umi-web3js-adapters": "^0.8.10", "@solana/spl-token": "^0.4.8", "@solana/web3.js": "^1.95.2", "dotenv": "^16.4.5" }, "devDependencies": { + "@metaplex-foundation/digital-asset-standard-api": "^1.0.4", + "@metaplex-foundation/mpl-bubblegum": "^4.2.1", + "@metaplex-foundation/umi-bundle-defaults": "^0.9.2", "@types/bn.js": "^5.1.0", "@types/chai": "^4.3.0", "@types/mocha": "^9.0.0", @@ -23,6 +24,7 @@ "mocha": "^9.0.3", "prettier": "^2.6.2", "ts-mocha": "^10.0.0", + "ts-node": "^10.9.2", "typescript": "^4.3.5" } }, @@ -38,12 +40,11 @@ } }, "node_modules/@coral-xyz/anchor": { - "version": "0.30.1", - "resolved": "https://registry.npmjs.org/@coral-xyz/anchor/-/anchor-0.30.1.tgz", - "integrity": "sha512-gDXFoF5oHgpriXAaLpxyWBHdCs8Awgf/gLHIo6crv7Aqm937CNdY+x+6hoj7QR5vaJV7MxWSQ0NGFzL3kPbWEQ==", + "version": "0.29.0", + "resolved": "https://registry.npmjs.org/@coral-xyz/anchor/-/anchor-0.29.0.tgz", + "integrity": "sha512-eny6QNG0WOwqV0zQ7cs/b1tIuzZGmP7U7EcH+ogt4Gdbl8HDmIYVMh/9aTmYZPaFWjtUaI8qSn73uYEXWfATdA==", "dependencies": { - "@coral-xyz/anchor-errors": "^0.30.1", - "@coral-xyz/borsh": "^0.30.1", + "@coral-xyz/borsh": "^0.29.0", "@noble/hashes": "^1.3.1", "@solana/web3.js": "^1.68.0", "bn.js": "^5.1.2", @@ -62,18 +63,10 @@ "node": ">=11" } }, - "node_modules/@coral-xyz/anchor-errors": { - "version": "0.30.1", - "resolved": "https://registry.npmjs.org/@coral-xyz/anchor-errors/-/anchor-errors-0.30.1.tgz", - "integrity": "sha512-9Mkradf5yS5xiLWrl9WrpjqOrAV+/W2RQHDlbnAZBivoGpOs1ECjoDCkVk4aRG8ZdiFiB8zQEVlxf+8fKkmSfQ==", - "engines": { - "node": ">=10" - } - }, "node_modules/@coral-xyz/borsh": { - "version": "0.30.1", - "resolved": "https://registry.npmjs.org/@coral-xyz/borsh/-/borsh-0.30.1.tgz", - "integrity": "sha512-aaxswpPrCFKl8vZTbxLssA2RvwX2zmKLlRCIktJOwW+VpVwYtXRtlWiIP+c2pPRKneiTiWCN2GEMSH9j1zTlWQ==", + "version": "0.29.0", + "resolved": "https://registry.npmjs.org/@coral-xyz/borsh/-/borsh-0.29.0.tgz", + "integrity": "sha512-s7VFVa3a0oqpkuRloWVPdCK7hMbAMY270geZOGfCnaqexrP5dTIpbEHL33req6IYPPJ0hYa71cdvJ1h6V55/oQ==", "dependencies": { "bn.js": "^5.1.2", "buffer-layout": "^1.2.0" @@ -85,10 +78,23 @@ "@solana/web3.js": "^1.68.0" } }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/@ethereumjs/rlp": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/@ethereumjs/rlp/-/rlp-4.0.1.tgz", "integrity": "sha512-tqsQiBQDQdmPWE1xkkBq4rlSW5QZpLOUJ5RJh2/9fug+q9tnUhuZoVLk7s0scUIKTOzEtR72DFBXI4WiZcMpvw==", + "dev": true, "bin": { "rlp": "bin/rlp" }, @@ -100,6 +106,7 @@ "version": "8.1.0", "resolved": "https://registry.npmjs.org/@ethereumjs/util/-/util-8.1.0.tgz", "integrity": "sha512-zQ0IqbdX8FZ9aw11vP+dZkKDkS+kgIvQPHnSAXzP9pLu+Rfu3D3XEeLbicvoXJTYnhZiPmsZUxgdzXwNKxRPbA==", + "dev": true, "dependencies": { "@ethereumjs/rlp": "^4.0.1", "ethereum-cryptography": "^2.0.0", @@ -109,10 +116,36 @@ "node": ">=14" } }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, "node_modules/@metaplex-foundation/digital-asset-standard-api": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/@metaplex-foundation/digital-asset-standard-api/-/digital-asset-standard-api-1.0.4.tgz", "integrity": "sha512-YSYyMnIoKNykDZTXsSCeiIOJ7NT5Ke2pzghXDsinRwHvwIZWv+zY5kJQBvTglAzYlt/GaI+noAhUZXXmSbp07A==", + "dev": true, "dependencies": { "package.json": "^2.0.1" }, @@ -121,12 +154,13 @@ } }, "node_modules/@metaplex-foundation/mpl-bubblegum": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@metaplex-foundation/mpl-bubblegum/-/mpl-bubblegum-4.2.0.tgz", - "integrity": "sha512-PKnfRI5bAKI4R+Hv2mLbkSDfWabYpfBPKQ+ji6Knufd1p3g0RuLQuDsZ6y3JqET/rfaEMaEx8AhNnMsm9mXCFg==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@metaplex-foundation/mpl-bubblegum/-/mpl-bubblegum-4.2.1.tgz", + "integrity": "sha512-r9kHrVmkzJApbXwd7cmJyO0mAV3qsJaTjv5ks6PUT1Bzjj9QCvlJYg2UYQJLUTcrY5TjE9wXLpwUqNgllXH/Cw==", + "dev": true, "dependencies": { "@metaplex-foundation/digital-asset-standard-api": "^1.0.4", - "@metaplex-foundation/mpl-token-metadata": "3.0.0-alpha.27", + "@metaplex-foundation/mpl-token-metadata": "3.2.1", "@metaplex-foundation/mpl-toolbox": "^0.9.0", "@noble/hashes": "^1.3.1", "merkletreejs": "^0.3.9" @@ -135,17 +169,6 @@ "@metaplex-foundation/umi": ">= 0.8.9 < 1" } }, - "node_modules/@metaplex-foundation/mpl-bubblegum/node_modules/@metaplex-foundation/mpl-token-metadata": { - "version": "3.0.0-alpha.27", - "resolved": "https://registry.npmjs.org/@metaplex-foundation/mpl-token-metadata/-/mpl-token-metadata-3.0.0-alpha.27.tgz", - "integrity": "sha512-MSERz5HB2XZ/K+FOMh0tPeqcZZEpGVzdy7e+Cy3MHg7x52JtbGBDtWIoxBJn1OBZayCBfX9gytEoqrXe2YRGqQ==", - "dependencies": { - "@metaplex-foundation/mpl-toolbox": "^0.9.0" - }, - "peerDependencies": { - "@metaplex-foundation/umi": "^0.8.2" - } - }, "node_modules/@metaplex-foundation/mpl-token-metadata": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/@metaplex-foundation/mpl-token-metadata/-/mpl-token-metadata-3.2.1.tgz", @@ -176,54 +199,71 @@ } }, "node_modules/@metaplex-foundation/umi-bundle-defaults": { - "version": "0.8.10", - "resolved": "https://registry.npmjs.org/@metaplex-foundation/umi-bundle-defaults/-/umi-bundle-defaults-0.8.10.tgz", - "integrity": "sha512-eqt5uJlDb6SNV0qB7BiTWbRAk1Mnl22ve3qHRxalqvDGQ2bklEY6RzBZWC+R/eQnJ+pVsp7Dd34bhxY3I+Ht7g==", - "dependencies": { - "@metaplex-foundation/umi-downloader-http": "^0.8.10", - "@metaplex-foundation/umi-eddsa-web3js": "^0.8.10", - "@metaplex-foundation/umi-http-fetch": "^0.8.10", - "@metaplex-foundation/umi-program-repository": "^0.8.10", - "@metaplex-foundation/umi-rpc-chunk-get-accounts": "^0.8.10", - "@metaplex-foundation/umi-rpc-web3js": "^0.8.10", - "@metaplex-foundation/umi-serializer-data-view": "^0.8.10", - "@metaplex-foundation/umi-transaction-factory-web3js": "^0.8.10" + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/@metaplex-foundation/umi-bundle-defaults/-/umi-bundle-defaults-0.9.2.tgz", + "integrity": "sha512-kV3tfvgvRjVP1p9OFOtH+ibOtN9omVJSwKr0We4/9r45e5LTj+32su0V/rixZUkG1EZzzOYBsxhtIE0kIw/Hrw==", + "dev": true, + "dependencies": { + "@metaplex-foundation/umi-downloader-http": "^0.9.2", + "@metaplex-foundation/umi-eddsa-web3js": "^0.9.2", + "@metaplex-foundation/umi-http-fetch": "^0.9.2", + "@metaplex-foundation/umi-program-repository": "^0.9.2", + "@metaplex-foundation/umi-rpc-chunk-get-accounts": "^0.9.2", + "@metaplex-foundation/umi-rpc-web3js": "^0.9.2", + "@metaplex-foundation/umi-serializer-data-view": "^0.9.2", + "@metaplex-foundation/umi-transaction-factory-web3js": "^0.9.2" }, "peerDependencies": { - "@metaplex-foundation/umi": "^0.8.10", + "@metaplex-foundation/umi": "^0.9.2", "@solana/web3.js": "^1.72.0" } }, "node_modules/@metaplex-foundation/umi-downloader-http": { - "version": "0.8.10", - "resolved": "https://registry.npmjs.org/@metaplex-foundation/umi-downloader-http/-/umi-downloader-http-0.8.10.tgz", - "integrity": "sha512-i0YbSaPvo0/49XazVL+jmm3PpRSeE4bc8E1TUUsUCXrpb6lSup6u0cx7vYij2mis91UDhdO8hTgdxFwNdqvFHQ==", + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/@metaplex-foundation/umi-downloader-http/-/umi-downloader-http-0.9.2.tgz", + "integrity": "sha512-tzPT9hBwenzTzAQg07rmsrqZfgguAXELbcJrsYMoASp5VqWFXYIP00g94KET6XLjWUXH4P1J2zoa6hGennPXHA==", + "dev": true, "peerDependencies": { - "@metaplex-foundation/umi": "^0.8.10" + "@metaplex-foundation/umi": "^0.9.2" } }, "node_modules/@metaplex-foundation/umi-eddsa-web3js": { - "version": "0.8.10", - "resolved": "https://registry.npmjs.org/@metaplex-foundation/umi-eddsa-web3js/-/umi-eddsa-web3js-0.8.10.tgz", - "integrity": "sha512-2CLsuQ67oPKczB7RuG07/Ro1rrW25vGZArren20/zBTgHubGIuFW7V8e9qZDqkHDt1nFecxrX55g0fNtQaU40g==", + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/@metaplex-foundation/umi-eddsa-web3js/-/umi-eddsa-web3js-0.9.2.tgz", + "integrity": "sha512-hhPCxXbYIp4BC4z9gK78sXpWLkNSrfv4ndhF5ruAkdIp7GcRVYKj0QnOUO6lGYGiIkNlw20yoTwOe1CT//OfTQ==", + "dev": true, "dependencies": { - "@metaplex-foundation/umi-web3js-adapters": "^0.8.10", + "@metaplex-foundation/umi-web3js-adapters": "^0.9.2", "@noble/curves": "^1.0.0" }, "peerDependencies": { - "@metaplex-foundation/umi": "^0.8.10", + "@metaplex-foundation/umi": "^0.9.2", + "@solana/web3.js": "^1.72.0" + } + }, + "node_modules/@metaplex-foundation/umi-eddsa-web3js/node_modules/@metaplex-foundation/umi-web3js-adapters": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/@metaplex-foundation/umi-web3js-adapters/-/umi-web3js-adapters-0.9.2.tgz", + "integrity": "sha512-RQqUTtHYY9fmEMnq7s3Hiv/81flGaoI0ZVVoafnFVaQLnxU6QBKxtboRZHk43XtD9CiFh5f9izrMJX7iK7KlOA==", + "dev": true, + "dependencies": { + "buffer": "^6.0.3" + }, + "peerDependencies": { + "@metaplex-foundation/umi": "^0.9.2", "@solana/web3.js": "^1.72.0" } }, "node_modules/@metaplex-foundation/umi-http-fetch": { - "version": "0.8.10", - "resolved": "https://registry.npmjs.org/@metaplex-foundation/umi-http-fetch/-/umi-http-fetch-0.8.10.tgz", - "integrity": "sha512-9QkVMaM8A8JFaTSanVJT3R7IzeLn05xrK7fFnfCTASaTvk+7Dj8ZsgXQjuyCi1pXQrMN+EsREn2NE/tn48ffMQ==", + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/@metaplex-foundation/umi-http-fetch/-/umi-http-fetch-0.9.2.tgz", + "integrity": "sha512-YCZuBu24T9ZzEDe4+w12LEZm/fO9pkyViZufGgASC5NX93814Lvf6Ssjn/hZzjfA7CvZbvLFbmujc6CV3Q/m9Q==", + "dev": true, "dependencies": { "node-fetch": "^2.6.7" }, "peerDependencies": { - "@metaplex-foundation/umi": "^0.8.10" + "@metaplex-foundation/umi": "^0.9.2" } }, "node_modules/@metaplex-foundation/umi-options": { @@ -232,11 +272,12 @@ "integrity": "sha512-jSQ61sZMPSAk/TXn8v8fPqtz3x8d0/blVZXLLbpVbo2/T5XobiI6/MfmlUosAjAUaQl6bHRF8aIIqZEFkJiy4A==" }, "node_modules/@metaplex-foundation/umi-program-repository": { - "version": "0.8.10", - "resolved": "https://registry.npmjs.org/@metaplex-foundation/umi-program-repository/-/umi-program-repository-0.8.10.tgz", - "integrity": "sha512-zw+UMOg9z3xqqeosRfctmcnaDYkaoMMvqhu7Vpwt7K9tpVtMaMT5yei29ORvaYpiEVG5hZSbywr/vQsNY0EV9g==", + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/@metaplex-foundation/umi-program-repository/-/umi-program-repository-0.9.2.tgz", + "integrity": "sha512-g3+FPqXEmYsBa8eETtUE2gb2Oe3mqac0z3/Ur1TvAg5TtIy3mzRzOy/nza+sgzejnfcxcVg835rmpBaxpBnjDA==", + "dev": true, "peerDependencies": { - "@metaplex-foundation/umi": "^0.8.10" + "@metaplex-foundation/umi": "^0.9.2" } }, "node_modules/@metaplex-foundation/umi-public-keys": { @@ -248,31 +289,47 @@ } }, "node_modules/@metaplex-foundation/umi-rpc-chunk-get-accounts": { - "version": "0.8.10", - "resolved": "https://registry.npmjs.org/@metaplex-foundation/umi-rpc-chunk-get-accounts/-/umi-rpc-chunk-get-accounts-0.8.10.tgz", - "integrity": "sha512-+fiQ+yza7C5N/vvCzDxoXkdE8NDg/Q5FOWCa4ysuupHB4P3/Ah+M5zJdB739I047ykIi+Fy/+JqmWsSZQsHNHA==", + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/@metaplex-foundation/umi-rpc-chunk-get-accounts/-/umi-rpc-chunk-get-accounts-0.9.2.tgz", + "integrity": "sha512-YRwVf6xH0jPBAUgMhEPi+UbjioAeqTXmjsN2TnmQCPAmHbrHrMRj0rlWYwFLWAgkmoxazYrXP9lqOFRrfOGAEA==", + "dev": true, "peerDependencies": { - "@metaplex-foundation/umi": "^0.8.10" + "@metaplex-foundation/umi": "^0.9.2" } }, "node_modules/@metaplex-foundation/umi-rpc-web3js": { - "version": "0.8.10", - "resolved": "https://registry.npmjs.org/@metaplex-foundation/umi-rpc-web3js/-/umi-rpc-web3js-0.8.10.tgz", - "integrity": "sha512-+60uxlX1OcThL2UIW9dbcy0Ihr011ggxkQYSxc1qh4qitgD9wrZZ/v9nX4tzEN88a52UJGhH5G3SF6CNmqy4aw==", + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/@metaplex-foundation/umi-rpc-web3js/-/umi-rpc-web3js-0.9.2.tgz", + "integrity": "sha512-MqcsBz8B4wGl6jxsf2Jo/rAEpYReU9VCSR15QSjhvADHMmdFxCIZCCAgE+gDE2Vuanfl437VhOcP3g5Uw8C16Q==", + "dev": true, "dependencies": { - "@metaplex-foundation/umi-web3js-adapters": "^0.8.10" + "@metaplex-foundation/umi-web3js-adapters": "^0.9.2" }, "peerDependencies": { - "@metaplex-foundation/umi": "^0.8.10", + "@metaplex-foundation/umi": "^0.9.2", + "@solana/web3.js": "^1.72.0" + } + }, + "node_modules/@metaplex-foundation/umi-rpc-web3js/node_modules/@metaplex-foundation/umi-web3js-adapters": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/@metaplex-foundation/umi-web3js-adapters/-/umi-web3js-adapters-0.9.2.tgz", + "integrity": "sha512-RQqUTtHYY9fmEMnq7s3Hiv/81flGaoI0ZVVoafnFVaQLnxU6QBKxtboRZHk43XtD9CiFh5f9izrMJX7iK7KlOA==", + "dev": true, + "dependencies": { + "buffer": "^6.0.3" + }, + "peerDependencies": { + "@metaplex-foundation/umi": "^0.9.2", "@solana/web3.js": "^1.72.0" } }, "node_modules/@metaplex-foundation/umi-serializer-data-view": { - "version": "0.8.10", - "resolved": "https://registry.npmjs.org/@metaplex-foundation/umi-serializer-data-view/-/umi-serializer-data-view-0.8.10.tgz", - "integrity": "sha512-DVKUQw7FEfpRIE9RF4YU73Mwlaf42RAWDgcycNiYFWpj/FLRebNr+2NT3ALYlOqXsAchnCAYjlQVxCB0Sopn9Q==", + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/@metaplex-foundation/umi-serializer-data-view/-/umi-serializer-data-view-0.9.2.tgz", + "integrity": "sha512-5vGptadJxUxvUcyrwFZxXlEc6Q7AYySBesizCtrBFUY8w8PnF2vzmS45CP1MLySEATNH6T9mD4Rs0tLb87iQyA==", + "dev": true, "peerDependencies": { - "@metaplex-foundation/umi": "^0.8.10" + "@metaplex-foundation/umi": "^0.9.2" } }, "node_modules/@metaplex-foundation/umi-serializers": { @@ -309,14 +366,28 @@ } }, "node_modules/@metaplex-foundation/umi-transaction-factory-web3js": { - "version": "0.8.10", - "resolved": "https://registry.npmjs.org/@metaplex-foundation/umi-transaction-factory-web3js/-/umi-transaction-factory-web3js-0.8.10.tgz", - "integrity": "sha512-hnkDKdtuZgY6DKH6aSEd6UrZGi5/WvfYqJUWeM8SVl1/8GhNypNKWvuppvFHpU9X2tLXuF4JSG4TVxAuIs9LBQ==", + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/@metaplex-foundation/umi-transaction-factory-web3js/-/umi-transaction-factory-web3js-0.9.2.tgz", + "integrity": "sha512-fR1Kf21uylMFd1Smkltmj4jTNxhqSWf416owsJ+T+cvJi2VCOcOwq/3UFzOrpz78fA0RhsajKYKj0HYsRnQI1g==", + "dev": true, "dependencies": { - "@metaplex-foundation/umi-web3js-adapters": "^0.8.10" + "@metaplex-foundation/umi-web3js-adapters": "^0.9.2" }, "peerDependencies": { - "@metaplex-foundation/umi": "^0.8.10", + "@metaplex-foundation/umi": "^0.9.2", + "@solana/web3.js": "^1.72.0" + } + }, + "node_modules/@metaplex-foundation/umi-transaction-factory-web3js/node_modules/@metaplex-foundation/umi-web3js-adapters": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/@metaplex-foundation/umi-web3js-adapters/-/umi-web3js-adapters-0.9.2.tgz", + "integrity": "sha512-RQqUTtHYY9fmEMnq7s3Hiv/81flGaoI0ZVVoafnFVaQLnxU6QBKxtboRZHk43XtD9CiFh5f9izrMJX7iK7KlOA==", + "dev": true, + "dependencies": { + "buffer": "^6.0.3" + }, + "peerDependencies": { + "@metaplex-foundation/umi": "^0.9.2", "@solana/web3.js": "^1.72.0" } }, @@ -358,6 +429,7 @@ "version": "1.1.7", "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.7.tgz", "integrity": "sha512-PPNYBslrLNNUQ/Yad37MHYsNQtK67EhWb6WtSvNLLPo7SdVZgkUjD6Dg+5On7zNwmskf8OX7I7Nx5oN+MIWE0g==", + "dev": true, "funding": { "url": "https://paulmillr.com/funding/" } @@ -366,6 +438,7 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.4.0.tgz", "integrity": "sha512-sVUpc0Vq3tXCkDGYVWGIZTRfnvu8LoTDaev7vbwh0omSvVORONr960MQWdKqJDCReIEmTj3PAr73O3aoxz7OPg==", + "dev": true, "dependencies": { "@noble/curves": "~1.4.0", "@noble/hashes": "~1.4.0", @@ -379,6 +452,7 @@ "version": "1.4.2", "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.4.2.tgz", "integrity": "sha512-TavHr8qycMChk8UwMld0ZDRvatedkzWfH8IiaeGCfymOP5i0hSCozz9vHOL0nkwk7HRMlFnAiKpS2jrUmSybcw==", + "dev": true, "dependencies": { "@noble/hashes": "1.4.0" }, @@ -390,6 +464,7 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.3.0.tgz", "integrity": "sha512-disdg7gHuTDZtY+ZdkmLpPCk7fxZSu3gBiEGuoC1XYxv9cGx3Z6cpTggCgW6odSOOIXCiDjuGejW+aJKCY/pIQ==", + "dev": true, "dependencies": { "@noble/hashes": "~1.4.0", "@scure/base": "~1.1.6" @@ -662,19 +737,6 @@ "node": ">=18" } }, - "node_modules/@solana/spl-token-group/node_modules/typescript": { - "version": "5.5.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", - "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", - "peer": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, "node_modules/@solana/spl-token-metadata": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/@solana/spl-token-metadata/-/spl-token-metadata-0.1.4.tgz", @@ -739,6 +801,30 @@ "tslib": "^2.4.0" } }, + "node_modules/@tsconfig/node10": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", + "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", + "dev": true + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "dev": true + }, "node_modules/@types/bn.js": { "version": "5.1.5", "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.5.tgz", @@ -812,10 +898,35 @@ "version": "1.3.14", "resolved": "https://registry.npmjs.org/abs/-/abs-1.3.14.tgz", "integrity": "sha512-PrS26IzwKLWwuURpiKl8wRmJ2KdR/azaVrLEBWG/TALwT20Y7qjtYp1qcMLHA4206hBHY5phv3w4pjf9NPv4Vw==", + "dev": true, "dependencies": { "ul": "^5.0.0" } }, + "node_modules/acorn": { + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", + "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", + "dev": true, + "dependencies": { + "acorn": "^8.11.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/agentkeepalive": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.5.0.tgz", @@ -889,7 +1000,6 @@ "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -1060,8 +1170,7 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true, - "license": "MIT" + "dev": true }, "node_modules/buffer-layout": { "version": "1.2.2", @@ -1074,7 +1183,8 @@ "node_modules/buffer-reverse": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/buffer-reverse/-/buffer-reverse-1.0.1.tgz", - "integrity": "sha512-M87YIUBsZ6N924W57vDwT/aOu8hw7ZgdByz6ijksLjmHJELBASmYTTlNHRgjE+pTsT9oJXGaDSgqqwfdHotDUg==" + "integrity": "sha512-M87YIUBsZ6N924W57vDwT/aOu8hw7ZgdByz6ijksLjmHJELBASmYTTlNHRgjE+pTsT9oJXGaDSgqqwfdHotDUg==", + "dev": true }, "node_modules/bufferutil": { "version": "4.0.8", @@ -1105,6 +1215,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.2.tgz", "integrity": "sha512-X/WM2UQs6VMHUtjUDnZTRI+i1crWteJySFzr9UpGoQa4WQffXVTTXuekjl7TjZRlcF2XfjgITT0HxZ9RnxeT0w==", + "dev": true, "engines": { "node": ">=0.10.0" }, @@ -1249,12 +1360,14 @@ "node_modules/core-util-is": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true }, "node_modules/create-error-class": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz", "integrity": "sha512-gYTKKexFO3kh200H1Nit76sRwRtOY32vQd3jpAQKpLtZqyNsSQNfI4N7o3eP2wUjV35pTWKRYqFUDBvUha/Pkw==", + "dev": true, "dependencies": { "capture-stack-trace": "^1.0.0" }, @@ -1262,6 +1375,12 @@ "node": ">=0.10.0" } }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true + }, "node_modules/cross-fetch": { "version": "3.1.8", "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.8.tgz", @@ -1286,7 +1405,8 @@ "node_modules/crypto-js": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.2.0.tgz", - "integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==" + "integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==", + "dev": true }, "node_modules/debug": { "version": "4.3.3", @@ -1343,6 +1463,7 @@ "version": "0.6.0", "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true, "engines": { "node": ">=4.0.0" } @@ -1351,6 +1472,7 @@ "version": "2.2.4", "resolved": "https://registry.npmjs.org/deffy/-/deffy-2.2.4.tgz", "integrity": "sha512-pLc9lsbsWjr6RxmJ2OLyvm+9l4j1yK69h+TML/gUit/t3vTijpkNGh8LioaJYTGO7F25m6HZndADcUOo2PsiUg==", + "dev": true, "dependencies": { "typpy": "^2.0.0" } @@ -1401,6 +1523,7 @@ "version": "0.1.4", "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", "integrity": "sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==", + "dev": true, "dependencies": { "readable-stream": "^2.0.2" } @@ -1416,6 +1539,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/err/-/err-1.1.1.tgz", "integrity": "sha512-N97Ybd2jJHVQ+Ft3Q5+C2gM3kgygkdeQmEqbN2z15UTVyyEsIwLA1VK39O1DHEJhXbwIFcJLqm6iARNhFANcQA==", + "dev": true, "dependencies": { "typpy": "^2.2.0" } @@ -1424,6 +1548,7 @@ "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, "dependencies": { "is-arrayish": "^0.2.1" } @@ -1468,6 +1593,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/ethereum-bloom-filters/-/ethereum-bloom-filters-1.2.0.tgz", "integrity": "sha512-28hyiE7HVsWubqhpVLVmZXFd4ITeHi+BUu05o9isf0GUpMtzBUi+8/gFrGaGYzvGAJQmJ3JKj77Mk9G98T84rA==", + "dev": true, "dependencies": { "@noble/hashes": "^1.4.0" } @@ -1476,6 +1602,7 @@ "version": "2.2.1", "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-2.2.1.tgz", "integrity": "sha512-r/W8lkHSiTLxUxW8Rf3u4HGB0xQweG2RyETjywylKZSzLWoWAijRz8WCuOtJ6wah+avllXBqZuk29HCCvhEIRg==", + "dev": true, "dependencies": { "@noble/curves": "1.4.2", "@noble/hashes": "1.4.0", @@ -1487,6 +1614,7 @@ "version": "1.4.2", "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.4.2.tgz", "integrity": "sha512-TavHr8qycMChk8UwMld0ZDRvatedkzWfH8IiaeGCfymOP5i0hSCozz9vHOL0nkwk7HRMlFnAiKpS2jrUmSybcw==", + "dev": true, "dependencies": { "@noble/hashes": "1.4.0" }, @@ -1498,6 +1626,7 @@ "version": "0.1.6", "resolved": "https://registry.npmjs.org/ethjs-unit/-/ethjs-unit-0.1.6.tgz", "integrity": "sha512-/Sn9Y0oKl0uqQuvgFk/zQgR7aw1g36qX/jzSQ5lSwlO0GigPymk4eGQfeNTD03w1dPOqfz8V77Cy43jH56pagw==", + "dev": true, "dependencies": { "bn.js": "4.11.6", "number-to-bn": "1.7.0" @@ -1510,7 +1639,8 @@ "node_modules/ethjs-unit/node_modules/bn.js": { "version": "4.11.6", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==" + "integrity": "sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==", + "dev": true }, "node_modules/eventemitter3": { "version": "4.0.7", @@ -1522,6 +1652,7 @@ "version": "3.2.13", "resolved": "https://registry.npmjs.org/exec-limiter/-/exec-limiter-3.2.13.tgz", "integrity": "sha512-86Ri699bwiHZVBzTzNj8gspqAhCPchg70zPVWIh3qzUOA1pUMcb272Em3LPk8AE0mS95B9yMJhtqF8vFJAn0dA==", + "dev": true, "dependencies": { "limit-it": "^3.0.0", "typpy": "^2.1.0" @@ -1540,12 +1671,6 @@ "resolved": "https://registry.npmjs.org/fast-stable-stringify/-/fast-stable-stringify-1.0.0.tgz", "integrity": "sha512-wpYMUmFu5f00Sm0cj2pfivpmawLZ0NKdviQ4w9zJeR8JVtOpOxHmLaJuj0vxvGqMJQWyP/COUkF75/57OKyRag==" }, - "node_modules/fastestsmallesttextencoderdecoder": { - "version": "1.0.22", - "resolved": "https://registry.npmjs.org/fastestsmallesttextencoderdecoder/-/fastestsmallesttextencoderdecoder-1.0.22.tgz", - "integrity": "sha512-Pb8d48e+oIuY4MaM64Cd7OW1gt4nxCHs7/ddPPZ/Ic3sg8yVGM7O9wDvZ7us6ScaUupzM+pfBolwtYhN1IxBIw==", - "peer": true - }, "node_modules/file-uri-to-path": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", @@ -1616,6 +1741,7 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -1624,6 +1750,7 @@ "version": "1.0.13", "resolved": "https://registry.npmjs.org/function.name/-/function.name-1.0.13.tgz", "integrity": "sha512-mVrqdoy5npWZyoXl4DxCeuVF6delDcQjVS9aPdvLYlBxtMTZDR2B5GVEQEoM1jJyspCqg3C0v4ABkLE7tp9xFA==", + "dev": true, "dependencies": { "noop6": "^1.0.1" } @@ -1652,6 +1779,7 @@ "version": "1.4.10", "resolved": "https://registry.npmjs.org/git-package-json/-/git-package-json-1.4.10.tgz", "integrity": "sha512-DRAcvbzd2SxGK7w8OgYfvKqhFliT5keX0lmSmVdgScgf1kkl5tbbo7Pam6uYoCa1liOiipKxQZG8quCtGWl/fA==", + "dev": true, "dependencies": { "deffy": "^2.2.1", "err": "^1.1.1", @@ -1668,6 +1796,7 @@ "version": "1.1.10", "resolved": "https://registry.npmjs.org/git-source/-/git-source-1.1.10.tgz", "integrity": "sha512-XZZ7ZgnLL35oLgM/xjnLYgtlKlxJG0FohC1kWDvGkU7s1VKGXK0pFF/g1itQEwQ3D+uTQzBnzPi8XbqOv7Wc1Q==", + "dev": true, "dependencies": { "git-url-parse": "^5.0.1" } @@ -1676,6 +1805,7 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/git-up/-/git-up-1.2.1.tgz", "integrity": "sha512-SRVN3rOLACva8imc7BFrB6ts5iISWKH1/h/1Z+JZYoUI7UVQM7gQqk4M2yxUENbq2jUUT09NEND5xwP1i7Ktlw==", + "dev": true, "dependencies": { "is-ssh": "^1.0.0", "parse-url": "^1.0.0" @@ -1685,6 +1815,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/git-url-parse/-/git-url-parse-5.0.1.tgz", "integrity": "sha512-4uSiOgrryNEMBX+gTWogenYRUh2j1D+95STTSEF2RCTgLkfJikl8c7BGr0Bn274hwuxTsbS2/FQ5pVS9FoXegQ==", + "dev": true, "dependencies": { "git-up": "^1.0.0" } @@ -1740,6 +1871,7 @@ "version": "5.6.0", "resolved": "https://registry.npmjs.org/got/-/got-5.6.0.tgz", "integrity": "sha512-MnypzkaW8dldA8AbJFjMs7y14+ykd2V8JCLKSvX1Gmzx1alH3Y+3LArywHDoAF2wS3pnZp4gacoYtvqBeF6drQ==", + "dev": true, "dependencies": { "create-error-class": "^3.0.1", "duplexer2": "^0.1.4", @@ -1766,6 +1898,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", + "dev": true, "engines": { "node": ">=0.10.0" } @@ -1784,6 +1917,7 @@ "version": "5.0.8", "resolved": "https://registry.npmjs.org/gry/-/gry-5.0.8.tgz", "integrity": "sha512-meq9ZjYVpLzZh3ojhTg7IMad9grGsx6rUUKHLqPnhLXzJkRQvEL2U3tQpS5/WentYTtHtxkT3Ew/mb10D6F6/g==", + "dev": true, "dependencies": { "abs": "^1.2.1", "exec-limiter": "^3.0.0", @@ -1805,6 +1939,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, "dependencies": { "function-bind": "^1.1.2" }, @@ -1825,7 +1960,8 @@ "node_modules/hosted-git-info": { "version": "2.8.9", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==" + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true }, "node_modules/humanize-ms": { "version": "1.2.1", @@ -1869,17 +2005,20 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true, "license": "ISC" }, "node_modules/ini": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true }, "node_modules/is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true }, "node_modules/is-binary-path": { "version": "2.1.0", @@ -1898,6 +2037,7 @@ "version": "2.15.0", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.0.tgz", "integrity": "sha512-Dd+Lb2/zvk9SKy1TGCt1wFJFo/MWBPMX5x7KcvLajWTGuomczdQX61PvY5yK6SVACwpoexWo81IfFyoKY2QnTA==", + "dev": true, "dependencies": { "hasown": "^2.0.2" }, @@ -1945,6 +2085,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz", "integrity": "sha512-WvtOiug1VFrE9v1Cydwm+FnXd3+w9GaeVUss5W4v/SLy3UW00vP+6iNF2SdnfiBoLy4bTqVdkftNGTUeOFVsbA==", + "dev": true, "engines": { "node": ">=6.5.0", "npm": ">=3" @@ -1974,6 +2115,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz", "integrity": "sha512-cr/SlUEe5zOGmzvj9bUyC4LVvkNVAXu4GytXLNMr1pny+a65MpQ9IJzFHD5vi7FyJgb4qt27+eS3TuQnqB+RQw==", + "dev": true, "engines": { "node": ">=0.10.0" } @@ -1982,6 +2124,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz", "integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==", + "dev": true, "engines": { "node": ">=0.10.0" } @@ -1990,6 +2133,7 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/is-ssh/-/is-ssh-1.4.0.tgz", "integrity": "sha512-x7+VxdxOdlV3CYpjvRLBv5Lo9OJerlYanjwFrPR9fuGPjCiNiCzFgAWpiLAohSbsnH4ZAys3SBh+hq5rJosxUQ==", + "dev": true, "dependencies": { "protocols": "^2.0.1" } @@ -1998,6 +2142,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", + "dev": true, "engines": { "node": ">=0.10.0" } @@ -2018,7 +2163,8 @@ "node_modules/isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true }, "node_modules/isexe": { "version": "2.0.0", @@ -2038,7 +2184,8 @@ "node_modules/iterate-object": { "version": "1.3.4", "resolved": "https://registry.npmjs.org/iterate-object/-/iterate-object-1.3.4.tgz", - "integrity": "sha512-4dG1D1x/7g8PwHS9aK6QV5V94+ZvyP4+d19qDv43EzImmrndysIl4prmJ1hWWIGCqrZHyaHBm6BSEWHOLnpoNw==" + "integrity": "sha512-4dG1D1x/7g8PwHS9aK6QV5V94+ZvyP4+d19qDv43EzImmrndysIl4prmJ1hWWIGCqrZHyaHBm6BSEWHOLnpoNw==", + "dev": true }, "node_modules/jayson": { "version": "4.1.1", @@ -2129,6 +2276,7 @@ "version": "3.2.10", "resolved": "https://registry.npmjs.org/limit-it/-/limit-it-3.2.10.tgz", "integrity": "sha512-T0NK99pHnkimldr1WUqvbGV1oWDku/xC9J/OqzJFsV1jeOS6Bwl8W7vkeQIBqwiON9dTALws+rX/XPMQqWerDQ==", + "dev": true, "dependencies": { "typpy": "^2.0.0" } @@ -2189,6 +2337,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", + "dev": true, "engines": { "node": ">=0.10.0" } @@ -2204,6 +2353,7 @@ "version": "0.3.11", "resolved": "https://registry.npmjs.org/merkletreejs/-/merkletreejs-0.3.11.tgz", "integrity": "sha512-LJKTl4iVNTndhL+3Uz/tfkjD0klIWsHlUzgtuNnNrsf7bAlXR30m+xYB7lHr5Z/l6e/yAIsr26Dabx6Buo4VGQ==", + "dev": true, "dependencies": { "bignumber.js": "^9.0.1", "buffer-reverse": "^1.0.1", @@ -2218,7 +2368,8 @@ "node_modules/micro-ftch": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/micro-ftch/-/micro-ftch-0.3.1.tgz", - "integrity": "sha512-/0LLxhzP0tfiR5hcQebtudP56gUurs2CLkGarnCiB/OqEyUFQ6U3paQi/tgLv0hBJYt2rnr9MNpxz4fiiugstg==" + "integrity": "sha512-/0LLxhzP0tfiR5hcQebtudP56gUurs2CLkGarnCiB/OqEyUFQ6U3paQi/tgLv0hBJYt2rnr9MNpxz4fiiugstg==", + "dev": true }, "node_modules/minimatch": { "version": "4.2.1", @@ -2237,6 +2388,7 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" @@ -2247,7 +2399,6 @@ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", "dev": true, - "license": "MIT", "dependencies": { "minimist": "^1.2.6" }, @@ -2363,6 +2514,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/node-status-codes/-/node-status-codes-1.0.0.tgz", "integrity": "sha512-1cBMgRxdMWE8KeWCqk2RIOrvUb0XCwYfEsY5/y2NlXyq4Y/RumnOZvTj4Nbr77+Vb2C+kyBoRTdkNOS8L3d/aQ==", + "dev": true, "engines": { "node": ">=0.10.0" } @@ -2370,12 +2522,14 @@ "node_modules/noop6": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/noop6/-/noop6-1.0.9.tgz", - "integrity": "sha512-DB3Hwyd89dPr5HqEPg3YHjzvwh/mCqizC1zZ8vyofqc+TQRyPDnT4wgXXbLGF4z9YAzwwTLi8pNLhGqcbSjgkA==" + "integrity": "sha512-DB3Hwyd89dPr5HqEPg3YHjzvwh/mCqizC1zZ8vyofqc+TQRyPDnT4wgXXbLGF4z9YAzwwTLi8pNLhGqcbSjgkA==", + "dev": true }, "node_modules/normalize-package-data": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, "dependencies": { "hosted-git-info": "^2.1.4", "resolve": "^1.10.0", @@ -2397,6 +2551,7 @@ "version": "1.7.0", "resolved": "https://registry.npmjs.org/number-to-bn/-/number-to-bn-1.7.0.tgz", "integrity": "sha512-wsJ9gfSz1/s4ZsJN01lyonwuxA1tml6X1yBDnfpMglypcBRFZZkus26EdPSlqS5GJfYddVZa22p3VNb3z5m5Ig==", + "dev": true, "dependencies": { "bn.js": "4.11.6", "strip-hex-prefix": "1.0.0" @@ -2409,12 +2564,14 @@ "node_modules/number-to-bn/node_modules/bn.js": { "version": "4.11.6", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==" + "integrity": "sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==", + "dev": true }, "node_modules/oargv": { "version": "3.4.10", "resolved": "https://registry.npmjs.org/oargv/-/oargv-3.4.10.tgz", "integrity": "sha512-SXaMANv9sr7S/dP0vj0+Ybipa47UE1ntTWQ2rpPRhC6Bsvfl+Jg03Xif7jfL0sWKOYWK8oPjcZ5eJ82t8AP/8g==", + "dev": true, "dependencies": { "iterate-object": "^1.1.0", "ul": "^5.0.0" @@ -2424,6 +2581,7 @@ "version": "1.0.9", "resolved": "https://registry.npmjs.org/obj-def/-/obj-def-1.0.9.tgz", "integrity": "sha512-bQ4ya3VYD6FAA1+s6mEhaURRHSmw4+sKaXE6UyXZ1XDYc5D+c7look25dFdydmLd18epUegh398gdDkMUZI9xg==", + "dev": true, "dependencies": { "deffy": "^2.2.2" } @@ -2432,6 +2590,7 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, "engines": { "node": ">=0.10.0" } @@ -2450,6 +2609,7 @@ "version": "3.2.8", "resolved": "https://registry.npmjs.org/one-by-one/-/one-by-one-3.2.8.tgz", "integrity": "sha512-HR/pSzZdm46Xqj58K+Bu64kMbSTw8/u77AwWvV+rprO/OsuR++pPlkUJn+SmwqBGRgHKwSKQ974V3uls7crIeQ==", + "dev": true, "dependencies": { "obj-def": "^1.0.0", "sliced": "^1.0.1" @@ -2459,6 +2619,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "dev": true, "engines": { "node": ">=0.10.0" } @@ -2499,6 +2660,7 @@ "version": "2.4.0", "resolved": "https://registry.npmjs.org/package-json/-/package-json-2.4.0.tgz", "integrity": "sha512-PRg65iXMTt/uK8Rfh5zvzkUbfAPitF17YaCY+IbHsYgksiLvtzWWTUildHth3mVaZ7871OJ7gtP4LBRBlmAdXg==", + "dev": true, "dependencies": { "got": "^5.0.0", "registry-auth-token": "^3.0.1", @@ -2513,6 +2675,7 @@ "version": "1.0.9", "resolved": "https://registry.npmjs.org/package-json-path/-/package-json-path-1.0.9.tgz", "integrity": "sha512-uNu7f6Ef7tQHZRnkyVnCtzdSYVN9uBtge/sG7wzcUaawFWkPYUq67iXxRGrQSg/q0tzxIB8jSyIYUKjG2Jn//A==", + "dev": true, "dependencies": { "abs": "^1.2.1" } @@ -2522,6 +2685,7 @@ "resolved": "https://registry.npmjs.org/package.json/-/package.json-2.0.1.tgz", "integrity": "sha512-pSxZ6XR5yEawRN2ekxx9IKgPN5uNAYco7MCPxtBEWMKO3UKWa1X2CtQMzMgloeGj2g2o6cue3Sb5iPkByIJqlw==", "deprecated": "Use pkg.json instead.", + "dev": true, "dependencies": { "git-package-json": "^1.4.0", "git-source": "^1.1.0", @@ -2538,6 +2702,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", "integrity": "sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ==", + "dev": true, "dependencies": { "error-ex": "^1.2.0" }, @@ -2549,6 +2714,7 @@ "version": "1.3.11", "resolved": "https://registry.npmjs.org/parse-url/-/parse-url-1.3.11.tgz", "integrity": "sha512-1wj9nkgH/5EboDxLwaTMGJh3oH3f+Gue+aGdh631oCqoSBpokzmMmOldvOeBPtB8GJBYJbaF93KPzlkU+Y1ksg==", + "dev": true, "dependencies": { "is-ssh": "^1.3.0", "protocols": "^1.4.0" @@ -2557,7 +2723,8 @@ "node_modules/parse-url/node_modules/protocols": { "version": "1.4.8", "resolved": "https://registry.npmjs.org/protocols/-/protocols-1.4.8.tgz", - "integrity": "sha512-IgjKyaUSjsROSO8/D49Ab7hP8mJgTYcqApOqdPhLoPxAplXmkp+zRvsrSQjFn5by0rhm4VH0GAUELIPpx7B1yg==" + "integrity": "sha512-IgjKyaUSjsROSO8/D49Ab7hP8mJgTYcqApOqdPhLoPxAplXmkp+zRvsrSQjFn5by0rhm4VH0GAUELIPpx7B1yg==", + "dev": true }, "node_modules/path-exists": { "version": "4.0.0", @@ -2582,7 +2749,8 @@ "node_modules/path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true }, "node_modules/pathval": { "version": "1.1.1", @@ -2611,6 +2779,7 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", "integrity": "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==", + "dev": true, "engines": { "node": ">=0.10.0" } @@ -2619,6 +2788,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", "integrity": "sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==", + "dev": true, "dependencies": { "pinkie": "^2.0.0" }, @@ -2630,6 +2800,7 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", "integrity": "sha512-PhmXi5XmoyKw1Un4E+opM2KcsJInDvKyuOumcjjw3waw86ZNjHwVUOOWLc4bCzLdcKNaWBH9e99sbWzDQsVaYg==", + "dev": true, "engines": { "node": ">=0.10.0" } @@ -2653,17 +2824,20 @@ "node_modules/process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true }, "node_modules/protocols": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/protocols/-/protocols-2.0.1.tgz", - "integrity": "sha512-/XJ368cyBJ7fzLMwLKv1e4vLxOju2MNAIokcr7meSaNcVbWz/CPcW22cP04mwxOErdA5mwjA8Q6w/cdAQxVn7Q==" + "integrity": "sha512-/XJ368cyBJ7fzLMwLKv1e4vLxOju2MNAIokcr7meSaNcVbWz/CPcW22cP04mwxOErdA5mwjA8Q6w/cdAQxVn7Q==", + "dev": true }, "node_modules/r-json": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/r-json/-/r-json-1.3.0.tgz", "integrity": "sha512-xesd+RHCpymPCYd9DvDvUr1w1IieSChkqYF1EpuAYrvCfLXji9NP36DvyYZJZZB5soVDvZ0WUtBoZaU1g5Yt9A==", + "dev": true, "dependencies": { "w-json": "1.3.10" } @@ -2672,6 +2846,7 @@ "version": "1.0.9", "resolved": "https://registry.npmjs.org/r-package-json/-/r-package-json-1.0.9.tgz", "integrity": "sha512-G4Vpf1KImWmmPFGdtWQTU0L9zk0SjqEC4qs/jE7AQ+Ylmr5kizMzGeC4wnHp5+ijPqNN+2ZPpvyjVNdN1CDVcg==", + "dev": true, "dependencies": { "package-json-path": "^1.0.0", "r-json": "^1.2.1" @@ -2681,6 +2856,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, "license": "MIT", "dependencies": { "safe-buffer": "^5.1.0" @@ -2690,6 +2866,7 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dev": true, "dependencies": { "deep-extend": "^0.6.0", "ini": "~1.3.0", @@ -2704,6 +2881,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "dev": true, "engines": { "node": ">=0.10.0" } @@ -2712,6 +2890,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/read-all-stream/-/read-all-stream-3.1.0.tgz", "integrity": "sha512-DI1drPHbmBcUDWrJ7ull/F2Qb8HkwBncVx8/RpKYFSIACYaVRQReISYPdZz/mt1y1+qMCOrfReTopERmaxtP6w==", + "dev": true, "dependencies": { "pinkie-promise": "^2.0.0", "readable-stream": "^2.0.0" @@ -2724,6 +2903,7 @@ "version": "2.3.8", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -2737,7 +2917,8 @@ "node_modules/readable-stream/node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true }, "node_modules/readdirp": { "version": "3.6.0", @@ -2761,6 +2942,7 @@ "version": "3.4.0", "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.4.0.tgz", "integrity": "sha512-4LM6Fw8eBQdwMYcES4yTnn2TqIasbXuwDx3um+QRs7S55aMKCBKBxvPXl2RiUjHwuJLTyYfxSpmfSAjQpcuP+A==", + "dev": true, "dependencies": { "rc": "^1.1.6", "safe-buffer": "^5.0.1" @@ -2770,6 +2952,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz", "integrity": "sha512-ZbgR5aZEdf4UKZVBPYIgaglBmSF2Hi94s2PcIHhRGFjKYu+chjJdYfHn4rt3hB6eCKLJ8giVIIfgMa1ehDfZKA==", + "dev": true, "dependencies": { "rc": "^1.0.1" }, @@ -2791,6 +2974,7 @@ "version": "1.22.8", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dev": true, "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", @@ -2882,6 +3066,7 @@ "version": "5.7.2", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, "bin": { "semver": "bin/semver" } @@ -2899,7 +3084,8 @@ "node_modules/sliced": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/sliced/-/sliced-1.0.1.tgz", - "integrity": "sha512-VZBmZP8WU3sMOZm1bdgTadsQbcscK0UM8oKxKVBs4XAhUo2Xxzm/OFMGBkPusxw9xL3Uy8LrzEqGqJhclsr0yA==" + "integrity": "sha512-VZBmZP8WU3sMOZm1bdgTadsQbcscK0UM8oKxKVBs4XAhUo2Xxzm/OFMGBkPusxw9xL3Uy8LrzEqGqJhclsr0yA==", + "dev": true }, "node_modules/snake-case": { "version": "3.0.4", @@ -2916,7 +3102,6 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, - "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } @@ -2926,7 +3111,6 @@ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", "dev": true, - "license": "MIT", "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" @@ -2936,6 +3120,7 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", + "dev": true, "dependencies": { "spdx-expression-parse": "^3.0.0", "spdx-license-ids": "^3.0.0" @@ -2944,12 +3129,14 @@ "node_modules/spdx-exceptions": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", - "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==" + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", + "dev": true }, "node_modules/spdx-expression-parse": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, "dependencies": { "spdx-exceptions": "^2.1.0", "spdx-license-ids": "^3.0.0" @@ -2958,12 +3145,14 @@ "node_modules/spdx-license-ids": { "version": "3.0.18", "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.18.tgz", - "integrity": "sha512-xxRs31BqRYHwiMzudOrpSiHtZ8i/GeionCBDSilhYRj+9gIcI8wCZTlXZKu9vZIVqViP3dcp9qE5G6AlIaD+TQ==" + "integrity": "sha512-xxRs31BqRYHwiMzudOrpSiHtZ8i/GeionCBDSilhYRj+9gIcI8wCZTlXZKu9vZIVqViP3dcp9qE5G6AlIaD+TQ==", + "dev": true }, "node_modules/string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, "dependencies": { "safe-buffer": "~5.1.0" } @@ -2971,7 +3160,8 @@ "node_modules/string_decoder/node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true }, "node_modules/string-width": { "version": "4.2.3", @@ -3016,6 +3206,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz", "integrity": "sha512-q8d4ue7JGEiVcypji1bALTos+0pWtyGlivAWyPuTkHzuTCJqrK9sWxYQZUq6Nq3cuyv3bm734IhHvHtGGURU6A==", + "dev": true, "dependencies": { "is-hex-prefixed": "1.0.0" }, @@ -3063,6 +3254,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, "engines": { "node": ">= 0.4" }, @@ -3084,6 +3276,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-2.0.0.tgz", "integrity": "sha512-pqqJOi1rF5zNs/ps4vmbE4SFCrM4iR7LW+GHAsHqO/EumqbIWceioevYLM5xZRgQSH6gFgL9J/uB7EcJhQ9niQ==", + "dev": true, "engines": { "node": ">=0.10.0" } @@ -3092,6 +3285,7 @@ "version": "0.0.28", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.28.tgz", "integrity": "sha512-c2mmfiBmND6SOVxzogm1oda0OJ1HZVIk/5n26N59dDTh80MUeavpiCls4PGAdkX1PFkKokLpcf7prSjCeXLsJg==", + "dev": true, "dependencies": { "os-tmpdir": "~1.0.1" }, @@ -3128,6 +3322,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/treeify/-/treeify-1.1.0.tgz", "integrity": "sha512-1m4RA7xVAJrSGrrXGs0L3YTwyvBs2S8PbRHaLZAkFw7JR8oIFwYtysxlBZhYIa7xSyiYJKZ3iGrrk55cGA3i9A==", + "dev": true, "engines": { "node": ">=0.6" } @@ -3154,12 +3349,20 @@ "mocha": "^3.X.X || ^4.X.X || ^5.X.X || ^6.X.X || ^7.X.X || ^8.X.X || ^9.X.X || ^10.X.X" } }, - "node_modules/ts-node": { + "node_modules/ts-mocha/node_modules/diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/ts-mocha/node_modules/ts-node": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-7.0.1.tgz", "integrity": "sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw==", "dev": true, - "license": "MIT", "dependencies": { "arrify": "^1.0.0", "buffer-from": "^1.1.0", @@ -3177,12 +3380,69 @@ "node": ">=4.2.0" } }, + "node_modules/ts-mocha/node_modules/yn": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz", + "integrity": "sha512-uTv8J/wiWTgUTg+9vLTi//leUl5vDQS6uii/emeTb2ssY7vl6QWf2fFbIIGjnhjvbdKlU0ed7QPgY1htTC86jQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/ts-node": { + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", + "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", + "dev": true, + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/ts-node/node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, "node_modules/ts-node/node_modules/diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", "dev": true, - "license": "BSD-3-Clause", "engines": { "node": ">=0.3.1" } @@ -3235,6 +3495,7 @@ "version": "2.3.13", "resolved": "https://registry.npmjs.org/typpy/-/typpy-2.3.13.tgz", "integrity": "sha512-vOxIcQz9sxHi+rT09SJ5aDgVgrPppQjwnnayTrMye1ODaU8gIZTDM19t9TxmEElbMihx2Nq/0/b/MtyKfayRqA==", + "dev": true, "dependencies": { "function.name": "^1.0.3" } @@ -3243,6 +3504,7 @@ "version": "5.2.15", "resolved": "https://registry.npmjs.org/ul/-/ul-5.2.15.tgz", "integrity": "sha512-svLEUy8xSCip5IWnsRa0UOg+2zP0Wsj4qlbjTmX6GJSmvKMHADBuHOm1dpNkWqWPIGuVSqzUkV3Cris5JrlTRQ==", + "dev": true, "dependencies": { "deffy": "^2.2.2", "typpy": "^2.3.4" @@ -3258,6 +3520,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-1.0.2.tgz", "integrity": "sha512-pwCcjjhEcpW45JZIySExBHYv5Y9EeL2OIGEfrSKp2dMUFGFv4CpvZkwJbVge8OvGH2BNNtJBx67DuKuJhf+N5Q==", + "dev": true, "engines": { "node": ">=0.10" } @@ -3266,6 +3529,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz", "integrity": "sha512-BVA4lR5PIviy2PMseNd2jbFQ+jwSwQGdJejf5ctd1rEXt0Ypd7yanUK9+lYechVlN5VaTJGsu2U/3MDDu6KgBA==", + "dev": true, "dependencies": { "prepend-http": "^1.0.1" }, @@ -3289,12 +3553,14 @@ "node_modules/utf8": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/utf8/-/utf8-3.0.0.tgz", - "integrity": "sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ==" + "integrity": "sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ==", + "dev": true }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true }, "node_modules/uuid": { "version": "8.3.2", @@ -3304,10 +3570,17 @@ "uuid": "dist/bin/uuid" } }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true + }, "node_modules/validate-npm-package-license": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, "dependencies": { "spdx-correct": "^3.0.0", "spdx-expression-parse": "^3.0.0" @@ -3316,12 +3589,14 @@ "node_modules/w-json": { "version": "1.3.10", "resolved": "https://registry.npmjs.org/w-json/-/w-json-1.3.10.tgz", - "integrity": "sha512-XadVyw0xE+oZ5FGApXsdswv96rOhStzKqL53uSe5UaTadABGkWIg1+DTx8kiZ/VqTZTBneoL0l65RcPe4W3ecw==" + "integrity": "sha512-XadVyw0xE+oZ5FGApXsdswv96rOhStzKqL53uSe5UaTadABGkWIg1+DTx8kiZ/VqTZTBneoL0l65RcPe4W3ecw==", + "dev": true }, "node_modules/web3-utils": { "version": "1.10.4", "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.10.4.tgz", "integrity": "sha512-tsu8FiKJLk2PzhDl9fXbGUWTkkVXYhtTA+SmEFkKft+9BgwLxfCRpU96sWv7ICC8zixBNd3JURVoiR3dUXgP8A==", + "dev": true, "dependencies": { "@ethereumjs/util": "^8.1.0", "bn.js": "^5.2.1", @@ -3486,13 +3761,12 @@ } }, "node_modules/yn": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz", - "integrity": "sha512-uTv8J/wiWTgUTg+9vLTi//leUl5vDQS6uii/emeTb2ssY7vl6QWf2fFbIIGjnhjvbdKlU0ed7QPgY1htTC86jQ==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", "dev": true, - "license": "MIT", "engines": { - "node": ">=4" + "node": ">=6" } }, "node_modules/yocto-queue": { diff --git a/package.json b/package.json index 7236fba..d2e34fa 100644 --- a/package.json +++ b/package.json @@ -4,17 +4,18 @@ "lint": "prettier */*.js \"*/**/*{.js,.ts}\" --check" }, "dependencies": { - "@coral-xyz/anchor": "^0.30.1", - "@metaplex-foundation/mpl-bubblegum": "^4.1.0", + "@coral-xyz/anchor": "^0.29.0", "@metaplex-foundation/mpl-token-metadata": "^3.2.1", "@metaplex-foundation/umi": "^0.8.10", - "@metaplex-foundation/umi-bundle-defaults": "^0.8.10", "@metaplex-foundation/umi-web3js-adapters": "^0.8.10", "@solana/spl-token": "^0.4.8", "@solana/web3.js": "^1.95.2", "dotenv": "^16.4.5" }, "devDependencies": { + "@metaplex-foundation/digital-asset-standard-api": "^1.0.4", + "@metaplex-foundation/mpl-bubblegum": "^4.2.1", + "@metaplex-foundation/umi-bundle-defaults": "^0.9.2", "@types/bn.js": "^5.1.0", "@types/chai": "^4.3.0", "@types/mocha": "^9.0.0", @@ -22,6 +23,7 @@ "mocha": "^9.0.3", "prettier": "^2.6.2", "ts-mocha": "^10.0.0", + "ts-node": "^10.9.2", "typescript": "^4.3.5" } } diff --git a/programs/core-sol-bond-stake-sc/Cargo.toml b/programs/core-sol-bond-stake-sc/Cargo.toml index cd11a6c..0a76fe8 100644 --- a/programs/core-sol-bond-stake-sc/Cargo.toml +++ b/programs/core-sol-bond-stake-sc/Cargo.toml @@ -14,14 +14,14 @@ no-idl = [] no-log-ix-name = [] cpi = ["no-entrypoint"] default = [] -idl-build = ["anchor-lang/idl-build", "anchor-spl/idl-build"] [dependencies] -anchor-lang = {version = "0.30.1", features = ["init-if-needed"]} -mpl-token-metadata={version = "4.1.2"} -solana-program = "1.18.18" -spl-token = "4.0.0" -anchor-spl = "0.30.0" +anchor-lang = { version = "0.29.0", features = ["init-if-needed"] } +spl-account-compression = { version = "0.3.1", features = ["cpi"] } +mpl-bubblegum = { version = "1.4.0"} +solana-program = "~1.18.15" +spl-token = { version = ">= 3.5.0, < 5.0", features = ["no-entrypoint"] } +anchor-spl = "0.29.0" uint = "0.9.1" solana-security-txt = "1.1.1" diff --git a/programs/core-sol-bond-stake-sc/src/constants.rs b/programs/core-sol-bond-stake-sc/src/constants.rs index 4cf5703..5044a2d 100644 --- a/programs/core-sol-bond-stake-sc/src/constants.rs +++ b/programs/core-sol-bond-stake-sc/src/constants.rs @@ -2,8 +2,7 @@ use solana_program::pubkey; use solana_program::pubkey::Pubkey; pub const BOND_SEED: &str = "bond"; -pub const ADDRESS_BONDS_SEED: &str = "address_bonds"; -pub const ADDRESS_REWARDS_SEED: &str = "address_rewards"; +pub const ADDRESS_BONDS_REWARDS_SEED: &str = "address_bonds_rewards"; pub const BOND_CONFIG_SEED: &str = "bond_config"; pub const REWARDS_CONFIG_SEED: &str = "rewards_config"; pub const VAULT_CONFIG_SEED: &str = "vault_config"; diff --git a/programs/core-sol-bond-stake-sc/src/errors.rs b/programs/core-sol-bond-stake-sc/src/errors.rs index d41c6aa..3133268 100644 --- a/programs/core-sol-bond-stake-sc/src/errors.rs +++ b/programs/core-sol-bond-stake-sc/src/errors.rs @@ -28,12 +28,16 @@ pub enum Errors { WrongBondId, #[msg("Invalid remaining accounts")] InvalidRemainingAccounts, - #[msg("Wrong owner")] - WrongOwner, #[msg("Wrong value")] WrongValue, #[msg("Bond is inactive")] BondIsInactive, #[msg("Bond is not a vault")] BondIsNotAVault, + #[msg("Merkle tree mismatch")] + MerkleTreeMismatch, + #[msg("Not creator")] + NotCreator, + #[msg("Asset Id mismatch")] + AssetIdMismatch, } diff --git a/programs/core-sol-bond-stake-sc/src/instructions/admin/create_bond_config.rs b/programs/core-sol-bond-stake-sc/src/instructions/admin/create_bond_config.rs index 5416445..11fc483 100644 --- a/programs/core-sol-bond-stake-sc/src/instructions/admin/create_bond_config.rs +++ b/programs/core-sol-bond-stake-sc/src/instructions/admin/create_bond_config.rs @@ -1,7 +1,6 @@ use std::ops::DerefMut; use anchor_lang::prelude::*; -use anchor_spl::token::Mint; use crate::{BondConfig, State, ADMIN_PUBKEY, BOND_CONFIG_SEED}; @@ -17,7 +16,8 @@ pub struct CreateBondConfig<'info> { )] pub bond_config: Account<'info, BondConfig>, - pub mint_of_collection: Account<'info, Mint>, + /// CHECK: unsafe + pub merkle_tree: UncheckedAccount<'info>, #[account( mut, @@ -25,7 +25,7 @@ pub struct CreateBondConfig<'info> { )] pub authority: Signer<'info>, - system_program: Program<'info, System>, + pub system_program: Program<'info, System>, } pub fn create_bond_config( @@ -40,11 +40,11 @@ pub fn create_bond_config( bond_config.bump = ctx.bumps.bond_config; bond_config.index = index; bond_config.bond_state = State::Inactive.to_code(); - bond_config.mint_of_collection = ctx.accounts.mint_of_collection.key(); + bond_config.merkle_tree = ctx.accounts.merkle_tree.key(); bond_config.lock_period = lock_period; bond_config.bond_amount = bond_amount; bond_config.withdraw_penalty = withdraw_penalty; - bond_config.padding = [0; 128]; + // bond_config.padding = [0; 32]; Ok(()) } diff --git a/programs/core-sol-bond-stake-sc/src/instructions/admin/initalize_vault.rs b/programs/core-sol-bond-stake-sc/src/instructions/admin/initalize_vault.rs new file mode 100644 index 0000000..29e29aa --- /dev/null +++ b/programs/core-sol-bond-stake-sc/src/instructions/admin/initalize_vault.rs @@ -0,0 +1,65 @@ +use std::ops::DerefMut; + +use anchor_lang::prelude::*; +use anchor_spl::{ + associated_token::AssociatedToken, + token::{Mint, Token, TokenAccount}, +}; + + +use crate::{ + VaultConfig, ADMIN_PUBKEY, + VAULT_CONFIG_SEED, +}; + +#[derive(Accounts)] + +pub struct InitializeVault<'info> { + #[account( + init, + payer=authority, + seeds=[VAULT_CONFIG_SEED.as_bytes()], + bump, + space=VaultConfig::INIT_SPACE, + )] + pub vault_config: Account<'info, VaultConfig>, + + #[account( + init_if_needed, + payer=authority, + associated_token::mint=mint_of_token, + associated_token::authority=vault_config, + )] + pub vault: Account<'info, TokenAccount>, + + pub mint_of_token: Account<'info, Mint>, + + #[account( + mut, + address=ADMIN_PUBKEY, + )] + pub authority: Signer<'info>, + + pub system_program: Program<'info, System>, + pub token_program: Program<'info, Token>, + pub associated_token_program: Program<'info, AssociatedToken>, +} + +pub fn initialize_vault( + ctx: Context, +) -> Result<()> { + + + let vault_config = ctx.accounts.vault_config.deref_mut(); + + vault_config.bump = ctx.bumps.vault_config; + vault_config.vault = ctx.accounts.vault.key(); + vault_config.mint_of_token = ctx.accounts.mint_of_token.key(); + vault_config.total_bond_amount = 0; + vault_config.total_penalized_amount = 0; + vault_config.padding = [0; 32]; + + + + Ok(()) +} diff --git a/programs/core-sol-bond-stake-sc/src/instructions/admin/initialize_contract.rs b/programs/core-sol-bond-stake-sc/src/instructions/admin/initialize_contract.rs index c0c7ffc..13f6eab 100644 --- a/programs/core-sol-bond-stake-sc/src/instructions/admin/initialize_contract.rs +++ b/programs/core-sol-bond-stake-sc/src/instructions/admin/initialize_contract.rs @@ -1,13 +1,10 @@ use std::ops::DerefMut; use anchor_lang::prelude::*; -use anchor_spl::{ - associated_token::AssociatedToken, - token::{Mint, Token, TokenAccount}, -}; +use anchor_spl::{associated_token::AssociatedToken, token::Token}; use crate::{ - BondConfig, RewardsConfig, State, VaultConfig, ADMIN_PUBKEY, BOND_CONFIG_SEED, REWARDS_CONFIG_SEED, VAULT_CONFIG_SEED + BondConfig, RewardsConfig, State, ADMIN_PUBKEY, BOND_CONFIG_SEED, REWARDS_CONFIG_SEED, }; #[derive(Accounts)] @@ -22,26 +19,6 @@ pub struct InitializeContract<'info> { )] pub bond_config: Box>, - #[account( - init, - payer=authority, - seeds=[VAULT_CONFIG_SEED.as_bytes()], - bump, - space=VaultConfig::INIT_SPACE, - )] - vault_config: Box>, - - #[account( - init_if_needed, - payer=authority, - associated_token::mint=mint_of_token, - associated_token::authority=vault_config, - )] - pub vault: Box>, - - pub mint_of_token: Box>, - pub mint_of_collection: Box>, - #[account( init, payer=authority, @@ -51,15 +28,18 @@ pub struct InitializeContract<'info> { )] pub rewards_config: Box>, + /// CHECK: unsafe + pub merkle_tree: UncheckedAccount<'info>, + #[account( mut, address=ADMIN_PUBKEY, )] pub authority: Signer<'info>, - system_program: Program<'info, System>, - token_program: Program<'info, Token>, - associated_token_program: Program<'info, AssociatedToken>, + pub system_program: Program<'info, System>, + pub token_program: Program<'info, Token>, + pub associated_token_program: Program<'info, AssociatedToken>, } pub fn initialize_contract( @@ -76,20 +56,11 @@ pub fn initialize_contract( bond_config.bump = ctx.bumps.bond_config; bond_config.index = index; bond_config.bond_state = State::Inactive.to_code(); - bond_config.mint_of_collection = ctx.accounts.mint_of_collection.key(); + bond_config.merkle_tree = ctx.accounts.merkle_tree.key(); bond_config.lock_period = lock_period; bond_config.bond_amount = bond_amount; bond_config.withdraw_penalty = withdraw_penalty; - bond_config.padding = [0; 128]; - - let vault_config = ctx.accounts.vault_config.deref_mut(); - - vault_config.bump = ctx.bumps.vault_config; - vault_config.vault = ctx.accounts.vault.key(); - vault_config.mint_of_token = ctx.accounts.mint_of_token.key(); - vault_config.total_bond_amount = 0; - vault_config.total_penalized_amount = 0; - vault_config.padding = [0; 64]; + bond_config.padding = [0; 32]; let rewards_config = ctx.accounts.rewards_config.deref_mut(); @@ -101,7 +72,7 @@ pub fn initialize_contract( rewards_config.rewards_per_share = 0; rewards_config.last_reward_slot = 0; rewards_config.max_apr = max_apr; - rewards_config.padding = [0; 128]; + rewards_config.padding = [0; 32]; Ok(()) } diff --git a/programs/core-sol-bond-stake-sc/src/instructions/admin/mod.rs b/programs/core-sol-bond-stake-sc/src/instructions/admin/mod.rs index 4304372..053f17c 100644 --- a/programs/core-sol-bond-stake-sc/src/instructions/admin/mod.rs +++ b/programs/core-sol-bond-stake-sc/src/instructions/admin/mod.rs @@ -8,3 +8,5 @@ pub mod create_bond_config; pub use create_bond_config::*; pub mod rewards; pub use rewards::*; +pub mod initalize_vault; +pub use initalize_vault::*; diff --git a/programs/core-sol-bond-stake-sc/src/instructions/admin/rewards.rs b/programs/core-sol-bond-stake-sc/src/instructions/admin/rewards.rs index 27e133a..03e501f 100644 --- a/programs/core-sol-bond-stake-sc/src/instructions/admin/rewards.rs +++ b/programs/core-sol-bond-stake-sc/src/instructions/admin/rewards.rs @@ -52,9 +52,9 @@ pub struct RewardsContext<'info> { )] pub authority_token_account: Account<'info, TokenAccount>, - system_program: Program<'info, System>, - token_program: Program<'info, Token>, - associated_token_program: Program<'info, AssociatedToken>, + pub system_program: Program<'info, System>, + pub token_program: Program<'info, Token>, + pub associated_token_program: Program<'info, AssociatedToken>, } pub fn add_rewards(ctx: Context, amount: u64) -> Result<()> { diff --git a/programs/core-sol-bond-stake-sc/src/instructions/admin/update_bond_config.rs b/programs/core-sol-bond-stake-sc/src/instructions/admin/update_bond_config.rs index 664ba44..1f20361 100644 --- a/programs/core-sol-bond-stake-sc/src/instructions/admin/update_bond_config.rs +++ b/programs/core-sol-bond-stake-sc/src/instructions/admin/update_bond_config.rs @@ -25,12 +25,9 @@ pub fn update_bond_state(ctx: Context, state: u8) -> Result<() Ok(()) } -pub fn update_mint_of_collection( - ctx: Context, - mint_of_collection: Pubkey, -) -> Result<()> { +pub fn update_merkle_tree(ctx: Context, merkle_tree: Pubkey) -> Result<()> { let bond_config = &mut ctx.accounts.bond_config; - bond_config.mint_of_collection = mint_of_collection; + bond_config.merkle_tree = merkle_tree; Ok(()) } diff --git a/programs/core-sol-bond-stake-sc/src/instructions/admin/update_rewards_config.rs b/programs/core-sol-bond-stake-sc/src/instructions/admin/update_rewards_config.rs index e95aaa2..50c0490 100644 --- a/programs/core-sol-bond-stake-sc/src/instructions/admin/update_rewards_config.rs +++ b/programs/core-sol-bond-stake-sc/src/instructions/admin/update_rewards_config.rs @@ -1,6 +1,6 @@ use anchor_lang::prelude::*; -use crate::{RewardsConfig, ADMIN_PUBKEY, REWARDS_CONFIG_SEED}; +use crate::{get_current_slot, RewardsConfig, State, ADMIN_PUBKEY, REWARDS_CONFIG_SEED}; #[derive(Accounts)] pub struct UpdateRewardsConfig<'info> { @@ -21,6 +21,9 @@ pub struct UpdateRewardsConfig<'info> { pub fn update_rewards_state(ctx: Context, state: u8) -> Result<()> { let rewards_config = &mut ctx.accounts.rewards_config; rewards_config.rewards_state = state; + if state == State::Active.to_code() { + rewards_config.last_reward_slot = get_current_slot()?; + } Ok(()) } diff --git a/programs/core-sol-bond-stake-sc/src/instructions/bond.rs b/programs/core-sol-bond-stake-sc/src/instructions/bond.rs index 92bb424..398f45b 100644 --- a/programs/core-sol-bond-stake-sc/src/instructions/bond.rs +++ b/programs/core-sol-bond-stake-sc/src/instructions/bond.rs @@ -5,39 +5,39 @@ use anchor_spl::{ associated_token::AssociatedToken, token::{self, Mint, Token, TokenAccount, TransferChecked}, }; -use mpl_token_metadata::accounts::Metadata; +use mpl_bubblegum::{types::LeafSchema, utils::get_asset_id}; +use spl_account_compression::program::SplAccountCompression; use crate::{ - get_current_timestamp, update_address_claimable_rewards, AddressBonds, AddressRewards, Bond, - BondConfig, Errors, RewardsConfig, State, VaultConfig, ADDRESS_BONDS_SEED, - ADDRESS_REWARDS_SEED, BOND_CONFIG_SEED, BOND_SEED, REWARDS_CONFIG_SEED, VAULT_CONFIG_SEED, + compute_decay, compute_weighted_liveliness_decay, compute_weighted_liveliness_new, + get_current_timestamp, update_address_claimable_rewards, AddressBondsRewards, AssetUsage, Bond, + BondConfig, Errors, RewardsConfig, State, VaultConfig, ADDRESS_BONDS_REWARDS_SEED, + BOND_CONFIG_SEED, BOND_SEED, MAX_PERCENT, REWARDS_CONFIG_SEED, VAULT_CONFIG_SEED, }; #[derive(Accounts)] -#[instruction(bond_config_index: u8, bond_id:u8, amount: u64)] +#[instruction(bond_config_index: u8, bond_id:u8, amount: u64,nonce: u64)] pub struct BondContext<'info> { #[account( - init_if_needed, - payer=authority, - seeds=[ADDRESS_BONDS_SEED.as_bytes(), authority.key().as_ref()], - bump, - space=AddressBonds::INIT_SPACE + mut, + seeds=[ADDRESS_BONDS_REWARDS_SEED.as_bytes(), authority.key().as_ref()], + bump=address_bonds_rewards.bump, )] - pub address_bonds: Account<'info, AddressBonds>, + pub address_bonds_rewards: Box>, #[account( - init_if_needed, + init, payer=authority, - seeds=[ADDRESS_REWARDS_SEED.as_bytes(), authority.key().as_ref()], + seeds=[get_asset_id(&merkle_tree.key(), nonce).as_ref()], bump, - space=AddressRewards::INIT_SPACE + space=AssetUsage::INIT_SPACE )] - pub address_rewards: Account<'info, AddressRewards>, + pub asset_usage: Account<'info, AssetUsage>, #[account( init, payer = authority, - constraint=address_bonds.current_index + 1 == bond_id @ Errors::WrongBondId, + constraint=address_bonds_rewards.current_index + 1 == bond_id @ Errors::WrongBondId, seeds = [ BOND_SEED.as_bytes(), authority.key().as_ref(), @@ -52,18 +52,22 @@ pub struct BondContext<'info> { seeds=[BOND_CONFIG_SEED.as_bytes(),&bond_config_index.to_be_bytes()], bump=bond_config.bump, )] - pub bond_config: Account<'info, BondConfig>, + pub bond_config: Box>, #[account( + mut, seeds=[REWARDS_CONFIG_SEED.as_bytes()], bump=rewards_config.bump, )] - pub rewards_config: Account<'info, RewardsConfig>, + pub rewards_config: Box>, + #[account( + mut, seeds=[VAULT_CONFIG_SEED.as_bytes()], bump=vault_config.bump, + has_one=vault, )] - pub vault_config: Account<'info, VaultConfig>, + pub vault_config: Box>, #[account( mut, @@ -77,14 +81,17 @@ pub struct BondContext<'info> { )] pub mint_of_token_sent: Account<'info, Mint>, - #[account(mut)] + #[account( + mut, + constraint=address_bonds_rewards.address == authority.key() @ Errors::OwnerMismatch, + )] pub authority: Signer<'info>, - pub mint_of_nft: Account<'info, Mint>, - - /// CHECK: This is the account we'll fetch metadata for - #[account(mut)] - pub metadata: AccountInfo<'info>, + /// CHECK: unsafe + #[account( + constraint= merkle_tree.key() == bond_config.merkle_tree.key() @ Errors::MerkleTreeMismatch, + )] + pub merkle_tree: UncheckedAccount<'info>, #[account( mut, @@ -93,89 +100,85 @@ pub struct BondContext<'info> { constraint=authority_token_account.mint==vault_config.mint_of_token @ Errors::MintMismatch, ) ] - pub authority_token_account: Account<'info, TokenAccount>, + pub authority_token_account: Box>, - system_program: Program<'info, System>, - token_program: Program<'info, Token>, - associated_token_program: Program<'info, AssociatedToken>, + pub system_program: Program<'info, System>, + pub token_program: Program<'info, Token>, + pub associated_token_program: Program<'info, AssociatedToken>, + pub compression_program: Program<'info, SplAccountCompression>, } pub fn bond<'a, 'b, 'c: 'info, 'info>( ctx: Context<'a, 'b, 'c, 'info, BondContext<'info>>, bond_id: u8, amount: u64, + nonce: u64, is_vault: bool, + root: [u8; 32], + data_hash: [u8; 32], + creator_hash: [u8; 32], ) -> Result<()> { require!( ctx.accounts.bond_config.bond_amount == amount, Errors::WrongAmount ); + let current_timestamp = get_current_timestamp()?; + + let weight_to_be_added = amount * MAX_PERCENT; + let bond_to_be_added = amount; + + let decay = compute_decay( + ctx.accounts.address_bonds_rewards.last_update_timestamp, + current_timestamp, + ctx.accounts.bond_config.lock_period, + ); + + let weighted_liveliness_score_decayed = compute_weighted_liveliness_decay( + ctx.accounts.address_bonds_rewards.weighted_liveliness_score, + decay, + ); + update_address_claimable_rewards( &mut ctx.accounts.rewards_config, - &mut ctx.accounts.address_rewards, - &mut ctx.accounts.address_bonds, - ctx.remaining_accounts, - ctx.accounts.vault_config.total_bond_amount, - true, + &mut ctx.accounts.vault_config, + &mut ctx.accounts.address_bonds_rewards, )?; - // if bond_id == 1 { - // self.address_rewards.set_inner(AddressRewards { - // bump: bumps.address_rewards, - // address: self.authority.key(), - // address_rewards_per_share: 0, // after generate aggregated rewards set this to actual rewards per share - // claimable_amount: 0, - // padding: [0; 32], - // }); - // } else { - // // claim rewards - // } - - // Check if this is updated even if account exists - ctx.accounts.address_bonds.set_inner(AddressBonds { - bump: ctx.bumps.address_bonds, - address: ctx.accounts.authority.key(), - address_total_bond_amount: ctx.accounts.address_bonds.address_total_bond_amount + amount, - current_index: bond_id, - padding: [0; 32], - }); - - // Not really required - let (metadata, _) = Pubkey::find_program_address( - &[ - "metadata".as_bytes(), - mpl_token_metadata::ID.as_ref(), - ctx.accounts.mint_of_nft.key().as_ref(), - ], - &mpl_token_metadata::ID, - ); - // Not really required - require!( - metadata == ctx.accounts.metadata.key(), - Errors::MetadataAccountMismatch + let weighted_liveliness_score_new = compute_weighted_liveliness_new( + weighted_liveliness_score_decayed, + ctx.accounts.address_bonds_rewards.address_total_bond_amount, + weight_to_be_added, + 0, + bond_to_be_added, + 0, ); - let mint_metadata = Metadata::safe_deserialize(&ctx.accounts.metadata.try_borrow_data()?)?; + let address_bonds_rewards = &mut ctx.accounts.address_bonds_rewards; - // Check if the creator is the same as the authority - let collection_key = mint_metadata - .collection - .ok_or(Errors::MintFromWrongCollection)? - .key; + address_bonds_rewards.weighted_liveliness_score = weighted_liveliness_score_new; + address_bonds_rewards.last_update_timestamp = current_timestamp; - require!( - ctx.accounts.bond_config.mint_of_collection == collection_key, - Errors::MintFromWrongCollection - ); + // check leaf owner here + let asset_id = get_asset_id(&ctx.accounts.merkle_tree.key(), nonce); - let is_creator = mint_metadata.creators.map_or(false, |creators| { - creators - .iter() - .any(|c| c.address == ctx.accounts.authority.key()) - }); + let leaf = LeafSchema::V1 { + id: asset_id, + owner: ctx.accounts.authority.key(), + delegate: ctx.accounts.authority.key(), + nonce, + data_hash, + creator_hash, + }; + let cpi_ctx = CpiContext::new( + ctx.accounts.compression_program.to_account_info(), + spl_account_compression::cpi::accounts::VerifyLeaf { + merkle_tree: ctx.accounts.merkle_tree.to_account_info(), + }, + ) + .with_remaining_accounts(ctx.remaining_accounts.to_vec()); - require!(is_creator, Errors::NotTheMintCreator); + spl_account_compression::cpi::verify_leaf(cpi_ctx, root, leaf.hash(), nonce as u32)?; let current_timestamp = get_current_timestamp()?; @@ -202,6 +205,10 @@ pub fn bond<'a, 'b, 'c: 'info, 'info>( ctx.accounts.mint_of_token_sent.decimals, )?; + address_bonds_rewards.address_total_bond_amount += amount; + address_bonds_rewards.current_index = bond_id; + ctx.accounts.vault_config.total_bond_amount += amount; + ctx.accounts.bond.set_inner(Bond { bump: ctx.bumps.bond, state: State::Active.to_code(), @@ -209,8 +216,7 @@ pub fn bond<'a, 'b, 'c: 'info, 'info>( unbond_timestamp: current_timestamp.add(ctx.accounts.bond_config.lock_period), bond_timestamp: current_timestamp, bond_amount: amount, - lock_period: ctx.accounts.bond_config.lock_period, - mint_of_nft: ctx.accounts.mint_of_nft.key(), + asset_id: asset_id.key(), owner: ctx.accounts.authority.key(), padding: [0; 64], }); diff --git a/programs/core-sol-bond-stake-sc/src/instructions/claim_rewards.rs b/programs/core-sol-bond-stake-sc/src/instructions/claim_rewards.rs index 55158ba..51c2f56 100644 --- a/programs/core-sol-bond-stake-sc/src/instructions/claim_rewards.rs +++ b/programs/core-sol-bond-stake-sc/src/instructions/claim_rewards.rs @@ -5,26 +5,28 @@ use anchor_spl::{ }; use crate::{ - update_address_claimable_rewards, AddressBonds, AddressRewards, Errors, RewardsConfig, - VaultConfig, ADDRESS_BONDS_SEED, REWARDS_CONFIG_SEED, VAULT_CONFIG_SEED, + compute_decay, compute_weighted_liveliness_decay, compute_weighted_liveliness_new, + full_math::MulDiv, get_current_timestamp, update_address_claimable_rewards, + AddressBondsRewards, BondConfig, Errors, RewardsConfig, VaultConfig, + ADDRESS_BONDS_REWARDS_SEED, BOND_CONFIG_SEED, MAX_PERCENT, REWARDS_CONFIG_SEED, + VAULT_CONFIG_SEED, }; #[derive(Accounts)] +#[instruction(bond_config_index:u8)] pub struct ClaimRewards<'info> { #[account( mut, - seeds=[ADDRESS_BONDS_SEED.as_bytes(), authority.key().as_ref()], - bump=address_bonds.bump, + seeds=[ADDRESS_BONDS_REWARDS_SEED.as_bytes(), authority.key().as_ref()], + bump=address_bonds_rewards.bump, )] - pub address_bonds: Account<'info, AddressBonds>, + pub address_bonds_rewards: Box>, #[account( - mut, - seeds=[ADDRESS_BONDS_SEED.as_bytes(), authority.key().as_ref()], - bump=address_rewards.bump, - + seeds=[BOND_CONFIG_SEED.as_bytes(),&bond_config_index.to_be_bytes()], + bump=bond_config.bump, )] - pub address_rewards: Account<'info, AddressRewards>, + pub bond_config: Account<'info, BondConfig>, #[account( mut, @@ -56,8 +58,7 @@ pub struct ClaimRewards<'info> { #[account( mut, - constraint=address_bonds.address == authority.key() @ Errors::WrongOwner, - constraint=address_rewards.address==authority.key() @Errors::WrongOwner, + constraint=address_bonds_rewards.address==authority.key() @Errors::OwnerMismatch, )] pub authority: Signer<'info>, @@ -81,27 +82,60 @@ pub fn claim_rewards<'a, 'b, 'c: 'info, 'info>( &[ctx.accounts.vault_config.bump], ]]; + let current_timestamp = get_current_timestamp()?; + + let decay = compute_decay( + ctx.accounts.address_bonds_rewards.last_update_timestamp, + current_timestamp, + ctx.accounts.bond_config.lock_period, + ); + + let weighted_liveliness_score_decayed = compute_weighted_liveliness_decay( + ctx.accounts.address_bonds_rewards.weighted_liveliness_score, + decay, + ); + + let weighted_liveliness_score_new = compute_weighted_liveliness_new( + weighted_liveliness_score_decayed, + ctx.accounts.address_bonds_rewards.address_total_bond_amount, + 0, + 0, + 0, + 0, + ); + update_address_claimable_rewards( &mut ctx.accounts.rewards_config, - &mut ctx.accounts.address_rewards, - &mut ctx.accounts.address_bonds, - ctx.remaining_accounts, - ctx.accounts.vault_config.total_bond_amount, - false, + &ctx.accounts.vault_config, + &mut ctx.accounts.address_bonds_rewards, )?; require!( - ctx.accounts.vault.amount >= ctx.accounts.address_rewards.claimable_amount, + ctx.accounts.vault.amount >= ctx.accounts.address_bonds_rewards.claimable_amount, Errors::NotEnoughBalance ); - let address_rewards = &mut ctx.accounts.address_rewards; + let address_bonds_rewards = &mut ctx.accounts.address_bonds_rewards; + + let actual_claimable_amount; + + if weighted_liveliness_score_decayed >= 95_00u64 { + actual_claimable_amount = address_bonds_rewards.claimable_amount; + } else { + actual_claimable_amount = address_bonds_rewards + .claimable_amount + .mul_div_floor(weighted_liveliness_score_decayed, MAX_PERCENT) + .unwrap(); + } + + address_bonds_rewards.weighted_liveliness_score = weighted_liveliness_score_new; + address_bonds_rewards.last_update_timestamp = current_timestamp; let cpi_accounts = TransferChecked { from: ctx.accounts.vault.to_account_info(), to: ctx.accounts.authority_token_account.to_account_info(), mint: ctx.accounts.mint_of_token_to_receive.to_account_info(), - authority: ctx.accounts.authority.to_account_info(), + authority: ctx.accounts.vault_config.to_account_info(), }; let cpi_ctx = CpiContext::new(ctx.accounts.token_program.to_account_info(), cpi_accounts) @@ -109,11 +143,11 @@ pub fn claim_rewards<'a, 'b, 'c: 'info, 'info>( transfer_checked( cpi_ctx, - address_rewards.claimable_amount, + actual_claimable_amount, ctx.accounts.mint_of_token_to_receive.decimals, )?; - address_rewards.claimable_amount = 0; + address_bonds_rewards.claimable_amount = 0; Ok(()) } diff --git a/programs/core-sol-bond-stake-sc/src/instructions/initialize_address.rs b/programs/core-sol-bond-stake-sc/src/instructions/initialize_address.rs new file mode 100644 index 0000000..6dbd947 --- /dev/null +++ b/programs/core-sol-bond-stake-sc/src/instructions/initialize_address.rs @@ -0,0 +1,47 @@ +use anchor_lang::prelude::*; + +use crate::{ + get_current_timestamp, AddressBondsRewards, RewardsConfig, ADDRESS_BONDS_REWARDS_SEED, + REWARDS_CONFIG_SEED, +}; + +#[derive(Accounts)] +pub struct InitializeAddress<'info> { + #[account( + init, + payer=authority, + seeds=[ADDRESS_BONDS_REWARDS_SEED.as_bytes(), authority.key().as_ref()], + bump, + space=AddressBondsRewards::INIT_SPACE + )] + pub address_bonds_rewards: Account<'info, AddressBondsRewards>, + + #[account( + seeds=[REWARDS_CONFIG_SEED.as_bytes()], + bump=rewards_config.bump, + )] + pub rewards_config: Box>, + + #[account(mut)] + pub authority: Signer<'info>, + + pub system_program: Program<'info, System>, +} + +pub fn initialize_address<'info>(ctx: Context>) -> Result<()> { + ctx.accounts + .address_bonds_rewards + .set_inner(AddressBondsRewards { + bump: ctx.bumps.address_bonds_rewards, + address: ctx.accounts.authority.key(), + address_total_bond_amount: 0, + current_index: 0, + weighted_liveliness_score: 0, + last_update_timestamp: get_current_timestamp()?, + address_rewards_per_share: ctx.accounts.rewards_config.rewards_per_share, + claimable_amount: 0, + padding: [0; 16], + }); + + Ok(()) +} diff --git a/programs/core-sol-bond-stake-sc/src/instructions/mod.rs b/programs/core-sol-bond-stake-sc/src/instructions/mod.rs index 444d305..6824bdd 100644 --- a/programs/core-sol-bond-stake-sc/src/instructions/mod.rs +++ b/programs/core-sol-bond-stake-sc/src/instructions/mod.rs @@ -13,3 +13,5 @@ pub mod stake_rewards; pub use stake_rewards::*; pub mod claim_rewards; pub use claim_rewards::*; +pub mod initialize_address; +pub use initialize_address::*; diff --git a/programs/core-sol-bond-stake-sc/src/instructions/renew.rs b/programs/core-sol-bond-stake-sc/src/instructions/renew.rs index 4e7219d..02ae1ce 100644 --- a/programs/core-sol-bond-stake-sc/src/instructions/renew.rs +++ b/programs/core-sol-bond-stake-sc/src/instructions/renew.rs @@ -1,10 +1,44 @@ use anchor_lang::prelude::*; -use crate::{get_current_timestamp, Bond, Errors, BOND_SEED}; +use crate::{ + compute_decay, compute_weighted_liveliness_decay, compute_weighted_liveliness_new, + full_math::MulDiv, get_current_timestamp, update_address_claimable_rewards, + AddressBondsRewards, Bond, BondConfig, Errors, RewardsConfig, State, VaultConfig, + ADDRESS_BONDS_REWARDS_SEED, BOND_CONFIG_SEED, BOND_SEED, MAX_PERCENT, REWARDS_CONFIG_SEED, + VAULT_CONFIG_SEED, +}; #[derive(Accounts)] -#[instruction(bond_id:u8)] +#[instruction(bond_config_index:u8,bond_id:u8)] pub struct Renew<'info> { + #[account( + seeds=[BOND_CONFIG_SEED.as_bytes(),&bond_config_index.to_be_bytes()], + bump=bond_config.bump, + )] + pub bond_config: Account<'info, BondConfig>, + + #[account( + mut, + seeds=[REWARDS_CONFIG_SEED.as_bytes()], + bump=rewards_config.bump, + + )] + pub rewards_config: Account<'info, RewardsConfig>, + + #[account( + mut, + seeds=[VAULT_CONFIG_SEED.as_bytes()], + bump=vault_config.bump, + )] + pub vault_config: Account<'info, VaultConfig>, + + #[account( + mut, + seeds=[ADDRESS_BONDS_REWARDS_SEED.as_bytes(), authority.key().as_ref()], + bump=address_bonds_rewards.bump, + )] + pub address_bonds_rewards: Box>, + #[account( mut, seeds = [ @@ -19,7 +53,8 @@ pub struct Renew<'info> { #[account( mut, - constraint=bond.owner == authority.key() @ Errors::WrongOwner, + constraint=bond.owner == authority.key() @ Errors::OwnerMismatch, + constraint=address_bonds_rewards.address==authority.key() @Errors::OwnerMismatch, )] pub authority: Signer<'info>, } @@ -29,7 +64,56 @@ pub fn renew(ctx: Context) -> Result<()> { let bond = &mut ctx.accounts.bond; - bond.unbond_timestamp = current_timestamp + bond.lock_period; + require!( + bond.state == State::Active.to_code(), + Errors::BondIsInactive + ); + + let weight_to_be_added = bond.bond_amount * MAX_PERCENT; + let weight_to_be_subtracted = if current_timestamp < bond.unbond_timestamp { + bond.bond_amount + .mul_div_floor( + bond.unbond_timestamp - current_timestamp, + ctx.accounts.bond_config.lock_period, + ) + .unwrap() + * MAX_PERCENT + } else { + 0 + }; + + let decay = compute_decay( + ctx.accounts.address_bonds_rewards.last_update_timestamp, + current_timestamp, + ctx.accounts.bond_config.lock_period, + ); + + let weighted_liveliness_score_decayed = compute_weighted_liveliness_decay( + ctx.accounts.address_bonds_rewards.weighted_liveliness_score, + decay, + ); + + update_address_claimable_rewards( + &mut ctx.accounts.rewards_config, + &ctx.accounts.vault_config, + &mut ctx.accounts.address_bonds_rewards, + )?; + + let weighted_liveliness_score_new = compute_weighted_liveliness_new( + weighted_liveliness_score_decayed, + ctx.accounts.address_bonds_rewards.address_total_bond_amount, + weight_to_be_added, + weight_to_be_subtracted, + 0, + 0, + ); + + let address_bonds_rewards = &mut ctx.accounts.address_bonds_rewards; + + address_bonds_rewards.weighted_liveliness_score = weighted_liveliness_score_new; + address_bonds_rewards.last_update_timestamp = current_timestamp; + + bond.unbond_timestamp = current_timestamp + ctx.accounts.bond_config.lock_period; bond.bond_timestamp = current_timestamp; Ok(()) diff --git a/programs/core-sol-bond-stake-sc/src/instructions/stake_rewards.rs b/programs/core-sol-bond-stake-sc/src/instructions/stake_rewards.rs index cafaeae..35e6055 100644 --- a/programs/core-sol-bond-stake-sc/src/instructions/stake_rewards.rs +++ b/programs/core-sol-bond-stake-sc/src/instructions/stake_rewards.rs @@ -1,28 +1,22 @@ use anchor_lang::prelude::*; use crate::{ - get_current_timestamp, update_address_claimable_rewards, AddressBonds, AddressRewards, Bond, - Errors, RewardsConfig, VaultConfig, ADDRESS_BONDS_SEED, BOND_SEED, REWARDS_CONFIG_SEED, + compute_decay, compute_weighted_liveliness_decay, compute_weighted_liveliness_new, + full_math::MulDiv, get_current_timestamp, update_address_claimable_rewards, + AddressBondsRewards, Bond, BondConfig, Errors, RewardsConfig, State, VaultConfig, + ADDRESS_BONDS_REWARDS_SEED, BOND_CONFIG_SEED, BOND_SEED, MAX_PERCENT, REWARDS_CONFIG_SEED, VAULT_CONFIG_SEED, }; #[derive(Accounts)] -#[instruction(bond_id:u8)] +#[instruction(bond_config_index:u8,bond_id:u8)] pub struct StakeRewards<'info> { #[account( mut, - seeds=[ADDRESS_BONDS_SEED.as_bytes(), authority.key().as_ref()], - bump=address_bonds.bump, + seeds=[ADDRESS_BONDS_REWARDS_SEED.as_bytes(), authority.key().as_ref()], + bump=address_bonds_rewards.bump, )] - pub address_bonds: Account<'info, AddressBonds>, - - #[account( - mut, - seeds=[ADDRESS_BONDS_SEED.as_bytes(), authority.key().as_ref()], - bump=address_rewards.bump, - - )] - pub address_rewards: Account<'info, AddressRewards>, + pub address_bonds_rewards: Box>, #[account( mut, @@ -36,6 +30,12 @@ pub struct StakeRewards<'info> { )] pub bond: Account<'info, Bond>, + #[account( + seeds=[BOND_CONFIG_SEED.as_bytes(),&bond_config_index.to_be_bytes()], + bump=bond_config.bump, + )] + pub bond_config: Account<'info, BondConfig>, + #[account( mut, seeds=[REWARDS_CONFIG_SEED.as_bytes()], @@ -53,8 +53,8 @@ pub struct StakeRewards<'info> { #[account( mut, - constraint=address_bonds.address == authority.key() @ Errors::WrongOwner, - constraint=address_rewards.address==authority.key() @Errors::WrongOwner, + constraint=bond.owner == authority.key() @ Errors::OwnerMismatch, + constraint=address_bonds_rewards.address==authority.key() @Errors::OwnerMismatch, )] pub authority: Signer<'info>, } @@ -64,31 +64,84 @@ pub fn stake_rewards<'a, 'b, 'c: 'info, 'info>( ) -> Result<()> { require!(ctx.accounts.bond.is_vault, Errors::BondIsNotAVault); + require!( + ctx.accounts.bond.state == State::Active.to_code(), + Errors::BondIsInactive + ); + + let current_timestamp = get_current_timestamp()?; + + let decay = compute_decay( + ctx.accounts.address_bonds_rewards.last_update_timestamp, + current_timestamp, + ctx.accounts.bond_config.lock_period, + ); + + let weighted_liveliness_score_decayed = compute_weighted_liveliness_decay( + ctx.accounts.address_bonds_rewards.weighted_liveliness_score, + decay, + ); + update_address_claimable_rewards( &mut ctx.accounts.rewards_config, - &mut ctx.accounts.address_rewards, - &mut ctx.accounts.address_bonds, - ctx.remaining_accounts, - ctx.accounts.vault_config.total_bond_amount, - false, + &mut ctx.accounts.vault_config, + &mut ctx.accounts.address_bonds_rewards, )?; let current_timestamp = get_current_timestamp()?; - let address_rewards = &mut ctx.accounts.address_rewards; - let address_bonds = &mut ctx.accounts.address_bonds; + let address_bonds_rewards = &mut ctx.accounts.address_bonds_rewards; let vault_config = &mut ctx.accounts.vault_config; let bond = &mut ctx.accounts.bond; - bond.unbond_timestamp = current_timestamp + bond.lock_period; + let weight_to_be_subtracted = if current_timestamp < bond.unbond_timestamp { + bond.bond_amount + .mul_div_floor( + bond.unbond_timestamp - current_timestamp, + ctx.accounts.bond_config.lock_period, + ) + .unwrap() + * MAX_PERCENT + } else { + 0 + }; + let bond_to_be_subtracted = bond.bond_amount; + + let actual_claimable_amount; + + if weighted_liveliness_score_decayed >= 95_00u64 { + actual_claimable_amount = address_bonds_rewards.claimable_amount; + } else { + actual_claimable_amount = address_bonds_rewards + .claimable_amount + .mul_div_floor(weighted_liveliness_score_decayed, MAX_PERCENT) + .unwrap(); + } + + bond.unbond_timestamp = current_timestamp + ctx.accounts.bond_config.lock_period; bond.bond_timestamp = current_timestamp; - bond.bond_amount += &address_rewards.claimable_amount; + bond.bond_amount += &actual_claimable_amount; + + address_bonds_rewards.address_total_bond_amount += actual_claimable_amount; + vault_config.total_bond_amount += &actual_claimable_amount; + + address_bonds_rewards.claimable_amount = 0; + + let weight_to_be_added = bond.bond_amount * MAX_PERCENT; + let bond_to_be_added: u64 = bond.bond_amount; - address_bonds.address_total_bond_amount += &address_rewards.claimable_amount; - vault_config.total_bond_amount += &address_rewards.claimable_amount; + let weighted_liveliness_score_new = compute_weighted_liveliness_new( + weighted_liveliness_score_decayed, + address_bonds_rewards.address_total_bond_amount, + weight_to_be_added, + weight_to_be_subtracted, + bond_to_be_added, + bond_to_be_subtracted, + ); - address_rewards.claimable_amount = 0; + address_bonds_rewards.weighted_liveliness_score = weighted_liveliness_score_new; + address_bonds_rewards.last_update_timestamp = current_timestamp; Ok(()) } diff --git a/programs/core-sol-bond-stake-sc/src/instructions/topup.rs b/programs/core-sol-bond-stake-sc/src/instructions/topup.rs index 5638de9..8062019 100644 --- a/programs/core-sol-bond-stake-sc/src/instructions/topup.rs +++ b/programs/core-sol-bond-stake-sc/src/instructions/topup.rs @@ -5,29 +5,29 @@ use anchor_spl::{ }; use crate::{ - get_current_timestamp, update_address_claimable_rewards, AddressBonds, AddressRewards, Bond, - Errors, RewardsConfig, State, VaultConfig, ADDRESS_BONDS_SEED, BOND_SEED, REWARDS_CONFIG_SEED, + compute_decay, compute_weighted_liveliness_decay, compute_weighted_liveliness_new, + full_math::MulDiv, get_current_timestamp, update_address_claimable_rewards, + AddressBondsRewards, Bond, BondConfig, Errors, RewardsConfig, State, VaultConfig, + ADDRESS_BONDS_REWARDS_SEED, BOND_CONFIG_SEED, BOND_SEED, MAX_PERCENT, REWARDS_CONFIG_SEED, VAULT_CONFIG_SEED, }; #[derive(Accounts)] -#[instruction(bond_id: u8, amount:u64)] +#[instruction(bond_config_index:u8,bond_id: u8, amount:u64)] pub struct TopUp<'info> { #[account( mut, - seeds=[ADDRESS_BONDS_SEED.as_bytes(), authority.key().as_ref()], - bump=address_bonds.bump, + seeds=[ADDRESS_BONDS_REWARDS_SEED.as_bytes(), authority.key().as_ref()], + bump=address_bonds_rewards.bump, )] - pub address_bonds: Account<'info, AddressBonds>, + pub address_bonds_rewards: Box>, #[account( - mut, - seeds=[ADDRESS_BONDS_SEED.as_bytes(), authority.key().as_ref()], - bump=address_rewards.bump, - + seeds=[BOND_CONFIG_SEED.as_bytes(),&bond_config_index.to_be_bytes()], + bump=bond_config.bump, )] - pub address_rewards: Account<'info, AddressRewards>, + pub bond_config: Account<'info, BondConfig>, #[account( mut, @@ -64,7 +64,6 @@ pub struct TopUp<'info> { #[account( mut, - constraint=vault.amount >= bond.bond_amount @ Errors::NotEnoughBalance, associated_token::mint=vault_config.mint_of_token, associated_token::authority=vault_config, )] @@ -72,9 +71,8 @@ pub struct TopUp<'info> { #[account( mut, - constraint=bond.owner == authority.key() @ Errors::WrongOwner, - constraint=address_bonds.address == authority.key() @ Errors::WrongOwner, - constraint=address_rewards.address==authority.key() @Errors::WrongOwner, + constraint=bond.owner == authority.key() @ Errors::OwnerMismatch, + constraint=address_bonds_rewards.address==authority.key() @Errors::OwnerMismatch, )] pub authority: Signer<'info>, @@ -94,15 +92,6 @@ pub fn top_up<'a, 'b, 'c: 'info, 'info>( ctx: Context<'a, 'b, 'c, 'info, TopUp<'info>>, amount: u64, ) -> Result<()> { - update_address_claimable_rewards( - &mut ctx.accounts.rewards_config, - &mut ctx.accounts.address_rewards, - &mut ctx.accounts.address_bonds, - ctx.remaining_accounts, - ctx.accounts.vault_config.total_bond_amount, - true, - )?; - let bond = &mut ctx.accounts.bond; require!( @@ -112,16 +101,61 @@ pub fn top_up<'a, 'b, 'c: 'info, 'info>( require!(bond.is_vault, Errors::BondIsNotAVault); - let vault_config = &mut ctx.accounts.vault_config; - let current_timestamp = get_current_timestamp()?; - bond.unbond_timestamp = current_timestamp + bond.lock_period; - bond.bond_timestamp = current_timestamp; - bond.bond_amount += amount; + let weight_to_be_added = (bond.bond_amount + amount) * MAX_PERCENT; + let bond_to_be_added = amount; + let weight_to_be_subtracted = if current_timestamp < bond.unbond_timestamp { + bond.bond_amount + .mul_div_floor( + bond.unbond_timestamp - current_timestamp, + ctx.accounts.bond_config.lock_period, + ) + .unwrap() + * MAX_PERCENT + } else { + 0 + }; + let decay = compute_decay( + ctx.accounts.address_bonds_rewards.last_update_timestamp, + current_timestamp, + ctx.accounts.bond_config.lock_period, + ); + + let weighted_liveliness_score_decayed = compute_weighted_liveliness_decay( + ctx.accounts.address_bonds_rewards.weighted_liveliness_score, + decay, + ); + + update_address_claimable_rewards( + &mut ctx.accounts.rewards_config, + &ctx.accounts.vault_config, + &mut ctx.accounts.address_bonds_rewards, + )?; + + let weighted_liveliness_score_new = compute_weighted_liveliness_new( + weighted_liveliness_score_decayed, + ctx.accounts.address_bonds_rewards.address_total_bond_amount, + weight_to_be_added, + weight_to_be_subtracted, + bond_to_be_added, + 0, + ); + + let address_bonds_rewards = &mut ctx.accounts.address_bonds_rewards; + + address_bonds_rewards.weighted_liveliness_score = weighted_liveliness_score_new; + address_bonds_rewards.last_update_timestamp = current_timestamp; + address_bonds_rewards.address_total_bond_amount += amount; + + let vault_config = &mut ctx.accounts.vault_config; vault_config.total_bond_amount += amount; + bond.unbond_timestamp = current_timestamp + ctx.accounts.bond_config.lock_period; + bond.bond_timestamp = current_timestamp; + bond.bond_amount += amount; + // transfer amount to vault let cpi_accounts = TransferChecked { diff --git a/programs/core-sol-bond-stake-sc/src/instructions/withdraw.rs b/programs/core-sol-bond-stake-sc/src/instructions/withdraw.rs index 246a89f..504a6c1 100644 --- a/programs/core-sol-bond-stake-sc/src/instructions/withdraw.rs +++ b/programs/core-sol-bond-stake-sc/src/instructions/withdraw.rs @@ -5,9 +5,11 @@ use anchor_spl::{ }; use crate::{ - get_current_timestamp, update_address_claimable_rewards, AddressBonds, AddressRewards, Bond, - BondConfig, Errors, RewardsConfig, State, VaultConfig, ADDRESS_BONDS_SEED, BOND_CONFIG_SEED, - BOND_SEED, MAX_PERCENT, REWARDS_CONFIG_SEED, VAULT_CONFIG_SEED, + compute_decay, compute_weighted_liveliness_decay, compute_weighted_liveliness_new, + full_math::MulDiv, get_current_timestamp, update_address_claimable_rewards, + AddressBondsRewards, Bond, BondConfig, Errors, RewardsConfig, State, VaultConfig, + ADDRESS_BONDS_REWARDS_SEED, BOND_CONFIG_SEED, BOND_SEED, MAX_PERCENT, REWARDS_CONFIG_SEED, + VAULT_CONFIG_SEED, }; #[derive(Accounts)] @@ -21,18 +23,10 @@ pub struct Withdraw<'info> { #[account( mut, - seeds=[ADDRESS_BONDS_SEED.as_bytes(), authority.key().as_ref()], - bump=address_bonds.bump, + seeds=[ADDRESS_BONDS_REWARDS_SEED.as_bytes(), authority.key().as_ref()], + bump=address_bonds_rewards.bump, )] - pub address_bonds: Account<'info, AddressBonds>, - - #[account( - mut, - seeds=[ADDRESS_BONDS_SEED.as_bytes(), authority.key().as_ref()], - bump=address_rewards.bump, - - )] - pub address_rewards: Account<'info, AddressRewards>, + pub address_bonds_rewards: Box>, #[account( mut, @@ -77,9 +71,8 @@ pub struct Withdraw<'info> { #[account( mut, - constraint=bond.owner == authority.key() @ Errors::WrongOwner, - constraint=address_bonds.address == authority.key() @ Errors::WrongOwner, - constraint=address_rewards.address==authority.key() @Errors::WrongOwner, + constraint=bond.owner == authority.key() @ Errors::OwnerMismatch, + constraint=address_bonds_rewards.address==authority.key() @Errors::OwnerMismatch, )] pub authority: Signer<'info>, @@ -103,15 +96,6 @@ pub fn withdraw<'a, 'b, 'c: 'info, 'info>( &[ctx.accounts.vault_config.bump], ]]; - update_address_claimable_rewards( - &mut ctx.accounts.rewards_config, - &mut ctx.accounts.address_rewards, - &mut ctx.accounts.address_bonds, - ctx.remaining_accounts, - ctx.accounts.vault_config.total_bond_amount, - true, - )?; - let bond_config = &ctx.accounts.bond_config; let vault_config = &mut ctx.accounts.vault_config; @@ -121,10 +105,54 @@ pub fn withdraw<'a, 'b, 'c: 'info, 'info>( bond.state == State::Active.to_code(), Errors::BondIsInactive ); + let current_timestamp = get_current_timestamp()?; - let mut penalty = 0u64; + let weight_to_be_subtracted = if current_timestamp < bond.unbond_timestamp { + bond.bond_amount + .mul_div_floor( + bond.unbond_timestamp - current_timestamp, + ctx.accounts.bond_config.lock_period, + ) + .unwrap() + * MAX_PERCENT + } else { + 0 + }; - let current_timestamp = get_current_timestamp()?; + let bond_amount_to_be_subtracted = bond.bond_amount; + + let decay = compute_decay( + ctx.accounts.address_bonds_rewards.last_update_timestamp, + current_timestamp, + ctx.accounts.bond_config.lock_period, + ); + + let weighted_liveliness_score_decayed = compute_weighted_liveliness_decay( + ctx.accounts.address_bonds_rewards.weighted_liveliness_score, + decay, + ); + + update_address_claimable_rewards( + &mut ctx.accounts.rewards_config, + vault_config, + &mut ctx.accounts.address_bonds_rewards, + )?; + + let weighted_liveliness_score_new = compute_weighted_liveliness_new( + weighted_liveliness_score_decayed, + ctx.accounts.address_bonds_rewards.address_total_bond_amount, + 0, + weight_to_be_subtracted, + 0, + bond_amount_to_be_subtracted, + ); + + let address_bonds_rewards = &mut ctx.accounts.address_bonds_rewards; + + address_bonds_rewards.weighted_liveliness_score = weighted_liveliness_score_new; + address_bonds_rewards.last_update_timestamp = current_timestamp; + + let mut penalty = 0u64; if bond.unbond_timestamp >= current_timestamp { penalty = bond.bond_amount * bond_config.withdraw_penalty / MAX_PERCENT; @@ -133,8 +161,6 @@ pub fn withdraw<'a, 'b, 'c: 'info, 'info>( vault_config.total_penalized_amount += penalty; vault_config.total_bond_amount -= bond.bond_amount; - bond.state = State::Inactive.to_code(); - // transfer bond to authority let cpi_accounts = TransferChecked { @@ -153,5 +179,11 @@ pub fn withdraw<'a, 'b, 'c: 'info, 'info>( ctx.accounts.mint_of_token_to_receive.decimals, )?; + address_bonds_rewards.address_total_bond_amount -= bond.bond_amount; + + bond.state = State::Inactive.to_code(); + bond.unbond_timestamp = current_timestamp; + bond.bond_amount = 0; + Ok(()) } diff --git a/programs/core-sol-bond-stake-sc/src/lib.rs b/programs/core-sol-bond-stake-sc/src/lib.rs index 245e178..983979e 100644 --- a/programs/core-sol-bond-stake-sc/src/lib.rs +++ b/programs/core-sol-bond-stake-sc/src/lib.rs @@ -13,7 +13,7 @@ use constants::*; mod errors; use errors::*; -declare_id!("2gxhxhiRqQazdyniirt9QHhJk9aguG1RgtAhfo5B4yDY"); +declare_id!("4zAKaiW68x31n7mRbYQBUgTC9BWL3q4uATjuBc5txYSN"); #[program] pub mod core_sol_bond_stake_sc { @@ -40,6 +40,10 @@ pub mod core_sol_bond_stake_sc { ) } + pub fn initialize_vault(ctx: Context) -> Result<()> { + instructions::initialize_vault(ctx) + } + // Create new bond config pub fn create_bond_config( ctx: Context, @@ -60,12 +64,12 @@ pub mod core_sol_bond_stake_sc { instructions::update_bond_state(ctx, State::Inactive.to_code()) } - pub fn update_mint_of_collection( + pub fn update_merkle_tree( ctx: Context, _index: u8, - mint_of_collection: Pubkey, + merkle_tree: Pubkey, ) -> Result<()> { - instructions::update_mint_of_collection(ctx, mint_of_collection) + instructions::update_merkle_tree(ctx, merkle_tree) } pub fn update_lock_period( @@ -123,17 +127,42 @@ pub mod core_sol_bond_stake_sc { // Bonding + pub fn initialize_address(ctx: Context) -> Result<()> { + instructions::initialize_address(ctx) + } + pub fn bond<'a, 'b, 'c: 'info, 'info>( ctx: Context<'a, 'b, 'info, 'info, BondContext<'info>>, _bond_config_index: u8, bond_id: u8, amount: u64, + nonce: u64, is_vault: bool, + root: [u8; 32], + data_hash: [u8; 32], + creator_hash: [u8; 32], ) -> Result<()> { - instructions::bond(ctx, bond_id, amount, is_vault) + require!( + ctx.accounts.bond_config.bond_state == State::Active.to_code(), + Errors::ProgramIsPaused + ); + instructions::bond( + ctx, + bond_id, + amount, + nonce, + is_vault, + root, + data_hash, + creator_hash, + ) } - pub fn renew(ctx: Context, _bond_id: u8) -> Result<()> { + pub fn renew(ctx: Context, _bond_config_index: u8, _bond_id: u8) -> Result<()> { + require!( + ctx.accounts.bond_config.bond_state == State::Active.to_code(), + Errors::ProgramIsPaused + ); instructions::renew(ctx) } @@ -142,14 +171,23 @@ pub mod core_sol_bond_stake_sc { _bond_config_index: u8, _bond_id: u8, ) -> Result<()> { + require!( + ctx.accounts.bond_config.bond_state == State::Active.to_code(), + Errors::ProgramIsPaused + ); instructions::withdraw(ctx) } pub fn top_up<'a, 'b, 'c: 'info, 'info>( ctx: Context<'a, 'b, 'c, 'info, TopUp<'info>>, + _bond_config_index: u8, _bond_id: u8, amount: u64, ) -> Result<()> { + require!( + ctx.accounts.bond_config.bond_state == State::Active.to_code(), + Errors::ProgramIsPaused + ); instructions::top_up(ctx, amount) } @@ -157,13 +195,28 @@ pub mod core_sol_bond_stake_sc { pub fn stake_rewards<'a, 'b, 'c: 'info, 'info>( ctx: Context<'a, 'b, 'c, 'info, StakeRewards<'info>>, + _bond_config_index: u8, + _bond_id: u8, ) -> Result<()> { + require!( + ctx.accounts.bond_config.bond_state == State::Active.to_code(), + Errors::ProgramIsPaused + ); + require!( + ctx.accounts.rewards_config.rewards_state == State::Active.to_code(), + Errors::ProgramIsPaused + ); instructions::stake_rewards(ctx) } pub fn claim_rewards<'a, 'b, 'c: 'info, 'info>( ctx: Context<'a, 'b, 'c, 'info, ClaimRewards<'info>>, + _bond_config_index: u8, ) -> Result<()> { + require!( + ctx.accounts.rewards_config.rewards_state == State::Active.to_code(), + Errors::ProgramIsPaused + ); instructions::claim_rewards(ctx) } } diff --git a/programs/core-sol-bond-stake-sc/src/libraries/rewards.rs b/programs/core-sol-bond-stake-sc/src/libraries/rewards.rs index d0dc6c0..8024405 100644 --- a/programs/core-sol-bond-stake-sc/src/libraries/rewards.rs +++ b/programs/core-sol-bond-stake-sc/src/libraries/rewards.rs @@ -1,23 +1,23 @@ use crate::{ - compute_bond_score, get_current_slot, get_current_timestamp, AddressBonds, AddressRewards, - Bond, Errors, RewardsConfig, State, DIVISION_SAFETY_CONST, MAX_PERCENT, SLOTS_IN_YEAR, + get_current_slot, AddressBondsRewards, RewardsConfig, State, VaultConfig, + DIVISION_SAFETY_CONST, MAX_PERCENT, SLOTS_IN_YEAR, }; use anchor_lang::prelude::*; use super::full_math::MulDiv; pub fn generate_aggregated_rewards<'a, 'b, 'c: 'info, 'info>( - total_bond_amount: u64, rewards_config: &mut Account<'info, RewardsConfig>, + vault_config: &Account<'info, VaultConfig>, ) -> Result<()> { let last_reward_slot = rewards_config.last_reward_slot; let extra_rewards_unbounded = calculate_rewards_since_last_allocation(rewards_config)?; let max_apr = rewards_config.max_apr; let extra_rewards: u64; - if max_apr == 0 { + if max_apr > 0 { let extra_rewards_apr_bonded_per_slot = - get_amount_apr_bounded(rewards_config.max_apr, rewards_config.rewards_reserve); + get_amount_apr_bounded(rewards_config.max_apr, vault_config.total_bond_amount); let current_slot = get_current_slot()?; @@ -32,7 +32,7 @@ pub fn generate_aggregated_rewards<'a, 'b, 'c: 'info, 'info>( if extra_rewards > 0 && extra_rewards <= rewards_config.rewards_reserve { let increment = extra_rewards - .mul_div_floor(DIVISION_SAFETY_CONST, total_bond_amount) + .mul_div_floor(DIVISION_SAFETY_CONST, vault_config.total_bond_amount) .unwrap(); rewards_config.rewards_per_share += increment; @@ -73,8 +73,6 @@ pub fn calculate_address_share_in_rewards( address_bond_amount: u64, address_rewards_per_share: u64, total_bond_amount: u64, - liveliness_score: u64, - bypass_liveliness_score: bool, ) -> u64 { if total_bond_amount == 0 { return 0; @@ -84,75 +82,66 @@ pub fn calculate_address_share_in_rewards( return 0; } + let diff = rewards_per_share - address_rewards_per_share; + let address_rewards = address_bond_amount - .mul_div_floor( - rewards_per_share - address_rewards_per_share, - DIVISION_SAFETY_CONST, - ) + .mul_div_floor(diff, DIVISION_SAFETY_CONST) .unwrap(); - if liveliness_score >= 95_00u64 || bypass_liveliness_score { - address_rewards - } else { - address_rewards - .mul_div_floor(liveliness_score, MAX_PERCENT) - .unwrap() - } + address_rewards } pub fn update_address_claimable_rewards<'info>( rewards_config: &mut Account<'info, RewardsConfig>, - address_rewards: &mut Account<'info, AddressRewards>, - address_bonds: &mut Account<'info, AddressBonds>, - remaining_accounts: &'info [AccountInfo<'info>], - total_bond_amount: u64, - bypass_liveliness_score: bool, + vault_config: &Account<'info, VaultConfig>, + address_bonds_rewards: &mut Account<'info, AddressBondsRewards>, ) -> Result<()> { - generate_aggregated_rewards(total_bond_amount, rewards_config)?; - - let current_timestamp = get_current_timestamp()?; - - let mut liveliness_score = 0u64; - - if !bypass_liveliness_score { - // fetch remaining accounts and compute liveliness - require!( - remaining_accounts.len() == address_bonds.current_index as usize, - Errors::InvalidRemainingAccounts - ); - - let mut total_bond_score = 0u64; - let mut bond_amounts = 0u64; - - // load remaining accounts on the heap - for account in remaining_accounts.iter() { - let bond = Box::new(Account::::try_from(account)?); - require!(bond.owner == address_bonds.address, Errors::WrongOwner); - if bond.state == State::Inactive.to_code() { - continue; - } - bond_amounts += bond.bond_amount; - total_bond_score += - compute_bond_score(bond.lock_period, current_timestamp, bond.unbond_timestamp) - * bond.bond_amount; - } - - liveliness_score = total_bond_score / bond_amounts; - } + generate_aggregated_rewards(rewards_config, vault_config)?; let address_claimable_rewards = calculate_address_share_in_rewards( rewards_config.accumulated_rewards, rewards_config.rewards_per_share, - address_bonds.address_total_bond_amount, - address_rewards.address_rewards_per_share, - total_bond_amount, - liveliness_score, - bypass_liveliness_score, + address_bonds_rewards.address_total_bond_amount, + address_bonds_rewards.address_rewards_per_share, + vault_config.total_bond_amount, ); - address_rewards.address_rewards_per_share = rewards_config.rewards_per_share; - address_rewards.claimable_amount += address_claimable_rewards; - rewards_config.accumulated_rewards -= address_claimable_rewards; + address_bonds_rewards.address_rewards_per_share = rewards_config.rewards_per_share; + address_bonds_rewards.claimable_amount += address_claimable_rewards; Ok(()) } + +pub fn compute_decay(last_update_timestamp: u64, current_timestamp: u64, lock_period: u64) -> u64 { + (current_timestamp - last_update_timestamp) + .mul_div_floor(DIVISION_SAFETY_CONST, lock_period) + .unwrap() +} + +pub fn compute_weighted_liveliness_decay(weighted_liveliness_score: u64, decay: u64) -> u64 { + let weighted_liveliness_score_decayed = weighted_liveliness_score + .mul_div_floor( + 1 * DIVISION_SAFETY_CONST.saturating_sub(decay), + DIVISION_SAFETY_CONST, + ) + .unwrap(); + + weighted_liveliness_score_decayed +} + +pub fn compute_weighted_liveliness_new( + weighted_liveliness_score_decayed: u64, + address_total_bond_amount: u64, + weight_to_be_added: u64, + weight_to_be_subtracted: u64, + bond_to_be_added: u64, + bond_to_be_subtracted: u64, +) -> u64 { + let new = (weighted_liveliness_score_decayed + .saturating_mul(address_total_bond_amount) + .saturating_sub(weight_to_be_subtracted) + .saturating_add(weight_to_be_added)) + .saturating_div(address_total_bond_amount + bond_to_be_added - bond_to_be_subtracted); + + new +} diff --git a/programs/core-sol-bond-stake-sc/src/states/address_bonds.rs b/programs/core-sol-bond-stake-sc/src/states/address_bonds.rs deleted file mode 100644 index b80ce98..0000000 --- a/programs/core-sol-bond-stake-sc/src/states/address_bonds.rs +++ /dev/null @@ -1,13 +0,0 @@ -use anchor_lang::prelude::*; - -#[account] -pub struct AddressBonds { - pub bump: u8, - pub address: Pubkey, - pub address_total_bond_amount: u64, - pub current_index: u8, - pub padding: [u8; 32], -} -impl Space for AddressBonds { - const INIT_SPACE: usize = 8 + 1 + 32 + 8 + 1 + 32; -} diff --git a/programs/core-sol-bond-stake-sc/src/states/address_bonds_rewards.rs b/programs/core-sol-bond-stake-sc/src/states/address_bonds_rewards.rs new file mode 100644 index 0000000..e05ca85 --- /dev/null +++ b/programs/core-sol-bond-stake-sc/src/states/address_bonds_rewards.rs @@ -0,0 +1,17 @@ +use anchor_lang::prelude::*; + +#[account] +pub struct AddressBondsRewards { + pub bump: u8, + pub address: Pubkey, + pub address_total_bond_amount: u64, + pub current_index: u8, + pub weighted_liveliness_score: u64, + pub last_update_timestamp: u64, + pub address_rewards_per_share: u64, + pub claimable_amount: u64, + pub padding: [u8; 16], +} +impl Space for AddressBondsRewards { + const INIT_SPACE: usize = 8 + 1 + 32 + 8 + 1 + 8 + 8 + 8 + 8 + 16; +} diff --git a/programs/core-sol-bond-stake-sc/src/states/address_rewards.rs b/programs/core-sol-bond-stake-sc/src/states/address_rewards.rs deleted file mode 100644 index b35292a..0000000 --- a/programs/core-sol-bond-stake-sc/src/states/address_rewards.rs +++ /dev/null @@ -1,13 +0,0 @@ -use anchor_lang::prelude::*; - -#[account] -pub struct AddressRewards { - pub bump: u8, - pub address: Pubkey, - pub address_rewards_per_share: u64, - pub claimable_amount: u64, - pub padding: [u8; 32], -} -impl Space for AddressRewards { - const INIT_SPACE: usize = 8 + 1 + 32 + 8 + 8 + 32; -} diff --git a/programs/core-sol-bond-stake-sc/src/states/asset_usage.rs b/programs/core-sol-bond-stake-sc/src/states/asset_usage.rs new file mode 100644 index 0000000..bc9d9a5 --- /dev/null +++ b/programs/core-sol-bond-stake-sc/src/states/asset_usage.rs @@ -0,0 +1,7 @@ +use anchor_lang::prelude::*; + +#[account] +pub struct AssetUsage {} +impl Space for AssetUsage { + const INIT_SPACE: usize = 8; +} diff --git a/programs/core-sol-bond-stake-sc/src/states/bond.rs b/programs/core-sol-bond-stake-sc/src/states/bond.rs index 298d00d..04637c9 100644 --- a/programs/core-sol-bond-stake-sc/src/states/bond.rs +++ b/programs/core-sol-bond-stake-sc/src/states/bond.rs @@ -8,11 +8,10 @@ pub struct Bond { pub bond_timestamp: u64, pub unbond_timestamp: u64, pub bond_amount: u64, - pub lock_period: u64, - pub mint_of_nft: Pubkey, + pub asset_id: Pubkey, pub owner: Pubkey, pub padding: [u8; 64], } impl Space for Bond { - const INIT_SPACE: usize = 8 + 1 + 1 + 1 + 8 + 8 + 8 + 8 + 32 + 32 + 64; + const INIT_SPACE: usize = 8 + 1 + 1 + 1 + 8 + 8 + 8 + 32 + 32 + 64; } diff --git a/programs/core-sol-bond-stake-sc/src/states/bond_config.rs b/programs/core-sol-bond-stake-sc/src/states/bond_config.rs index 050010f..0f56135 100644 --- a/programs/core-sol-bond-stake-sc/src/states/bond_config.rs +++ b/programs/core-sol-bond-stake-sc/src/states/bond_config.rs @@ -5,12 +5,12 @@ pub struct BondConfig { pub bump: u8, pub index: u8, pub bond_state: u8, - pub mint_of_collection: Pubkey, + pub merkle_tree: Pubkey, pub lock_period: u64, pub bond_amount: u64, pub withdraw_penalty: u64, - pub padding: [u8; 128], + pub padding: [u8; 32], } impl Space for BondConfig { - const INIT_SPACE: usize = 8 + 1 + 1 + 1 + 32 + 8 + 8 + 8 + 128; + const INIT_SPACE: usize = 8 + 1 + 1 + 1 + 32 + 8 + 8 + 8 + 32; } diff --git a/programs/core-sol-bond-stake-sc/src/states/mod.rs b/programs/core-sol-bond-stake-sc/src/states/mod.rs index 1d77deb..67290e7 100644 --- a/programs/core-sol-bond-stake-sc/src/states/mod.rs +++ b/programs/core-sol-bond-stake-sc/src/states/mod.rs @@ -4,9 +4,9 @@ pub mod rewards_config; pub use rewards_config::*; pub mod vault_config; pub use vault_config::*; -pub mod address_bonds; -pub use address_bonds::*; pub mod bond; pub use bond::*; -pub mod address_rewards; -pub use address_rewards::*; +pub mod asset_usage; +pub use asset_usage::*; +pub mod address_bonds_rewards; +pub use address_bonds_rewards::*; diff --git a/programs/core-sol-bond-stake-sc/src/states/rewards_config.rs b/programs/core-sol-bond-stake-sc/src/states/rewards_config.rs index 1349ca1..94b7481 100644 --- a/programs/core-sol-bond-stake-sc/src/states/rewards_config.rs +++ b/programs/core-sol-bond-stake-sc/src/states/rewards_config.rs @@ -10,9 +10,9 @@ pub struct RewardsConfig { pub rewards_per_share: u64, pub last_reward_slot: u64, pub max_apr: u64, - pub padding: [u8; 128], + pub padding: [u8; 32], } impl Space for RewardsConfig { - const INIT_SPACE: usize = 8 + 1 + 1 + 8 + 8 + 8 + 8 + 8 + 8 + 128; + const INIT_SPACE: usize = 8 + 1 + 1 + 8 + 8 + 8 + 8 + 8 + 8 + 32; } diff --git a/programs/core-sol-bond-stake-sc/src/states/vault_config.rs b/programs/core-sol-bond-stake-sc/src/states/vault_config.rs index 151978a..d11ce60 100644 --- a/programs/core-sol-bond-stake-sc/src/states/vault_config.rs +++ b/programs/core-sol-bond-stake-sc/src/states/vault_config.rs @@ -7,8 +7,8 @@ pub struct VaultConfig { pub mint_of_token: Pubkey, pub total_bond_amount: u64, pub total_penalized_amount: u64, - pub padding: [u8; 64], + pub padding: [u8; 32], } impl Space for VaultConfig { - const INIT_SPACE: usize = 8 + 1 + 32 + 32 + 8 + 8 + 64; + const INIT_SPACE: usize = 8 + 1 + 32 + 32 + 8 + 8 + 32; } diff --git a/programs/core-sol-bond-stake-sc/src/utils.rs b/programs/core-sol-bond-stake-sc/src/utils.rs index 9a254d6..0be9243 100644 --- a/programs/core-sol-bond-stake-sc/src/utils.rs +++ b/programs/core-sol-bond-stake-sc/src/utils.rs @@ -1,45 +1,6 @@ use anchor_lang::prelude::*; use solana_program::clock; -pub fn compute_bond_score(lock_period: u64, current_timestamp: u64, unbond_timestamp: u64) -> u64 { - if current_timestamp >= unbond_timestamp { - 0 - } else { - let difference = unbond_timestamp - current_timestamp; - - if lock_period == 0 { - 0 - } else { - let div_result = 10000u64.checked_div(lock_period).unwrap_or(0); - div_result.checked_mul(difference).unwrap_or(0) - } - } -} - -#[cfg(test)] -mod compute_bond_score_tests { - use super::*; - - use quickcheck::quickcheck; - - quickcheck! { - fn test_compute_bond_score(lock_period: u64, current_timestamp: u64, unbond_timestamp: u64) -> bool { - let result = compute_bond_score(lock_period, current_timestamp, unbond_timestamp); - - if current_timestamp >= unbond_timestamp { - result == 0 - } else if lock_period == 0 { - result == 0 - } else { - let difference = unbond_timestamp - current_timestamp; - let expected = (10000u64 / lock_period).saturating_mul(difference); - - result == expected - } - } - } -} - #[derive(AnchorSerialize, AnchorDeserialize, Clone, Copy, PartialEq)] pub enum State { Inactive = 0, diff --git a/tests/core-sol-bond-stake-sc.ts b/tests/core-sol-bond-stake-sc.ts index 5c8a899..bfc9bb3 100644 --- a/tests/core-sol-bond-stake-sc.ts +++ b/tests/core-sol-bond-stake-sc.ts @@ -2,13 +2,16 @@ import * as anchor from '@coral-xyz/anchor' import {Program} from '@coral-xyz/anchor' import {CoreSolBondStakeSc} from '../target/types/core_sol_bond_stake_sc' import { + Connection, Keypair, LAMPORTS_PER_SOL, PublicKey, SystemProgram, Transaction, + TransactionSignature, } from '@solana/web3.js' import { + ASSOCIATED_TOKEN_PROGRAM_ID, createAssociatedTokenAccountIdempotentInstruction, createInitializeMint2Instruction, createMintToInstruction, @@ -24,9 +27,14 @@ import { } from '@metaplex-foundation/umi' import { createTree, + getAssetWithProof, + getCurrentRoot, + LeafSchema, MetadataArgsArgs, mintToCollectionV1, mplBubblegum, + parseLeafFromMintToCollectionV1Transaction, + SPL_ACCOUNT_COMPRESSION_PROGRAM_ID, } from '@metaplex-foundation/mpl-bubblegum' import {assert, expect} from 'chai' import { @@ -35,9 +43,11 @@ import { } from '@metaplex-foundation/mpl-token-metadata' import { fromWeb3JsKeypair, + fromWeb3JsPublicKey, toWeb3JsPublicKey, } from '@metaplex-foundation/umi-web3js-adapters' import {createUmi} from '@metaplex-foundation/umi-bundle-defaults' +import {bs58} from '@coral-xyz/anchor/dist/cjs/utils/bytes' require('dotenv').config() @@ -45,9 +55,7 @@ describe('core-sol-bond-stake-sc', () => { anchor.setProvider(anchor.AnchorProvider.env()) const provider = anchor.getProvider() - const connection = provider.connection - const program = anchor.workspace .CoreSolBondStakeSc as Program @@ -60,8 +68,9 @@ describe('core-sol-bond-stake-sc', () => { ) let collection_mint: PublicKey - let user_nft_mint: PublicKey - let user2_nft_mint: PublicKey + let user_nft_leaf_schemas: LeafSchema[] = [] + let user2_nft_leaf_schemas: LeafSchema[] = [] + let merkleTree: PublicKey const itheum_token_user_ata = getAssociatedTokenAddressSync( itheum_token_mint.publicKey, @@ -119,6 +128,8 @@ describe('core-sol-bond-stake-sc', () => { true ) + let activation_slot: number = 0 + const confirm = async (signature: string): Promise => { const block = await connection.getLatestBlockhash() await connection.confirmTransaction({ @@ -212,7 +223,9 @@ describe('core-sol-bond-stake-sc', () => { await provider.sendAndConfirm(tx, [admin]) - const umi = createUmi(connection) + let umiConnection = new Connection('http://localhost:8899', 'confirmed') + + const umi = createUmi(umiConnection) umi.use(mplTokenMetadata()) umi.use(keypairIdentity(fromWeb3JsKeypair(admin))) @@ -229,19 +242,21 @@ describe('core-sol-bond-stake-sc', () => { isCollection: true, }).sendAndConfirm(umi) - const umi2 = createUmi(connection) + const umi2 = createUmi(umiConnection) umi2.use(keypairIdentity(fromWeb3JsKeypair(admin))) umi2.use(mplBubblegum()) - const merkleTree = generateSigner(umi2) + const merkleTreeKey = generateSigner(umi2) const builder = await createTree(umi2, { - merkleTree, + merkleTree: merkleTreeKey, maxDepth: 14, maxBufferSize: 64, }) await builder.sendAndConfirm(umi2) + merkleTree = toWeb3JsPublicKey(merkleTreeKey.publicKey) + const metadata: MetadataArgsArgs = { name: 'Vault NFMEID user1', uri: 'https://indigo-complete-silverfish-271.mypinata.cloud/ipfs/QmcgwWW47d9FjHksKhZ5DWJYWvzPbVR1uhgH8kwBgNkJ9F/GetBitzNFTunesMainM.json', @@ -270,26 +285,37 @@ describe('core-sol-bond-stake-sc', () => { ], } - const nft_mint1 = generateSigner(umi2) - - user_nft_mint = toWeb3JsPublicKey(nft_mint1.publicKey) + for (let i = 0; i < 5; i++) { + const resp = await mintToCollectionV1(umi2, { + leafOwner: fromWeb3JsKeypair(user).publicKey, + merkleTree: fromWeb3JsPublicKey(merkleTree), + collectionMint: collection.publicKey, + metadata: metadata, + }).sendAndConfirm(umi2) + + let nft_leaf_schema = await parseLeafFromMintToCollectionV1Transaction( + umi2, + resp.signature + ) - const resp3 = await mintToCollectionV1(umi2, { - leafOwner: fromWeb3JsKeypair(user).publicKey, - merkleTree: merkleTree.publicKey, - collectionMint: collection.publicKey, - metadata: metadata, - }).sendAndConfirm(umi2) + user_nft_leaf_schemas.push(nft_leaf_schema) + } - const nft_mint_2 = generateSigner(umi2) - const resp4 = await mintToCollectionV1(umi2, { - leafOwner: fromWeb3JsKeypair(user2).publicKey, - merkleTree: merkleTree.publicKey, - collectionMint: collection.publicKey, - metadata: metadata2, - }).sendAndConfirm(umi2) + for (let i = 0; i < 5; i++) { + const resp4 = await mintToCollectionV1(umi2, { + leafOwner: fromWeb3JsKeypair(user2).publicKey, + merkleTree: fromWeb3JsPublicKey(merkleTree), + collectionMint: collection.publicKey, + metadata: metadata2, + }).sendAndConfirm(umi2) + + let nft2_leaf_schema = await parseLeafFromMintToCollectionV1Transaction( + umi2, + resp4.signature + ) - user2_nft_mint = toWeb3JsPublicKey(nft_mint_2.publicKey) + user2_nft_leaf_schemas.push(nft2_leaf_schema) + } }) it('Initialize contract - by user (should fail)', async () => { @@ -304,12 +330,9 @@ describe('core-sol-bond-stake-sc', () => { new anchor.BN(6000) ) .signers([user]) - .accountsPartial({ + .accounts({ bondConfig: bondConfigPda1, - vaultConfig: vaultConfigPda, - vault: vault_ata, - mintOfToken: itheum_token_mint.publicKey, - mintOfCollection: collection_mint, + merkleTree: merkleTree, rewardsConfig: rewardsConfigPda, authority: user.publicKey, }) @@ -324,7 +347,7 @@ describe('core-sol-bond-stake-sc', () => { }) it('Initialize Contract by admin', async () => { - await program.methods + const sig = await program.methods .initializeContract( 1, new anchor.BN(900), @@ -334,13 +357,21 @@ describe('core-sol-bond-stake-sc', () => { new anchor.BN(6000) ) .signers([admin]) - .accountsPartial({ + .accounts({ bondConfig: bondConfigPda1, + rewardsConfig: rewardsConfigPda, + merkleTree: merkleTree, + authority: admin.publicKey, + }) + .rpc() + + await program.methods + .initializeVault() + .signers([admin]) + .accounts({ vaultConfig: vaultConfigPda, vault: vault_ata, mintOfToken: itheum_token_mint.publicKey, - mintOfCollection: collection_mint, - rewardsConfig: rewardsConfigPda, authority: admin.publicKey, }) .rpc() @@ -354,7 +385,7 @@ describe('core-sol-bond-stake-sc', () => { assert(bond_config.bondAmount.eq(new anchor.BN(100e9))) assert(bond_config.bondState == 0) assert(bond_config.lockPeriod.eq(new anchor.BN(900))) - assert(bond_config.mintOfCollection.equals(collection_mint)) + assert(bond_config.merkleTree.equals(merkleTree)) assert(bond_config.withdrawPenalty.eq(new anchor.BN(6000))) assert(bond_config.index == 1) @@ -383,10 +414,10 @@ describe('core-sol-bond-stake-sc', () => { new anchor.BN(6000) ) .signers([user]) - .accountsPartial({ + .accounts({ bondConfig: bondConfigPda2, authority: user.publicKey, - mintOfCollection: collection_mint, + merkleTree: merkleTree, }) .rpc() assert(false, 'Should have thrown error') @@ -412,10 +443,10 @@ describe('core-sol-bond-stake-sc', () => { new anchor.BN(6000) ) .signers([admin]) - .accountsPartial({ + .accounts({ bondConfig: bondConfigPda2, authority: admin.publicKey, - mintOfCollection: collection_mint, + merkleTree: merkleTree, }) .rpc() @@ -424,7 +455,7 @@ describe('core-sol-bond-stake-sc', () => { assert(bond_config.bondAmount.eq(new anchor.BN(100e9))) assert(bond_config.bondState == 0) assert(bond_config.lockPeriod.eq(new anchor.BN(900))) - assert(bond_config.mintOfCollection.equals(collection_mint)) + assert(bond_config.merkleTree.equals(merkleTree)) assert(bond_config.withdrawPenalty.eq(new anchor.BN(6000))) assert(bond_config.index == 2) }) @@ -434,7 +465,7 @@ describe('core-sol-bond-stake-sc', () => { await program.methods .setBondStateActive(1) .signers([user]) - .accountsPartial({ + .accounts({ bondConfig: bondConfigPda1, authority: user.publicKey, }) @@ -450,7 +481,7 @@ describe('core-sol-bond-stake-sc', () => { await program.methods .setBondStateInactive(1) .signers([user]) - .accountsPartial({ + .accounts({ bondConfig: bondConfigPda1, authority: user.publicKey, }) @@ -471,7 +502,7 @@ describe('core-sol-bond-stake-sc', () => { await program.methods .setBondStateActive(2) .signers([user]) - .accountsPartial({ + .accounts({ bondConfig: bondConfigPda2, authority: user.publicKey, }) @@ -487,7 +518,7 @@ describe('core-sol-bond-stake-sc', () => { await program.methods .setBondStateInactive(2) .signers([user]) - .accountsPartial({ + .accounts({ bondConfig: bondConfigPda2, authority: user.publicKey, }) @@ -504,7 +535,7 @@ describe('core-sol-bond-stake-sc', () => { await program.methods .setBondStateActive(1) .signers([admin]) - .accountsPartial({ + .accounts({ bondConfig: bondConfigPda1, authority: admin.publicKey, }) @@ -522,7 +553,7 @@ describe('core-sol-bond-stake-sc', () => { await program.methods .setBondStateActive(2) .signers([admin]) - .accountsPartial({ + .accounts({ bondConfig: bondConfigPda2, authority: admin.publicKey, }) @@ -537,7 +568,7 @@ describe('core-sol-bond-stake-sc', () => { await program.methods .setBondStateInactive(1) .signers([admin]) - .accountsPartial({ + .accounts({ bondConfig: bondConfigPda1, authority: admin.publicKey, }) @@ -550,7 +581,7 @@ describe('core-sol-bond-stake-sc', () => { await program.methods .setBondStateInactive(2) .signers([admin]) - .accountsPartial({ + .accounts({ bondConfig: bondConfigPda2, authority: admin.publicKey, }) @@ -564,9 +595,9 @@ describe('core-sol-bond-stake-sc', () => { it('Update mint of collection by user (should fail)', async () => { try { await program.methods - .updateMintOfCollection(1, collection_mint) + .updateMerkleTree(1, merkleTree) .signers([user]) - .accountsPartial({ + .accounts({ bondConfig: bondConfigPda1, authority: user.publicKey, }) @@ -586,9 +617,9 @@ describe('core-sol-bond-stake-sc', () => { try { await program.methods - .updateMintOfCollection(2, collection_mint) + .updateMerkleTree(2, merkleTree) .signers([user]) - .accountsPartial({ + .accounts({ bondConfig: bondConfigPda2, authority: user.publicKey, }) @@ -604,9 +635,9 @@ describe('core-sol-bond-stake-sc', () => { it('Update mint of collection by admin', async () => { await program.methods - .updateMintOfCollection(1, collection_mint) + .updateMerkleTree(1, merkleTree) .signers([admin]) - .accountsPartial({ + .accounts({ bondConfig: bondConfigPda1, authority: admin.publicKey, }) @@ -614,7 +645,7 @@ describe('core-sol-bond-stake-sc', () => { let bond_config = await program.account.bondConfig.fetch(bondConfigPda1) - assert(bond_config.mintOfCollection.equals(collection_mint)) + assert(bond_config.merkleTree.equals(merkleTree)) const bondConfigPda2 = PublicKey.findProgramAddressSync( [Buffer.from('bond_config'), Buffer.from([2])], @@ -622,9 +653,9 @@ describe('core-sol-bond-stake-sc', () => { )[0] await program.methods - .updateMintOfCollection(2, collection_mint) + .updateMerkleTree(2, merkleTree) .signers([admin]) - .accountsPartial({ + .accounts({ bondConfig: bondConfigPda2, authority: admin.publicKey, }) @@ -632,7 +663,7 @@ describe('core-sol-bond-stake-sc', () => { let bond_config2 = await program.account.bondConfig.fetch(bondConfigPda2) - assert(bond_config2.mintOfCollection.equals(collection_mint)) + assert(bond_config2.merkleTree.equals(merkleTree)) }) it('Update lock period by user (should fail)', async () => { @@ -640,7 +671,7 @@ describe('core-sol-bond-stake-sc', () => { await program.methods .updateLockPeriod(1, new anchor.BN(1000)) .signers([user]) - .accountsPartial({ + .accounts({ bondConfig: bondConfigPda1, authority: user.publicKey, }) @@ -662,7 +693,7 @@ describe('core-sol-bond-stake-sc', () => { await program.methods .updateLockPeriod(2, new anchor.BN(1000)) .signers([user]) - .accountsPartial({ + .accounts({ bondConfig: bondConfigPda2, authority: user.publicKey, }) @@ -680,7 +711,7 @@ describe('core-sol-bond-stake-sc', () => { await program.methods .updateLockPeriod(1, new anchor.BN(1000)) .signers([admin]) - .accountsPartial({ + .accounts({ bondConfig: bondConfigPda1, authority: admin.publicKey, }) @@ -698,7 +729,7 @@ describe('core-sol-bond-stake-sc', () => { await program.methods .updateLockPeriod(2, new anchor.BN(1000)) .signers([admin]) - .accountsPartial({ + .accounts({ bondConfig: bondConfigPda2, authority: admin.publicKey, }) @@ -714,7 +745,7 @@ describe('core-sol-bond-stake-sc', () => { await program.methods .updateBondAmount(1, new anchor.BN(200e9)) .signers([user]) - .accountsPartial({ + .accounts({ bondConfig: bondConfigPda1, authority: user.publicKey, }) @@ -736,7 +767,7 @@ describe('core-sol-bond-stake-sc', () => { await program.methods .updateBondAmount(2, new anchor.BN(200e9)) .signers([user]) - .accountsPartial({ + .accounts({ bondConfig: bondConfigPda2, authority: user.publicKey, }) @@ -754,7 +785,7 @@ describe('core-sol-bond-stake-sc', () => { await program.methods .updateBondAmount(1, new anchor.BN(200e9)) .signers([admin]) - .accountsPartial({ + .accounts({ bondConfig: bondConfigPda1, authority: admin.publicKey, }) @@ -772,7 +803,7 @@ describe('core-sol-bond-stake-sc', () => { await program.methods .updateBondAmount(2, new anchor.BN(200e9)) .signers([admin]) - .accountsPartial({ + .accounts({ bondConfig: bondConfigPda2, authority: admin.publicKey, }) @@ -781,6 +812,15 @@ describe('core-sol-bond-stake-sc', () => { let bond_config2 = await program.account.bondConfig.fetch(bondConfigPda2) assert(bond_config2.bondAmount.eq(new anchor.BN(200e9))) + + await program.methods + .updateBondAmount(1, new anchor.BN(100e9)) + .signers([admin]) + .accounts({ + bondConfig: bondConfigPda1, + authority: admin.publicKey, + }) + .rpc() }) it('Update withdraw penalty by user (should fail)', async () => { @@ -788,7 +828,7 @@ describe('core-sol-bond-stake-sc', () => { await program.methods .updateWithdrawPenalty(1, new anchor.BN(5000)) .signers([user]) - .accountsPartial({ + .accounts({ bondConfig: bondConfigPda1, authority: user.publicKey, }) @@ -810,7 +850,7 @@ describe('core-sol-bond-stake-sc', () => { await program.methods .updateWithdrawPenalty(2, new anchor.BN(5000)) .signers([user]) - .accountsPartial({ + .accounts({ bondConfig: bondConfigPda2, authority: user.publicKey, }) @@ -828,7 +868,7 @@ describe('core-sol-bond-stake-sc', () => { await program.methods .updateWithdrawPenalty(1, new anchor.BN(5000)) .signers([admin]) - .accountsPartial({ + .accounts({ bondConfig: bondConfigPda1, authority: admin.publicKey, }) @@ -846,7 +886,7 @@ describe('core-sol-bond-stake-sc', () => { await program.methods .updateWithdrawPenalty(2, new anchor.BN(5000)) .signers([admin]) - .accountsPartial({ + .accounts({ bondConfig: bondConfigPda2, authority: admin.publicKey, }) @@ -864,7 +904,7 @@ describe('core-sol-bond-stake-sc', () => { await program.methods .setRewardsStateActive() .signers([user]) - .accountsPartial({ + .accounts({ rewardsConfig: rewardsConfigPda, authority: user.publicKey, }) @@ -880,7 +920,7 @@ describe('core-sol-bond-stake-sc', () => { await program.methods .setRewardsStateInactive() .signers([user]) - .accountsPartial({ + .accounts({ rewardsConfig: rewardsConfigPda, authority: user.publicKey, }) @@ -897,7 +937,7 @@ describe('core-sol-bond-stake-sc', () => { await program.methods .setRewardsStateActive() .signers([admin]) - .accountsPartial({ + .accounts({ rewardsConfig: rewardsConfigPda, authority: admin.publicKey, }) @@ -912,7 +952,7 @@ describe('core-sol-bond-stake-sc', () => { await program.methods .setRewardsStateInactive() .signers([admin]) - .accountsPartial({ + .accounts({ rewardsConfig: rewardsConfigPda, authority: admin.publicKey, }) @@ -930,7 +970,7 @@ describe('core-sol-bond-stake-sc', () => { await program.methods .updateRewardsPerSlot(new anchor.BN(2e9)) .signers([user]) - .accountsPartial({ + .accounts({ rewardsConfig: rewardsConfigPda, authority: user.publicKey, }) @@ -948,7 +988,7 @@ describe('core-sol-bond-stake-sc', () => { await program.methods .updateRewardsPerSlot(new anchor.BN(2e9)) .signers([admin]) - .accountsPartial({ + .accounts({ rewardsConfig: rewardsConfigPda, authority: admin.publicKey, }) @@ -966,7 +1006,7 @@ describe('core-sol-bond-stake-sc', () => { await program.methods .updateMaxApr(new anchor.BN(10)) .signers([user]) - .accountsPartial({ + .accounts({ rewardsConfig: rewardsConfigPda, authority: user.publicKey, }) @@ -984,7 +1024,7 @@ describe('core-sol-bond-stake-sc', () => { await program.methods .updateMaxApr(new anchor.BN(10)) .signers([admin]) - .accountsPartial({ + .accounts({ rewardsConfig: rewardsConfigPda, authority: admin.publicKey, }) @@ -1002,7 +1042,7 @@ describe('core-sol-bond-stake-sc', () => { await program.methods .addRewards(new anchor.BN(1000e9)) .signers([user]) - .accountsPartial({ + .accounts({ rewardsConfig: rewardsConfigPda, vaultConfig: vaultConfigPda, vault: vault_ata, @@ -1023,7 +1063,7 @@ describe('core-sol-bond-stake-sc', () => { await program.methods .addRewards(new anchor.BN(1_000_000e9)) .signers([admin]) - .accountsPartial({ + .accounts({ rewardsConfig: rewardsConfigPda, vaultConfig: vaultConfigPda, vault: vault_ata, @@ -1045,7 +1085,7 @@ describe('core-sol-bond-stake-sc', () => { await program.methods .removeRewards(new anchor.BN(1000e9)) .signers([user]) - .accountsPartial({ + .accounts({ rewardsConfig: rewardsConfigPda, vaultConfig: vaultConfigPda, vault: vault_ata, @@ -1065,7 +1105,7 @@ describe('core-sol-bond-stake-sc', () => { await program.methods .removeRewards(new anchor.BN(1000e9)) .signers([user]) - .accountsPartial({ + .accounts({ rewardsConfig: rewardsConfigPda, vaultConfig: vaultConfigPda, vault: vault_ata, @@ -1086,7 +1126,7 @@ describe('core-sol-bond-stake-sc', () => { await program.methods .removeRewards(new anchor.BN(1000e9)) .signers([admin]) - .accountsPartial({ + .accounts({ rewardsConfig: rewardsConfigPda, vaultConfig: vaultConfigPda, vault: vault_ata, @@ -1105,7 +1145,7 @@ describe('core-sol-bond-stake-sc', () => { await program.methods .addRewards(new anchor.BN(1_000e9)) .signers([admin]) - .accountsPartial({ + .accounts({ rewardsConfig: rewardsConfigPda, vaultConfig: vaultConfigPda, vault: vault_ata, @@ -1127,7 +1167,7 @@ describe('core-sol-bond-stake-sc', () => { await program.methods .removeRewards(new anchor.BN(1000e9)) .signers([admin]) - .accountsPartial({ + .accounts({ rewardsConfig: rewardsConfigPda, vaultConfig: vaultConfigPda, vault: vault_ata, @@ -1149,7 +1189,7 @@ describe('core-sol-bond-stake-sc', () => { await program.methods .removeRewards(new anchor.BN(1000e9)) .signers([admin]) - .accountsPartial({ + .accounts({ rewardsConfig: rewardsConfigPda, vaultConfig: vaultConfigPda, vault: vault_ata, @@ -1171,7 +1211,7 @@ describe('core-sol-bond-stake-sc', () => { await program.methods .removeRewards(new anchor.BN(1000e9)) .signers([admin]) - .accountsPartial({ + .accounts({ rewardsConfig: rewardsConfigPda, vaultConfig: vaultConfigPda, vault: vault_ata, @@ -1193,7 +1233,7 @@ describe('core-sol-bond-stake-sc', () => { await program.methods .removeRewards(new anchor.BN(1000e9)) .signers([admin]) - .accountsPartial({ + .accounts({ rewardsConfig: rewardsConfigPda, vaultConfig: vaultConfigPda, vault: itheum_token_admin_ata, @@ -1210,20 +1250,1388 @@ describe('core-sol-bond-stake-sc', () => { } }) - it('Activate rewards by admin', async () => { + it('Bond 1 by user - should fail (address not initialized)', async () => { + const userBondsRewards = PublicKey.findProgramAddressSync( + [Buffer.from('address_bonds_rewards'), user.publicKey.toBuffer()], + program.programId + )[0] + + const bond1 = PublicKey.findProgramAddressSync( + [Buffer.from('bond'), user.publicKey.toBuffer(), Buffer.from([1])], + program.programId + )[0] + + const assetUsage1 = PublicKey.findProgramAddressSync( + [toWeb3JsPublicKey(user_nft_leaf_schemas[0].id).toBuffer()], + program.programId + )[0] + + try { + await program.methods + .bond( + 1, + 1, + new anchor.BN(100e9), + toWeb3JsPublicKey(user_nft_leaf_schemas[0].id), + false, + Array.from(bs58.decode(user_nft_leaf_schemas[0].id)), + Array.from(user_nft_leaf_schemas[0].dataHash), + Array.from(user_nft_leaf_schemas[0].creatorHash), + new anchor.BN(user_nft_leaf_schemas[0].nonce.toString()), + 1 + ) + .signers([user]) + .accounts({ + addressBondsRewards: userBondsRewards, + assetUsage: assetUsage1, + bond: bond1, + bondConfig: bondConfigPda1, + rewardsConfig: rewardsConfigPda, + vaultConfig: vaultConfigPda, + vault: vault_ata, + mintOfTokenSent: itheum_token_mint.publicKey, + authority: user.publicKey, + merkleTree: merkleTree, + authorityTokenAccount: itheum_token_user_ata, + systemProgram: anchor.web3.SystemProgram.programId, + tokenProgram: TOKEN_PROGRAM_ID, + associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ID, + compressionProgram: SPL_ACCOUNT_COMPRESSION_PROGRAM_ID, + }) + .remainingAccounts([ + { + pubkey: new PublicKey(merkleTree), + isSigner: false, + isWritable: false, + }, + ]) + .rpc() + assert(false, 'Should have thrown error') + } catch (err) { + expect((err as anchor.AnchorError).error.errorCode.number).to.equal(3012) + expect((err as anchor.AnchorError).error.errorMessage).to.equal( + 'The program expected this account to be already initialized' + ) + } + }) + + it('Unpause bond program', async () => { await program.methods - .setRewardsStateActive() + .setBondStateActive(1) .signers([admin]) - .accountsPartial({ + .accounts({bondConfig: bondConfigPda1, authority: admin.publicKey}) + .rpc() + }) + + it('Bond 1 by user - wrong bond amount (should fail)', async () => { + const userBondsRewards = PublicKey.findProgramAddressSync( + [Buffer.from('address_bonds_rewards'), user.publicKey.toBuffer()], + program.programId + )[0] + + const bond1 = PublicKey.findProgramAddressSync( + [Buffer.from('bond'), user.publicKey.toBuffer(), Buffer.from([1])], + program.programId + )[0] + + const assetUsage1 = PublicKey.findProgramAddressSync( + [toWeb3JsPublicKey(user_nft_leaf_schemas[0].id).toBuffer()], + program.programId + )[0] + + await program.methods + .initializeAddress() + .signers([user]) + .accounts({ + addressBondsRewards: userBondsRewards, rewardsConfig: rewardsConfigPda, - authority: admin.publicKey, + authority: user.publicKey, }) .rpc() - let rewards_config = await program.account.rewardsConfig.fetch( - rewardsConfigPda + try { + await program.methods + .bond( + 1, + 1, + new anchor.BN(200e9), + toWeb3JsPublicKey(user_nft_leaf_schemas[0].id), + false, + Array.from(bs58.decode(user_nft_leaf_schemas[0].id)), + Array.from(user_nft_leaf_schemas[0].dataHash), + Array.from(user_nft_leaf_schemas[0].creatorHash), + new anchor.BN(user_nft_leaf_schemas[0].nonce.toString()), + 1 + ) + .signers([user]) + .accounts({ + addressBondsRewards: userBondsRewards, + assetUsage: assetUsage1, + bond: bond1, + bondConfig: bondConfigPda1, + rewardsConfig: rewardsConfigPda, + vaultConfig: vaultConfigPda, + vault: vault_ata, + mintOfTokenSent: itheum_token_mint.publicKey, + authority: user.publicKey, + merkleTree: merkleTree, + authorityTokenAccount: itheum_token_user_ata, + systemProgram: anchor.web3.SystemProgram.programId, + tokenProgram: TOKEN_PROGRAM_ID, + associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ID, + compressionProgram: SPL_ACCOUNT_COMPRESSION_PROGRAM_ID, + }) + .remainingAccounts([ + { + pubkey: new PublicKey(merkleTree), + isSigner: false, + isWritable: false, + }, + ]) + .rpc() + assert(false, 'Should have thrown error') + } catch (err) { + expect((err as anchor.AnchorError).error.errorCode.number).to.equal(6010) + expect((err as anchor.AnchorError).error.errorMessage).to.equal( + 'Wrong amount' + ) + } + }) + + it('Bond 1 by user - wrong bond id (should fail)', async () => { + const userBondsRewards = PublicKey.findProgramAddressSync( + [Buffer.from('address_bonds_rewards'), user.publicKey.toBuffer()], + program.programId + )[0] + + const bond1 = PublicKey.findProgramAddressSync( + [Buffer.from('bond'), user.publicKey.toBuffer(), Buffer.from([2])], + program.programId + )[0] + + const assetUsage1 = PublicKey.findProgramAddressSync( + [toWeb3JsPublicKey(user_nft_leaf_schemas[0].id).toBuffer()], + program.programId + )[0] + + try { + await program.methods + .bond( + 1, + 2, + new anchor.BN(100e9), + toWeb3JsPublicKey(user_nft_leaf_schemas[0].id), + false, + Array.from(bs58.decode(user_nft_leaf_schemas[0].id)), + Array.from(user_nft_leaf_schemas[0].dataHash), + Array.from(user_nft_leaf_schemas[0].creatorHash), + new anchor.BN(user_nft_leaf_schemas[0].nonce.toString()), + 1 + ) + .signers([user]) + .accounts({ + addressBondsRewards: userBondsRewards, + assetUsage: assetUsage1, + bond: bond1, + bondConfig: bondConfigPda1, + rewardsConfig: rewardsConfigPda, + vaultConfig: vaultConfigPda, + vault: vault_ata, + mintOfTokenSent: itheum_token_mint.publicKey, + authority: user.publicKey, + merkleTree: merkleTree, + authorityTokenAccount: itheum_token_user_ata, + systemProgram: anchor.web3.SystemProgram.programId, + tokenProgram: TOKEN_PROGRAM_ID, + associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ID, + compressionProgram: SPL_ACCOUNT_COMPRESSION_PROGRAM_ID, + }) + .remainingAccounts([ + { + pubkey: new PublicKey(merkleTree), + isSigner: false, + isWritable: false, + }, + ]) + .rpc() + assert(false, 'Should have thrown error') + } catch (err) { + expect((err as anchor.AnchorError).error.errorCode.number).to.equal(6011) + expect((err as anchor.AnchorError).error.errorMessage).to.equal( + 'Wrong bond id' + ) + } + }) + + it('Bond 1 by user', async () => { + const userBondsRewards = PublicKey.findProgramAddressSync( + [Buffer.from('address_bonds_rewards'), user.publicKey.toBuffer()], + program.programId + )[0] + + const bond1 = PublicKey.findProgramAddressSync( + [Buffer.from('bond'), user.publicKey.toBuffer(), Buffer.from([1])], + program.programId + )[0] + + const assetUsage1 = PublicKey.findProgramAddressSync( + [toWeb3JsPublicKey(user_nft_leaf_schemas[0].id).toBuffer()], + program.programId + )[0] + + let x = await program.methods + .bond( + 1, + 1, + new anchor.BN(100e9), + toWeb3JsPublicKey(user_nft_leaf_schemas[0].id), + true, + Array.from(bs58.decode(user_nft_leaf_schemas[0].id)), + Array.from(user_nft_leaf_schemas[0].dataHash), + Array.from(user_nft_leaf_schemas[0].creatorHash), + new anchor.BN(user_nft_leaf_schemas[0].nonce.toString()), + 1 + ) + .signers([user]) + .accounts({ + addressBondsRewards: userBondsRewards, + assetUsage: assetUsage1, + bond: bond1, + bondConfig: bondConfigPda1, + rewardsConfig: rewardsConfigPda, + vaultConfig: vaultConfigPda, + vault: vault_ata, + mintOfTokenSent: itheum_token_mint.publicKey, + authority: user.publicKey, + merkleTree: merkleTree, + authorityTokenAccount: itheum_token_user_ata, + systemProgram: anchor.web3.SystemProgram.programId, + tokenProgram: TOKEN_PROGRAM_ID, + associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ID, + compressionProgram: SPL_ACCOUNT_COMPRESSION_PROGRAM_ID, + }) + .remainingAccounts([ + { + pubkey: new PublicKey(merkleTree), + isSigner: false, + isWritable: false, + }, + ]) + .rpc() + + const normalWeighted = await calculateWeightedLivelinessScore( + x, + userBondsRewards, + bondConfigPda1, + program ) - assert(rewards_config.rewardsState == 1) + const addressBondsFetched = await program.account.addressBondsRewards.fetch( + userBondsRewards + ) + + assert( + addressBondsFetched.weightedLivelinessScore.toNumber() == normalWeighted + ) }) -}) + + it('Bond 2 by user', async () => { + const userBondsRewards = PublicKey.findProgramAddressSync( + [Buffer.from('address_bonds_rewards'), user.publicKey.toBuffer()], + program.programId + )[0] + + const bond2 = PublicKey.findProgramAddressSync( + [Buffer.from('bond'), user.publicKey.toBuffer(), Buffer.from([2])], + program.programId + )[0] + + const assetUsage2 = PublicKey.findProgramAddressSync( + [toWeb3JsPublicKey(user_nft_leaf_schemas[1].id).toBuffer()], + program.programId + )[0] + + let x = await program.methods + .bond( + 1, + 2, + new anchor.BN(100e9), + toWeb3JsPublicKey(user_nft_leaf_schemas[1].id), + false, + Array.from(bs58.decode(user_nft_leaf_schemas[1].id)), + Array.from(user_nft_leaf_schemas[1].dataHash), + Array.from(user_nft_leaf_schemas[1].creatorHash), + new anchor.BN(user_nft_leaf_schemas[1].nonce.toString()), + 1 + ) + .signers([user]) + .accounts({ + addressBondsRewards: userBondsRewards, + assetUsage: assetUsage2, + bond: bond2, + bondConfig: bondConfigPda1, + rewardsConfig: rewardsConfigPda, + vaultConfig: vaultConfigPda, + vault: vault_ata, + mintOfTokenSent: itheum_token_mint.publicKey, + authority: user.publicKey, + merkleTree: merkleTree, + authorityTokenAccount: itheum_token_user_ata, + systemProgram: anchor.web3.SystemProgram.programId, + tokenProgram: TOKEN_PROGRAM_ID, + associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ID, + compressionProgram: SPL_ACCOUNT_COMPRESSION_PROGRAM_ID, + }) + .remainingAccounts([ + { + pubkey: new PublicKey(merkleTree), + isSigner: false, + isWritable: false, + }, + ]) + .rpc() + + const normalWeighted = await calculateWeightedLivelinessScore( + x, + userBondsRewards, + bondConfigPda1, + program + ) + + const addressBondsFetched = await program.account.addressBondsRewards.fetch( + userBondsRewards + ) + + assert( + addressBondsFetched.weightedLivelinessScore.toNumber() == normalWeighted + ) + }) + + it('Bond 1 by user2', async () => { + const userBondsRewards = PublicKey.findProgramAddressSync( + [Buffer.from('address_bonds_rewards'), user2.publicKey.toBuffer()], + program.programId + )[0] + + const bond1 = PublicKey.findProgramAddressSync( + [Buffer.from('bond'), user2.publicKey.toBuffer(), Buffer.from([1])], + program.programId + )[0] + + const assetUsage1 = PublicKey.findProgramAddressSync( + [toWeb3JsPublicKey(user2_nft_leaf_schemas[0].id).toBuffer()], + program.programId + )[0] + + await program.methods + .initializeAddress() + .signers([user2]) + .accounts({ + addressBondsRewards: userBondsRewards, + rewardsConfig: rewardsConfigPda, + authority: user2.publicKey, + }) + .rpc() + + let x = await program.methods + .bond( + 1, + 1, + new anchor.BN(100e9), + toWeb3JsPublicKey(user2_nft_leaf_schemas[0].id), + true, + Array.from(bs58.decode(user2_nft_leaf_schemas[0].id)), + Array.from(user2_nft_leaf_schemas[0].dataHash), + Array.from(user2_nft_leaf_schemas[0].creatorHash), + new anchor.BN(user2_nft_leaf_schemas[0].nonce.toString()), + 1 + ) + .signers([user2]) + .accounts({ + addressBondsRewards: userBondsRewards, + assetUsage: assetUsage1, + bond: bond1, + bondConfig: bondConfigPda1, + rewardsConfig: rewardsConfigPda, + vaultConfig: vaultConfigPda, + vault: vault_ata, + mintOfTokenSent: itheum_token_mint.publicKey, + authority: user2.publicKey, + merkleTree: merkleTree, + authorityTokenAccount: itheum_token_user2_ata, + systemProgram: anchor.web3.SystemProgram.programId, + tokenProgram: TOKEN_PROGRAM_ID, + associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ID, + compressionProgram: SPL_ACCOUNT_COMPRESSION_PROGRAM_ID, + }) + .remainingAccounts([ + { + pubkey: new PublicKey(merkleTree), + isSigner: false, + isWritable: false, + }, + ]) + .rpc() + + const normalWeighted = await calculateWeightedLivelinessScore( + x, + userBondsRewards, + bondConfigPda1, + program + ) + + const addressBondsFetched = await program.account.addressBondsRewards.fetch( + userBondsRewards + ) + + assert( + addressBondsFetched.weightedLivelinessScore.toNumber() == normalWeighted + ) + }) + + it('Renew bond 1 by user - wrong bond (should fail)', async () => { + const userBondsRewards = PublicKey.findProgramAddressSync( + [Buffer.from('address_bonds_rewards'), user.publicKey.toBuffer()], + program.programId + )[0] + + const bond1 = PublicKey.findProgramAddressSync( + [Buffer.from('bond'), user2.publicKey.toBuffer(), Buffer.from([1])], + program.programId + )[0] + + try { + let x = await program.methods + .renew(1, 1) + .signers([user]) + .accounts({ + bondConfig: bondConfigPda1, + rewardsConfig: rewardsConfigPda, + vaultConfig: vaultConfigPda, + addressBondsRewards: userBondsRewards, + bond: bond1, + authority: user.publicKey, + }) + .rpc() + assert(false, 'Should have thrown error') + } catch (err) { + expect((err as anchor.AnchorError).error.errorCode.number).to.equal(2006) + expect((err as anchor.AnchorError).error.errorMessage).to.equal( + 'A seeds constraint was violated' + ) + } + }) + + it('Renew bond 1 by user', async () => { + const userBondsRewards = PublicKey.findProgramAddressSync( + [Buffer.from('address_bonds_rewards'), user.publicKey.toBuffer()], + program.programId + )[0] + + const bond1 = PublicKey.findProgramAddressSync( + [Buffer.from('bond'), user.publicKey.toBuffer(), Buffer.from([1])], + program.programId + )[0] + + let x = await program.methods + .renew(1, 1) + .signers([user]) + .accounts({ + bondConfig: bondConfigPda1, + rewardsConfig: rewardsConfigPda, + vaultConfig: vaultConfigPda, + addressBondsRewards: userBondsRewards, + bond: bond1, + authority: user.publicKey, + }) + .rpc() + + const normalWeighted = await calculateWeightedLivelinessScore( + x, + userBondsRewards, + bondConfigPda1, + program + ) + + const addressBondsFetched = await program.account.addressBondsRewards.fetch( + userBondsRewards + ) + + assert( + addressBondsFetched.weightedLivelinessScore.toNumber() == normalWeighted + ) + }) + + it('TopUp bond 2 by user - bond not vault (should fail)', async () => { + const userBondsRewards = PublicKey.findProgramAddressSync( + [Buffer.from('address_bonds_rewards'), user.publicKey.toBuffer()], + program.programId + )[0] + + const bond2 = PublicKey.findProgramAddressSync( + [Buffer.from('bond'), user.publicKey.toBuffer(), Buffer.from([2])], + program.programId + )[0] + + try { + let x = await program.methods + .topUp(1, 2, new anchor.BN(100e9)) + .signers([user]) + .accounts({ + addressBondsRewards: userBondsRewards, + bondConfig: bondConfigPda1, + rewardsConfig: rewardsConfigPda, + mintOfTokenSent: itheum_token_mint.publicKey, + bond: bond2, + vaultConfig: vaultConfigPda, + vault: vault_ata, + authority: user.publicKey, + authorityTokenAccount: itheum_token_user_ata, + }) + .rpc() + assert(false, 'Should have thrown error') + } catch (err) { + expect((err as anchor.AnchorError).error.errorCode.number).to.equal(6015) + expect((err as anchor.AnchorError).error.errorMessage).to.equal( + 'Bond is not a vault' + ) + } + }) + it('TopUp bond 1 by user - wrong mint of token (should fail)', async () => { + const userBondsRewards = PublicKey.findProgramAddressSync( + [Buffer.from('address_bonds_rewards'), user.publicKey.toBuffer()], + program.programId + )[0] + + const bond1 = PublicKey.findProgramAddressSync( + [Buffer.from('bond'), user.publicKey.toBuffer(), Buffer.from([1])], + program.programId + )[0] + + try { + let x = await program.methods + .topUp(1, 1, new anchor.BN(100e9)) + .signers([user]) + .accounts({ + addressBondsRewards: userBondsRewards, + bondConfig: bondConfigPda1, + rewardsConfig: rewardsConfigPda, + mintOfTokenSent: another_token_mint.publicKey, + bond: bond1, + vaultConfig: vaultConfigPda, + vault: vault_ata, + authority: user.publicKey, + authorityTokenAccount: itheum_token_user_ata, + }) + .rpc() + assert(false, 'Should have thrown error') + } catch (err) { + expect((err as anchor.AnchorError).error.errorCode.number).to.equal(6006) + expect((err as anchor.AnchorError).error.errorMessage).to.equal( + 'Mint mismatch' + ) + } + }) + + it('TopUp bond 1 by user - wrong user accounts (should fail)', async () => { + const userBondsRewards = PublicKey.findProgramAddressSync( + [Buffer.from('address_bonds_rewards'), user2.publicKey.toBuffer()], + program.programId + )[0] + + const bond1 = PublicKey.findProgramAddressSync( + [Buffer.from('bond'), user2.publicKey.toBuffer(), Buffer.from([1])], + program.programId + )[0] + + try { + let x = await program.methods + .topUp(1, 1, new anchor.BN(100e9)) + .signers([user]) + .accounts({ + addressBondsRewards: userBondsRewards, + bondConfig: bondConfigPda1, + rewardsConfig: rewardsConfigPda, + mintOfTokenSent: itheum_token_mint.publicKey, + bond: bond1, + vaultConfig: vaultConfigPda, + vault: vault_ata, + authority: user.publicKey, + authorityTokenAccount: itheum_token_user_ata, + }) + .rpc() + assert(false, 'Should have thrown error') + } catch (err) { + expect((err as anchor.AnchorError).error.errorCode.number).to.equal(2006) + expect((err as anchor.AnchorError).error.errorMessage).to.equal( + 'A seeds constraint was violated' + ) + } + }) + + it('TopUp bond 1 by user', async () => { + const userBondsRewards = PublicKey.findProgramAddressSync( + [Buffer.from('address_bonds_rewards'), user.publicKey.toBuffer()], + program.programId + )[0] + + const bond1 = PublicKey.findProgramAddressSync( + [Buffer.from('bond'), user.publicKey.toBuffer(), Buffer.from([1])], + program.programId + )[0] + + let x = await program.methods + .topUp(1, 1, new anchor.BN(100e9)) + .signers([user]) + .accounts({ + addressBondsRewards: userBondsRewards, + bondConfig: bondConfigPda1, + rewardsConfig: rewardsConfigPda, + mintOfTokenSent: itheum_token_mint.publicKey, + bond: bond1, + vaultConfig: vaultConfigPda, + vault: vault_ata, + authority: user.publicKey, + authorityTokenAccount: itheum_token_user_ata, + }) + .rpc() + + const normalWeighted = await calculateWeightedLivelinessScore( + x, + userBondsRewards, + bondConfigPda1, + program + ) + + const addressBondsFetched = await program.account.addressBondsRewards.fetch( + userBondsRewards + ) + + assert( + addressBondsFetched.weightedLivelinessScore.toNumber() == normalWeighted + ) + }) + it('Withdraw bond 1 by user', async () => { + const userBondsRewards = PublicKey.findProgramAddressSync( + [Buffer.from('address_bonds_rewards'), user.publicKey.toBuffer()], + program.programId + )[0] + + const bond1 = PublicKey.findProgramAddressSync( + [Buffer.from('bond'), user.publicKey.toBuffer(), Buffer.from([1])], + program.programId + )[0] + + let x = await program.methods + .withdraw(1, 1) + .signers([user]) + .accounts({ + addressBondsRewards: userBondsRewards, + bondConfig: bondConfigPda1, + rewardsConfig: rewardsConfigPda, + mintOfTokenToReceive: itheum_token_mint.publicKey, + bond: bond1, + vaultConfig: vaultConfigPda, + vault: vault_ata, + authority: user.publicKey, + authorityTokenAccount: itheum_token_user_ata, + }) + .rpc({skipPreflight: true}) + + const normalWeighted = await calculateWeightedLivelinessScore( + x, + userBondsRewards, + bondConfigPda1, + program + ) + + const addressBondsFetched = await program.account.addressBondsRewards.fetch( + userBondsRewards + ) + + const tolerance = normalWeighted * 0.001 + const lowerBound = normalWeighted - tolerance + const upperBound = normalWeighted + tolerance + + assert( + addressBondsFetched.weightedLivelinessScore.toNumber() >= lowerBound && + addressBondsFetched.weightedLivelinessScore.toNumber() <= upperBound, + `Score ${addressBondsFetched.weightedLivelinessScore.toNumber()} is out of range!` + ) + }) + + it('Withdraw bond 1 by user - already withdrawn (should fail)', async () => { + const userBondsRewards = PublicKey.findProgramAddressSync( + [Buffer.from('address_bonds_rewards'), user.publicKey.toBuffer()], + program.programId + )[0] + + const bond1 = PublicKey.findProgramAddressSync( + [Buffer.from('bond'), user.publicKey.toBuffer(), Buffer.from([1])], + program.programId + )[0] + + try { + await program.methods + .withdraw(1, 1) + .signers([user]) + .accounts({ + addressBondsRewards: userBondsRewards, + bondConfig: bondConfigPda1, + rewardsConfig: rewardsConfigPda, + mintOfTokenToReceive: itheum_token_mint.publicKey, + bond: bond1, + vaultConfig: vaultConfigPda, + vault: vault_ata, + authority: user.publicKey, + authorityTokenAccount: itheum_token_user_ata, + }) + .rpc() + assert(false, 'Should have thrown error') + } catch (err) { + expect((err as anchor.AnchorError).error.errorCode.number).to.equal(6014) + expect((err as anchor.AnchorError).error.errorMessage).to.equal( + 'Bond is inactive' + ) + } + }) + + it('Top up bond 1 by user - bond inactive (should fail)', async () => { + const userBondsRewards = PublicKey.findProgramAddressSync( + [Buffer.from('address_bonds_rewards'), user.publicKey.toBuffer()], + program.programId + )[0] + + const bond1 = PublicKey.findProgramAddressSync( + [Buffer.from('bond'), user.publicKey.toBuffer(), Buffer.from([1])], + program.programId + )[0] + + try { + await program.methods + .topUp(1, 1, new anchor.BN(100e9)) + .signers([user]) + .accounts({ + addressBondsRewards: userBondsRewards, + bondConfig: bondConfigPda1, + rewardsConfig: rewardsConfigPda, + mintOfTokenSent: itheum_token_mint.publicKey, + bond: bond1, + vaultConfig: vaultConfigPda, + vault: vault_ata, + authority: user.publicKey, + authorityTokenAccount: itheum_token_user_ata, + }) + .rpc() + assert(false, 'Should have thrown error') + } catch (err) { + expect((err as anchor.AnchorError).error.errorCode.number).to.equal(6014) + expect((err as anchor.AnchorError).error.errorMessage).to.equal( + 'Bond is inactive' + ) + } + }) + it('Renew bond 1 by user - bond inactive (should fail)', async () => { + const userBondsRewards = PublicKey.findProgramAddressSync( + [Buffer.from('address_bonds_rewards'), user.publicKey.toBuffer()], + program.programId + )[0] + + const bond1 = PublicKey.findProgramAddressSync( + [Buffer.from('bond'), user.publicKey.toBuffer(), Buffer.from([1])], + program.programId + )[0] + + try { + await program.methods + .renew(1, 1) + .signers([user]) + .accounts({ + bondConfig: bondConfigPda1, + rewardsConfig: rewardsConfigPda, + vaultConfig: vaultConfigPda, + addressBondsRewards: userBondsRewards, + bond: bond1, + authority: user.publicKey, + }) + .rpc() + assert(false, 'Should have thrown error') + } catch (err) { + expect((err as anchor.AnchorError).error.errorCode.number).to.equal(6014) + expect((err as anchor.AnchorError).error.errorMessage).to.equal( + 'Bond is inactive' + ) + } + }) + + it('Update rewards per slot by admin', async () => { + await program.methods + .updateRewardsPerSlot(new anchor.BN(1e6)) + .signers([admin]) + .accounts({ + rewardsConfig: rewardsConfigPda, + authority: admin.publicKey, + }) + .rpc() + }) + + it('Activate rewards by admin', async () => { + await program.methods + .updateMaxApr(new anchor.BN(0)) + .signers([admin]) + .accounts({rewardsConfig: rewardsConfigPda, authority: admin.publicKey}) + .rpc() + + let x = await program.methods + .setRewardsStateActive() + .signers([admin]) + .accounts({rewardsConfig: rewardsConfigPda, authority: admin.publicKey}) + .rpc() + + let newConn = new Connection('http://localhost:8899', 'confirmed') + + let sigStatus = await newConn.getSignatureStatus(x) + + activation_slot = sigStatus.context.slot + }) + + it('Check user rewards - (renew bond 2 by user)', async () => { + const userBondsRewards = PublicKey.findProgramAddressSync( + [Buffer.from('address_bonds_rewards'), user.publicKey.toBuffer()], + program.programId + )[0] + + const bond2 = PublicKey.findProgramAddressSync( + [Buffer.from('bond'), user.publicKey.toBuffer(), Buffer.from([2])], + program.programId + )[0] + + let addressRewardsAccBefore = + await program.account.addressBondsRewards.fetch(userBondsRewards) + + let userBondsBefore = await program.account.addressBondsRewards.fetch( + userBondsRewards + ) + + let x = await program.methods + .renew(1, 2) + .signers([user]) + .accounts({ + bondConfig: bondConfigPda1, + rewardsConfig: rewardsConfigPda, + vaultConfig: vaultConfigPda, + addressBondsRewards: userBondsRewards, + bond: bond2, + authority: user.publicKey, + }) + .rpc({skipPreflight: true}) + + const normalWeighted = await calculateWeightedLivelinessScore( + x, + userBondsRewards, + bondConfigPda1, + program + ) + + const addressBondsFetched = await program.account.addressBondsRewards.fetch( + userBondsRewards + ) + + assert( + addressBondsFetched.weightedLivelinessScore.toNumber() == normalWeighted + ) + + let rewardsConfigAcc = await program.account.rewardsConfig.fetch( + rewardsConfigPda + ) + + let total_rewards = await calculateTotalRewardsInInterval( + activation_slot, + rewardsConfigPda, + program + ) + + let userRewardsAcc = await program.account.addressBondsRewards.fetch( + userBondsRewards + ) + + let user_rewards = await calculateUserRewards( + normalWeighted, + addressRewardsAccBefore.addressRewardsPerShare, + userBondsBefore.addressTotalBondAmount, + rewardsConfigPda, + true, + program + ) + + assert( + addressRewardsAccBefore.claimableAmount.toNumber() + + user_rewards / 10 ** 9 === + userRewardsAcc.claimableAmount.toNumber() + ) + + assert(rewardsConfigAcc.accumulatedRewards.toNumber() == total_rewards) + }) + + it('Check user2 rewards - (renew bond 1 by user2)', async () => { + const userBondsRewards = PublicKey.findProgramAddressSync( + [Buffer.from('address_bonds_rewards'), user2.publicKey.toBuffer()], + program.programId + )[0] + + const bond1 = PublicKey.findProgramAddressSync( + [Buffer.from('bond'), user2.publicKey.toBuffer(), Buffer.from([1])], + program.programId + )[0] + + let addressRewardsAccBefore = + await program.account.addressBondsRewards.fetch(userBondsRewards) + + let userBondsBefore = await program.account.addressBondsRewards.fetch( + userBondsRewards + ) + + let x = await program.methods + .renew(1, 1) + .signers([user2]) + .accounts({ + bondConfig: bondConfigPda1, + rewardsConfig: rewardsConfigPda, + vaultConfig: vaultConfigPda, + addressBondsRewards: userBondsRewards, + bond: bond1, + authority: user2.publicKey, + }) + .rpc({skipPreflight: true}) + + const normalWeighted = await calculateWeightedLivelinessScore( + x, + userBondsRewards, + bondConfigPda1, + program + ) + + const addressBondsFetched = await program.account.addressBondsRewards.fetch( + userBondsRewards + ) + + assert( + addressBondsFetched.weightedLivelinessScore.toNumber() == normalWeighted + ) + + let rewardsConfigAcc = await program.account.rewardsConfig.fetch( + rewardsConfigPda + ) + + let total_rewards = await calculateTotalRewardsInInterval( + activation_slot, + rewardsConfigPda, + program + ) + + let userRewardsAcc = await program.account.addressBondsRewards.fetch( + userBondsRewards + ) + + let user_rewards = await calculateUserRewards( + normalWeighted, + addressRewardsAccBefore.addressRewardsPerShare, + userBondsBefore.addressTotalBondAmount, + rewardsConfigPda, + true, + program + ) + + assert( + addressRewardsAccBefore.claimableAmount.toNumber() + + user_rewards / 10 ** 9 === + userRewardsAcc.claimableAmount.toNumber() + ) + + assert(rewardsConfigAcc.accumulatedRewards.toNumber() == total_rewards) + }) + + it('Check user rewards - bond 3 by user', async () => { + const userBondsRewards = PublicKey.findProgramAddressSync( + [Buffer.from('address_bonds_rewards'), user.publicKey.toBuffer()], + program.programId + )[0] + + const assetUsage3 = PublicKey.findProgramAddressSync( + [toWeb3JsPublicKey(user_nft_leaf_schemas[2].id).toBuffer()], + program.programId + )[0] + + const bond3 = PublicKey.findProgramAddressSync( + [Buffer.from('bond'), user.publicKey.toBuffer(), Buffer.from([3])], + program.programId + )[0] + + let addressRewardsAccBefore = + await program.account.addressBondsRewards.fetch(userBondsRewards) + + let userBondsBefore = await program.account.addressBondsRewards.fetch( + userBondsRewards + ) + + let x = await program.methods + .bond( + 1, + 3, + new anchor.BN(100e9), + toWeb3JsPublicKey(user_nft_leaf_schemas[2].id), + false, + Array.from(bs58.decode(user_nft_leaf_schemas[2].id)), + Array.from(user_nft_leaf_schemas[2].dataHash), + Array.from(user_nft_leaf_schemas[2].creatorHash), + new anchor.BN(user_nft_leaf_schemas[2].nonce.toString()), + 1 + ) + .signers([user]) + .accounts({ + addressBondsRewards: userBondsRewards, + assetUsage: assetUsage3, + bond: bond3, + bondConfig: bondConfigPda1, + rewardsConfig: rewardsConfigPda, + vaultConfig: vaultConfigPda, + vault: vault_ata, + mintOfTokenSent: itheum_token_mint.publicKey, + authority: user.publicKey, + merkleTree: merkleTree, + authorityTokenAccount: itheum_token_user_ata, + systemProgram: anchor.web3.SystemProgram.programId, + tokenProgram: TOKEN_PROGRAM_ID, + associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ID, + compressionProgram: SPL_ACCOUNT_COMPRESSION_PROGRAM_ID, + }) + .remainingAccounts([ + { + pubkey: new PublicKey(merkleTree), + isSigner: false, + isWritable: false, + }, + ]) + .rpc() + + const normalWeighted = await calculateWeightedLivelinessScore( + x, + userBondsRewards, + bondConfigPda1, + program + ) + + const addressBondsFetched = await program.account.addressBondsRewards.fetch( + userBondsRewards + ) + + const tolerance = normalWeighted * 0.0001 + const lowerBound = normalWeighted - tolerance + const upperBound = normalWeighted + tolerance + + assert( + addressBondsFetched.weightedLivelinessScore.toNumber() >= lowerBound && + addressBondsFetched.weightedLivelinessScore.toNumber() <= upperBound, + `Score ${addressBondsFetched.weightedLivelinessScore.toNumber()} is out of range!` + ) + + let userRewardsAcc = await program.account.addressBondsRewards.fetch( + userBondsRewards + ) + + let user_rewards = await calculateUserRewards( + addressBondsFetched.weightedLivelinessScore.toNumber(), + addressRewardsAccBefore.addressRewardsPerShare, + userBondsBefore.addressTotalBondAmount, + rewardsConfigPda, + true, + program + ) + + assert( + addressRewardsAccBefore.claimableAmount.toNumber() + + user_rewards / 10 ** 9 === + userRewardsAcc.claimableAmount.toNumber() + ) + }) + + it('Stake rewards user2', async () => { + const addressBondsRewards = PublicKey.findProgramAddressSync( + [Buffer.from('address_bonds_rewards'), user2.publicKey.toBuffer()], + program.programId + )[0] + + const bond = PublicKey.findProgramAddressSync( + [Buffer.from('bond'), user2.publicKey.toBuffer(), Buffer.from([1])], + program.programId + )[0] + + let rewardsConfigAcc = await program.account.rewardsConfig.fetch( + rewardsConfigPda + ) + + let addressRewardsAccBefore = + await program.account.addressBondsRewards.fetch(addressBondsRewards) + + let bondBefore = await program.account.bond.fetch(bond) + + let userBondsBefore = await program.account.addressBondsRewards.fetch( + addressBondsRewards + ) + + let x = await program.methods + .stakeRewards(1, 1) + .signers([user2]) + .accounts({ + addressBondsRewards: addressBondsRewards, + bondConfig: bondConfigPda1, + rewardsConfig: rewardsConfigPda, + vaultConfig: vaultConfigPda, + bond: bond, + authority: user2.publicKey, + }) + .rpc() + + const normalWeighted = await calculateWeightedLivelinessScore( + x, + addressBondsRewards, + bondConfigPda1, + program + ) + + const addressBondsFetched = await program.account.addressBondsRewards.fetch( + addressBondsRewards + ) + + const tolerance = normalWeighted * 0.0001 + const lowerBound = normalWeighted - tolerance + const upperBound = normalWeighted + tolerance + + assert( + addressBondsFetched.weightedLivelinessScore.toNumber() >= lowerBound && + addressBondsFetched.weightedLivelinessScore.toNumber() <= upperBound, + `Score ${addressBondsFetched.weightedLivelinessScore.toNumber()} is out of range!` + ) + + let userRewardsAcc = await program.account.addressBondsRewards.fetch( + addressBondsRewards + ) + + let bondAfter = await program.account.bond.fetch(bond) + + let user_rewards = await calculateUserRewards( + addressBondsFetched.weightedLivelinessScore.toNumber(), + addressRewardsAccBefore.addressRewardsPerShare, + userBondsBefore.addressTotalBondAmount, + rewardsConfigPda, + false, + program + ) + + assert( + addressRewardsAccBefore.claimableAmount.toNumber() + + user_rewards / 10 ** 9 + + bondBefore.bondAmount.toNumber() === + bondAfter.bondAmount.toNumber() + ) + assert(userRewardsAcc.claimableAmount.toNumber() === 0) + }) + + it('Claim rewards user', async () => { + const addressBondsRewards = PublicKey.findProgramAddressSync( + [Buffer.from('address_bonds_rewards'), user.publicKey.toBuffer()], + program.programId + )[0] + + let addressRewardsAccBefore = + await program.account.addressBondsRewards.fetch(addressBondsRewards) + let userBondsBefore = await program.account.addressBondsRewards.fetch( + addressBondsRewards + ) + + let user_balance_before = await provider.connection.getTokenAccountBalance( + itheum_token_user_ata + ) + + let x = await program.methods + .claimRewards(1) + .signers([user]) + .accounts({ + addressBondsRewards: addressBondsRewards, + bondConfig: bondConfigPda1, + rewardsConfig: rewardsConfigPda, + vaultConfig: vaultConfigPda, + vault: vault_ata, + mintOfTokenToReceive: itheum_token_mint.publicKey, + authority: user.publicKey, + authorityTokenAccount: itheum_token_user_ata, + }) + .rpc() + + let normalWeighted = await calculateWeightedLivelinessScore( + x, + addressBondsRewards, + bondConfigPda1, + program + ) + + let addressBondsFetched = await program.account.addressBondsRewards.fetch( + addressBondsRewards + ) + + const tolerance = normalWeighted * 0.0001 + const lowerBound = normalWeighted - tolerance + const upperBound = normalWeighted + tolerance + + assert( + addressBondsFetched.weightedLivelinessScore.toNumber() >= lowerBound && + addressBondsFetched.weightedLivelinessScore.toNumber() <= upperBound, + `Score ${addressBondsFetched.weightedLivelinessScore.toNumber()} is out of range!` + ) + + let user_rewards = await calculateUserRewards( + addressBondsFetched.weightedLivelinessScore.toNumber(), + addressRewardsAccBefore.addressRewardsPerShare, + userBondsBefore.addressTotalBondAmount, + rewardsConfigPda, + false, + program + ) + + let user_balance_after = await provider.connection.getTokenAccountBalance( + itheum_token_user_ata + ) + + assert( + addressRewardsAccBefore.claimableAmount.toNumber() + + user_rewards / 10 ** 9 + + Number(user_balance_before.value.amount) === + Number(user_balance_after.value.amount) + ) + + let addressRewardsAccAfter = + await program.account.addressBondsRewards.fetch(addressBondsRewards) + + assert(addressRewardsAccAfter.claimableAmount.toNumber() === 0) + }) +}) + +function delay(ms: number) { + return new Promise((resolve) => setTimeout(resolve, ms)) +} + +async function calculateTotalRewardsInInterval( + previous_slot: number, + rewardsConfigPda: PublicKey, + program: anchor.Program +) { + let rewards_config = await program.account.rewardsConfig.fetch( + rewardsConfigPda + ) + + let slots = rewards_config.lastRewardSlot.toNumber() - previous_slot + + let total_rewards = rewards_config.rewardsPerSlot.mul(new anchor.BN(slots)) + + return total_rewards.toNumber() +} + +// calculate user rewards based on the total rewards +async function calculateUserRewards( + normalWeighted: number, + address_last_rewards_per_share: anchor.BN, + address_last_total_bond_amount: anchor.BN, + rewards_config: PublicKey, + bypassLiveliness: boolean, + program: anchor.Program +) { + const rewardsAcc = await program.account.rewardsConfig.fetch(rewards_config) + + let user_rewards = address_last_total_bond_amount.mul( + rewardsAcc.rewardsPerShare.sub(address_last_rewards_per_share) + ) + + if (normalWeighted >= 9500 || bypassLiveliness) { + return user_rewards.toNumber() + } else { + return (user_rewards.toNumber() * normalWeighted) / 10000 + } +} + +async function calculateWeightedLivelinessScore( + signature: TransactionSignature, + userBondsPda: PublicKey, + bondsConfigPda: PublicKey, + program: anchor.Program +) { + let newConn = new Connection('http://localhost:8899', 'confirmed') + + let sigStatus = await newConn.getSignatureStatus(signature) + + let blockTime = await newConn.getBlockTime(sigStatus.context.slot) + if (!blockTime) { + throw new Error('Unable to fetch block time for the provided slot') + } + + let current_timestamp = blockTime + + const userBondsAcc = await program.account.addressBondsRewards.fetch( + userBondsPda + ) + + const bondConfigAcc = await program.account.bondConfig.fetch(bondsConfigPda) + + let totalBondAmount = new anchor.BN(0) + let totalBondWeight = new anchor.BN(0) + + for (let bond_id = 1; bond_id <= userBondsAcc.currentIndex; bond_id++) { + const bond_pda = PublicKey.findProgramAddressSync( + [ + Buffer.from('bond'), + userBondsAcc.address.toBuffer(), + Buffer.from([bond_id]), + ], + program.programId + )[0] + + const bondAcc = await program.account.bond.fetch(bond_pda) + + if (bondAcc.state === 0) { + continue + } + + const score = computeBondScore( + bondConfigAcc.lockPeriod.toNumber(), + current_timestamp, + bondAcc.unbondTimestamp.toNumber() + ) + + const bond_weight = bondAcc.bondAmount.mul(new anchor.BN(score)) + totalBondWeight = totalBondWeight.add(bond_weight) + + totalBondAmount = totalBondAmount.add(bondAcc.bondAmount) + } + + const weighted_score = totalBondWeight.div(totalBondAmount) + + return weighted_score.toNumber() +} + +function computeBondScore( + lockPeriod: number, + currentTimestamp: number, + unbondTimestamp: number +): number { + if (currentTimestamp >= unbondTimestamp) { + return 0 + } else { + const difference = unbondTimestamp - currentTimestamp + + if (lockPeriod === 0) { + return 0 + } else { + const divResult = Math.floor(10000 / lockPeriod) + return divResult * difference + } + } +} diff --git a/yarn.lock b/yarn.lock index 40bc714..7844486 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9,18 +9,12 @@ dependencies: regenerator-runtime "^0.14.0" -"@coral-xyz/anchor-errors@^0.30.1": - version "0.30.1" - resolved "https://registry.npmjs.org/@coral-xyz/anchor-errors/-/anchor-errors-0.30.1.tgz" - integrity sha512-9Mkradf5yS5xiLWrl9WrpjqOrAV+/W2RQHDlbnAZBivoGpOs1ECjoDCkVk4aRG8ZdiFiB8zQEVlxf+8fKkmSfQ== - -"@coral-xyz/anchor@^0.30.1": - version "0.30.1" - resolved "https://registry.npmjs.org/@coral-xyz/anchor/-/anchor-0.30.1.tgz" - integrity sha512-gDXFoF5oHgpriXAaLpxyWBHdCs8Awgf/gLHIo6crv7Aqm937CNdY+x+6hoj7QR5vaJV7MxWSQ0NGFzL3kPbWEQ== - dependencies: - "@coral-xyz/anchor-errors" "^0.30.1" - "@coral-xyz/borsh" "^0.30.1" +"@coral-xyz/anchor@^0.29.0": + version "0.29.0" + resolved "https://registry.npmjs.org/@coral-xyz/anchor/-/anchor-0.29.0.tgz" + integrity sha512-eny6QNG0WOwqV0zQ7cs/b1tIuzZGmP7U7EcH+ogt4Gdbl8HDmIYVMh/9aTmYZPaFWjtUaI8qSn73uYEXWfATdA== + dependencies: + "@coral-xyz/borsh" "^0.29.0" "@noble/hashes" "^1.3.1" "@solana/web3.js" "^1.68.0" bn.js "^5.1.2" @@ -35,14 +29,21 @@ superstruct "^0.15.4" toml "^3.0.0" -"@coral-xyz/borsh@^0.30.1": - version "0.30.1" - resolved "https://registry.npmjs.org/@coral-xyz/borsh/-/borsh-0.30.1.tgz" - integrity sha512-aaxswpPrCFKl8vZTbxLssA2RvwX2zmKLlRCIktJOwW+VpVwYtXRtlWiIP+c2pPRKneiTiWCN2GEMSH9j1zTlWQ== +"@coral-xyz/borsh@^0.29.0": + version "0.29.0" + resolved "https://registry.npmjs.org/@coral-xyz/borsh/-/borsh-0.29.0.tgz" + integrity sha512-s7VFVa3a0oqpkuRloWVPdCK7hMbAMY270geZOGfCnaqexrP5dTIpbEHL33req6IYPPJ0hYa71cdvJ1h6V55/oQ== dependencies: bn.js "^5.1.2" buffer-layout "^1.2.0" +"@cspotcode/source-map-support@^0.8.0": + version "0.8.1" + resolved "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz" + integrity sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw== + dependencies: + "@jridgewell/trace-mapping" "0.3.9" + "@ethereumjs/rlp@^4.0.1": version "4.0.1" resolved "https://registry.npmjs.org/@ethereumjs/rlp/-/rlp-4.0.1.tgz" @@ -57,6 +58,24 @@ ethereum-cryptography "^2.0.0" micro-ftch "^0.3.1" +"@jridgewell/resolve-uri@^3.0.3": + version "3.1.2" + resolved "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz" + integrity sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw== + +"@jridgewell/sourcemap-codec@^1.4.10": + version "1.5.0" + resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz" + integrity sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ== + +"@jridgewell/trace-mapping@0.3.9": + version "0.3.9" + resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz" + integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ== + dependencies: + "@jridgewell/resolve-uri" "^3.0.3" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@metaplex-foundation/digital-asset-standard-api@^1.0.4": version "1.0.4" resolved "https://registry.npmjs.org/@metaplex-foundation/digital-asset-standard-api/-/digital-asset-standard-api-1.0.4.tgz" @@ -64,67 +83,60 @@ dependencies: package.json "^2.0.1" -"@metaplex-foundation/mpl-bubblegum@^4.1.0": - version "4.2.0" - resolved "https://registry.npmjs.org/@metaplex-foundation/mpl-bubblegum/-/mpl-bubblegum-4.2.0.tgz" - integrity sha512-PKnfRI5bAKI4R+Hv2mLbkSDfWabYpfBPKQ+ji6Knufd1p3g0RuLQuDsZ6y3JqET/rfaEMaEx8AhNnMsm9mXCFg== +"@metaplex-foundation/mpl-bubblegum@^4.2.1": + version "4.2.1" + resolved "https://registry.npmjs.org/@metaplex-foundation/mpl-bubblegum/-/mpl-bubblegum-4.2.1.tgz" + integrity sha512-r9kHrVmkzJApbXwd7cmJyO0mAV3qsJaTjv5ks6PUT1Bzjj9QCvlJYg2UYQJLUTcrY5TjE9wXLpwUqNgllXH/Cw== dependencies: "@metaplex-foundation/digital-asset-standard-api" "^1.0.4" - "@metaplex-foundation/mpl-token-metadata" "3.0.0-alpha.27" + "@metaplex-foundation/mpl-token-metadata" "3.2.1" "@metaplex-foundation/mpl-toolbox" "^0.9.0" "@noble/hashes" "^1.3.1" merkletreejs "^0.3.9" -"@metaplex-foundation/mpl-token-metadata@^3.2.1": +"@metaplex-foundation/mpl-token-metadata@^3.2.1", "@metaplex-foundation/mpl-token-metadata@3.2.1": version "3.2.1" resolved "https://registry.npmjs.org/@metaplex-foundation/mpl-token-metadata/-/mpl-token-metadata-3.2.1.tgz" integrity sha512-26W1NhQwDWmLOg/pBRYut7x/vEs/5kFS2sWVEY5/X0f2jJOLhnd4NaZQcq+5u+XZsXvm1jq2AtrRGPNK43oqWQ== dependencies: "@metaplex-foundation/mpl-toolbox" "^0.9.4" -"@metaplex-foundation/mpl-token-metadata@3.0.0-alpha.27": - version "3.0.0-alpha.27" - resolved "https://registry.npmjs.org/@metaplex-foundation/mpl-token-metadata/-/mpl-token-metadata-3.0.0-alpha.27.tgz" - integrity sha512-MSERz5HB2XZ/K+FOMh0tPeqcZZEpGVzdy7e+Cy3MHg7x52JtbGBDtWIoxBJn1OBZayCBfX9gytEoqrXe2YRGqQ== - dependencies: - "@metaplex-foundation/mpl-toolbox" "^0.9.0" - "@metaplex-foundation/mpl-toolbox@^0.9.0", "@metaplex-foundation/mpl-toolbox@^0.9.4": version "0.9.4" resolved "https://registry.npmjs.org/@metaplex-foundation/mpl-toolbox/-/mpl-toolbox-0.9.4.tgz" integrity sha512-fd6JxfoLbj/MM8FG2x91KYVy1U6AjBQw4qjt7+Da3trzQaWnSaYHDcYRG/53xqfvZ9qofY1T2t53GXPlD87lnQ== -"@metaplex-foundation/umi-bundle-defaults@^0.8.10": - version "0.8.10" - resolved "https://registry.npmjs.org/@metaplex-foundation/umi-bundle-defaults/-/umi-bundle-defaults-0.8.10.tgz" - integrity sha512-eqt5uJlDb6SNV0qB7BiTWbRAk1Mnl22ve3qHRxalqvDGQ2bklEY6RzBZWC+R/eQnJ+pVsp7Dd34bhxY3I+Ht7g== - dependencies: - "@metaplex-foundation/umi-downloader-http" "^0.8.10" - "@metaplex-foundation/umi-eddsa-web3js" "^0.8.10" - "@metaplex-foundation/umi-http-fetch" "^0.8.10" - "@metaplex-foundation/umi-program-repository" "^0.8.10" - "@metaplex-foundation/umi-rpc-chunk-get-accounts" "^0.8.10" - "@metaplex-foundation/umi-rpc-web3js" "^0.8.10" - "@metaplex-foundation/umi-serializer-data-view" "^0.8.10" - "@metaplex-foundation/umi-transaction-factory-web3js" "^0.8.10" - -"@metaplex-foundation/umi-downloader-http@^0.8.10": - version "0.8.10" - resolved "https://registry.npmjs.org/@metaplex-foundation/umi-downloader-http/-/umi-downloader-http-0.8.10.tgz" - integrity sha512-i0YbSaPvo0/49XazVL+jmm3PpRSeE4bc8E1TUUsUCXrpb6lSup6u0cx7vYij2mis91UDhdO8hTgdxFwNdqvFHQ== - -"@metaplex-foundation/umi-eddsa-web3js@^0.8.10": - version "0.8.10" - resolved "https://registry.npmjs.org/@metaplex-foundation/umi-eddsa-web3js/-/umi-eddsa-web3js-0.8.10.tgz" - integrity sha512-2CLsuQ67oPKczB7RuG07/Ro1rrW25vGZArren20/zBTgHubGIuFW7V8e9qZDqkHDt1nFecxrX55g0fNtQaU40g== - dependencies: - "@metaplex-foundation/umi-web3js-adapters" "^0.8.10" +"@metaplex-foundation/umi-bundle-defaults@^0.9.2": + version "0.9.2" + resolved "https://registry.npmjs.org/@metaplex-foundation/umi-bundle-defaults/-/umi-bundle-defaults-0.9.2.tgz" + integrity sha512-kV3tfvgvRjVP1p9OFOtH+ibOtN9omVJSwKr0We4/9r45e5LTj+32su0V/rixZUkG1EZzzOYBsxhtIE0kIw/Hrw== + dependencies: + "@metaplex-foundation/umi-downloader-http" "^0.9.2" + "@metaplex-foundation/umi-eddsa-web3js" "^0.9.2" + "@metaplex-foundation/umi-http-fetch" "^0.9.2" + "@metaplex-foundation/umi-program-repository" "^0.9.2" + "@metaplex-foundation/umi-rpc-chunk-get-accounts" "^0.9.2" + "@metaplex-foundation/umi-rpc-web3js" "^0.9.2" + "@metaplex-foundation/umi-serializer-data-view" "^0.9.2" + "@metaplex-foundation/umi-transaction-factory-web3js" "^0.9.2" + +"@metaplex-foundation/umi-downloader-http@^0.9.2": + version "0.9.2" + resolved "https://registry.npmjs.org/@metaplex-foundation/umi-downloader-http/-/umi-downloader-http-0.9.2.tgz" + integrity sha512-tzPT9hBwenzTzAQg07rmsrqZfgguAXELbcJrsYMoASp5VqWFXYIP00g94KET6XLjWUXH4P1J2zoa6hGennPXHA== + +"@metaplex-foundation/umi-eddsa-web3js@^0.9.2": + version "0.9.2" + resolved "https://registry.npmjs.org/@metaplex-foundation/umi-eddsa-web3js/-/umi-eddsa-web3js-0.9.2.tgz" + integrity sha512-hhPCxXbYIp4BC4z9gK78sXpWLkNSrfv4ndhF5ruAkdIp7GcRVYKj0QnOUO6lGYGiIkNlw20yoTwOe1CT//OfTQ== + dependencies: + "@metaplex-foundation/umi-web3js-adapters" "^0.9.2" "@noble/curves" "^1.0.0" -"@metaplex-foundation/umi-http-fetch@^0.8.10": - version "0.8.10" - resolved "https://registry.npmjs.org/@metaplex-foundation/umi-http-fetch/-/umi-http-fetch-0.8.10.tgz" - integrity sha512-9QkVMaM8A8JFaTSanVJT3R7IzeLn05xrK7fFnfCTASaTvk+7Dj8ZsgXQjuyCi1pXQrMN+EsREn2NE/tn48ffMQ== +"@metaplex-foundation/umi-http-fetch@^0.9.2": + version "0.9.2" + resolved "https://registry.npmjs.org/@metaplex-foundation/umi-http-fetch/-/umi-http-fetch-0.9.2.tgz" + integrity sha512-YCZuBu24T9ZzEDe4+w12LEZm/fO9pkyViZufGgASC5NX93814Lvf6Ssjn/hZzjfA7CvZbvLFbmujc6CV3Q/m9Q== dependencies: node-fetch "^2.6.7" @@ -133,10 +145,10 @@ resolved "https://registry.npmjs.org/@metaplex-foundation/umi-options/-/umi-options-0.8.9.tgz" integrity sha512-jSQ61sZMPSAk/TXn8v8fPqtz3x8d0/blVZXLLbpVbo2/T5XobiI6/MfmlUosAjAUaQl6bHRF8aIIqZEFkJiy4A== -"@metaplex-foundation/umi-program-repository@^0.8.10": - version "0.8.10" - resolved "https://registry.npmjs.org/@metaplex-foundation/umi-program-repository/-/umi-program-repository-0.8.10.tgz" - integrity sha512-zw+UMOg9z3xqqeosRfctmcnaDYkaoMMvqhu7Vpwt7K9tpVtMaMT5yei29ORvaYpiEVG5hZSbywr/vQsNY0EV9g== +"@metaplex-foundation/umi-program-repository@^0.9.2": + version "0.9.2" + resolved "https://registry.npmjs.org/@metaplex-foundation/umi-program-repository/-/umi-program-repository-0.9.2.tgz" + integrity sha512-g3+FPqXEmYsBa8eETtUE2gb2Oe3mqac0z3/Ur1TvAg5TtIy3mzRzOy/nza+sgzejnfcxcVg835rmpBaxpBnjDA== "@metaplex-foundation/umi-public-keys@^0.8.9": version "0.8.9" @@ -145,22 +157,22 @@ dependencies: "@metaplex-foundation/umi-serializers-encodings" "^0.8.9" -"@metaplex-foundation/umi-rpc-chunk-get-accounts@^0.8.10": - version "0.8.10" - resolved "https://registry.npmjs.org/@metaplex-foundation/umi-rpc-chunk-get-accounts/-/umi-rpc-chunk-get-accounts-0.8.10.tgz" - integrity sha512-+fiQ+yza7C5N/vvCzDxoXkdE8NDg/Q5FOWCa4ysuupHB4P3/Ah+M5zJdB739I047ykIi+Fy/+JqmWsSZQsHNHA== +"@metaplex-foundation/umi-rpc-chunk-get-accounts@^0.9.2": + version "0.9.2" + resolved "https://registry.npmjs.org/@metaplex-foundation/umi-rpc-chunk-get-accounts/-/umi-rpc-chunk-get-accounts-0.9.2.tgz" + integrity sha512-YRwVf6xH0jPBAUgMhEPi+UbjioAeqTXmjsN2TnmQCPAmHbrHrMRj0rlWYwFLWAgkmoxazYrXP9lqOFRrfOGAEA== -"@metaplex-foundation/umi-rpc-web3js@^0.8.10": - version "0.8.10" - resolved "https://registry.npmjs.org/@metaplex-foundation/umi-rpc-web3js/-/umi-rpc-web3js-0.8.10.tgz" - integrity sha512-+60uxlX1OcThL2UIW9dbcy0Ihr011ggxkQYSxc1qh4qitgD9wrZZ/v9nX4tzEN88a52UJGhH5G3SF6CNmqy4aw== +"@metaplex-foundation/umi-rpc-web3js@^0.9.2": + version "0.9.2" + resolved "https://registry.npmjs.org/@metaplex-foundation/umi-rpc-web3js/-/umi-rpc-web3js-0.9.2.tgz" + integrity sha512-MqcsBz8B4wGl6jxsf2Jo/rAEpYReU9VCSR15QSjhvADHMmdFxCIZCCAgE+gDE2Vuanfl437VhOcP3g5Uw8C16Q== dependencies: - "@metaplex-foundation/umi-web3js-adapters" "^0.8.10" + "@metaplex-foundation/umi-web3js-adapters" "^0.9.2" -"@metaplex-foundation/umi-serializer-data-view@^0.8.10": - version "0.8.10" - resolved "https://registry.npmjs.org/@metaplex-foundation/umi-serializer-data-view/-/umi-serializer-data-view-0.8.10.tgz" - integrity sha512-DVKUQw7FEfpRIE9RF4YU73Mwlaf42RAWDgcycNiYFWpj/FLRebNr+2NT3ALYlOqXsAchnCAYjlQVxCB0Sopn9Q== +"@metaplex-foundation/umi-serializer-data-view@^0.9.2": + version "0.9.2" + resolved "https://registry.npmjs.org/@metaplex-foundation/umi-serializer-data-view/-/umi-serializer-data-view-0.9.2.tgz" + integrity sha512-5vGptadJxUxvUcyrwFZxXlEc6Q7AYySBesizCtrBFUY8w8PnF2vzmS45CP1MLySEATNH6T9mD4Rs0tLb87iQyA== "@metaplex-foundation/umi-serializers-core@^0.8.9": version "0.8.9" @@ -192,12 +204,12 @@ "@metaplex-foundation/umi-serializers-encodings" "^0.8.9" "@metaplex-foundation/umi-serializers-numbers" "^0.8.9" -"@metaplex-foundation/umi-transaction-factory-web3js@^0.8.10": - version "0.8.10" - resolved "https://registry.npmjs.org/@metaplex-foundation/umi-transaction-factory-web3js/-/umi-transaction-factory-web3js-0.8.10.tgz" - integrity sha512-hnkDKdtuZgY6DKH6aSEd6UrZGi5/WvfYqJUWeM8SVl1/8GhNypNKWvuppvFHpU9X2tLXuF4JSG4TVxAuIs9LBQ== +"@metaplex-foundation/umi-transaction-factory-web3js@^0.9.2": + version "0.9.2" + resolved "https://registry.npmjs.org/@metaplex-foundation/umi-transaction-factory-web3js/-/umi-transaction-factory-web3js-0.9.2.tgz" + integrity sha512-fR1Kf21uylMFd1Smkltmj4jTNxhqSWf416owsJ+T+cvJi2VCOcOwq/3UFzOrpz78fA0RhsajKYKj0HYsRnQI1g== dependencies: - "@metaplex-foundation/umi-web3js-adapters" "^0.8.10" + "@metaplex-foundation/umi-web3js-adapters" "^0.9.2" "@metaplex-foundation/umi-web3js-adapters@^0.8.10": version "0.8.10" @@ -206,7 +218,14 @@ dependencies: buffer "^6.0.3" -"@metaplex-foundation/umi@^0.8.10", "@metaplex-foundation/umi@^0.8.2", "@metaplex-foundation/umi@>= 0.8.2 < 1", "@metaplex-foundation/umi@>= 0.8.9 < 1": +"@metaplex-foundation/umi-web3js-adapters@^0.9.2": + version "0.9.2" + resolved "https://registry.npmjs.org/@metaplex-foundation/umi-web3js-adapters/-/umi-web3js-adapters-0.9.2.tgz" + integrity sha512-RQqUTtHYY9fmEMnq7s3Hiv/81flGaoI0ZVVoafnFVaQLnxU6QBKxtboRZHk43XtD9CiFh5f9izrMJX7iK7KlOA== + dependencies: + buffer "^6.0.3" + +"@metaplex-foundation/umi@^0.8.10": version "0.8.10" resolved "https://registry.npmjs.org/@metaplex-foundation/umi/-/umi-0.8.10.tgz" integrity sha512-iGuGIfJh2+YFvUIkZ0nB/69EsQcaoq89DDPRPYvPBtOunfv8TH8SNrwcsXHlp9aBtn5FGKCPx3V3X/eurB32Fg== @@ -437,7 +456,7 @@ dependencies: buffer "^6.0.3" -"@solana/web3.js@^1.32.0", "@solana/web3.js@^1.68.0", "@solana/web3.js@^1.72.0", "@solana/web3.js@^1.91.6", "@solana/web3.js@^1.94.0", "@solana/web3.js@^1.95.2": +"@solana/web3.js@^1.32.0", "@solana/web3.js@^1.68.0", "@solana/web3.js@^1.95.2": version "1.95.2" resolved "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.95.2.tgz" integrity sha512-SjlHp0G4qhuhkQQc+YXdGkI8EerCqwxvgytMgBpzMUQTafrkNant3e7pgilBGgjy/iM40ICvWBLgASTPMrQU7w== @@ -465,6 +484,26 @@ dependencies: tslib "^2.4.0" +"@tsconfig/node10@^1.0.7": + version "1.0.11" + resolved "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz" + integrity sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw== + +"@tsconfig/node12@^1.0.7": + version "1.0.11" + resolved "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz" + integrity sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag== + +"@tsconfig/node14@^1.0.0": + version "1.0.3" + resolved "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz" + integrity sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow== + +"@tsconfig/node16@^1.0.2": + version "1.0.4" + resolved "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz" + integrity sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA== + "@types/bn.js@^5.1.0": version "5.1.5" resolved "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.5.tgz" @@ -537,6 +576,18 @@ abs@^1.2.1: dependencies: ul "^5.0.0" +acorn-walk@^8.1.1: + version "8.3.4" + resolved "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz" + integrity sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g== + dependencies: + acorn "^8.11.0" + +acorn@^8.11.0, acorn@^8.4.1: + version "8.12.1" + resolved "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz" + integrity sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg== + agentkeepalive@^4.5.0: version "4.5.0" resolved "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.5.0.tgz" @@ -569,6 +620,11 @@ anymatch@~3.1.2: normalize-path "^3.0.0" picomatch "^2.0.4" +arg@^4.1.0: + version "4.1.3" + resolved "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz" + integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== + argparse@^2.0.1: version "2.0.1" resolved "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz" @@ -812,6 +868,11 @@ create-error-class@^3.0.1: dependencies: capture-stack-trace "^1.0.0" +create-require@^1.1.0: + version "1.1.1" + resolved "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz" + integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== + cross-fetch@^3.1.5: version "3.1.8" resolved "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.8.tgz" @@ -870,6 +931,11 @@ diff@^3.1.0: resolved "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz" integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA== +diff@^4.0.1: + version "4.0.2" + resolved "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz" + integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== + diff@5.0.0: version "5.0.0" resolved "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz" @@ -989,11 +1055,6 @@ fast-stable-stringify@^1.0.0: resolved "https://registry.npmjs.org/fast-stable-stringify/-/fast-stable-stringify-1.0.0.tgz" integrity sha512-wpYMUmFu5f00Sm0cj2pfivpmawLZ0NKdviQ4w9zJeR8JVtOpOxHmLaJuj0vxvGqMJQWyP/COUkF75/57OKyRag== -fastestsmallesttextencoderdecoder@^1.0.22: - version "1.0.22" - resolved "https://registry.npmjs.org/fastestsmallesttextencoderdecoder/-/fastestsmallesttextencoderdecoder-1.0.22.tgz" - integrity sha512-Pb8d48e+oIuY4MaM64Cd7OW1gt4nxCHs7/ddPPZ/Ic3sg8yVGM7O9wDvZ7us6ScaUupzM+pfBolwtYhN1IxBIw== - file-uri-to-path@1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz" @@ -1437,7 +1498,7 @@ mkdirp@^0.5.1: dependencies: minimist "^1.2.6" -"mocha@^3.X.X || ^4.X.X || ^5.X.X || ^6.X.X || ^7.X.X || ^8.X.X || ^9.X.X || ^10.X.X", mocha@^9.0.3: +mocha@^9.0.3: version "9.2.2" resolved "https://registry.npmjs.org/mocha/-/mocha-9.2.2.tgz" integrity sha512-L6XC3EdwT6YrIk0yXpavvLkn8h+EU+Y5UcCHKECyMbdUIxyMuZj4bX4U9e1nvnvUUvQVsV2VHQr5zLdcUkhW/g== @@ -2013,6 +2074,25 @@ ts-mocha@^10.0.0: optionalDependencies: tsconfig-paths "^3.5.0" +ts-node@^10.9.2: + version "10.9.2" + resolved "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz" + integrity sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ== + dependencies: + "@cspotcode/source-map-support" "^0.8.0" + "@tsconfig/node10" "^1.0.7" + "@tsconfig/node12" "^1.0.7" + "@tsconfig/node14" "^1.0.0" + "@tsconfig/node16" "^1.0.2" + acorn "^8.4.1" + acorn-walk "^8.1.1" + arg "^4.1.0" + create-require "^1.1.0" + diff "^4.0.1" + make-error "^1.1.1" + v8-compile-cache-lib "^3.0.1" + yn "3.1.1" + ts-node@7.0.1: version "7.0.1" resolved "https://registry.npmjs.org/ts-node/-/ts-node-7.0.1.tgz" @@ -2052,11 +2132,6 @@ typescript@^4.3.5: resolved "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz" integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g== -typescript@>=5: - version "5.5.4" - resolved "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz" - integrity sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q== - typpy@^2.0.0, typpy@^2.1.0, typpy@^2.2.0, typpy@^2.3.4: version "2.3.13" resolved "https://registry.npmjs.org/typpy/-/typpy-2.3.13.tgz" @@ -2089,7 +2164,7 @@ url-parse-lax@^1.0.0: dependencies: prepend-http "^1.0.1" -utf-8-validate@^5.0.2, utf-8-validate@>=5.0.2: +utf-8-validate@^5.0.2: version "5.0.10" resolved "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.10.tgz" integrity sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ== @@ -2111,6 +2186,11 @@ uuid@^8.3.2: resolved "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz" integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== +v8-compile-cache-lib@^3.0.1: + version "3.0.1" + resolved "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz" + integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg== + validate-npm-package-license@^3.0.1: version "3.0.4" resolved "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz" @@ -2177,7 +2257,7 @@ wrappy@1: resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== -ws@*, ws@^7.5.10: +ws@^7.5.10: version "7.5.10" resolved "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz" integrity sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ== @@ -2230,6 +2310,11 @@ yn@^2.0.0: resolved "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz" integrity sha512-uTv8J/wiWTgUTg+9vLTi//leUl5vDQS6uii/emeTb2ssY7vl6QWf2fFbIIGjnhjvbdKlU0ed7QPgY1htTC86jQ== +yn@3.1.1: + version "3.1.1" + resolved "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz" + integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== + yocto-queue@^0.1.0: version "0.1.0" resolved "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz"