forge_lint/sol/low/
delegatecall_loop.rs1use super::{DelegatecallLoop, payable_loop::for_each_payable_loop_expr};
2use crate::{
3 linter::{LateLintPass, LintContext},
4 sol::{Severity, SolLint},
5};
6use solar::sema::{
7 Gcx,
8 builtins::Builtin,
9 hir::{ExprKind, Function},
10};
11
12declare_forge_lint!(
13 DELEGATECALL_LOOP,
14 Severity::Low,
15 "delegatecall-loop",
16 "payable function uses `delegatecall` inside a loop"
17);
18
19impl<'gcx> LateLintPass<'gcx> for DelegatecallLoop {
20 fn check_function(&mut self, ctx: &LintContext, gcx: Gcx<'gcx>, func: &'gcx Function<'gcx>) {
21 for_each_payable_loop_expr(gcx, func, |expr| {
22 if let ExprKind::Call(callee, ..) = &expr.kind
23 && gcx.resolved_builtin(callee) == Some(Builtin::AddressDelegatecall)
24 {
25 ctx.emit(&DELEGATECALL_LOOP, expr.span);
26 }
27 });
28 }
29}