module 0xCAFE::IMCoin {
use Std::Signer;
const MAX_SUPPLY: u64 = 1024;
const ISSUER: address = @0xCAFE;
struct Coin has key {
supply: u64,
holders: u64,
}
struct Balance {
value: u64
}
// complete this function
public fun issue(issuer: &signer) {
let issuer_addr = Signer::address_of(issuer);
assert!(issuer_addr == ISSUER, 1001);
assert!(exists<Coin>(issuer_addr) == false, 1002);
move_to(issuer, Coin { supply: 0, holders: 0 };
}
// complete this function
public fun supply(): u64 acquires Coin {
assert!(exists<Coin>(ISSUER), 1003);
borrow_global<Coin>(ISSUER).supply
}
public fun holders(): u64 acquires Coin {
assert!(exists<Coin>(ISSUER), 1003);
borrow_global<Coin>(ISSUER).holders
}
// complete this function
public fun register(account: &signer) {
let addr: address = Signer::address_of(account);
assert!(exists<Coin>(ISSUER), 1003);
assert!(exists<Balance>(addr), 2001);
let holders: u64 = &mut borrow_global_mut<Coin>(ISSUER).holders;
*holders = *holders + 1;
}
// complete this function
public fun deposit(issuer: &signer, receiver: address, amount: u64) {
let issuer_addr = Signer::address_of(issuer);
assert!(issuer_addr == ISSUER, 1001);
let supply: u64 = &mut borrow_global_mut<Coin>(ISSUER).supply;
if(*supply + amount <= MAX_SUPPLY) {
*supply = *supply + amount;
} else {
abort 1004;
};
}
// complete this function
public fun balance(addr: address): u64 acquires Balance {
assert!(exists<Balance>(addr), 2002);
borrow_global<Balance>(addr).value
}
// complete this function
public fun transfer(sender: &signer, receiver: address, amount: u64) acquires Balance {
sub_balance(Signer::address_of(sender), amount);
assert!(Signer::address_of(sender) != receiver, 2003);
let balance:u64 = borrow_global<Balance>(Signer::address_of(sender)).value
assert!(balance >= amount, 2004);
add_balance(receiver, amount);
}
fun add_balance(addr: address, amount: u64) acquires Balance {
assert!(exists<Balance>(addr), 2002);
let value_ref = &mut borrow_global_mut<Balance>(addr).value;
*value_ref = *value_ref + amount;
}
fun sub_balance(addr: address, amount: u64) acquires Balance {
assert!(exists<Balance>(addr), 2002);
let value_ref = &mut borrow_global_mut<Balance>(addr).value;
assert!(*value_ref >= amount, 2004);
*value_ref = *value_ref - amount;
}
}