By using the relayCalls function, a malicious user can call the processCalls function with the same parameters more than once without increasing the nonce value.
This can be exploited by the attacker to execute the same calls multiple times.
Proof of Concept
There is a potential reentrancy vulnerability in the processCalls function.
The function calls the inbox.createRetryableTicket function, which is a payable function,
and it passes the msg.sender address as one of the parameters.
This allows an attacker to call processCalls with a malicious contract address and then call the inbox.createRetryableTicket function to reenter the processCalls function.
Tools Used
Slither, Echidna, MythX
Recommended Mitigation Steps
To fix this bug, we can add a require(msg.sender == user) or
require(!msg.sender.call.value(0)()) statement at the beginning of the processCalls function.
Lines of code
https://github.com/pooltogether/ERC5164/blob/5647bd84f2a6d1a37f41394874d567e45a97bf48/src/ethereum-arbitrum/EthereumToArbitrumRelayer.sol#L101-L132
Vulnerability details
Impact
By using the
relayCalls
function, a malicious user can call theprocessCalls
function with the same parameters more than once without increasing thenonce
value. This can be exploited by the attacker to execute the same calls multiple times.Proof of Concept
There is a potential reentrancy vulnerability in the
processCalls
function.inbox.createRetryableTicket
function, which is a payable function,msg.sender
address as one of the parameters.processCalls
with a malicious contract address and then call theinbox.createRetryableTicket
function to reenter theprocessCalls
function.Tools Used
Slither, Echidna, MythX
Recommended Mitigation Steps
require(msg.sender == user)
orrequire(!msg.sender.call.value(0)())
statement at the beginning of theprocessCalls
function.