Skip to content

perf: modifyRailPayment and modifyRailLockup don't need to be nonreentrant #291

Description

@wjmelements

The only external call they do is FVM.burn (via calculateAndPayFees), which cannot lead to reentrancy.

Claude Sonnet 4.6 says:

  The only external call sites in the entire contract are:
  - FVMPay.burn (lines 1089, 1783)
  - FVMPay.pay (line 778)
  - token.safeTransfer (line 794)
  - token.safeTransferFrom (line 802)
  - IERC20Permit.permit (line 518)
  - IValidator.validatePayment (line 441)
  - IValidator.railTerminated (line 1434)

The functions that can reach these methods are:

  FVMPay.burn (line 1089) — via calculateAndPayFees (native token only, non-zero amount):
  - modifyRailPayment → processOneTimePayment → calculateAndPayFees
  - settleRail → settleRailInternal → calculateAndPayFees
  - settleTerminatedRailWithoutValidation → settleRailInternal → calculateAndPayFees

  ---
  FVMPay.burn (line 1783) — directly in burnForFees:
  - burnForFees

  ---
  FVMPay.pay (line 778) — via withdrawToInternal (native token only):
  - withdraw → withdrawToInternal
  - withdrawTo → withdrawToInternal

  ---
  token.safeTransfer (line 794) — via transferOut (ERC-20 only):
  - withdraw → withdrawToInternal → transferOut
  - withdrawTo → withdrawToInternal → transferOut
  - burnForFees

  ---
  token.safeTransferFrom (line 802) — via transferIn (ERC-20 only):
  - deposit → transferIn
  - depositWithPermit → _depositWithPermit → transferIn
  - depositWithPermitAndApproveOperator → _depositWithPermit → transferIn
  - depositWithPermitAndIncreaseOperatorApproval → _depositWithPermit → transferIn

  ---
  IERC20Permit.permit (line 518) — via _depositWithPermit:
  - depositWithPermit → _depositWithPermit
  - depositWithPermitAndApproveOperator → _depositWithPermit
  - depositWithPermitAndIncreaseOperatorApproval → _depositWithPermit

  ---
  IValidator.validatePayment (line 1434)
  - settleRail

  ---
  IValidator.railTerminated (line 441)
  - terminateRail

This analysis excluded staticcall like balanceOf, which are also not a reentrancy risk.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    Status
    🐱 Todo

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions