Skip to content

Commit

Permalink
Add setters and remove owner from CoinPayment (#56)
Browse files Browse the repository at this point in the history
  • Loading branch information
JohnChangUK authored Apr 23, 2024
1 parent b6a2bed commit 69fd63e
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 30 deletions.
4 changes: 1 addition & 3 deletions ez-launch/sources/ez_launch.move
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ module ez_launch::ez_launch {
let object_addr = signer::address_of(&object_signer);
let ez_launch_config_obj = object::address_to_object(object_addr);

add_mint_fee(creator, &mut mint_fee, creator_addr, ez_launch_config_obj);
add_mint_fee(&mut mint_fee, creator_addr, ez_launch_config_obj);

// (jill) add whitelist

Expand Down Expand Up @@ -309,7 +309,6 @@ module ez_launch::ez_launch {
}

fun add_mint_fee(
creator: &signer,
mint_fee: &mut Option<u64>,
creator_addr: address,
ez_launch_config_obj: Object<EZLaunchConfig>,
Expand All @@ -318,7 +317,6 @@ module ez_launch::ez_launch {
if (option::is_some(mint_fee)) {
let mint_fee_category = b"Mint Fee";
let coin_payment = coin_payment::create<AptosCoin>(
creator,
option::extract(mint_fee),
creator_addr,
string::utf8(mint_fee_category),
Expand Down
9 changes: 4 additions & 5 deletions launchpad/sources/launchpad.move
Original file line number Diff line number Diff line change
Expand Up @@ -85,12 +85,11 @@ module launchpad::launchpad {
};

let fees = borrow_global_mut<Fees<T>>(launchpad_addr);
let coin_payment = coin_payment::create(creator, amount, destination, category);
let coin_payment = coin_payment::create(amount, destination, category);
vector::push_back(&mut fees.coin_payments, coin_payment);

// Take launchpad fees - 0.3% of each coin payment amount.
let launchpad_fee = create_launchpad_fee<T>(
launchpad_signer,
(amount * LAUNCHPAD_FEE_BPS_NUMERATOR) / LAUNCHPAD_FEE_BPS_DENOMINATOR
);
vector::push_back(&mut fees.coin_payments, launchpad_fee);
Expand All @@ -113,7 +112,7 @@ module launchpad::launchpad {
let coin_payment = vector::borrow(&fees.coin_payments, i);
if (coin_payment::category(coin_payment) == category) {
let coin_payment = vector::remove(&mut fees.coin_payments, i);
coin_payment::destroy(creator, coin_payment);
coin_payment::destroy(coin_payment);
return
};
i = i + 1;
Expand Down Expand Up @@ -177,8 +176,8 @@ module launchpad::launchpad {
});
}

fun create_launchpad_fee<T>(launchpad_signer: &signer, amount: u64): CoinPayment<T> {
coin_payment::create(launchpad_signer, amount, @launchpad_admin, string::utf8(LAUNCHPAD_FEE_CATEGORY))
fun create_launchpad_fee<T>(amount: u64): CoinPayment<T> {
coin_payment::create(amount, @launchpad_admin, string::utf8(LAUNCHPAD_FEE_CATEGORY))
}

/// When calling this function, the `creator` will be have ownership of the collection.
Expand Down
47 changes: 30 additions & 17 deletions token-minter/sources/modules/coin_payment.move
Original file line number Diff line number Diff line change
@@ -1,17 +1,23 @@
/// This module allows users to create recurring payments for services, fees, or subscriptions in any type of coin.
/// The `CoinPayment<T>` struct holds the details of such payments, including the amount, recipient, and payment category.
///
/// ## Features
/// # Features
/// - Users can create recurring payment instructions to be executed as needed.
/// - Only the owner of the `CoinPayment<T>` can destroy it.
/// - All payment executions emit events that can be tracked and audited.
/// - Payments can be categorized (e.g., mint fees, subscription fees), making it easier to manage and report financial activities.
///
/// ## Usage
/// # Usage
///
/// ## Example
/// # Notes
/// `CoinPayment<T>` must not be used in function parameters or return types,
/// as the value can be changed by anyone with reference to it.
///
/// `CoinPayment<T>` acts as a contract which holds the details of a payment instruction.
///
/// # Example
/// ```
/// // Create a recurring payment instruction for a subscription fee.
/// Create a recurring payment instruction for a subscription fee.
/// let payment = coin_payment::create<T>(owner, 100, recipient_address, "Subscription Fee");
///
/// // Execute the payment when due.
Expand All @@ -37,8 +43,6 @@ module minter::coin_payment {
const ENOT_OWNER: u64 = 3;

struct CoinPayment<phantom T> has store {
/// The owner of the coin payment.
owner: address,
/// The amount of coin to be paid.
amount: u64,
/// The address to which the coin is to be paid to.
Expand All @@ -50,16 +54,19 @@ module minter::coin_payment {
#[event]
/// Event emitted when a coin payment of type `T` is made.
struct CoinPaymentEvent<phantom T> has drop, store {
owner: address,
from: address,
amount: u64,
destination: address,
category: String,
}

public fun create<T>(owner: &signer, amount: u64, destination: address, category: String): CoinPayment<T> {
/// Creates a new `CoinPayment<T>` instance which is to be stored in a data structure for future reference.
/// `CoinPayment<T>` acts as a contract which holds the details of a payment instruction.
/// `CoinPayment<T>` must not be used in function parameters or return types,
/// as the value can be changed by anyone with reference to it.
public fun create<T>(amount: u64, destination: address, category: String): CoinPayment<T> {
assert!(amount > 0, error::invalid_argument(EINVALID_AMOUNT));
CoinPayment<T> { owner: signer::address_of(owner), amount, destination, category }
CoinPayment<T> { amount, destination, category }
}

public fun execute<T>(minter: &signer, coin_payment: &CoinPayment<T>) {
Expand All @@ -74,21 +81,15 @@ module minter::coin_payment {
coin::transfer<T>(minter, destination, amount);

event::emit(CoinPaymentEvent<T> {
owner: owner(coin_payment),
from,
amount,
destination,
category: category(coin_payment),
});
}

public fun destroy<T>(owner: &signer, coin_payment: CoinPayment<T>) {
assert!(coin_payment.owner == signer::address_of(owner), error::unauthenticated(ENOT_OWNER));
let CoinPayment { owner: _, amount: _, destination: _, category: _ } = coin_payment;
}

public fun owner<T>(coin_payment: &CoinPayment<T>): address {
coin_payment.owner
public fun destroy<T>(coin_payment: CoinPayment<T>) {
let CoinPayment { amount: _, destination: _, category: _ } = coin_payment;
}

public fun amount<T>(coin_payment: &CoinPayment<T>): u64 {
Expand All @@ -102,4 +103,16 @@ module minter::coin_payment {
public fun category<T>(coin_payment: &CoinPayment<T>): String {
coin_payment.category
}

public fun set_amount<T>(coin_payment: &mut CoinPayment<T>, amount: u64) {
coin_payment.amount = amount;
}

public fun set_destination<T>(coin_payment: &mut CoinPayment<T>, destination: address) {
coin_payment.destination = destination;
}

public fun set_category<T>(coin_payment: &mut CoinPayment<T>, category: String) {
coin_payment.category = category;
}
}
8 changes: 3 additions & 5 deletions token-minter/tests/modules/coin_payment_tests.move
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,12 @@ module minter::coin_payment_tests {
let destination = signer::address_of(creator);
let coin_payments = vector<CoinPayment<AptosCoin>>[];
let mint_coin_payment = coin_payment::create<AptosCoin>(
creator,
mint_fee,
destination,
string::utf8(b"Mint fee"),
);
vector::push_back(&mut coin_payments, mint_coin_payment);
let launchpad_coin_payment = coin_payment::create<AptosCoin>(
creator,
launchpad_fee,
destination,
string::utf8(b"Launchpad fee"),
Expand All @@ -57,12 +55,12 @@ module minter::coin_payment_tests {
let user_balance = coin::balance<AptosCoin>(signer::address_of(user));
assert!(user_balance == user_initial_balance - total_cost, 0);

destroy_coin_payments(creator, coin_payments);
destroy_coin_payments(coin_payments);
}

fun destroy_coin_payments(owner: &signer, coin_payments: vector<CoinPayment<AptosCoin>>) {
fun destroy_coin_payments(coin_payments: vector<CoinPayment<AptosCoin>>) {
vector::destroy(coin_payments, |coin_payment| {
coin_payment::destroy(owner, coin_payment)
coin_payment::destroy(coin_payment)
});
}
}

0 comments on commit 69fd63e

Please sign in to comment.