EarningFarm is a set of smart contracts that manage crypto assets. It has a native token, EF, that is used to demonstrate the amount of funds put into the protocol.
The amount of EF token is passed to the withdraw() function to determines the amount of Ether that can be withdrawn. Prior to performing the withdraw, the contract may not have the funds to perform it with the proper token. So, it may take out a flashloan from balancer in order to do this.
The amount of the flashloan and withdrawal depends on the balance of the EF token held by the user. The callback for the flashloan does a sanity check to see if it's coming from balancer or not.
A user can manually invoke the flashloan via balancer and use ENF as the recipient. This completely bypasses the withdrawal limits. This means that a large sum of ETH was believed to be OWNED by the contract. The attacker could withdraw a small sum of funds but withdraw() always sends the full amount, since the difference is extremely large.
In essence, bad input validation wins the day again. Here, the authors didn't consider that somebody else could invoke the call for receiveFlashLoan.