Skip to content

Commit

Permalink
Change contract 'owner' to 'recipient', to clarify their role (#35)
Browse files Browse the repository at this point in the history
  • Loading branch information
paulbellamy authored Oct 8, 2022
1 parent 2caef95 commit 6bc932b
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 39 deletions.
51 changes: 28 additions & 23 deletions contracts/crowdfund/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ pub mod testutils;
#[contracttype]
pub enum DataKey {
Deadline,
Owner,
Recipient,
Started,
Target,
Token,
Expand Down Expand Up @@ -42,9 +42,9 @@ fn get_ledger_timestamp(e: &Env) -> u64 {
e.ledger().timestamp()
}

fn get_owner(e: &Env) -> Identifier {
fn get_recipient(e: &Env) -> Identifier {
e.data()
.get(DataKey::Owner)
.get(DataKey::Recipient)
.expect("not initialized")
.unwrap()
}
Expand Down Expand Up @@ -120,33 +120,33 @@ struct Crowdfund;
/*
How to use this contract to run a crowdfund
1. Call initialize(provider, deadline_unix_epoch, target_amount, token).
2. Donors send USDC to this contract's address
3. Once the target_amount is reached, the contract owner can withdraw the USDC.
4. If the deadline passes without reaching the target_amount, the donors can withdraw their USDC again.
1. Call initialize(recipient, deadline_unix_epoch, target_amount, token).
2. Donors send tokens to this contract's address
3. Once the target_amount is reached, the contract recipient can withdraw the tokens.
4. If the deadline passes without reaching the target_amount, the donors can withdraw their tokens again.
*/
#[contractimpl]
impl Crowdfund {
pub fn initialize(
e: Env,
owner: Identifier,
recipient: Identifier,
deadline: u64,
target_amount: BigInt,
token: BytesN<32>,
) {
if e.data().has(DataKey::Owner) {
if e.data().has(DataKey::Recipient) {
panic!("already initialized");
}

e.data().set(DataKey::Owner, owner);
e.data().set(DataKey::Recipient, recipient);
e.data().set(DataKey::Started, get_ledger_timestamp(&e));
e.data().set(DataKey::Deadline, deadline);
e.data().set(DataKey::Target, target_amount);
e.data().set(DataKey::Token, token);
}

pub fn owner(e: Env) -> Identifier {
get_owner(&e)
pub fn recipient(e: Env) -> Identifier {
get_recipient(&e)
}

pub fn deadline(e: Env) -> u64 {
Expand All @@ -170,9 +170,9 @@ impl Crowdfund {
}

pub fn balance(e: Env, user: Identifier) -> BigInt {
let owner = get_owner(&e);
let recipient = get_recipient(&e);
if get_state(&e) == State::Success {
if user != owner {
if user != recipient {
return BigInt::zero(&e);
};
return get_balance(&e, get_token(&e));
Expand All @@ -186,9 +186,9 @@ impl Crowdfund {
panic!("sale is not running")
};

let owner = get_owner(&e);
if user == owner {
panic!("owner may not deposit")
let recipient = get_recipient(&e);
if user == recipient {
panic!("recipient may not deposit")
}

let balance = get_user_deposited(&e, &user);
Expand All @@ -207,21 +207,26 @@ impl Crowdfund {

pub fn withdraw(e: Env, to: Identifier) {
let state = get_state(&e);
let owner = get_owner(&e);
let recipient = get_recipient(&e);

match state {
State::Running => {
panic!("sale is still running")
}
State::Success => {
if to != owner {
panic!("sale was successful, only the owner may withdraw")
if to != recipient {
panic!("sale was successful, only the recipient may withdraw")
}
transfer(&e, get_token(&e), &owner, &get_balance(&e, get_token(&e)))
transfer(
&e,
get_token(&e),
&recipient,
&get_balance(&e, get_token(&e)),
)
}
State::Expired => {
if to == owner {
panic!("sale expired, the owner may not withdraw")
if to == recipient {
panic!("sale expired, the recipient may not withdraw")
}

// Withdraw full amount
Expand Down
30 changes: 15 additions & 15 deletions contracts/crowdfund/src/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ fn create_token_contract(e: &Env, admin: &AccountId) -> (BytesN<32>, Token) {

fn create_crowdfund_contract(
e: &Env,
owner: &AccountId,
recipient: &AccountId,
deadline: &u64,
target_amount: &BigInt,
token: &BytesN<32>,
Expand All @@ -42,7 +42,7 @@ fn create_crowdfund_contract(
register_crowdfund(&e, &id);
let crowdfund = Crowdfund::new(e, &id);
crowdfund.client().initialize(
&Identifier::Account(owner.clone()),
&Identifier::Account(recipient.clone()),
&deadline,
&target_amount,
&token,
Expand All @@ -59,7 +59,7 @@ fn advance_ledger(e: &Env, delta: u64) {
struct Setup {
env: Env,
user2: AccountId,
owner_id: Identifier,
recipient_id: Identifier,
user1_id: Identifier,
user2_id: Identifier,
token: Token,
Expand All @@ -75,8 +75,8 @@ struct Setup {
impl Setup {
fn new() -> Self {
let e: Env = Default::default();
let owner = e.accounts().generate_and_create();
let owner_id = Identifier::Account(owner.clone());
let recipient = e.accounts().generate_and_create();
let recipient_id = Identifier::Account(recipient.clone());
let user1 = e.accounts().generate_and_create();
let user1_id = Identifier::Account(user1.clone());
let user2 = e.accounts().generate_and_create();
Expand All @@ -90,7 +90,7 @@ impl Setup {
let (contract_token, token) = create_token_contract(&e, &token_admin);

let (contract_crowdfund, crowdfund) =
create_crowdfund_contract(&e, &owner, &deadline, &target_amount, &contract_token);
create_crowdfund_contract(&e, &recipient, &deadline, &target_amount, &contract_token);
let crowdfund_id = Identifier::Contract(contract_crowdfund);

token.with_source_account(&token_admin).mint(
Expand Down Expand Up @@ -118,7 +118,7 @@ impl Setup {

Self {
env: e,
owner_id: owner_id,
recipient_id: recipient_id,
user1_id: user1_id,
user2: user2,
user2_id: user2_id,
Expand Down Expand Up @@ -174,7 +174,7 @@ fn test_success() {
);

advance_ledger(&setup.env, 10);
setup.crowdfund.client().withdraw(&setup.owner_id);
setup.crowdfund.client().withdraw(&setup.recipient_id);

assert_eq!(
setup.token.balance(&setup.user1_id),
Expand All @@ -189,7 +189,7 @@ fn test_success() {
BigInt::zero(&setup.env)
);
assert_eq!(
setup.token.balance(&setup.owner_id),
setup.token.balance(&setup.recipient_id),
BigInt::from_u32(&setup.env, 15)
);
}
Expand All @@ -198,12 +198,12 @@ fn test_success() {
#[should_panic(expected = "sale is still running")]
fn sale_still_running() {
let setup = Setup::new();
setup.crowdfund.client().withdraw(&setup.owner_id);
setup.crowdfund.client().withdraw(&setup.recipient_id);
}

#[test]
#[should_panic(expected = "sale was successful, only the owner may withdraw")]
fn sale_successful_only_owner() {
#[should_panic(expected = "sale was successful, only the recipient may withdraw")]
fn sale_successful_only_recipient() {
let setup = Setup::new();
setup.token.with_source_account(&setup.user2).approve(
&Signature::Invoker,
Expand All @@ -221,12 +221,12 @@ fn sale_successful_only_owner() {
}

#[test]
#[should_panic(expected = "sale expired, the owner may not withdraw")]
fn sale_expired_owner_not_allowed() {
#[should_panic(expected = "sale expired, the recipient may not withdraw")]
fn sale_expired_recipient_not_allowed() {
let setup = Setup::new();
advance_ledger(&setup.env, 10);

setup.crowdfund.client().withdraw(&setup.owner_id);
setup.crowdfund.client().withdraw(&setup.recipient_id);
}

#[test]
Expand Down
2 changes: 1 addition & 1 deletion initialize.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

set -e

# TODO: Set the owner to something reasonable here. Probably whatever account
# TODO: Set the recipient to something reasonable here. Probably whatever account
# soroban is running stuff as?
# This is an Identifier for Account GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWHF
# TODO: Have a nicer way to build Identifiers on the CLI
Expand Down

0 comments on commit 6bc932b

Please sign in to comment.