@@ -30,8 +30,8 @@ pub mod PrizeComponent {
3030 use crate :: prize :: prize_store :: {PrizeStoreImpl , PrizeStoreTrait };
3131 use crate :: prize :: store :: Store ;
3232 use crate :: prize :: structs :: {
33- CustomShares , ERC20Data , ExtensionPrize , Prize , PrizeType , StoredPrize , TokenPrize ,
34- TokenTypeData ,
33+ CustomShares , ERC20Data , ExtensionPrizePayload , Prize , PrizeRecord , PrizeType , StoredPrize ,
34+ TokenPrizePayload , TokenTypeData ,
3535 };
3636
3737 #[storage]
@@ -62,6 +62,10 @@ pub mod PrizeComponent {
6262 /// prizes have their context_id stored in `StoredPrize.context_id`
6363 /// and are absent from this map.
6464 Prize_extension_prize_context : Map <u64 , u64 >,
65+ /// `prize_id -> sponsor_address` for extension prizes (the
66+ /// caller of `add_prize` at registration). Built-in prizes
67+ /// keep sponsor on `StoredPrize.sponsor_address`.
68+ Prize_extension_prize_sponsor : Map <u64 , ContractAddress >,
6569 }
6670
6771 #[event]
@@ -148,6 +152,18 @@ pub mod PrizeComponent {
148152 ) {
149153 self . Prize_extension_prize_context . entry (prize_id ). write (context_id );
150154 }
155+
156+ fn get_extension_prize_sponsor (
157+ self : @ ComponentState <TContractState >, prize_id : u64 ,
158+ ) -> ContractAddress {
159+ self . Prize_extension_prize_sponsor . entry (prize_id ). read ()
160+ }
161+
162+ fn set_extension_prize_sponsor (
163+ ref self : ComponentState <TContractState >, prize_id : u64 , sponsor : ContractAddress ,
164+ ) {
165+ self . Prize_extension_prize_sponsor . entry (prize_id ). write (sponsor );
166+ }
151167 }
152168
153169 /// Resolve a `prize_id` to its full `Prize` sum-type view.
@@ -161,27 +177,31 @@ pub mod PrizeComponent {
161177 /// `PrizeStoreTrait::get_token_prize` store-bridge path.
162178 fn resolve_prize <TContractState , + HasComponent <TContractState >>(
163179 self : @ ComponentState <TContractState >, prize_id : u64 ,
164- ) -> Prize {
180+ ) -> PrizeRecord {
165181 let context_id = Store :: get_extension_prize_context (self , prize_id );
166182 if context_id == 0 {
167- return Prize :: Token ( PrizeStoreTrait :: get_token_prize (self , prize_id ) );
183+ return PrizeStoreTrait :: get_token_record (self , prize_id );
168184 }
169185 let extension_address = Store :: get_extension_address (self , context_id , prize_id );
186+ let sponsor_address = Store :: get_extension_prize_sponsor (self , prize_id );
170187 let context_owner = get_contract_address ();
171188 let dispatcher = IPrizeExtensionDispatcher { contract_address : extension_address };
172189 let extension_config = dispatcher . get_config (context_owner , context_id , prize_id );
173- Prize :: Extension (
174- ExtensionPrize {
175- id : prize_id , context_id , address : extension_address , config : extension_config ,
176- },
177- )
190+ PrizeRecord {
191+ id : prize_id ,
192+ context_id ,
193+ sponsor_address ,
194+ prize : Prize :: Extension (
195+ ExtensionPrizePayload { address : extension_address , config : extension_config },
196+ ),
197+ }
178198 }
179199
180200 #[embeddable_as(PrizeImpl )]
181201 impl PrizeComponentImpl <
182202 TContractState , + HasComponent <TContractState >,
183203 > of IPrize <ComponentState <TContractState >> {
184- fn get_prize (self : @ ComponentState <TContractState >, prize_id : u64 ) -> Prize {
204+ fn get_prize (self : @ ComponentState <TContractState >, prize_id : u64 ) -> PrizeRecord {
185205 resolve_prize (self , prize_id )
186206 }
187207
@@ -218,7 +238,7 @@ pub mod PrizeComponent {
218238 /// Note: extension prizes incur a cross-contract call on every
219239 /// read. Callers wanting bulk reads should batch / cache
220240 /// accordingly.
221- fn _get_prize (self : @ ComponentState <TContractState >, prize_id : u64 ) -> Prize {
241+ fn _get_prize (self : @ ComponentState <TContractState >, prize_id : u64 ) -> PrizeRecord {
222242 resolve_prize (self , prize_id )
223243 }
224244
@@ -228,12 +248,18 @@ pub mod PrizeComponent {
228248 PrizeStoreTrait :: get_custom_shares (self , prize_id )
229249 }
230250
231- /// Store a token prize (converts to StoredPrize for storage).
251+ /// Store a token- prize record (converts to StoredPrize for storage).
232252 /// Extension prizes are not persisted via this path.
233- fn set_token_prize (
234- ref self : ComponentState <TContractState >, prize_id : u64 , prize : TokenPrize ,
253+ fn set_token_record (
254+ ref self : ComponentState <TContractState >,
255+ prize_id : u64 ,
256+ context_id : u64 ,
257+ sponsor_address : ContractAddress ,
258+ payload : TokenPrizePayload ,
235259 ) {
236- PrizeStoreTrait :: set_token_prize (ref self , prize_id , prize );
260+ PrizeStoreTrait :: set_token_record (
261+ ref self , prize_id , context_id , sponsor_address , payload ,
262+ );
237263 }
238264
239265 /// Get total prizes count (internal)
@@ -302,20 +328,19 @@ pub mod PrizeComponent {
302328
303329 /// Add a prize or set extension for a context.
304330 /// Returns the prize_id in both cases.
305- /// - `Prize::Token` : deposits tokens, stores prize data. Host-
306- /// assigned fields on the input variant (`id`, `context_id`,
307- /// `sponsor_address`) are ignored — the host overwrites them.
308- /// - `Prize::Extension` : increments prize count, registers the
309- /// extension address keyed by `(context_id, prize_id)`, and
310- /// dispatches `IPrizeExtension.add_prize(...)`. Input host
311- /// fields (`id`, `context_id`) are likewise ignored.
331+ /// - `Prize::Token(payload)`: deposits tokens, stores prize
332+ /// data. Host assigns id/context_id/sponsor_address.
333+ /// - `Prize::Extension(payload)`: increments prize count,
334+ /// registers the extension address keyed by
335+ /// `(context_id, prize_id)`, captures sponsor, and
336+ /// dispatches `IPrizeExtension.add_prize(...)`.
312337 fn add_prize (
313338 ref self : ComponentState <TContractState >, context_id : u64 , prize : Prize ,
314339 ) -> u64 {
315340 match prize {
316- Prize :: Token (input ) => self . _add_token_prize (context_id , input ),
317- Prize :: Extension (input ) => {
318- let ext = ExtensionConfig { address : input . address, config : input . config };
341+ Prize :: Token (payload ) => self . _add_token_prize (context_id , payload ),
342+ Prize :: Extension (payload ) => {
343+ let ext = ExtensionConfig { address : payload . address, config : payload . config };
319344 assert! (! ext . address. is_zero (), " Prize: Extension address cannot be zero" );
320345 let src5 = ISRC5Dispatcher { contract_address : ext . address };
321346 let display_address : felt252 = ext . address. into ();
@@ -332,15 +357,14 @@ pub mod PrizeComponent {
332357 }
333358
334359 /// Internal: deposit tokens, store prize data, return prize_id.
335- /// `input` is a `TokenPrize` whose host-assigned fields (id,
336- /// context_id, sponsor_address) are ignored — the host
337- /// overwrites them with the assigned id, the caller-supplied
338- /// `context_id` parameter, and `get_caller_address()`.
360+ /// Host fills in the id (assigned), context_id (caller-supplied),
361+ /// and sponsor_address (`get_caller_address()`) around the
362+ /// supplied `payload`.
339363 fn _add_token_prize (
340- ref self : ComponentState <TContractState >, context_id : u64 , input : TokenPrize ,
364+ ref self : ComponentState <TContractState >, context_id : u64 , payload : TokenPrizePayload ,
341365 ) -> u64 {
342- let token_address = input . token_address;
343- let token_type = input . token_type;
366+ let token_address = payload . token_address;
367+ let token_type = payload . token_type;
344368
345369 // Deposit the prize tokens
346370 match @ token_type {
@@ -379,14 +403,11 @@ pub mod PrizeComponent {
379403 }
380404 }
381405
382- // Persist the built-in token prize. Host-assigned fields
383- // (id, context_id, sponsor_address) overwrite whatever the
384- // caller passed in `input`.
406+ // Persist the built-in token prize. Host fills id,
407+ // context_id, sponsor_address around the supplied payload.
385408 let sponsor = get_caller_address ();
386- let prize = TokenPrize {
387- id , context_id , sponsor_address : sponsor , token_address , token_type ,
388- };
389- PrizeStoreTrait :: set_token_prize (ref self , id , prize );
409+ let payload = TokenPrizePayload { token_address , token_type };
410+ PrizeStoreTrait :: set_token_record (ref self , id , context_id , sponsor , payload );
390411
391412 id
392413 }
@@ -405,6 +426,8 @@ pub mod PrizeComponent {
405426 Store :: set_extension_address (ref self , context_id , prize_id , ext . address);
406427 // Reverse index for the prize_id-only `get_prize` lookup.
407428 Store :: set_extension_prize_context (ref self , prize_id , context_id );
429+ // Capture sponsor (the caller of the host's `add_prize`).
430+ Store :: set_extension_prize_sponsor (ref self , prize_id , get_caller_address ());
408431
409432 let dispatcher = IPrizeExtensionDispatcher { contract_address : ext . address };
410433 dispatcher . add_prize (context_id , prize_id , ext . config);
@@ -457,10 +480,14 @@ pub mod PrizeComponent {
457480 fn refund_prize_erc20 (
458481 ref self : ComponentState <TContractState >, prize_id : u64 , amount : u128 ,
459482 ) {
460- let prize = PrizeStoreTrait :: get_token_prize (@ self , prize_id );
461- let erc20 = IERC20Dispatcher { contract_address : prize . token_address };
483+ let record = PrizeStoreTrait :: get_token_record (@ self , prize_id );
484+ let token_address = match record . prize {
485+ Prize :: Token (payload ) => payload . token_address,
486+ Prize :: Extension (_ ) => panic! (" Prize: extension prize cannot be refunded as ERC20" ),
487+ };
488+ let erc20 = IERC20Dispatcher { contract_address : token_address };
462489 assert! (
463- erc20 . transfer (prize . sponsor_address, amount . into ()),
490+ erc20 . transfer (record . sponsor_address, amount . into ()),
464491 " Prize: ERC20 refund transfer failed" ,
465492 );
466493 }
@@ -469,9 +496,15 @@ pub mod PrizeComponent {
469496 fn refund_prize_erc721 (
470497 ref self : ComponentState <TContractState >, prize_id : u64 , token_id : u128 ,
471498 ) {
472- let prize = PrizeStoreTrait :: get_token_prize (@ self , prize_id );
473- let erc721 = IERC721Dispatcher { contract_address : prize . token_address };
474- erc721 . transfer_from (get_contract_address (), prize . sponsor_address, token_id . into ());
499+ let record = PrizeStoreTrait :: get_token_record (@ self , prize_id );
500+ let token_address = match record . prize {
501+ Prize :: Token (payload ) => payload . token_address,
502+ Prize :: Extension (_ ) => panic! (
503+ " Prize: extension prize cannot be refunded as ERC721" ,
504+ ),
505+ };
506+ let erc721 = IERC721Dispatcher { contract_address : token_address };
507+ erc721 . transfer_from (get_contract_address (), record . sponsor_address, token_id . into ());
475508 }
476509
477510 // --- Extension helpers ---
0 commit comments