diff --git a/congress/CHANGELOG.md b/congress/CHANGELOG.md index 346fe2d..52021f2 100644 --- a/congress/CHANGELOG.md +++ b/congress/CHANGELOG.md @@ -26,6 +26,17 @@ Change log entries are to be added to the Unreleased section. Example entry: ### Bug Fixes +## v1.1.2 (2023-12-28) + +### Improvements + +- `create_proposal` has additional checks for the function call actions. We observed that too much gas was set in the actions, prohibiting correct contract execution (not enough gas to do self execution). +- Temporal gas adjustment to allow TC execution of dismiss proposals (related to the point above). + +### Bug Fixes + +- Added Dismiss hook permission to dismiss members of TC by TC (`congress-tc-v1.ndc-gwg.near`). + ## v1.1.1 (2023-12-16) ### Features @@ -34,7 +45,7 @@ Change log entries are to be added to the Unreleased section. Example entry: ### Bug Fixes -- Updating Transparency Commission mainnet instance to add `FunctionCall` permission. +- Updating Transparency Commission mainnet instance to add `FunctionCall` permission. ## v1.1.0 (2023-11-20) diff --git a/congress/Cargo.toml b/congress/Cargo.toml index 2741d00..8f0613d 100644 --- a/congress/Cargo.toml +++ b/congress/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "congress" -version = "1.1.1" +version = "1.1.2" authors = { workspace = true } edition = { workspace = true } repository = { workspace = true } diff --git a/congress/README.md b/congress/README.md index bdc1d1c..e1e6c85 100644 --- a/congress/README.md +++ b/congress/README.md @@ -160,7 +160,7 @@ If proposal execution breaks an invariant check (eg: crossing the budget cap), t Example CLI command to execute a proposal: ``` shell -near call HOUSE '{"id": PROP_ID}' --accountId YOU +near call HOUSE execute '{"id": PROP_ID}' --gas 300000000000000 --accountId YOU ``` ## Queries diff --git a/congress/src/constants.rs b/congress/src/constants.rs index 50f8690..a941056 100644 --- a/congress/src/constants.rs +++ b/congress/src/constants.rs @@ -6,7 +6,10 @@ pub const MILI_NEAR: Balance = ONE_NEAR / 1_000; pub const FAILURE_CALLBACK_GAS: Gas = Gas(3 * Gas::ONE_TERA.0); pub const EXECUTE_CALLBACK_GAS: Gas = Gas(4 * Gas::ONE_TERA.0); -pub const EXECUTE_GAS: Gas = Gas(8 * Gas::ONE_TERA.0); +pub const EXEC_CTR_CALL_GAS: Gas = Gas(8 * Gas::ONE_TERA.0); +pub const EXEC_SELF_GAS: Gas = Gas(20 * Gas::ONE_TERA.0); +pub const MAX_EXEC_FUN_CALL_GAS: Gas = + Gas(300 * Gas::ONE_TERA.0 - EXEC_SELF_GAS.0 - EXECUTE_CALLBACK_GAS.0); // 64bytes(accountID) + 1byte (prefix) + 4bytes(proposal_id) + vote(byte) = 72B -> add 20% margin = < 90B pub const VOTE_STORAGE: u64 = 90; diff --git a/congress/src/errors.rs b/congress/src/errors.rs index b55d55c..37ecf3a 100644 --- a/congress/src/errors.rs +++ b/congress/src/errors.rs @@ -52,6 +52,7 @@ pub enum CreatePropError { NotAuthorized, KindNotAllowed, Storage(String), + Gas(String), } impl FunctionError for CreatePropError { @@ -61,6 +62,7 @@ impl FunctionError for CreatePropError { CreatePropError::NotAuthorized => panic_str("not authorized"), CreatePropError::KindNotAllowed => panic_str("proposal kind not allowed"), CreatePropError::Storage(reason) => panic_str(reason), + CreatePropError::Gas(reason) => panic_str(reason), } } } diff --git a/congress/src/lib.rs b/congress/src/lib.rs index 2c336cd..ac19916 100644 --- a/congress/src/lib.rs +++ b/congress/src/lib.rs @@ -143,13 +143,29 @@ impl Contract { let now = env::block_timestamp_ms(); let mut new_budget = 0; - match kind { + match &kind { PropKind::FundingRequest(b) => { new_budget = self.budget_spent + b.0; } PropKind::RecurrentFundingRequest(b) => { new_budget = self.budget_spent + b.0 * (self.remaining_months(now) as u128); } + PropKind::FunctionCall { actions, .. } => { + let mut sum_gas = 0; + for a in actions { + if a.gas.0 < EXEC_CTR_CALL_GAS.0 || a.gas.0 > MAX_EXEC_FUN_CALL_GAS.0 { + return Err(CreatePropError::Gas( + "action gas must be between 8tgas and 280tgas".to_owned(), + )); + } + sum_gas += a.gas.0; + } + if sum_gas > MAX_EXEC_FUN_CALL_GAS.0 { + return Err(CreatePropError::Gas( + "sum of action gas can't exceed 276tgas".to_owned(), + )); + } + } _ => (), }; if new_budget > self.budget_cap { @@ -278,8 +294,9 @@ impl Contract { promise = promise.function_call( action.method_name.clone(), action.args.clone().into(), - action.deposit.0, - Gas(action.gas.0), + // TODO: remove the following changes in v1.2 + 0, //action.deposit.0, + Gas(action.gas.0) - EXEC_SELF_GAS, ); } result = promise.into(); @@ -302,14 +319,14 @@ impl Contract { .as_bytes() .to_vec(), 0, - EXECUTE_GAS, + EXEC_CTR_CALL_GAS, ); let dismiss_promise = Promise::new(house.clone()).function_call( "dismiss_hook".to_owned(), json!({ "member": member }).to_string().as_bytes().to_vec(), 0, - EXECUTE_GAS, + EXEC_CTR_CALL_GAS, ); return Ok(PromiseOrValue::Promise( @@ -547,6 +564,7 @@ impl Contract { } } + /// Every house should be able to make a fun call proposals pub fn add_fun_call_perm(&mut self) { require!(env::predecessor_account_id() == env::current_account_id()); let mut m = self.members.get().unwrap(); @@ -555,6 +573,25 @@ impl Contract { self.members.set(&m); } } + + /// v1.1.2 release: we missed TC perm to dismiss a member from "self" + // TODO: we can remove this method in the next release + pub fn add_tc_dismiss_perm(&mut self) { + let tc = env::predecessor_account_id(); + require!(tc.as_str() == "congress-tc-v1.ndc-gwg.near"); + let mut hooks = self.hook_auth.get().unwrap(); + match hooks.get_mut(&tc) { + None => { + hooks.insert(tc, vec![HookPerm::Dismiss]); + } + Some(tc_perms) => { + if !tc_perms.contains(&HookPerm::Dismiss) { + tc_perms.push(HookPerm::Dismiss); + } + } + } + self.hook_auth.set(&hooks); + } } #[cfg(all(test, not(target_arch = "wasm32")))] @@ -1291,7 +1328,7 @@ mod unit_tests { json!({ "member": acc(2) }).to_string().as_bytes().to_vec(), ), deposit: U128(0), - gas: U64(0), + gas: U64(EXEC_CTR_CALL_GAS.0), }] .to_vec(), },