@@ -136,24 +136,28 @@ pub contract ContractInstanceRegistry {
136136 context .assert_nullifier_exists (nullifier_existence_request );
137137
138138 // Determine the deployer based on universal_deploy flag
139- let deployer : AztecAddress = if universal_deploy {
139+ let deployer = if universal_deploy {
140140 AztecAddress ::zero ()
141141 } else {
142142 context .maybe_msg_sender ().unwrap ()
143143 };
144144
145- // Compute the contract address
146- let partial_address : PartialAddress =
145+ let partial_address =
147146 PartialAddress ::compute (contract_class_id , salt , initialization_hash , deployer );
148147
149- // Validate public keys are on curve
148+ // Note: Out of all the public keys, only the Ivpk_m is checked to be on the curve
149+ // (implicitly as part of the `add` operation of deriving the address). This at least
150+ // protects the AVM against DoS attacks.
151+ // For thoroughness, we also ensure the other points are on the curve:
150152 validate_on_curve (public_keys .npk_m .inner );
151153 validate_on_curve (public_keys .ovpk_m .inner );
152154 validate_on_curve (public_keys .tpk_m .inner );
153155
154- let address : AztecAddress = AztecAddress ::compute (public_keys , partial_address );
156+ let address = AztecAddress ::compute (public_keys , partial_address );
155157
156- // Push nullifier to mark the contract as deployed
158+ // Emit the address as a nullifier:
159+ // - to demonstrate that this contract instance hasn't been published before
160+ // - to enable apps to read that this contract instance has been published.
157161 context .push_nullifier (address .to_field ());
158162
159163 // Emit the deployment event
@@ -167,24 +171,20 @@ pub contract ContractInstanceRegistry {
167171 deployer ,
168172 version : 1 ,
169173 };
170- let payload : [ Field ; 15 ] = event .serialize_non_standard ();
174+ let payload = event .serialize_non_standard ();
171175 debug_log_format ("ContractInstancePublished: {}" , payload );
172- let padded_log : [ Field ; 18 ] = payload .concat ([0 ; 3 ]);
173- let length : u32 = payload .len ();
176+ let padded_log = payload .concat ([0 ; 3 ]);
177+ let length = payload .len ();
174178 context .emit_private_log (padded_log , length );
175179
176180 // MACRO CODE START
177181 context .finish ()
178182 // MACRO CODE END
179183 }
180184
181- /**
182- * Updates the contract class ID for the caller's deployed contract instance.
183- *
184- * @param new_contract_class_id The new contract class ID to update to
185- */
186185 #[aztec::macros::internals_functions_generation::abi_attributes::abi_public]
187186 unconstrained fn update (new_contract_class_id : ContractClassId ) {
187+ // MACRO CODE START
188188 let context : PublicContext = PublicContext ::new (
189189 || -> Field {
190190 let serialized_args : [Field ; 1 ] =
@@ -193,16 +193,19 @@ pub contract ContractInstanceRegistry {
193193 },
194194 );
195195 let storage : Storage <PublicContext > = Storage ::init (context );
196+ // MACRO CODE END
196197
197- let address : AztecAddress = avm:: sender ();
198+ let address = msg_sender (). unwrap ();
198199
199- // Verify that the caller (msg.sender) is a deployed contract
200+ // Safety: we're using the nullifier's existence as a guarantee of the availability of the contract's
201+ // information through publishing, which is safe - we just need this information to be _eventually_ available.
200202 assert (
201203 context .nullifier_exists_unsafe (address .to_field (), context .this_address ()),
202204 "msg.sender is not deployed" ,
203205 );
204206
205- // Verify that the new contract class is registered
207+ // Safety: we're using the nullifier's existence as a guarantee of the availability of the new contract class'
208+ // information through registration, which is safe - we just need this information to be _eventually_ available.
206209 assert (
207210 context .nullifier_exists_unsafe (
208211 new_contract_class_id .to_field (),
@@ -211,14 +214,12 @@ pub contract ContractInstanceRegistry {
211214 "New contract class is not registered" ,
212215 );
213216
214- // Schedule the contract class update
215217 let scheduled_value_update = storage
216218 .updated_class_ids
217219 .at (address )
218220 .schedule_and_return_value_change (new_contract_class_id );
219221 let (prev_contract_class_id , timestamp_of_change ) = scheduled_value_update .get_previous ();
220222
221- // Emit the update event
222223 let event = ContractInstanceUpdated {
223224 CONTRACT_INSTANCE_UPDATED_MAGIC_VALUE ,
224225 address ,
@@ -229,33 +230,29 @@ pub contract ContractInstanceRegistry {
229230 context .emit_public_log (event );
230231 }
231232
232- /**
233- * Sets a new update delay for the caller's contract instance.
234- *
235- * @param new_update_delay The new delay value (must be >= MINIMUM_UPDATE_DELAY)
236- */
237233 #[aztec::macros::internals_functions_generation::abi_attributes::abi_public]
238234 unconstrained fn set_update_delay (new_update_delay : u64 ) {
235+ // MACRO CODE START
239236 let context : PublicContext = PublicContext ::new (
240237 || -> Field {
241238 let serialized_args : [Field ; 1 ] = avm:: calldata_copy (1 , <u64 as Serialize >::N );
242239 hash_args (serialized_args )
243240 },
244241 );
245242 let storage : Storage <PublicContext > = Storage ::init (context );
243+ // MACRO CODE END
246244
247- let msg_sender : AztecAddress = avm:: sender ();
245+ let msg_sender = context . maybe_msg_sender (). unwrap ();
248246
249- // Verify that the caller (msg.sender) is a deployed contract
247+ // Safety: we're using the nullifier's existence as a guarantee of the availability of the contract's
248+ // information through publishing, which is safe - we just need this information to be _eventually_ available.
250249 assert (
251250 context .nullifier_exists_unsafe (msg_sender .to_field (), context .this_address ()),
252251 "msg.sender is not deployed" ,
253252 );
254253
255- // Verify the new delay meets the minimum requirement
256254 assert (new_update_delay >= MINIMUM_UPDATE_DELAY , "New update delay is too low" );
257255
258- // Schedule the delay change
259256 storage .updated_class_ids .at (msg_sender ).schedule_delay_change (new_update_delay );
260257 }
261258
@@ -265,16 +262,18 @@ pub contract ContractInstanceRegistry {
265262 * @return The current update delay value
266263 */
267264 #[aztec::macros::internals_functions_generation::abi_attributes::abi_public]
265+ #[aztec::macros::internals_functions_generation::abi_attributes::abi_view]
268266 unconstrained fn get_update_delay () -> pub u64 {
267+ // MACRO CODE START
269268 let context : PublicContext = PublicContext ::new (
270269 || -> Field {
271270 let serialized_args : [Field ; 0 ] = avm:: calldata_copy (1 , 0 );
272271 hash_args (serialized_args )
273272 },
274273 );
275274 let storage : Storage <PublicContext > = Storage ::init (context );
276-
277275 assert (context .is_static_call (), "Function get_update_delay can only be called statically" );
276+ // MACRO CODE END
278277
279278 storage .updated_class_ids .at (avm:: sender ()).get_current_delay ()
280279 }
0 commit comments