The auction contract can only store the last bid of any user. If the bidder is not the highest bidder, his earlier bids will be lost but he can get his last bid back but for the highest_bidder he should not get this last bid since it is highest bid but he should be able to get his earlier bids back but he will not be able to withdraw them since there's no record of them. For highest bidder this is special case of bids lost.
The highest bidder will not be able to withdraw his amount that he bid before highest bid.
#[test]
fn test_multiple_bids_by_highest_bidder() {
let (auction_dispatcher, auction_contract, erc20_contract_address, _) =
deploy_auction_contract();
auction_dispatcher.start(86400, 10);
let erc20_dispatcher = IMockERC20TokenDispatcher { contract_address: erc20_contract_address };
let first_bidder_address: ContractAddress = 123.try_into().unwrap();
start_cheat_caller_address_global(first_bidder_address);
erc20_dispatcher.mint(first_bidder_address, 60);
erc20_dispatcher.token_approve(auction_contract, 60);
auction_dispatcher.bid(15);
auction_dispatcher.bid(20);
auction_dispatcher.bid(25);
stop_cheat_caller_address_global();
let balance_auction_contract = erc20_dispatcher.token_balance_of(auction_contract);
println!("auction contract balance {:?}", balance_auction_contract);
let balance_first_bidder_after = erc20_dispatcher.token_balance_of(first_bidder_address);
println!("first bidder balance after bidding {:?}", balance_first_bidder_after);
let highest_bid = load(auction_contract, selector!("highest_bid"), 1);
println!("Highest bid is {highest_bid:?}");
let highest_bidder = load(auction_contract, selector!("highest_bidder"), 1);
println!("Highest bidder is {highest_bidder:?}");
let values = load(
auction_contract,
map_entry_address(
selector!("bid_values"), array![first_bidder_address.try_into().unwrap()].span(),
),
3,
);
let time = get_block_timestamp();
start_cheat_block_timestamp(auction_contract, time + 86401);
auction_dispatcher.end();
let owner = get_contract_address();
start_cheat_caller_address_global(auction_contract);
erc20_dispatcher.token_approve(owner, 25);
stop_cheat_caller_address_global();
let balance_owner = erc20_dispatcher.token_balance_of(owner);
println!("owner contract balance before owner called withdraw {:?}", balance_owner);
start_cheat_caller_address_global(owner);
auction_dispatcher.withdraw();
stop_cheat_caller_address_global();
let balance_owner = erc20_dispatcher.token_balance_of(owner);
println!("owner contract balance after owner called withdraw {:?}", balance_owner);
let balance_auction_contract = erc20_dispatcher.token_balance_of(auction_contract);
println!("auction contract balance after owner called withdraw {:?}", balance_auction_contract);
stop_cheat_block_timestamp(auction_contract);
println!("bid values by highest bidder {:?}", values);
}
Instead of using the map to store the last bid, it should hold the sum of the bids and when the bidding ends the highest bid should be substracted from the maped value for highest bidder.