diff --git a/contracts/registry/CHANGELOG.md b/contracts/registry/CHANGELOG.md index 32c684e..e7ba14b 100644 --- a/contracts/registry/CHANGELOG.md +++ b/contracts/registry/CHANGELOG.md @@ -21,6 +21,8 @@ Change log entries are to be added to the Unreleased section. Example entry: ### Features +- New `GovBan` flag. Reserved for accounts with a history of misconduct, limiting their governance role while maintaining their voting rights as valued members of the Voting Body. + ### Breaking Changes ### Bug Fixes diff --git a/contracts/registry/README.md b/contracts/registry/README.md index eab7c04..1a7f3f6 100644 --- a/contracts/registry/README.md +++ b/contracts/registry/README.md @@ -54,7 +54,7 @@ See the function docs for more complete documentation. - `admin_flag_accounts(flag: AccountFlag, accounts: Vec, memo: String)` - sets a flag for every account in the `accounts` list, overwriting if needed. Must be called by an authorized flagger. - `admin_flag_accounts(flag: AccountFlag, accounts: Vec, memo: String)` - removes a flag for every account in the `accounts` list, overwriting if needed. Must be called by an authorized flagger. - Valid account flags are: "Verified", "Blacklisted". + Valid account flags are: "Verified", "Blacklisted", "GovBan". - `admin_add_sbt_issuer(issuer: AccountId)` - authorizes new issuer to issue SBTs. ## Soul transfer diff --git a/contracts/registry/src/events.rs b/contracts/registry/src/events.rs index 4cfc18b..cb72fe3 100644 --- a/contracts/registry/src/events.rs +++ b/contracts/registry/src/events.rs @@ -16,6 +16,7 @@ pub(crate) fn emit_iah_flag_accounts(flag: crate::AccountFlag, accounts: Vec "flag_blacklisted", AccountFlag::Verified => "flag_verified", + AccountFlag::GovBan => "flag_govban", }; emit_iah_event(EventPayload { event, diff --git a/contracts/registry/src/lib.rs b/contracts/registry/src/lib.rs index c58649d..a5da3d8 100644 --- a/contracts/registry/src/lib.rs +++ b/contracts/registry/src/lib.rs @@ -208,18 +208,13 @@ impl Contract { pub(crate) fn _transfer_flag(&mut self, from: &AccountId, recipient: &AccountId) { if let Some(flag_from) = self.flagged.get(from) { - match self.flagged.get(recipient) { - Some(AccountFlag::Verified) => require!( - flag_from != AccountFlag::Blacklisted, - "can't transfer soul from a blacklisted account to a verified account" - ), - Some(AccountFlag::Blacklisted) => require!( - flag_from != AccountFlag::Verified, - "can't transfer soul from a verified account to a blacklisted account" - ), - None => { - self.flagged.insert(recipient, &flag_from); - } + if let Some(flag_to) = self.flagged.get(recipient) { + require!( + flag_from == flag_to, + "can't transfer soul when there is a flag conflict" + ) + } else { + self.flagged.insert(recipient, &flag_from); } } } @@ -2966,9 +2961,7 @@ mod tests { } #[test] - #[should_panic( - expected = "can't transfer soul from a blacklisted account to a verified account" - )] + #[should_panic(expected = "can't transfer soul when there is a flag conflict")] fn flagged_soul_transfer() { let (mut ctx, mut ctr) = setup(&issuer1(), 2 * MINT_DEPOSIT); @@ -3005,9 +2998,7 @@ mod tests { } #[test] - #[should_panic( - expected = "can't transfer soul from a verified account to a blacklisted account" - )] + #[should_panic(expected = "can't transfer soul when there is a flag conflict")] fn flagged_soul_transfer2() { let (mut ctx, mut ctr) = setup(&issuer1(), 2 * MINT_DEPOSIT); diff --git a/contracts/registry/src/storage.rs b/contracts/registry/src/storage.rs index 3389f1c..60b177c 100644 --- a/contracts/registry/src/storage.rs +++ b/contracts/registry/src/storage.rs @@ -28,9 +28,13 @@ pub enum StorageKey { #[serde(crate = "near_sdk::serde")] #[cfg_attr(not(target_arch = "wasm32"), derive(Debug))] pub enum AccountFlag { - /// Account is "blacklisted" when it was marked as a scam or breaking the IAH rules. + /// Account is "blacklisted" when it was marked as a scam or suspectible to be a mnipulated account or not a human. Blacklisted, + /// Manually verified account. Verified, + /// Account misbehaved and should be refused to have a significant governance role. However + /// it will be able to vote as a Voting Body member. + GovBan, } /// Composition of issuer address and token id used for indexing