Open source repository donation scheme design
Prerequisites
Create and initialize the token contract
// CREATE TOKEN CONTRACT
let (token_id, token_client) = create_and_init_token_contract(&env, &admin_id);
Valid accounts for the individuals
Let's create some test accounts
// Admin for the Token Contract init.
let admin = env.accounts().generate(); let admin_id = Identifier::Account(admin.clone());
// Account that will donate to the parent project
let donor = env.accounts().generate();
let donor_id = Identifier::Account(donor.clone());
// PARENT CONTRACT (PARENT PROJECT)
let contract_id = env.register_contract(None, CascadeDonationContract);
let contract_client = CascadeDonationContractClient::new(&env, &contract_id);
// PARENT PROJECT CHILDREN ACCOUNTS
let dependency_1 = env.accounts().generate();
let dependency1_id = Identifier::Account(dependencie_1.clone());
//CHILD PARENT PROJECT (CHILD CONTRACT)
let child_contract_id = env.register_contract_wasm(None, cascade_donation_contract::WASM);
let child_contract_client = CascadeDonationContractClient::new(&env, &child_contract_id);
// CHILD PARENT PROJECT CHILDREN
let sub_dependency_1 = env.accounts().generate();
let sub_dependency_1_id = Identifier::Account(sub_dependencie_1.clone());
let sub_dependency_2 = env.accounts().generate();
let sub_dependency_2_id = Identifier::Account(sub_dependencie_2.clone());
Define distribution rules
// CHILD PARENT CHILDREN
let mut parent1_children: Vec<Node> = vec![&env];
let parent_1_child_1 =
Recipient {
address: soroban_sdk::Address::Account(sub_dependency_1.clone()),
name: symbol!("subdep_1"),
percentage: 20
};
let parent_1_child_2 =
Recipient {
address: soroban_sdk::Address::Account(sub_dependency_2.clone()),
name: symbol!("subdep_2"),
percentage: 20
};
parent1_children.push_back(parent_1_child_1);
parent1_children.push_back(parent_1_child_2);
// END CHILD PARENT CHILDREN
//PARENT CHILDREN
let child_parent_1 =
Recipient {
address: soroban_sdk::Address::Contract(child_contract_id.clone()),
name: symbol!("c_parent_1"),
percentage: 20
};
let child_1 =
Recipient {
address: soroban_sdk::Address::Account(dependency_1.clone()),
name: symbol!("dep_1"),
percentage: 20
};
// END CHILDREN
let mut children: Vec<Node> = vec![&env];
children.push_back(child_1);
children.push_back(child_parent_1);
Initialize the CascadeDonation contract
We need to initialize the second one too for the purpose of the test.
// Child contract
child_contract_client.initialize(&token_id, &parent1_children);
// Root contract
contract_client.initialize(&token_id, &children);
Mint donor account
token_client.with_source_account(&admin).mint(
&Signature::Invoker,
&BigInt::zero(&env),
&donator_id,
&BigInt::from_u32(&env, 2000)
);
Approve donation from donor
token_client.with_source_account(&donor).approve(
&Signature::Invoker,
&BigInt::zero(&env),
&Identifier::Contract(contract_id.clone()),
&BigInt::from_u32(&env, 1000)
);
Donate to the CascadingDonation
root contract
contract_client.with_source_account(&donor).donate(&BigInt::from_u32(&env, 1000), &donator_id);
Expected result
Main Contract balance -> 600
Recipient 1 balance -> 200
Recipient 2 balance -> 120
Recipient 3 balance -> 40
Recipient 4 balance -> 40