Untitled
user_8098220
plain_text
3 years ago
7.4 kB
10
Indexable
module overmind::birthday_bot {
use aptos_std::table::Table;
use std::signer;
use std::error;
use aptos_framework::account;
use std::vector;
use aptos_framework::coin;
use aptos_framework::aptos_coin::{Self, AptosCoin};
use aptos_std::table;
use aptos_framework::timestamp;
//
// Errors
//
const ERROR_DISTRIBUTION_STORE_EXIST: u64 = 0;
const ERROR_DISTRIBUTION_STORE_DOES_NOT_EXIST: u64 = 1;
const ERROR_LENGTHS_NOT_EQUAL: u64 = 2;
const ERROR_BIRTHDAY_GIFT_DOES_NOT_EXIST: u64 = 3;
const ERROR_BIRTHDAY_TIMESTAMP_SECONDS_HAS_NOT_PASSED: u64 = 4;
//
// Data structures
//
struct BirthdayGift has drop, store {
amount: u64,
birthday_timestamp_seconds: u64,
}
struct DistributionStore has key {
birthday_gifts: Table<address, BirthdayGift>,
signer_capability: account::SignerCapability,
}
//
// Assert functions
//
public fun assert_distribution_store_exists(
account_address: address,
) {
// TODO: assert that `DistributionStore` exists
assert!(exists<DistributionStore>(account_address), 1);
}
public fun assert_distribution_store_does_not_exist(
account_address: address,
) {
// TODO: assert that `DistributionStore` does not exist
assert!(!exists<DistributionStore>(account_address), 0);
}
public fun assert_lengths_are_equal(
addresses: vector<address>,
amounts: vector<u64>,
timestamps: vector<u64>
) {
// TODO: assert that the lengths of `addresses`, `amounts`, and `timestamps` are all equal
let single_vector_len = vector::length<address>(&addresses);
assert!(vector::length<u64>(&amounts) == single_vector_len, 2);
assert!(vector::length<u64>(×tamps) == single_vector_len, 2);
}
public fun assert_birthday_gift_exists(
distribution_address: address,
address: address,
) acquires DistributionStore {
// TODO: assert that `birthday_gifts` exists
let distribution_store = borrow_global<DistributionStore>(distribution_address);
assert!(table::contains(&distribution_store.birthday_gifts, address), 0);
}
public fun assert_birthday_timestamp_seconds_has_passed(
distribution_address: address,
address: address,
) acquires DistributionStore {
// TODO: assert that the current timestamp is greater than or equal to `birthday_timestamp_seconds`
let distribution_store = borrow_global<DistributionStore>(distribution_address);
let birthday_store = table::borrow(&distribution_store.birthday_gifts, address);
assert!(timestamp::now_seconds() >= birthday_store.birthday_timestamp_seconds, 4);
// let timestamp: Table<address, BirthdayGift> = table::borrow(&mut distribution_store.birthday_gifts, address);
}
//
// Entry functions
//
/**
* Initializes birthday gift distribution contract
* @param account - account signer executing the function
* @param addresses - list of addresses that can claim their birthday gifts
* @param amounts - list of amounts for birthday gifts
* @param birthday_timestamps - list of birthday timestamps in seconds (only claimable after this timestamp has passed)
**/
public entry fun initialize_distribution(
account: &signer,
addresses: vector<address>,
amounts: vector<u64>,
birthday_timestamps: vector<u64>
) acquires DistributionStore {
// TODO: check `DistributionStore` does not exist
assert_distribution_store_does_not_exist(signer::address_of(account));
// TODO: check all lengths of `addresses`, `amounts`, and `birthday_timestamps` are equal
assert_lengths_are_equal(addresses, amounts, birthday_timestamps);
// TODO: create resource account
let (the_signer, signer_capability) = account::create_resource_account(account, vector::empty<u8>());
// TODO: register Aptos coin to resource account
aptos_framework::managed_coin::register<AptosCoin>(&the_signer);
// TODO: loop through the lists and push items to birthday_gifts table
let birthday_gift_store = table::new<address, BirthdayGift>();
let i = 0;
let sum_of_all_amounts = 0;
while (i < vector::length(&addresses)) {
let addr = vector::borrow<address>(&addresses, i);
let amount = vector::borrow<u64>(&amounts, i);
let birthday_timestamp_seconds = vector::borrow<u64>(&birthday_timestamps, i);
let gift = BirthdayGift {
amount: *amount, birthday_timestamp_seconds: *birthday_timestamp_seconds
};
table::upsert(&mut birthday_gift_store, *addr, gift);
i = i + 1;
sum_of_all_amounts = sum_of_all_amounts + *amount;
};
// TODO: transfer the sum of all items in `amounts` from initiator to resource account
aptos_framework::coin::transfer<AptosCoin>(account, signer::address_of(&the_signer), sum_of_all_amounts);
// TODO: move_to resource `DistributionStore` to account signer
move_to(account, DistributionStore {birthday_gifts: birthday_gift_store,signer_capability: signer_capability});
}
/**
* Add birthday gift to `DistributionStore.birthday_gifts`
* @param account - account signer executing the function
* @param address - address that can claim the birthday gift
* @param amount - amount for the birthday gift
* @param birthday_timestamp_seconds - birthday timestamp in seconds (only claimable after this timestamp has passed)
**/
public entry fun add_birthday_gift(
account: &signer,
address: address,
amount: u64,
birthday_timestamp_seconds: u64
) acquires DistributionStore {
// TODO: check that the distribution store exists
// TODO: set new birthday gift to new `amount` and `birthday_timestamp_seconds` (birthday_gift already exists, sum `amounts` and override the `birthday_timestamp_seconds`
// TODO: transfer the `amount` from initiator to resource account
}
/**
* Remove birthday gift from `DistributionStore.birthday_gifts`
* @param account - account signer executing the function
* @param address - `birthday_gifts` address
**/
public entry fun remove_birthday_gift(
account: &signer,
address: address,
) acquires DistributionStore {
// TODO: check that the distribution store exists
// TODO: if `birthday_gifts` exists, remove `birthday_gift` from table and transfer `amount` from resource account to initiator
}
/**
* Claim birthday gift from `DistributionStore.birthday_gifts`
* @param account - account signer executing the function
* @param distribution_address - distribution contract address
**/
public entry fun claim_birthday_gift(
account: &signer,
distribution_address: address,
) acquires DistributionStore {
// TODO: check that the distribution store exists
// TODO: check that the `birthday_gift` exists
// TODO: check that the `birthday_timestamp_seconds` has passed
// TODO: remove `birthday_gift` from table and transfer `amount` from resource account to initiator
}
}
Editor is loading...