DSAI4206 Assignment Solution
Individual Assignment: Specialized Vehicle Registration Mark (SVRM) Auction
1. Overview

In this assignment, you will implement a Vickrey (Second-Price) Auction smart contract for the Hong Kong Transport Department's Personalized Vehicle Registration Marks (PVRM) scheme. To ensure privacy, the auction follows a Commit-Reveal pattern. Bidders first submit a "blinded" (hashed) version of their bid with a deposit. Later, they reveal their actual bid and a secret "salt" to prove they are the ones who placed the bid.

In this assignment, you will build a decentralized auction system for Hong Kong PVRMs.

You must deploy two contracts:

i. DSAI4206Token: A custom ERC-20 token used for bidding.
ii. PVRMAuction: A privacy-preserving Vickrey (Second-Price) Auction contract using a Commit-Reveal pattern.

2. Learning Objectives

  • Architect a Custom Token Ecosystem: Students must design and deploy their own DSAI4206Token (ERC-20) to act as the auction's native currency. This includes managing initial supply through mint functions and establishing a multi-contract environment where the Auction contract interacts with the Student’s unique currency.
  • Implement ERC-20 Token Interactivity: Master the transferFrom and transfer patterns to handle automated deposits and final settlement payments between users and a smart contract
  • • Enforce complex validation rules (HK PVRM character restrictions)
  • • Develop a Commit-Reveal scheme to ensure bid privacy.
  • • Apply Vickrey Auction logic to determine the final price and winner.
  • Practice the "Pull-over-Push" security pattern for safe token refunds.

Before deploying the auction, you must create your own "currency." Use the following specification to generate your token via openzeppelin wizard: https://wizard.openzeppelin.com/

  • Name: DSAI4206Token
  • Symbol: DSAI4206Token[YourStudentID]
  • Features: Ownable , ERC20Permit .
    • Ownable: Simple mechanism with a single account authorized for all privileged actions.
    • ERC20Permit: Without paying gas, token holders will be able to allow third parties to transfer from their account.
  • Functionality: Include a mint function restricted to the onlyOwner to provide yourself with an initial balance.

Since the DSAI4206Token (ERC-20) contract is designed such that only the Owner can mint tokens, you must manually distribute funds to different accounts to simulate a realistic auction with multiple bidders.

Account Preparation

To test the Vickrey Auction properly, you will need at least three distinct accounts:
  • Account A (Owner/Deployer): The account that deploys the contracts and has the exclusive right to mint tokens.
  • Account B, C, D (Bidder 1, 2, 3): Testing accounts to act as the participants.

Token Distribution Workflow

Follow these steps to fund your bidders before the auction begins:
1. Fund the Bidders: Use the Owner account (Account A) to mint an initial supply.

Then, use the standard ERC-20 transfer() function to distribute tokens to at least two other testing accounts (Account B and Account C).

2. Verify Setup: Before starting the auction, use balanceOf()to confirm that your testing accounts actually hold the tokens they need to bid.

Deliverable 1: Document the token distribution workflow in the report.

Capture the successful transaction logs (from the console or block explorer) showing the

Owner distributing tokens to separate bidder addresses.

A screenshot of the balanceOf() results for at least two different bidder accounts before the auction starts.

