diff --git a/sputnikdao-factory2/res/sputnikdao_factory2.wasm b/sputnikdao-factory2/res/sputnikdao_factory2.wasm index b46555039..e11c55200 100755 Binary files a/sputnikdao-factory2/res/sputnikdao_factory2.wasm and b/sputnikdao-factory2/res/sputnikdao_factory2.wasm differ diff --git a/sputnikdao-factory2/src/factory_manager.rs b/sputnikdao-factory2/src/factory_manager.rs index b40848810..406233e7b 100644 --- a/sputnikdao-factory2/src/factory_manager.rs +++ b/sputnikdao-factory2/src/factory_manager.rs @@ -7,13 +7,13 @@ use near_sdk::serde_json; use near_sdk::{env, AccountId, Balance, CryptoHash, Gas}; /// Gas spent on the call & account creation. -const CREATE_CALL_GAS: Gas = Gas(75_000_000_000_000); +const CREATE_CALL_GAS: Gas = Gas(40_000_000_000_000); /// Gas allocated on the callback. const ON_CREATE_CALL_GAS: Gas = Gas(10_000_000_000_000); /// Leftover gas after creating promise and calling update. -const GAS_UPDATE_LEFTOVER: Gas = Gas(20_000_000_000_000); +const GAS_UPDATE_LEFTOVER: Gas = Gas(10_000_000_000_000); const NO_DEPOSIT: Balance = 0; diff --git a/sputnikdao2/res/sputnikdao2.wasm b/sputnikdao2/res/sputnikdao2.wasm index 3fa95e943..c64845ff8 100755 Binary files a/sputnikdao2/res/sputnikdao2.wasm and b/sputnikdao2/res/sputnikdao2.wasm differ diff --git a/sputnikdao2/src/lib.rs b/sputnikdao2/src/lib.rs index 4b0e2da08..b95e81b77 100644 --- a/sputnikdao2/src/lib.rs +++ b/sputnikdao2/src/lib.rs @@ -8,7 +8,9 @@ use near_sdk::{ }; pub use crate::bounties::{Bounty, BountyClaim, VersionedBounty}; -pub use crate::policy::{Policy, RoleKind, RolePermission, VersionedPolicy, VotePolicy}; +pub use crate::policy::{ + default_policy, Policy, RoleKind, RolePermission, VersionedPolicy, VotePolicy, +}; use crate::proposals::VersionedProposal; pub use crate::proposals::{Proposal, ProposalInput, ProposalKind, ProposalStatus}; pub use crate::types::{Action, Config, OldAccountId, OLD_BASE_TOKEN}; diff --git a/sputnikdao2/src/policy.rs b/sputnikdao2/src/policy.rs index e376330c5..396c1d66d 100644 --- a/sputnikdao2/src/policy.rs +++ b/sputnikdao2/src/policy.rs @@ -176,7 +176,7 @@ pub enum VersionedPolicy { /// - non token weighted voting, requires 1/2 of the group to vote /// - proposal & bounty bond is 1N /// - proposal & bounty forgiveness period is 1 day -fn default_policy(council: Vec) -> Policy { +pub fn default_policy(council: Vec) -> Policy { Policy { roles: vec![ RolePermission { diff --git a/sputnikdao2/src/upgrade.rs b/sputnikdao2/src/upgrade.rs index c11652b13..74323bd3b 100644 --- a/sputnikdao2/src/upgrade.rs +++ b/sputnikdao2/src/upgrade.rs @@ -7,14 +7,12 @@ use crate::*; const FACTORY_KEY: &[u8; 7] = b"FACTORY"; const ERR_MUST_BE_SELF_OR_FACTORY: &str = "ERR_MUST_BE_SELF_OR_FACTORY"; -const UPDATE_GAS_LEFTOVER: Gas = Gas(5_000_000_000_000); +const UPDATE_GAS_LEFTOVER: Gas = Gas(10_000_000_000_000); const FACTORY_UPDATE_GAS_LEFTOVER: Gas = Gas(15_000_000_000_000); const NO_DEPOSIT: Balance = 0; -/// Gas for upgrading this contract on promise creation + deploying new contract. -pub const GAS_FOR_UPGRADE_SELF_DEPLOY: Gas = Gas(30_000_000_000_000); - -pub const GAS_FOR_UPGRADE_REMOTE_DEPLOY: Gas = Gas(10_000_000_000_000); +pub const GAS_FOR_UPGRADE_SELF_DEPLOY: Gas = Gas(15_000_000_000_000); +pub const GAS_FOR_UPGRADE_REMOTE_DEPLOY: Gas = Gas(15_000_000_000_000); /// Info about factory that deployed this contract and if auto-update is allowed. #[derive(BorshSerialize, BorshDeserialize, Serialize, Deserialize)] @@ -117,22 +115,26 @@ pub(crate) fn upgrade_using_factory(code_hash: Base58CryptoHash) { #[allow(dead_code)] pub(crate) fn upgrade_self(hash: &[u8]) { let current_id = env::current_account_id(); - let attached_gas = env::prepaid_gas() - env::used_gas() - GAS_FOR_UPGRADE_SELF_DEPLOY; let input = env::storage_read(hash).expect("ERR_NO_HASH"); let promise_id = env::promise_batch_create(¤t_id); env::promise_batch_action_deploy_contract(promise_id, &input); - env::promise_batch_action_function_call(promise_id, "migrate", &[], NO_DEPOSIT, attached_gas); + env::promise_batch_action_function_call( + promise_id, + "migrate", + &[], + NO_DEPOSIT, + env::prepaid_gas() - env::used_gas() - GAS_FOR_UPGRADE_SELF_DEPLOY, + ); } pub(crate) fn upgrade_remote(receiver_id: &AccountId, method_name: &str, hash: &[u8]) { let input = env::storage_read(hash).expect("ERR_NO_HASH"); let promise_id = env::promise_batch_create(receiver_id); - let attached_gas = env::prepaid_gas() - env::used_gas() - GAS_FOR_UPGRADE_REMOTE_DEPLOY; env::promise_batch_action_function_call( promise_id, method_name, &input, NO_DEPOSIT, - attached_gas, + env::prepaid_gas() - env::used_gas() - GAS_FOR_UPGRADE_REMOTE_DEPLOY, ); } diff --git a/sputnikdao2/tests/test_general.rs b/sputnikdao2/tests/test_general.rs index 10f3ded84..07e1611a3 100644 --- a/sputnikdao2/tests/test_general.rs +++ b/sputnikdao2/tests/test_general.rs @@ -1,14 +1,16 @@ use std::collections::HashMap; use near_sdk::json_types::U128; +use near_sdk::serde_json::json; use near_sdk::{env, AccountId}; -use near_sdk_sim::{call, to_yocto, view}; +use near_sdk_sim::{call, init_simulator, to_yocto, view}; use crate::utils::*; use sputnik_staking::User; use sputnikdao2::{ - Action, BountyClaim, BountyOutput, Policy, Proposal, ProposalInput, ProposalKind, - ProposalOutput, ProposalStatus, RoleKind, RolePermission, VersionedPolicy, VotePolicy, + default_policy, Action, BountyClaim, BountyOutput, Config, Policy, Proposal, ProposalInput, + ProposalKind, ProposalOutput, ProposalStatus, RoleKind, RolePermission, VersionedPolicy, + VotePolicy, }; mod utils; @@ -17,6 +19,76 @@ fn user(id: u32) -> AccountId { format!("user{}", id).parse().unwrap() } +#[test] +fn test_large_policy() { + let root = init_simulator(None); + let factory = setup_factory(&root); + factory + .user_account + .call( + factory.user_account.account_id.clone(), + "new", + &[], + near_sdk_sim::DEFAULT_GAS, + 0, + ) + .assert_success(); + + let config = Config { + name: "testdao".to_string(), + purpose: "to test".to_string(), + metadata: Base64VecU8(vec![]), + }; + let mut policy = default_policy(vec![root.account_id()]); + const NO_OF_COUNCILS: u32 = 10; + const USERS_PER_COUNCIL: u32 = 100; + for council_no in 0..NO_OF_COUNCILS { + let mut council = vec![]; + let user_id_start = council_no * USERS_PER_COUNCIL; + let user_id_end = user_id_start + USERS_PER_COUNCIL; + for user_id in user_id_start..user_id_end { + council.push(user(user_id)); + } + + let role = RolePermission { + name: format!("council{}", council_no), + kind: RoleKind::Group(council.into_iter().collect()), + permissions: vec![ + "*:AddProposal".to_string(), + "*:VoteApprove".to_string(), + "*:VoteReject".to_string(), + "*:VoteRemove".to_string(), + "*:Finalize".to_string(), + ] + .into_iter() + .collect(), + vote_policy: HashMap::default(), + }; + policy.add_or_update_role(&role); + } + + let params = json!({ "config": config, "policy": policy }) + .to_string() + .into_bytes(); + + call!( + root, + factory.create( + AccountId::new_unchecked("testdao".to_string()), + Base64VecU8(params) + ), + deposit = to_yocto("10") + ) + .assert_success(); + + let dao_account_id = AccountId::new_unchecked("testdao.factory".to_string()); + let dao_list = factory + .user_account + .view(factory.user_account.account_id.clone(), "get_dao_list", &[]) + .unwrap_json::>(); + assert_eq!(dao_list, vec![dao_account_id.clone()]); +} + #[test] fn test_multi_council() { let (root, dao) = setup_dao();