Admins can steal funds by self-sandwiching swaps
Description
Admins are authorized to run the day-to-day operations of the contract, such as initiating Lido withdrawals and completing EigenLayer withdrawals. However, they are not authorized to do things like withdraw funds from the contract to themselves or upgrade the contracts.
One thing admins are allowed to do is use predefined Curve pools to swap cbETH and wbETH into ETH:
function swapCbEthToEth(uint256 _amount, uint256 _minOutputAmount) external onlyAdmin returns (uint256) {
cbEth.approve(address(cbEth_Eth_Pool), _amount);
return cbEth_Eth_Pool.exchange_underlying(1, 0, _amount, _minOutputAmount);
}
function swapWbEthToEth(uint256 _amount, uint256 _minOutputAmount) external onlyAdmin returns (uint256) {
wbEth.approve(address(wbEth_Eth_Pool), _amount);
return wbEth_Eth_Pool.exchange(1, 0, _amount, _minOutputAmount);
}
Note how the minimum output amount is controlled entirely by the admin calling these functions.
Impact
An admin wishing to steal funds can conduct a sandwich attack on the protocol's swap easily and safely, and move value from cbETH/wbETH into their own pockets during this swap. If the admin is a smart contract, then it may even be possible to do the sandwiching with a flash loan, which would make this attack require no startup funds / off-chain loans.
Recommendations
Have a lower bound on the minimum output amount such that the protocol does not lose money. Alternatively, make the swap functions owner-only.
Remediation
Gadze Finance SEZC will ensure that admins do not conduct sandwich attacks by requiring that they submit swap requests through an oracle node.