feat(order): add price snapshot and restaurant-scoped validation to place_order()#298
Merged
Leothosine merged 2 commits intoJun 26, 2026
Conversation
…lace_order() - Add MenuItem struct: on-chain authoritative menu item registry keyed by (restaurant_id, menu_item_id) - Add MenuItemSnapshot struct: immutable price record captured at order time - Add DataKey::MenuItem(u64, u64) storage key - Add register_menu_item(), remove_menu_item(), get_menu_item() admin functions - Update OrderItem to include snapshot field with price_at_order - Rewrite place_order() to: - Validate each menu_item_id belongs to the restaurant_id via on-chain registry - Panic with 'item not on menu' if validation fails - Ignore caller-supplied unit_price; always use authoritative registry price - Capture MenuItemSnapshot for each item in persistent storage - Add 9 unit tests (all passing): - Caller-supplied unit_price is ignored; registry price is used - price_at_order snapshot is stored correctly - Item from wrong restaurant panics with 'item not on menu' - Unregistered item panics with 'item not on menu' - All existing lifecycle tests updated to register menu items first Closes tosirano#287
5 tasks
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Summary
Fixes the price manipulation and cross-restaurant pollution vulnerabilities in
place_order()by introducing an on-chain menu item registry and capturing an immutable price snapshot at order time.Problem
place_order()accepted caller-suppliedunit_pricevalues with no on-chain validation, enabling:menu_item_idfrom a different restaurantImplementation
New types:
MenuItem— on-chain authoritative menu item keyed by(restaurant_id, menu_item_id)MenuItemSnapshot— immutable price record captured at order time (menu_item_id,name,price_at_order)OrderItem.snapshot— embedded snapshot on each stored line itemNew storage key:
DataKey::MenuItem(restaurant_id, menu_item_id)New admin functions:
register_menu_item()— register/update an item's authoritative priceremove_menu_item()— remove an item from a restaurant's menuget_menu_item()— view a registered itemUpdated
place_order():menu_item_idbelongs to the givenrestaurant_idvia on-chain registry; panics with"item not on menu"if not foundunit_price; always uses the registry priceMenuItemSnapshot(name +price_at_order) on everyOrderItemValidation
All 9 tests pass (0 failures):
price_at_order"item not on menu""item not on menu"place_order+get_order(existing)advance_statuslifecycle (existing)get_restaurant_orders(existing)Closes #287