Flash loans enable borrowing without collateral and repaying within a single transaction, but create security risks when implemented incorrectly. This article examines how flash loan vulnerabilities can lead to side entrance attacks and why proper implementation is essential.
If you would like to learn hands-on, clone this repository and run wake test tests/test_4_flash_loan.py
.
Expected usage
When the flashLoan
is called, its user can access and use many tokens in one transaction.
If the borrower fails to repay by the transaction’s end, the entire transaction reverts, which is what enables lending without requiring collateral:
- Vault sends tokens to the
msg.sender
. - External call to the
msg.sender
from Vault. - Vault checks the vault’s token balance.
Attack example
The vulnerability exists because the contract only verifies the vault’s token balance. This allows alternate transfer
methods to satisfy repayment conditions, enabling a side entrance attack.
Users can call the deposit
function, which increases the token balance of the vault. Attackers can call the deposit
function during the flash loan to increase both the vault’s token balance and their own vault balance credit, which they can later withdraw.
These are steps of attack.
-
The attacker calls a
flashLoan()
value from the vault.-
The vault sends the token to lend to the attacker.
-
token.balanceOf(Vault)
decreases. - Vault call attacker external function
onFlashLoan()
- The attacker executes
deposit()
value into vault. token.balanceOf(Vault)
will increase.
- The attacker executes
-
-
The attacker can call
withdraw()
on that deposit.
This is the attacker contract.
Exploit
This is Wake’s output, showing the contract successfully drained the token balance.
Prevention
To prevent a side entrance attack, the lender should transfer the token from the borrower at the end of the flash loan. A reentrancy guard would work here.
Developers must always follow the specifications and best practices for ERC-3156 to prevent all possible attacks.
Conclusion
When a developer wants to use some functionality from ERCs, they must follow the specification of those functionalities.
We have a Reentrancy Examples Github Repository. There are other types of reentrancy attacks and also protocol-specific reentrancies.
Also, we have written type-specific reentrancy attacks.