Skip to content

Commit

Permalink
adds deployer
Browse files Browse the repository at this point in the history
  • Loading branch information
gangov committed Aug 14, 2024
1 parent 5f27794 commit dc1847b
Show file tree
Hide file tree
Showing 7 changed files with 174 additions and 35 deletions.
9 changes: 2 additions & 7 deletions contracts/collections/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,8 @@ pub struct Collections;
impl Collections {
// takes an address and uses it as an administrator
#[allow(dead_code)]
pub fn initialize(
env: Env,
admin: Address,
name: String,
image: URIValue,
) -> Result<(), ContractError> {
let config = Config { name, image };
pub fn initialize(env: Env, admin: Address, name: String) -> Result<(), ContractError> {
let config = Config { name };

save_config(&env, config)?;
save_admin(&env, &admin)?;
Expand Down
1 change: 0 additions & 1 deletion contracts/collections/src/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ pub struct URIValue {
#[contracttype]
pub struct Config {
pub name: String,
pub image: URIValue,
}

pub const ADMIN: Symbol = symbol_short!("admin");
Expand Down
14 changes: 3 additions & 11 deletions contracts/collections/src/test/setup.rs
Original file line number Diff line number Diff line change
@@ -1,29 +1,21 @@
use soroban_sdk::{testutils::Address as _, Address, Bytes, Env, String};
use soroban_sdk::{testutils::Address as _, Address, Env, String};

use crate::{
contract::{Collections, CollectionsClient},
storage::URIValue,
};
use crate::contract::{Collections, CollectionsClient};

pub fn initialize_collection_contract<'a>(
env: &Env,
admin: Option<&Address>,
name: Option<&String>,
image: Option<&URIValue>,
) -> CollectionsClient<'a> {
let collections = CollectionsClient::new(env, &env.register_contract(None, Collections {}));

let alt_admin = &Address::generate(env);
let alt_name = &String::from_str(env, "Stellar kitties");
let alt_image = URIValue {
uri: Bytes::from_slice(env, &[64]),
};

let admin = admin.unwrap_or(alt_admin);
let name = name.unwrap_or(alt_name);
let image = image.unwrap_or(&alt_image);

collections.initialize(admin, name, image);
collections.initialize(admin, name);

collections
}
24 changes: 8 additions & 16 deletions contracts/collections/src/test/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,26 +10,18 @@ fn proper_initialization() {
env.mock_all_auths();

let admin = Address::generate(&env);
let uri_value = URIValue {
uri: Bytes::from_slice(&env, &[64]),
};

let name = &String::from_str(&env, "Stellar kitties");

let collections_client =
initialize_collection_contract(&env, Some(&admin), Some(name), Some(&uri_value));
let collections_client = initialize_collection_contract(&env, Some(&admin), Some(name));

let actual_admin_addr = collections_client.show_admin();
assert_eq!(admin, actual_admin_addr);

let actual_config = collections_client.show_config();
let expected_config = Config {
name: name.clone(),
image: uri_value,
};
let expected_config = Config { name: name.clone() };

assert_eq!(actual_config.name, expected_config.name);
assert_eq!(actual_config.image, expected_config.image);
}

#[test]
Expand All @@ -40,7 +32,7 @@ fn mint_and_check_balance() {
let admin = Address::generate(&env);
let user = Address::generate(&env);

let collections_client = initialize_collection_contract(&env, Some(&admin), None, None);
let collections_client = initialize_collection_contract(&env, Some(&admin), None);

collections_client.mint(&admin, &user, &1, &10);

Expand All @@ -60,7 +52,7 @@ fn mint_batch_and_balance_of_batch() {
let id_list = vec![&env, 1, 2, 3, 4, 5];
let amounts_list = vec![&env, 10, 20, 30, 40, 50];

let collections_client = initialize_collection_contract(&env, Some(&admin), None, None);
let collections_client = initialize_collection_contract(&env, Some(&admin), None);

collections_client.mint_batch(&admin, &user, &id_list, &amounts_list);

Expand All @@ -87,7 +79,7 @@ fn approval_tests() {
let user = Address::generate(&env);
let operator = Address::generate(&env);

let collectoins_client = initialize_collection_contract(&env, None, None, None);
let collectoins_client = initialize_collection_contract(&env, None, None);

collectoins_client.set_approval_for_all(&user, &operator, &true);

Expand All @@ -102,7 +94,7 @@ fn burning() {
let admin = Address::generate(&env);
let user = Address::generate(&env);

let collectoins_client = initialize_collection_contract(&env, Some(&admin), None, None);
let collectoins_client = initialize_collection_contract(&env, Some(&admin), None);

collectoins_client.mint(&admin, &user, &1, &2);
assert_eq!(collectoins_client.balance_of(&user, &1), 2);
Expand All @@ -119,7 +111,7 @@ fn batch_burning() {
let admin = Address::generate(&env);
let user = Address::generate(&env);

let collections_client = initialize_collection_contract(&env, Some(&admin), None, None);
let collections_client = initialize_collection_contract(&env, Some(&admin), None);

collections_client.mint_batch(
&admin,
Expand Down Expand Up @@ -173,7 +165,7 @@ fn test_uri() {
let admin = Address::generate(&env);
let user = Address::generate(&env);

let collections_client = initialize_collection_contract(&env, Some(&admin), None, None);
let collections_client = initialize_collection_contract(&env, Some(&admin), None);

collections_client.mint(&admin, &user, &1, &5);

Expand Down
19 changes: 19 additions & 0 deletions contracts/deployer/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
[package]
name = "phoenix-multisig-deployer"
version = { workspace = true }
authors = ["Jakub <[email protected]", "Kaloyan <[email protected]"]
repository = { workspace = true }
edition = { workspace = true }
license = { workspace = true }

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

[features]
testutils = ["soroban-sdk/testutils"]

[dependencies]
soroban-sdk = { workspace = true }

[dev_dependencies]
soroban-sdk = { workspace = true, features = ["testutils"] }
21 changes: 21 additions & 0 deletions contracts/deployer/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
default: all

all: lint build test

test: build
$(MAKE) -C ../multisig build || break;
cargo test

build:
cargo build --target wasm32-unknown-unknown --release

lint: fmt clippy

fmt:
cargo fmt --all

clippy: build
cargo clippy --all-targets -- -D warnings

clean:
cargo clean
121 changes: 121 additions & 0 deletions contracts/deployer/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
#![no_std]

use soroban_sdk::{
contract, contractimpl, contractmeta, contracttype, log, vec, Address, BytesN, Env, IntoVal,
String, Symbol, Val, Vec,
};

// Metadata that is added on to the WASM custom section
contractmeta!(
key = "Description",
val = "Phoenix Multisig Deployer Contract"
);

#[contract]
pub struct CollectionsDeployer;

#[contractimpl]
impl CollectionsDeployer {
#[allow(dead_code)]
pub fn initialize(env: Env, collections_wasm_hash: BytesN<32>) {
if is_initialized(&env) {
log!(
&env,
"Multisig Deployer: Initialize: initializing the contract twice is not allowed"
);
panic!("Multisig Deployer: Initialize: initializing the contract twice is not allowed");
}
set_initialized(&env);

set_wasm_hash(&env, &collections_wasm_hash);
}

#[allow(dead_code)]
pub fn deploy_new_collection(
env: Env,
salt: BytesN<32>,
admin: Address,
name: String,
) -> Address {
admin.require_auth();
let collections_wasm_hash = get_wasm_hash(&env);

let deployed_multisig = env
.deployer()
.with_address(admin.clone(), salt)
.deploy(collections_wasm_hash);

let init_fn = Symbol::new(&env, "initialize");
let init_fn_args: Vec<Val> = vec![&env, admin.into_val(&env), name.into_val(&env)];
let _: Val = env.invoke_contract(&deployed_multisig, &init_fn, init_fn_args);

save_collection_with_generic_key(&env, name.clone());
save_collection_with_admin_key(&env, name, admin);

deployed_multisig
}
}

// ---------- Storage types ----------

#[contracttype]
#[derive(Clone)]
pub enum DataKey {
IsInitialized,
CollectionsWasmHash,
AllCollections,
AdminId(Address),
}

pub fn set_initialized(env: &Env) {
env.storage().instance().set(&DataKey::IsInitialized, &());
}

pub fn is_initialized(env: &Env) -> bool {
env.storage()
.instance()
.get::<_, ()>(&DataKey::IsInitialized)
.is_some()
}

pub fn set_wasm_hash(env: &Env, hash: &BytesN<32>) {
env.storage()
.instance()
.set(&DataKey::CollectionsWasmHash, hash);
}

pub fn get_wasm_hash(env: &Env) -> BytesN<32> {
env.storage()
.instance()
.get(&DataKey::CollectionsWasmHash)
.unwrap()
}

pub fn save_collection_with_generic_key(env: &Env, name: String) {
let mut existent_collection: Vec<String> = env
.storage()
.persistent()
.get(&DataKey::AllCollections)
.unwrap_or(vec![&env]);

existent_collection.push_back(name);

env.storage()
.persistent()
.set(&DataKey::AllCollections, &existent_collection);
}

pub fn save_collection_with_admin_key(env: &Env, name: String, admin: Address) {
let mut existent_collection: Vec<String> = env
.storage()
.persistent()
.get(&DataKey::AdminId(admin.clone()))
.unwrap_or(vec![&env]);

existent_collection.push_back(name);

env.storage()
.persistent()
.set(&DataKey::AdminId(admin), &existent_collection);
}

0 comments on commit dc1847b

Please sign in to comment.