-
Notifications
You must be signed in to change notification settings - Fork 37
feat: add sealed bid auction example #115
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,69 @@ | ||
| # Sealed Auction | ||
|
|
||
| Private first-price sealed-bid auction using a MagicBlock private Ephemeral Rollup and SPL Token | ||
| escrow. | ||
|
|
||
| The seller escrows a fixed Token A lot in an L1 SPL token account owned by the auction PDA. Bidders | ||
| pre-fund Token B however they want, can consolidate balances on the ER, and then submit hidden, | ||
| fully collateralized Token B bids on the private ER. After the deadline, the program reads the | ||
| private bid accounts on-chain, selects the highest bid, and releases the L1 Token A lot to the | ||
| winner. Token B proceeds and loser refunds are settled on the ER from a delegated auction-owned | ||
| Token B escrow, while auction-sponsored private bid accounts are closed before the auction PDA is | ||
| undelegated. | ||
|
|
||
| ## What This Teaches | ||
|
|
||
| - Private ER permissions for hidden bid state. | ||
| - L1 SPL Token escrow for a public seller lot. | ||
| - Auction-sponsored ER-only bid PDAs plus an auction-owned delegated Token B escrow. | ||
| - Count-checked bid scanning and cleanup-gated auction undelegation. | ||
|
|
||
| ## Flow | ||
|
|
||
| 1. `initialize_auction` creates the auction, parks the seller's Token A in an auction PDA ATA, | ||
| creates the auction PDA's Token B ATA/eATA, delegates that Token B escrow to the ER, and preloads | ||
| sponsor lamports into the auction PDA. | ||
| 2. Bidders can pre-fund and consolidate Token B outside the auction using normal delegated SPL token | ||
| transfers. | ||
| 3. `delegate_auction` moves the count-only auction state to ER; auction state remains public because | ||
| it does not store bid amounts or bidder keys. | ||
| 4. `place_bid` creates an auction-sponsored `Bid` PDA and moves Token B from the bidder's ER balance | ||
| into the auction-owned Token B escrow. | ||
| 5. `init_bid_permission` immediately attaches private PER access to the created bid PDA. | ||
| 6. `end_auction` requires exactly `bid_count` unique valid bid PDAs, scans them on ER, and records | ||
| the winner without undelegating the auction. | ||
| 7. `settle_winning_bid` pays the winning Token B amount from the auction escrow to the seller on ER | ||
| and closes the winning bid account back to the auction PDA. | ||
| 8. Losing bidders run `claim_refund` on ER; refunds are paid from the auction escrow and close losing | ||
| bid accounts back to the auction PDA. | ||
| 9. `undelegate_auction` is allowed only after every accepted bid has been closed. | ||
| 10. `finalize` runs on L1 after auction undelegation and transfers Token A to the winner. | ||
|
|
||
| No-bid auctions can be undelegated immediately after `end_auction`, then use `reclaim_unsold_lot`. | ||
|
|
||
| ## Run | ||
|
|
||
| From this directory: | ||
|
|
||
| ```bash | ||
| yarn build | ||
| yarn test:local | ||
| ``` | ||
|
|
||
| `yarn test:local` runs the deterministic account-graph checks without requiring a live local stack. | ||
| Those checks assert the auction-sponsored count-only instruction surface: no separate sponsor PDA, | ||
| no bidder key array in auction state, `end_auction` stays on ER, and `undelegate_auction` remains the | ||
| only commit/undelegate step. Under the repository harness, the localnet tests also verify Token A L1 | ||
| custody and that sponsor lamports are preloaded into the auction PDA during initialization. | ||
| The full privacy and settlement walkthrough needs the standard MagicBlock local stack and QFS/TEE | ||
| endpoints from `../../scripts/local-env.sh`: | ||
|
|
||
| ```bash | ||
| yarn setup | ||
| RUN_SEALED_AUCTION_LIVE=1 yarn test:local | ||
| ``` | ||
|
|
||
| ## Out Of Scope | ||
|
|
||
| Reserve prices, Vickrey pricing, Dutch auctions, cranks, session keys, unbounded bidder sets, and a | ||
| frontend UI. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| [toolchain] | ||
| anchor_version = "1.0.2" | ||
|
|
||
| [features] | ||
| resolution = true | ||
| skip-lint = false | ||
|
|
||
| [programs.devnet] | ||
| sealed-auction = "F4vB5Ki7ZWnkht1shp2TCHG7GszLxRZ6pbizGNQecmor" | ||
|
|
||
| [programs.localnet] | ||
| sealed-auction = "F4vB5Ki7ZWnkht1shp2TCHG7GszLxRZ6pbizGNQecmor" | ||
|
|
||
| [registry] | ||
| url = "https://api.apr.dev" | ||
|
|
||
| [provider] | ||
| cluster = "devnet" | ||
| wallet = "~/.config/solana/id.json" | ||
|
|
||
| [[test.genesis]] | ||
| address = "DELeGGvXpWV2fqJUhqcF5ZSYMS4JTLjteaAMARRSaeSh" | ||
| program = "tests/fixtures/dlp.so" | ||
| upgradeable = false | ||
|
|
||
| [[test.genesis]] | ||
| address = "SPLxh1LVZzEkX99H6rqYizhytLWPZVV296zyYDPagv2" | ||
| program = "tests/fixtures/ephemeral_token_program.so" | ||
| upgradeable = false | ||
|
|
||
| [scripts] | ||
| test = "yarn run ts-mocha -p ./tsconfig.json -t 1000000 tests/sealed-auction.ts" | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.