English Auction
The English auction, also known as an open ascending price auction, is a widely recognized auction format.
The auction starts with a low initial price and gradually increases as bidders place higher bids.
It encourages competition among participants and is commonly used for unique items or high-value goods.
The transparent nature of the auction allows bidders to gauge the demand and value of the item, leading to intense bidding wars.
The auction format has seamlessly transitioned into the digital era with online platforms, enabling a larger audience to participate.
module my_addrx::English_Auction{
use 0x1::vector;
use 0x1::signer;
use 0x1::simple_map::{Self, SimpleMap};
/// Error codes
const YOU_ARE_WINNER: u64 = 1;
const EINSUFFICIENT_BALANCE: u64 = 2;
struct BetAddrList has key {
bet_addr_list: SimpleMap<address, u64>,
b_list: vector<address>,
winner: address
}
public fun assert_is_owner(addr: address) {
assert!(addr == @my_addrx, 0);
}
public fun assert_is_initialized(addr: address) {
assert!(exists<BetAddrList>(addr), 1);
}
public fun assert_uninitialized(addr: address) {
assert!(!exists<BetAddrList>(addr), 3);
}
public fun assert_contains_key(map: &SimpleMap<address, u64>, addr: &address) {
assert!(simple_map::contains_key(map, addr), 2);
}
public fun assert_not_contains_key(map: &SimpleMap<address, u64>, addr: &address) {
assert!(!simple_map::contains_key(map, addr), 4);
}
public entry fun initialize_with_bet(acc: &signer, amount:u64) acquires BetAddrList {
let addr = signer::address_of(acc);
let balance = my_addrx::BasicTokens::balance_of(addr);
assert!(balance >= amount, EINSUFFICIENT_BALANCE);
assert_is_owner(addr);
assert_uninitialized(addr);
let b_store = BetAddrList{
bet_addr_list:simple_map::create(),
b_list: vector::empty<address>(),
winner: @0x0,
};
move_to(acc, b_store);
let b_store = borrow_global_mut<BetAddrList>(addr);
simple_map::add(&mut b_store.bet_addr_list, addr, amount);
vector::push_back(&mut b_store.b_list, addr);
my_addrx::BasicTokens::withdraw(addr, amount);
}
public entry fun placeBet(acc: &signer, store_addr: address, amount:u64) acquires BetAddrList {
let b_addr = signer::address_of(acc);
let balance = my_addrx::BasicTokens::balance_of(b_addr);
assert!(balance >= amount, EINSUFFICIENT_BALANCE);
let b_store = borrow_global_mut<BetAddrList>(store_addr);
assert!(b_store.winner == @0x0, 5);
let balance = my_addrx::BasicTokens::balance_of(b_addr);
assert!(balance >= amount, EINSUFFICIENT_BALANCE);
simple_map::add(&mut b_store.bet_addr_list, b_addr, amount);
vector::push_back(&mut b_store.b_list, b_addr);
my_addrx::BasicTokens::withdraw(b_addr, amount);
}
public entry fun declare_winner(acc: &signer) acquires BetAddrList {
let addr = signer::address_of(acc);
assert_is_owner(addr);
assert_is_initialized(addr);
let b_store = borrow_global_mut<BetAddrList>(addr);
assert!(b_store.winner == @0x0, 5);
let total_betters = vector::length(&b_store.b_list);
let i = 0;
let winner: address = @0x0;
let highest_bet: u64 = 0;
while (i < total_betters) {
let better = *vector::borrow(&b_store.b_list, (i as u64));
let bet_amount = simple_map::borrow(&b_store.bet_addr_list, &better);
if(highest_bet < *bet_amount) {
highest_bet = *bet_amount;
winner = better;
};
i = i + 1;
};
b_store.winner = winner;
}
public fun claim_your_amount(acc_own: &signer, store_addr: address) acquires BetAddrList{
let addr = signer::address_of(acc_own);
let b_store = borrow_global_mut<BetAddrList>(store_addr);
let bet_amount = simple_map::borrow_mut(&mut b_store.bet_addr_list, &addr);
assert!(b_store.winner != addr, 5);
assert!(*bet_amount != 0, 6);
my_addrx::BasicTokens::withdraw(addr, *bet_amount);
*bet_amount = 0;
}
#[test(admin = @my_addrx,alice=@0x11,bob=@0x2)]
public entry fun test_betting(admin: signer,alice : signer, bob : signer) acquires BetAddrList{
let better = account::create_account_for_test(signer::address_of(&admin));
let better2 = account::create_account_for_test(signer::address_of(&alice));
let better3 = account::create_account_for_test(signer::address_of(&bob));
// Publish balance for Alice and Bob
my_addrx::BasicTokens::publish_balance(&admin);
my_addrx::BasicTokens::publish_balance(&alice);
my_addrx::BasicTokens::publish_balance(&bob);
// Mint some tokens to Alice
my_addrx::BasicTokens::mint<my_addrx::BasicTokens::Coin>(signer::address_of(&admin), 1000);
my_addrx::BasicTokens::mint<my_addrx::BasicTokens::Coin>(signer::address_of(&alice), 1000);
my_addrx::BasicTokens::mint<my_addrx::BasicTokens::Coin>(signer::address_of(&bob), 1000);
initialize_with_bet(&better,100);
placeBet(&better2, signer::address_of(&admin),200);
placeBet(&better3, signer::address_of(&admin),300);
let b_store = &borrow_global<BetAddrList>(signer::address_of(&admin)).bet_addr_list;
assert_contains_key(b_store, &signer::address_of(&better));
assert_contains_key(b_store, &signer::address_of(&better2));
assert_contains_key(b_store, &signer::address_of(&better3));
declare_winner(&admin);
}
}
module my_addrx::BasicTokens{
use std::error;
use std::signer;
/// Error codes
const ENOT_MODULE_OWNER: u64 = 0;
const EINSUFFICIENT_BALANCE: u64 = 1;
const EALREADY_HAS_BALANCE: u64 = 2;
const EALREADY_INITIALIZED: u64 = 3;
const EEQUAL_ADDR: u64 = 4;
struct Coin has store,drop {
value: u64
}
struct Balance has key {
coin: Coin
}
public fun createCoin(v:u64): Coin
{
let coin = Coin {
value:v
};
return coin
}
public fun publish_balance(account: &signer) {
let empty_coin = Coin { value: 0 };
assert!(!exists<Balance>(signer::address_of(account)), error::already_exists(EALREADY_HAS_BALANCE));
move_to(account, Balance { coin: empty_coin });
}
public fun mint<CoinType: drop>(mint_addr: address, amount: u64) acquires Balance {
deposit(mint_addr, Coin{ value: amount });
}
public fun burn(burn_addr: address, amount: u64) acquires Balance {
let Coin { value: _ } = withdraw(burn_addr, amount);
}
public fun balance_of(owner: address): u64 acquires Balance {
borrow_global<Balance>(owner).coin.value
}
public fun transfer(from: &signer, to: address, amount: u64) acquires Balance {
let from_addr = signer::address_of(from);
assert!(from_addr != to, EEQUAL_ADDR);
let check = withdraw(from_addr, amount);
deposit(to, check);
}
public fun withdraw(addr: address, amount: u64) : Coin acquires Balance {
let balance = balance_of(addr);
assert!(balance >= amount, EINSUFFICIENT_BALANCE);
let balance_ref = &mut borrow_global_mut<Balance>(addr).coin.value;
*balance_ref = balance - amount;
Coin { value: amount }
}
public fun deposit(addr: address, check: Coin) acquires Balance{
let balance = balance_of(addr);
let balance_ref = &mut borrow_global_mut<Balance>(addr).coin.value;
let Coin { value } = check;
*balance_ref = balance + value;
}
}
Last updated