3. Auction Rules & Logic
Phase 1: Bidding (Commit)
  • Deposit: Every bidder must pay a mandatory deposit of 5,000 tokens (18 decimals) to enter. (i.e. 1 token = 1 × 10!")
  • Blinded Bid: Submit a bytes32 hash of your (Amount + Secret Salt) . This keeps your bid private from other bidders.
Phase 2: Revealing
  • Verification: Bidders provide their Amount and Secret . The contract re-hashes them to verify the original commitment.
  • Vickrey Logic:
    • Contested: If multiple bidders (more than one bidder), the winner pays the Second-Highest Bid.
    • Solo: If only 1 bidder, the winner pays their Highest Bid.
  • Reserve Price: Initialized to 5,000 tokens.
Phase 3: Settlement


  • Winner Payment: The 5,000 deposit is applied to the final price. If the final price exceeds the 5,000 deposit, the winner must approve the auction contract for the difference before ending the auction.
  • Refunds: Losing bidders must pull their 5,000 deposit back using a withdrawRefund() function.


4. Technical Requirements
PVRM Character Validation (Constructor)
The auctioned mark (e.g., "HK 888") must be validated:
  • Length: 1 to 8 characters.
  • Prohibited: Letters "I", "O", and "Q" are strictly banned.
  • Characters: Only A-Z (uppercase) and 0-9 are allowed.
Contract Interface: Your contract must interact with an external Mock ERC-20 Token using the IERC20 interface.
5. Implementation Tasks
  • IERC20 Interface: Link the auction to your DSAI4206Token address.
  • State Machine: Use an enum for Bidding , Revealing , and Finished stages.
  • Hashing Helper: Include a pure function to generate the blindedBid hash.
  • Security: Use the Check-Effect-Interaction pattern for all token transfers.
Functions to implement:

1. constructor(address _tokenAddress, string memory _mark, uint256_biddingDuration, uint256 _revealDuration) : Initialize the durations, set the reserve prices to 5,000, and implement the PVRM string validation loop.

2. currentStage() : Create a helper to return the current phase ( Bidding , Revealing , or Finished ) based on block.timestamp .

3. commitBid(bytes32 _blindedBid) : Pull the 5,000 token deposit and store the blindedBid .

4. revealBid(uint256 _amount, bytes32 _secret) : Verify the hash and update highestBidder and secondHighestBidder state variables.

5. endAuction() : Finalize the winner's payment. Ensure you handle the case where the winner owes more than the initial deposit.

6. withdrawRefund() : Implement a safe way for losing bidders to pull their deposits back.

7. generateBlindedBid( uint256 amount, uint256 userSeed ) : Provide a pure helper function to assist in generating hashes for testing. This function should return a pair consisting of the hashedBlindBid and the hashedSecret

Emit Event Logs
    • commitBid() : Must emit a log confirming the bid hash is stored.
    • revealBid() : Must emit a log confirming the bid value is validated and updated.
    • endAuction() : Must emit a log confirming the winner is finalized and the auction is closed.
6. Delivarables
Deliverable 1: Token Distribution Workflow.

Capture the successful transaction logs (from the console or block explorer) showing the

Owner distributing tokens to separate bidder addresses.

A screenshot of the balanceOf() results for at least two different bidder accounts before the auction starts.

Deliverable 2: Logical Flow Diagram

You must provide a high-level flow diagram (e.g., draw.io, Mermaid.js or hand-drawn) illustrating the interaction between the User, the Token Contract, and the Auction
Contract. Your diagram should clearly show:
1. Approval Flow: When the user must interact with the Token contract directly.
2. State Transitions: How the currentStage changes based on time.
3. The "Pull" Mechanism: How losing bidders retrieve their tokens
Deliverable 3: Testing Scenarios Report
Provide a comprehensive report documenting the outcome of the following three scenariosusing Remix IDE:

Scenario
Description
Expected Outcome
A: Invalid PVRM
Deploy with a mark containing "I", "O", "Q" or > 8 chars.
Constructor Revert: Deployment must fail.
B: Solo Bidder
Only one user reveals a bid of 10,000 tokens.
Winner Pays High: Final price is 10,000.
C: Competitive
 Bidder 1 (15k), Bidder 2 (12k), Bidder 3 (8k).
Vickrey: Bidder 1 wins, pays 12,000.

Report Requirements:

• Screenshots of the Console Output for each transaction.

• Proof of the Final Token Balances of the Winner and the Auction Contract after endAuction() .

6. Submission Guidelines (Deadline: 18 Mar 23:55, Week 9)
1. Code: Submit the .sol files for both contracts (DSAI4206Token and PVRMAuction).

2. Report that include both deliverable 1 2, and 3.


7. PVRMAuctionContract Framework:


// SPDX-License-Identifier: MIT

pragma solidity ^0.8.27;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
contract PVRMAuction {
//Define the enum for Bidding, Revealing, and Finished stages
struct Bid {
bytes32 blindedBid; // The hash (Amount + Secret)
uint256 deposit; // 5000 tokens sent during Commit
bool revealed;
}
IERC20 public auctionToken; // Your DSAI4206 Token address
// Declare your own variables:
mapping(address => Bid) public bids;
// Define your functions (Function 1 – 7)
// Kindly stick to the provided function name and parameters,
// but you will have to formulate the function header by yourself.
// E.g. which modifier(s) to use for each function
}