F-2023-0002·reentrancy

Reentrancy on meta TXs execution can lead to loss of funds

TL;DR

executeMetaTransaction performs address(this).call without a reentrancy guard, letting a malicious target re-enter the function and manipulate nonce state or value transfers.

Severity
HIGH
Impact
HIGH
Likelihood
MEDIUM
Method
MManual review
CAT.
Complexity
MEDIUM
Exploitability
HIGH
02Section · Description

Description

The executeMetaTransaction function of the NativeMetaTransaction contract is at risk of reentrancy attacks due to its design. During the execution of this function, external calls are made without the implementation of safeguards, like the reentrancy guard.

Specifically, the code uses the address(this).call method without the necessary precautions to prevent reentrancy. Attackers could exploit this vulnerability by initiating a recursive call back into the function, manipulating the contract's state (like nonces), and leading to unexpected behavior or even loss of funds.

03Section · Impact

Impact

  • Unauthorized Actions: A reentrancy attack might allow malicious actors to perform unauthorized actions within the contract, leading to unexpected behavior of the executeMetaTransaction function.
  • State Manipulation: An attacker can manipulate the contract's state, including the nonces mapping, facilitating subsequent attacks, including replay attacks.
  • Loss of Funds: Successful reentrancy attacks may lead to the loss of funds held within the contract if the function is dealing with value transfers, affecting both users and the contract owner negatively.

The attacker contract would look something like this:

solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract AttackerReentrant {
address payable target;
bytes functionSignature;
constructor(address payable _target, bytes memory _functionSignature) {
target = _target;
functionSignature = _functionSignature;
}
fallback() external payable {
if (address(target).balance > 0) {
// Call the vulnerable function again (reentrancy)
(bool success, ) = target.call(functionSignature);
require(success, "Reentrant call failed");
}
}
receive() external payable {}
// Function to initiate the attack
function attack() external payable {
(bool success, ) = target.call{value: msg.value}(functionSignature);
require(success, "Initial call failed");
}
}
04Section · Recommendation

Recommendation

Reentrancy Guard: Implement a reentrancy guard modifier to secure the function against reentrancy attacks. The reentrancy guard ensures that a function cannot be re-entered during its execution.

Considering the reentrancy guard is already present, it would require adding the nonReentrant modifier to the function.

F-2023-0002

oog
zealynx

Smart Contract Security Digest

Monthly exploit breakdowns, audit checklists, and DeFi security research — straight to your inbox

© 2026 Zealynx