import "./interfaces/IERC20.sol";
import "./interfaces/IERC3156FlashBorrower.sol";
import "./interfaces/IERC3156FlashLender.sol";
contract FlashBorrower is IERC3156FlashBorrower {
enum Action {NORMAL, OTHER}
IERC3156FlashLender lender;
IERC3156FlashLender lender_
/// @dev ERC-3156 Flash loan callback
) external override returns (bytes32) {
msg.sender == address(lender),
"FlashBorrower: Untrusted lender"
initiator == address(this),
"FlashBorrower: Untrusted loan initiator"
(Action action) = abi.decode(data, (Action));
if (action == Action.NORMAL) {
require(IERC20(token).balanceOf(address(this)) >= amount);
// make a profitable trade here
IERC20(token).transfer(initiator, amount + fee);
} else if (action == Action.OTHER) {
return keccak256("ERC3156FlashBorrower.onFlashLoan");
/// @dev Initiate a flash loan
bytes memory data = abi.encode(Action.NORMAL);
uint256 _allowance = IERC20(token).allowance(address(this), address(lender));
uint256 _fee = lender.flashFee(token, amount);
uint256 _repayment = amount + _fee;
IERC20(token).approve(address(lender), _allowance + _repayment);
lender.flashLoan(this, token, amount, data);