defuse/contract/accounts/
force.rs

1use defuse_core::{accounts::AccountEvent, engine::StateView, events::DefuseEvent};
2use defuse_near_utils::Lock;
3use near_plugins::{AccessControllable, access_control_any};
4use near_sdk::{AccountId, assert_one_yocto, near};
5
6use crate::{
7    accounts::ForceAccountManager,
8    contract::{Contract, ContractExt, Role},
9};
10
11#[near]
12impl ForceAccountManager for Contract {
13    fn is_account_locked(&self, account_id: &AccountId) -> bool {
14        StateView::is_account_locked(self, account_id)
15    }
16
17    #[access_control_any(roles(
18        Role::DAO,
19        Role::UnrestrictedAccountLocker,
20        Role::UnrestrictedAccountManager
21    ))]
22    #[payable]
23    fn force_lock_account(&mut self, account_id: AccountId) -> bool {
24        assert_one_yocto();
25        let locked = self
26            .accounts
27            .get_or_create(account_id.clone())
28            .lock()
29            .is_some();
30        if locked {
31            DefuseEvent::AccountLocked(AccountEvent::new(account_id, ())).emit();
32        }
33        locked
34    }
35
36    #[access_control_any(roles(
37        Role::DAO,
38        Role::UnrestrictedAccountUnlocker,
39        Role::UnrestrictedAccountManager
40    ))]
41    #[payable]
42    fn force_unlock_account(&mut self, account_id: &AccountId) -> bool {
43        assert_one_yocto();
44        let unlocked = self
45            .accounts
46            .get_mut(account_id)
47            .and_then(Lock::unlock)
48            .is_some();
49        if unlocked {
50            DefuseEvent::AccountUnlocked(AccountEvent::new(account_id, ())).emit();
51        }
52        unlocked
53    }
54
55    #[access_control_any(roles(
56        Role::DAO,
57        Role::UnrestrictedAccountLocker,
58        Role::UnrestrictedAccountManager
59    ))]
60    #[payable]
61    fn force_disable_auth_by_predecessor_ids(&mut self, account_ids: Vec<AccountId>) {
62        assert_one_yocto();
63
64        for account_id in account_ids {
65            // NOTE: omit errors
66            let _ = self.set_auth_by_predecessor_id_and_emit_event(&account_id, false, true);
67        }
68    }
69
70    #[access_control_any(roles(
71        Role::DAO,
72        Role::UnrestrictedAccountUnlocker,
73        Role::UnrestrictedAccountManager
74    ))]
75    #[payable]
76    fn force_enable_auth_by_predecessor_ids(&mut self, account_ids: Vec<AccountId>) {
77        assert_one_yocto();
78
79        for account_id in account_ids {
80            // NOTE: omit errors
81            let _ = self.set_auth_by_predecessor_id_and_emit_event(&account_id, true, true);
82        }
83    }
84}
85
86#[cfg(feature = "far")]
87const _: () = {
88    use crate::far::ForcePublicKeyManager;
89    use defuse_core::crypto::PublicKey;
90    use std::collections::{HashMap, HashSet};
91
92    #[near]
93    impl ForcePublicKeyManager for Contract {
94        #[access_control_any(roles(Role::DAO, Role::UnrestrictedAccountManager))]
95        #[payable]
96        fn force_add_public_keys(&mut self, public_keys: HashMap<AccountId, HashSet<PublicKey>>) {
97            assert_one_yocto();
98
99            for (account_id, pks) in public_keys {
100                for pk in pks {
101                    self.add_public_key_and_emit_event(account_id.as_ref(), pk);
102                }
103            }
104        }
105
106        #[access_control_any(roles(Role::DAO, Role::UnrestrictedAccountManager))]
107        #[payable]
108        fn force_remove_public_keys(
109            &mut self,
110            public_keys: HashMap<AccountId, HashSet<PublicKey>>,
111        ) {
112            assert_one_yocto();
113
114            for (account_id, pks) in public_keys {
115                for pk in pks {
116                    self.remove_public_key_and_emit_event(account_id.as_ref(), pk);
117                }
118            }
119        }
120    }
121};