Skip to main content

forge_lint/sol/low/
delegatecall_loop.rs

1use 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}