TokenTrade event parameters can be incorrect
Description
During a call to swapTokenForETH
, the native transfer of ETH to the sender happens before the TokenTrade
event's parameters are fixed:
function swapTokenForETH(
uint256 _amountIn,
uint256 _amountOutMin,
address _address,
bool _isWETH
) public payable tokenExists(_address) {
// [...]
if (_isWETH) {
weth.deposit{ value: amountOutWithFee }();
_safeTransferToken(address(weth), msg.sender, amountOutWithFee);
} else {
_safeTransferETH(msg.sender, amountOutWithFee);
}
// [...]
emit TokenTrade(msg.sender, token.token, amountOut, _amountIn, false, curve.vETHReserves, curve.vTokenReserves, block.timestamp);
}
This means that if the sender reenters the contract during the _safeTransferETH
, they can submit another swap, which modifies the curve
storage variable.
Impact
In the emitted TokenTrade event, the curve.vETHReserves
and curve.vTokenReserves
may not accurately reflect the reserves after the trade that caused the event to be emitted, if a user reenters the contract to do a second trade.
This breaks invariants for off-chain code that monitors those events.
Recommendations
We recommend emitting the event before the reentrancy site, following the standard checks-effects-interactions pattern.
Remediation
This issue has been acknowledged by PondFun, and a fix was implemented in commit 8d50446f↗.