From 2a10b3a6bceb95d46dbf21e3bfdab4d841d44e53 Mon Sep 17 00:00:00 2001 From: Serkan Reis Date: Thu, 18 Jan 2024 18:50:47 +0200 Subject: [PATCH] Royalty increase update for v1 collections (#631) * Modify royalty update logic * Update unit tests * Bump version for sg721-updatable * Address linter issues * Update schema files * Address clippy issues * Update rust version for CI * Update parameter name for sg721-updatable/migrate() * Update rust version for CI --- .circleci/config.yml | 54 +++++----- Cargo.lock | 2 +- .../minter/src/contract_updatable_tests.rs | 101 ++++++++++++------ contracts/sg721-updatable/Cargo.toml | 2 +- .../schema/collection_info_response.json | 22 ---- .../schema/instantiate_msg.json | 22 ---- contracts/sg721-updatable/src/contract.rs | 92 ++++++++-------- contracts/sg721-updatable/src/error.rs | 9 +- contracts/sg721-updatable/src/msg.rs | 5 +- contracts/sg721-updatable/src/state.rs | 2 +- 10 files changed, 154 insertions(+), 157 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index b9b577448..7f97cfa62 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -24,7 +24,7 @@ workflows: jobs: contract_sg721: docker: - - image: rust:1.64.0 + - image: rust:1.68.0 working_directory: ~/project/contracts/sg721 steps: - checkout: @@ -34,7 +34,7 @@ jobs: command: rustc --version; cargo --version; rustup --version - restore_cache: keys: - - cargocache-sg721-rust:1.64.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-sg721-rust:1.68.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Unit Tests environment: @@ -56,10 +56,10 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-sg721-rust:1.64.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-sg721-rust:1.68.0-{{ checksum "~/project/Cargo.lock" }} contract_sg721_updatable: docker: - - image: rust:1.64.0 + - image: rust:1.68.0 working_directory: ~/project/contracts/sg721-updatable steps: - checkout: @@ -69,7 +69,7 @@ jobs: command: rustc --version; cargo --version; rustup --version - restore_cache: keys: - - cargocache-sg721-rust:1.64.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-sg721-rust:1.68.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Unit Tests environment: @@ -91,11 +91,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-sg721-updatable-rust:1.64.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-sg721-updatable-rust:1.68.0-{{ checksum "~/project/Cargo.lock" }} contract_minter: docker: - - image: rust:1.64.0 + - image: rust:1.68.0 working_directory: ~/project/contracts/minter steps: - checkout: @@ -105,7 +105,7 @@ jobs: command: rustc --version; cargo --version; rustup --version - restore_cache: keys: - - cargocache-minter-rust:1.64.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-minter-rust:1.68.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Unit Tests environment: @@ -127,11 +127,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-minter-rust:1.64.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-minter-rust:1.68.0-{{ checksum "~/project/Cargo.lock" }} contract_whitelist: docker: - - image: rust:1.64.0 + - image: rust:1.68.0 working_directory: ~/project/contracts/whitelist steps: - checkout: @@ -141,7 +141,7 @@ jobs: command: rustc --version; cargo --version; rustup --version - restore_cache: keys: - - cargocache-whitelist-rust:1.64.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-whitelist-rust:1.68.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Unit Tests environment: @@ -163,11 +163,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-whitelist-rust:1.64.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-whitelist-rust:1.68.0-{{ checksum "~/project/Cargo.lock" }} contract_royalty_group: docker: - - image: rust:1.64.0 + - image: rust:1.68.0 working_directory: ~/project/contracts/royalty-group steps: - checkout: @@ -177,7 +177,7 @@ jobs: command: rustc --version; cargo --version; rustup --version - restore_cache: keys: - - cargocache-royalty-rust:1.64.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-royalty-rust:1.68.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Unit Tests environment: @@ -199,11 +199,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-royalty-rust:1.64.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-royalty-rust:1.68.0-{{ checksum "~/project/Cargo.lock" }} package_sg_std: docker: - - image: rust:1.64.0 + - image: rust:1.68.0 working_directory: ~/project/package/sg-std steps: - checkout: @@ -213,7 +213,7 @@ jobs: command: rustc --version; cargo --version; rustup --version - restore_cache: keys: - - cargocache-sg-std-rust:1.64.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-sg-std-rust:1.68.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Unit Tests environment: @@ -223,11 +223,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-sg-std-rust:1.64.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-sg-std-rust:1.68.0-{{ checksum "~/project/Cargo.lock" }} package_sg_utils: docker: - - image: rust:1.64.0 + - image: rust:1.68.0 working_directory: ~/project/package/sg-utils steps: - checkout: @@ -237,7 +237,7 @@ jobs: command: rustc --version; cargo --version; rustup --version - restore_cache: keys: - - cargocache-sg-utils-rust:1.64.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-sg-utils-rust:1.68.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Unit Tests environment: @@ -247,11 +247,11 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-sg-utils-rust:1.64.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-sg-utils-rust:1.68.0-{{ checksum "~/project/Cargo.lock" }} lint: docker: - - image: rust:1.64.0 + - image: rust:1.68.0 steps: - checkout - run: @@ -259,7 +259,7 @@ jobs: command: rustc --version; cargo --version; rustup --version; rustup target list --installed - restore_cache: keys: - - cargocache-v2-lint-rust:1.64.0-{{ checksum "Cargo.lock" }} + - cargocache-v2-lint-rust:1.68.0-{{ checksum "Cargo.lock" }} - run: name: Add rustfmt component command: rustup component add rustfmt @@ -278,7 +278,7 @@ jobs: - target/debug/.fingerprint - target/debug/build - target/debug/deps - key: cargocache-v2-lint-rust:1.64.0-{{ checksum "Cargo.lock" }} + key: cargocache-v2-lint-rust:1.68.0-{{ checksum "Cargo.lock" }} # This runs one time on the top level to ensure all contracts compile properly into wasm. # We don't run the wasm build per contract build, and then reuse a lot of the same dependencies, so this speeds up CI time @@ -286,7 +286,7 @@ jobs: # We also sanity-check the resultant wasm files. wasm-build: docker: - - image: rust:1.64.0 + - image: rust:1.68.0 steps: - checkout: path: ~/project @@ -295,7 +295,7 @@ jobs: command: rustc --version; cargo --version; rustup --version - restore_cache: keys: - - cargocache-wasm-rust:1.64.0-{{ checksum "~/project/Cargo.lock" }} + - cargocache-wasm-rust:1.68.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Add wasm32 target command: rustup target add wasm32-unknown-unknown @@ -315,7 +315,7 @@ jobs: paths: - /usr/local/cargo/registry - target - key: cargocache-wasm-rust:1.64.0-{{ checksum "~/project/Cargo.lock" }} + key: cargocache-wasm-rust:1.68.0-{{ checksum "~/project/Cargo.lock" }} - run: name: Check wasm contracts command: | diff --git a/Cargo.lock b/Cargo.lock index 55cea4f33..221edce82 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -915,7 +915,7 @@ dependencies = [ [[package]] name = "sg721-updatable" -version = "0.8.4" +version = "0.8.5" dependencies = [ "cosmwasm-schema", "cosmwasm-std", diff --git a/contracts/minter/src/contract_updatable_tests.rs b/contracts/minter/src/contract_updatable_tests.rs index 3e1c2f084..8eee2d665 100644 --- a/contracts/minter/src/contract_updatable_tests.rs +++ b/contracts/minter/src/contract_updatable_tests.rs @@ -1538,7 +1538,10 @@ fn test_update_none_royalties() { assert_eq!( err.source().unwrap().to_string(), - sg721_updatable::ContractError::RoyaltyShareIncreasedTooMuch {}.to_string() + sg721_updatable::ContractError::InvalidRoyalties( + "Share percentage cannot be greater than 10%".to_string() + ) + .to_string() ); let update_royalty_msg: Sg721UpdatableExecuteMsg = @@ -1547,6 +1550,29 @@ fn test_update_none_royalties() { share_bps: 400, }; + let res = router.execute_contract( + creator.clone(), + Addr::unchecked(sg71_address.clone()), + &update_royalty_msg, + &[], + ); + + let err = res.unwrap_err(); + + assert_eq!( + err.source().unwrap().to_string(), + sg721_updatable::ContractError::InvalidRoyalties( + "Share increase cannot be greater than 2%".to_string() + ) + .to_string() + ); + + let update_royalty_msg: Sg721UpdatableExecuteMsg = + Sg721UpdatableExecuteMsg::UpdateRoyaltyInfo { + payment_address: "creator2".to_string(), + share_bps: 100, + }; + let res = router .execute_contract( creator.clone(), @@ -1563,7 +1589,7 @@ fn test_update_none_royalties() { assert_eq!(res.events[1].attributes[2].key, "payment_address"); assert_eq!(res.events[1].attributes[2].value, "creator2"); assert_eq!(res.events[1].attributes[3].key, "share"); - assert_eq!(res.events[1].attributes[3].value, "0.04"); + assert_eq!(res.events[1].attributes[3].value, "0.01"); let update_royalty_msg: Sg721UpdatableExecuteMsg = Sg721UpdatableExecuteMsg::UpdateRoyaltyInfo { @@ -1586,6 +1612,29 @@ fn test_update_none_royalties() { setup_block_time(&mut router, GENESIS_MINT_START_TIME + 86400000000000); + let res = router.execute_contract( + creator.clone(), + Addr::unchecked(sg71_address.clone()), + &update_royalty_msg, + &[], + ); + + let err = res.unwrap_err(); + + assert_eq!( + err.source().unwrap().to_string(), + sg721_updatable::ContractError::InvalidRoyalties( + "Share increase cannot be greater than 2%".to_string() + ) + .to_string() + ); + + let update_royalty_msg: Sg721UpdatableExecuteMsg = + Sg721UpdatableExecuteMsg::UpdateRoyaltyInfo { + payment_address: "creator2".to_string(), + share_bps: 200, + }; + let res = router .execute_contract( creator.clone(), @@ -1602,9 +1651,9 @@ fn test_update_none_royalties() { assert_eq!(res.events[1].attributes[2].key, "payment_address"); assert_eq!(res.events[1].attributes[2].value, "creator2"); assert_eq!(res.events[1].attributes[3].key, "share"); - assert_eq!(res.events[1].attributes[3].value, "0.05"); + assert_eq!(res.events[1].attributes[3].value, "0.02"); - setup_block_time(&mut router, GENESIS_MINT_START_TIME + 86500000000000); + setup_block_time(&mut router, GENESIS_MINT_START_TIME + 186500000000000); let update_royalty_msg: Sg721UpdatableExecuteMsg = Sg721UpdatableExecuteMsg::UpdateRoyaltyInfo { @@ -1699,13 +1748,16 @@ fn test_update_royalties() { assert_eq!( err.source().unwrap().to_string(), - sg721_updatable::ContractError::RoyaltyShareIncreasedTooMuch {}.to_string() + sg721_updatable::ContractError::InvalidRoyalties( + "Share percentage cannot be greater than 10%".to_string() + ) + .to_string() ); let update_royalty_msg: sg721_updatable::msg::ExecuteMsg = sg721_updatable::msg::ExecuteMsg::UpdateRoyaltyInfo { payment_address: "creator2".to_string(), - share_bps: 900, + share_bps: 200, }; let res = router.execute_contract( creator.clone(), @@ -1731,12 +1783,12 @@ fn test_update_royalties() { ); assert!(res.is_ok()); - setup_block_time(&mut router, GENESIS_MINT_START_TIME + 86500000000000); + setup_block_time(&mut router, GENESIS_MINT_START_TIME + 186500000000000); let update_royalty_msg: sg721_updatable::msg::ExecuteMsg = sg721_updatable::msg::ExecuteMsg::UpdateRoyaltyInfo { payment_address: "creator2".to_string(), - share_bps: 800, + share_bps: 300, }; let res = router.execute_contract( creator, @@ -1860,7 +1912,7 @@ fn try_migrate() { ); // // no op when same version - set_contract_version(&mut deps.storage, "crates.io:sg-721", "0.8.4").unwrap(); + set_contract_version(&mut deps.storage, "crates.io:sg-721", "0.8.5").unwrap(); sg721_updatable::contract::migrate(deps.as_mut(), env, Empty {}).unwrap(); // Migration happy path @@ -1915,29 +1967,12 @@ fn try_migrate() { let sg721_base_address = config.sg721_address; - let collection_info: CollectionInfo = router - .wrap() - .query_wasm_smart( - sg721_base_address.clone(), - &sg721::msg::QueryMsg::CollectionInfo {}, - ) - .unwrap(); - - assert!(collection_info.royalty_info.unwrap().updated_at.is_none()); - - router - .migrate_contract( - creator, - Addr::unchecked(sg721_base_address.clone()), - &Empty {}, - sg721_code_id, - ) - .unwrap(); - - let collection_info: CollectionInfo = router - .wrap() - .query_wasm_smart(sg721_base_address, &sg721::msg::QueryMsg::CollectionInfo {}) - .unwrap(); + let res = router.migrate_contract( + creator, + Addr::unchecked(sg721_base_address), + &Empty {}, + sg721_code_id, + ); - assert!(collection_info.royalty_info.unwrap().updated_at.is_some(),); + assert!(res.is_ok()); } diff --git a/contracts/sg721-updatable/Cargo.toml b/contracts/sg721-updatable/Cargo.toml index f0a28ab99..3e2fb5786 100644 --- a/contracts/sg721-updatable/Cargo.toml +++ b/contracts/sg721-updatable/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sg721-updatable" -version = "0.8.4" +version = "0.8.5" authors = ["John Y "] edition = "2018" diff --git a/contracts/sg721-updatable/schema/collection_info_response.json b/contracts/sg721-updatable/schema/collection_info_response.json index 326778c7f..d285d1113 100644 --- a/contracts/sg721-updatable/schema/collection_info_response.json +++ b/contracts/sg721-updatable/schema/collection_info_response.json @@ -51,30 +51,8 @@ }, "share": { "$ref": "#/definitions/Decimal" - }, - "updated_at": { - "anyOf": [ - { - "$ref": "#/definitions/Timestamp" - }, - { - "type": "null" - } - ] } } - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" } } } diff --git a/contracts/sg721-updatable/schema/instantiate_msg.json b/contracts/sg721-updatable/schema/instantiate_msg.json index f187ad52e..fb28071b6 100644 --- a/contracts/sg721-updatable/schema/instantiate_msg.json +++ b/contracts/sg721-updatable/schema/instantiate_msg.json @@ -74,30 +74,8 @@ }, "share": { "$ref": "#/definitions/Decimal" - }, - "updated_at": { - "anyOf": [ - { - "$ref": "#/definitions/Timestamp" - }, - { - "type": "null" - } - ] } } - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" } } } diff --git a/contracts/sg721-updatable/src/contract.rs b/contracts/sg721-updatable/src/contract.rs index 72e372d8e..3234d8e1e 100644 --- a/contracts/sg721-updatable/src/contract.rs +++ b/contracts/sg721-updatable/src/contract.rs @@ -3,8 +3,8 @@ use semver::Version; #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{ - to_binary, Binary, Decimal, Deps, DepsMut, Empty, Env, Event, MessageInfo, StdError, StdResult, - Uint128, + ensure, to_binary, Binary, Decimal, Deps, DepsMut, Empty, Env, Event, MessageInfo, StdError, + StdResult, Uint128, }; use cw2::set_contract_version; use cw_utils::{nonpayable, Expiration, DAY}; @@ -18,7 +18,9 @@ use url::Url; use crate::msg::{ CollectionInfoResponse, ExecuteMsg, InstantiateMsg, QueryMsg, RoyaltyInfoResponse, }; -use crate::state::{CollectionInfo, RoyaltyInfo, COLLECTION_INFO, FROZEN_TOKEN_METADATA}; +use crate::state::{ + CollectionInfo, RoyaltyInfo, COLLECTION_INFO, FROZEN_TOKEN_METADATA, ROYALTY_UPDATED_AT, +}; // version info for migration info const COMPATIBLE_MIGRATION_CONTRACT_NAME: &str = "crates.io:sg-721"; @@ -27,6 +29,7 @@ const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); const CREATION_FEE: u128 = 1_000_000_000; const MAX_ROYALTY_SHARE_BPS: u64 = 1_000; +const MAX_ROYALTY_SHARE_DELTA_BPS: u64 = 200; // Disable instantiation for production build #[cfg(target = "wasm32-unknown-unknown")] @@ -81,7 +84,6 @@ pub fn instantiate( Some(royalty_info) => Some(RoyaltyInfo { payment_address: deps.api.addr_validate(&royalty_info.payment_address)?, share: royalty_info.share_validate()?, - updated_at: Some(env.block.time), }), None => None, }; @@ -97,6 +99,7 @@ pub fn instantiate( }; FROZEN_TOKEN_METADATA.save(deps.storage, &false)?; + ROYALTY_UPDATED_AT.save(deps.storage, &env.block.time)?; COLLECTION_INFO.save(deps.storage, &collection_info)?; Ok(Response::default() @@ -147,40 +150,59 @@ pub fn execute_update_royalty_info( let payment_addr = deps.api.addr_validate(&payment_address)?; let share = Decimal::percent(share_bps) / Uint128::from(100u128); let max_share_limit = Decimal::percent(MAX_ROYALTY_SHARE_BPS) / Uint128::from(100u128); - - if share > max_share_limit { - return Err(ContractError::RoyaltyShareIncreasedTooMuch {}); - } - - let current_royalty_info = collection_info.royalty_info; - - if let Some(curr_royalty_info) = current_royalty_info { - let updated_at = match curr_royalty_info.updated_at { - Some(updated_at) => updated_at, - // If current royalty info updated_at is None, it might be an older version that has not been migrated properly. - None => return Err(ContractError::RoyaltyInfoInvalid {}), - }; - - // make sure the update time is after 24 hours + let max_share_delta = Decimal::percent(MAX_ROYALTY_SHARE_DELTA_BPS) / Uint128::from(100u128); + ensure!( + share <= max_share_limit, + // multiply by 100 to get the percentage for error message + ContractError::InvalidRoyalties(format!( + "Share percentage cannot be greater than {}%", + max_share_limit * Uint128::from(100u128) + )) + ); + + let updated_at = ROYALTY_UPDATED_AT.load(deps.storage)?; + + if let Some(old_royalty_info) = collection_info.royalty_info { + // make sure the update time is at least 24 hours after the last one let end = (Expiration::AtTime(updated_at) + DAY)?; - let update_too_soon = !end.is_expired(&env.block); - - if share > curr_royalty_info.share && update_too_soon { - return Err(ContractError::RoyaltyUpdateTooSoon {}); + ensure!( + end.is_expired(&env.block), + ContractError::RoyaltyUpdateTooSoon {} + ); + // Make sure the share is not increased more than MAX_ROYALTY_SHARE_DELTA_BPS at a time + if share > old_royalty_info.share { + let share_delta = share - old_royalty_info.share; + ensure!( + share_delta <= max_share_delta, + ContractError::InvalidRoyalties(format!( + "Share increase cannot be greater than {}%", + max_share_delta * Uint128::from(100u128) + )) + ); } + } else { + ensure!( + share <= max_share_delta, + ContractError::InvalidRoyalties(format!( + "Share increase cannot be greater than {}%", + max_share_delta * Uint128::from(100u128) + )) + ); } + collection_info.royalty_info = Some(RoyaltyInfo { payment_address: payment_addr, share, - updated_at: Some(env.block.time), }); COLLECTION_INFO.save(deps.storage, &collection_info)?; + ROYALTY_UPDATED_AT.save(deps.storage, &env.block.time)?; let event = Event::new("update_royalty_info") .add_attribute("sender", info.sender) .add_attribute("payment_address", payment_address) - .add_attribute("share", share.to_string()); + .add_attribute("share", share.to_string()) + .add_attribute("updated_at", env.block.time.to_string()); Ok(Response::new().add_event(event)) } @@ -256,7 +278,6 @@ fn query_config(deps: Deps) -> StdResult { Some(royalty_info) => Some(RoyaltyInfoResponse { payment_address: royalty_info.payment_address.to_string(), share: royalty_info.share, - updated_at: royalty_info.updated_at, }), None => None, }; @@ -271,7 +292,7 @@ fn query_config(deps: Deps) -> StdResult { } #[cfg_attr(not(feature = "library"), entry_point)] -pub fn migrate(deps: DepsMut, _env: Env, _msg: Empty) -> Result { +pub fn migrate(deps: DepsMut, env: Env, _msg: Empty) -> Result { let current_version = cw2::get_contract_version(deps.storage)?; if ![CONTRACT_NAME, COMPATIBLE_MIGRATION_CONTRACT_NAME] .contains(¤t_version.contract.as_str()) @@ -295,19 +316,8 @@ pub fn migrate(deps: DepsMut, _env: Env, _msg: Empty) -> Result; pub struct RoyaltyInfoResponse { pub payment_address: String, pub share: Decimal, - pub updated_at: Option, } impl RoyaltyInfoResponse { pub fn share_validate(&self) -> Result { if self.share > Decimal::one() { - return Err(ContractError::InvalidRoyalties {}); + return Err(ContractError::InvalidRoyalties( + "Invalid royalty percentage".to_string(), + )); } Ok(self.share) diff --git a/contracts/sg721-updatable/src/state.rs b/contracts/sg721-updatable/src/state.rs index 227694e15..3386f475a 100644 --- a/contracts/sg721-updatable/src/state.rs +++ b/contracts/sg721-updatable/src/state.rs @@ -16,8 +16,8 @@ pub struct CollectionInfo { pub struct RoyaltyInfo { pub payment_address: Addr, pub share: Decimal, - pub updated_at: Option, } pub const FROZEN_TOKEN_METADATA: Item = Item::new("frozen_token_metadata"); pub const COLLECTION_INFO: Item> = Item::new("collection_info"); +pub const ROYALTY_UPDATED_AT: Item = Item::new("royalty_updated_at");