Skip to main content

defuse/contract/accounts/
force.rs

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