Sherlock is a blockchain auditing platform in the form of contests. They had a staking pool setup with Euler.
The function balanceOf on the EulerStrategy.sol is used to determine the current value held by the EulerStrategy. This result is then used to calculate the price per share of the user's withdrawing position.
The function balanceOf calls EUSDC.balanceOfUnderlying() underneath it. The problem with this is that the actual value being returned may be manipulated. Although the contract believes this will be an atomic call (no other paths ran), this is NOT the case.
Specifically, the totalAssets is updated prior to the call but the totalBalances is NOT updated yet. This results in computeExchangeRate() being higher than the actual value. An attacker could use this to change the price and obtain more money than anticipated.
This attack is only possible because arbitrary calls from 1inch can be made while swapping. To manipulate the pool, an attacker needs to transfer a large amount of USDC to Euler, inflating the price of computeExchangeRate. Since the price per share is higher, an attacker can redeem more USDC than they should be able to.
In the proof of concept, the author has to setup the stage for the swaps and stake money. In Foundry, it is possible to fast forward the chain to a different time in order to allow this POC to be possible. Neat! Once they have performed the swap, they setup the callback on 1inch.
With the setup done, we can make the call. The callback is hit on the withdraw. Upon hitting the callback, USDC is transferred to Euler while in the callback of 1inch. This cross-protocol reentrancy creates a manipulated exchange rate. At this point, we exit the position, collect our winnings and repay the flash loan.
To fix this vulnerability, a reentrancy lock was added in Euler. This bug was missed by Trail of Bits for Sherlock but found during an audit of Euler. However, it was only noted as a medium severity finding and never fixed as a result. Overall, an interesting article for a crazy cross protocol reentrancy. The POC is very well explained as well.