DSAI4206 Individual Assignment: Specialized Vehicle Registration Mark (SVRM) Auction
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:
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
- 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
Then, use the standard ERC-20 transfer() function to distribute tokens to at least two other testing accounts (Account B and Account C).
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.
- 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.
- 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.
- 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.
- Length: 1 to 8 characters.
- Prohibited: Letters "I", "O", and "Q" are strictly banned.
- Characters: Only A-Z (uppercase) and 0-9 are allowed.
- 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.
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
- 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.
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
|
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.
|
• Screenshots of the Console Output for each transaction.
• Proof of the Final Token Balances of the Winner and the Auction Contract after endAuction() .
2. Report that include both deliverable 1 2, and 3.
// SPDX-License-Identifier: MIT
//Define the enum for Bidding, Revealing, and Finished stagesstruct Bid {
bytes32 blindedBid; // The hash (Amount + Secret)uint256 deposit; // 5000 tokens sent during Commitbool 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
2026-03-16