Skip to content

Commit

Permalink
[multisig] Add option for multisig to be managed by other accounts (#125
Browse files Browse the repository at this point in the history
)

* Add option for multisig to be managed by other accounts

* Address filter_map comment and fix tests

* Adding multisig factory

* Adjust to use member types to be named to avoid potential collision issues

* Updating readme with changes in aPI

* Modify factory to take new multisig member format

* Return old version of multisig and move the version to multisig2 folder

* update README to include section on building for production

* update Cargo.toml to use near-sdk 4.0.0-pre.4 and the proper sim test deps

* update build script to find multisig2.wasm (new name)

* add test.sh script

* update contract code for latest version of sdk

* rewrite sim tests using normal deps

* remove old multisig.wasm, add new multisig2.wasm compiled Wasm files

* optimizing contract size

* fixed negation errors in new assert (if) statements. test should be ok now

* attached a bit slimmer multisig2.wasm

* Update few more things with new SDK

* Update the contract with manual asset

* Build wasm with docker. Add multisig2 into tests

* Remove extra derives that are not used in prod

* Rebuild all contracts with the same toolchain version

* Addressing comments

* Rebuild contracts

Co-authored-by: Mike Purvis <mikedotexe@gmail.com>
Co-authored-by: adsick <adsick@protonmail.com>
  • Loading branch information
3 people committed Dec 9, 2021
1 parent 92ab8e5 commit 60fc493
Show file tree
Hide file tree
Showing 22 changed files with 5,327 additions and 4 deletions.
Binary file modified lockup-factory/res/lockup_factory.wasm
Binary file not shown.
Binary file modified lockup/res/lockup_contract.wasm
Binary file not shown.
476 changes: 476 additions & 0 deletions multisig-factory/Cargo.lock

Large diffs are not rendered by default.

21 changes: 21 additions & 0 deletions multisig-factory/Cargo.toml
@@ -0,0 +1,21 @@
[package]
name = "multisig-factory"
version = "0.1.0"
authors = ["Near Inc <hello@near.org>"]
edition = "2018"
publish = false

[lib]
crate-type = ["cdylib"]

[profile.release]
codegen-units = 1
# Tell `rustc` to optimize for small code size.
opt-level = "z"
lto = true
debug = false
panic = "abort"
overflow-checks = true

[dependencies]
near-sdk = "2.0.0"
30 changes: 30 additions & 0 deletions multisig-factory/README.md
@@ -0,0 +1,30 @@
# Multisig Factory

Allows to create new [Multisig contracts](../multisig) just by sending a transactions with the required configuration and funds.
E.g. Removes need for using `near repl` and having wasm file available.

# Deployment & Usage

## TestNet

Deploy to new developer account on TestNet:

```
near dev-deploy --wasmFile=res/multisig_factory.wasm
```

Setup variable for the contract to use commands below easier:

```
# bash
CONTRACT_ID="dev-1608694678554-8567049"
# fish
set CONTRACT_ID "dev-1608694678554-8567049"
```

Create a new multisig with the given parameters and attached amount (50N) passed to multisig contract:

```
near call $CONTRACT_ID create '{"name": "test", "members": [{"account_id": "illia"}, {"account_id": "testmewell.testnet"}, {"public_key": "ed25519:Eg2jtsiMrprn7zgKKUk79qM1hWhANsFyE6JSX4txLEuy"}], "num_confirmations": 1}' --accountId $CONTRACT_ID --amount 50 --gas 100000000000000
```
5 changes: 5 additions & 0 deletions multisig-factory/build.sh
@@ -0,0 +1,5 @@
#!/bin/bash
set -e

RUSTFLAGS='-C link-arg=-s' cargo +stable build --target wasm32-unknown-unknown --release
cp target/wasm32-unknown-unknown/release/multisig_factory.wasm ./res/
Binary file added multisig-factory/res/multisig_factory.wasm
Binary file not shown.
50 changes: 50 additions & 0 deletions multisig-factory/src/lib.rs
@@ -0,0 +1,50 @@
use near_sdk::borsh::{self, BorshDeserialize, BorshSerialize};
use near_sdk::json_types::Base58PublicKey;
use near_sdk::serde::{Deserialize, Serialize};
use near_sdk::serde_json::json;
use near_sdk::{env, near_bindgen, AccountId, Promise};

#[global_allocator]
static ALLOC: near_sdk::wee_alloc::WeeAlloc<'_> = near_sdk::wee_alloc::WeeAlloc::INIT;

const CODE: &[u8] = include_bytes!("../../multisig2/res/multisig2.wasm");

/// This gas spent on the call & account creation, the rest goes to the `new` call.
const CREATE_CALL_GAS: u64 = 50_000_000_000_000;

#[derive(Serialize, Deserialize)]
#[serde(crate = "near_sdk::serde", untagged)]
pub enum MultisigMember {
AccessKey { public_key: Base58PublicKey },
Account { account_id: AccountId },
}

#[near_bindgen]
#[derive(BorshSerialize, BorshDeserialize, Default)]
pub struct MultisigFactory {}

#[near_bindgen]
impl MultisigFactory {
#[payable]
pub fn create(
&mut self,
name: AccountId,
members: Vec<MultisigMember>,
num_confirmations: u64,
) -> Promise {
let account_id = format!("{}.{}", name, env::current_account_id());
Promise::new(account_id)
.create_account()
.deploy_contract(CODE.to_vec())
.transfer(env::attached_deposit())
.function_call(
b"new".to_vec(),
json!({ "members": members, "num_confirmations": num_confirmations })
.to_string()
.as_bytes()
.to_vec(),
0,
env::prepaid_gas() - CREATE_CALL_GAS,
)
}
}
6 changes: 3 additions & 3 deletions multisig/src/lib.rs
Expand Up @@ -4,8 +4,8 @@ use std::convert::TryFrom;
use near_sdk::borsh::{self, BorshDeserialize, BorshSerialize};
use near_sdk::collections::UnorderedMap;
use near_sdk::json_types::{Base58PublicKey, Base64VecU8, U128, U64};
use near_sdk::{env, near_bindgen, AccountId, Promise, PromiseOrValue, PublicKey};
use near_sdk::serde::{Deserialize, Serialize};
use near_sdk::{env, near_bindgen, AccountId, Promise, PromiseOrValue, PublicKey};

/// Unlimited allowance for multisig keys.
const DEFAULT_ALLOWANCE: u128 = 0;
Expand Down Expand Up @@ -153,15 +153,15 @@ impl MultiSigContract {
}

/// Remove given request and associated confirmations.
pub fn delete_request(&mut self, request_id: RequestId) {
pub fn delete_request(&mut self, request_id: RequestId) -> MultiSigRequest {
self.assert_valid_request(request_id);
let request_with_signer = self.requests.get(&request_id).expect("No such request");
// can't delete requests before 15min
assert!(
env::block_timestamp() > request_with_signer.added_timestamp + REQUEST_COOLDOWN,
"Request cannot be deleted immediately after creation."
);
self.remove_request(request_id);
self.remove_request(request_id)
}

fn execute_request(&mut self, request: MultiSigRequest) -> PromiseOrValue<bool> {
Expand Down

0 comments on commit 60fc493

Please sign in to comment.