@@ -148,12 +148,15 @@ pub type Executive = domain_pallet_executive::Executive<
148
148
AllPalletsWithSystem ,
149
149
> ;
150
150
151
+ const MAX_CONTRACT_RECURSION_DEPTH : u16 = 5 ;
152
+
151
153
/// Rejects contracts that can't be created under the current allow list.
152
154
/// Returns false if the call is a contract call, and the account is *not* allowed to call it.
153
155
/// Otherwise, returns true.
154
156
pub fn is_create_contract_allowed ( call : & RuntimeCall , signer : & AccountId ) -> bool {
155
- if is_create_contract ( call)
156
- && !pallet_evm_nonce_tracker:: Pallet :: < Runtime > :: is_allowed_to_create_contracts ( signer)
157
+ // Only enter recursive code if this account can't create contracts
158
+ if !pallet_evm_nonce_tracker:: Pallet :: < Runtime > :: is_allowed_to_create_contracts ( signer)
159
+ && is_create_contract ( call, MAX_CONTRACT_RECURSION_DEPTH )
157
160
{
158
161
return false ;
159
162
}
@@ -163,7 +166,14 @@ pub fn is_create_contract_allowed(call: &RuntimeCall, signer: &AccountId) -> boo
163
166
}
164
167
165
168
/// Returns true if the call is a contract creation call.
166
- pub fn is_create_contract ( call : & RuntimeCall ) -> bool {
169
+ pub fn is_create_contract ( call : & RuntimeCall , mut recursion_depth_left : u16 ) -> bool {
170
+ if recursion_depth_left == 0 {
171
+ // If the recursion depth is reached, we assume the call contains a contract.
172
+ return true ;
173
+ }
174
+
175
+ recursion_depth_left -= 1 ;
176
+
167
177
match call {
168
178
RuntimeCall :: EVM ( pallet_evm:: Call :: create { .. } )
169
179
| RuntimeCall :: EVM ( pallet_evm:: Call :: create2 { .. } ) => true ,
@@ -179,14 +189,17 @@ pub fn is_create_contract(call: &RuntimeCall) -> bool {
179
189
transaction : EthereumTransaction :: EIP1559 ( transaction) ,
180
190
..
181
191
} ) => transaction. action == TransactionAction :: Create ,
182
- // TODO: does this need a recursion limit?
183
192
RuntimeCall :: Utility ( utility_call) => match utility_call {
184
193
pallet_utility:: Call :: batch { calls }
185
194
| pallet_utility:: Call :: batch_all { calls }
186
- | pallet_utility:: Call :: force_batch { calls } => calls. iter ( ) . any ( is_create_contract) ,
195
+ | pallet_utility:: Call :: force_batch { calls } => calls
196
+ . iter ( )
197
+ . any ( |call| is_create_contract ( call, recursion_depth_left) ) ,
187
198
pallet_utility:: Call :: as_derivative { call, .. }
188
199
| pallet_utility:: Call :: dispatch_as { call, .. }
189
- | pallet_utility:: Call :: with_weight { call, .. } => is_create_contract ( call) ,
200
+ | pallet_utility:: Call :: with_weight { call, .. } => {
201
+ is_create_contract ( call, recursion_depth_left)
202
+ }
190
203
pallet_utility:: Call :: __Ignore( ..) => false ,
191
204
} ,
192
205
_ => false ,
0 commit comments