borrowing unwanted flashloan on behalf of receiver #503
Labels
3 (High Risk)
Assets can be stolen/lost/compromised directly
bug
Something isn't working
duplicate-769
edited-by-warden
satisfactory
satisfies C4 submission criteria; eligible for awards
upgraded by judge
Original issue severity upgraded from QA/Gas by judge
Lines of code
https://github.com/code-423n4/2023-06-lybra/blob/7b73ef2fbb542b569e182d9abf79be643ca883ee/contracts/lybra/token/PeUSDMainnetStableVision.sol#L129
Vulnerability details
Impact
There is no control on borrowing flashloan, so anyone can borrow an unwanted flashloan on behalf of a receiver, and the receiver must burn share to pay the fee (in case it has nonzero eUSD balance).
Proof of Concept
Suppose there is an innocent contract (called
FlashloanBorrower.sol
) which is deployed to borrow flashloan from LybraFinance protocol. This contract must have the interfaceFlashBorrower
implemented to be used during the flashloan callback:https://github.com/code-423n4/2023-06-lybra/blob/7b73ef2fbb542b569e182d9abf79be643ca883ee/contracts/lybra/token/PeUSDMainnetStableVision.sol#L21C1-L27C2
During executing flashloan, the requested amount is transferred to the receiver:
https://github.com/code-423n4/2023-06-lybra/blob/7b73ef2fbb542b569e182d9abf79be643ca883ee/contracts/lybra/token/PeUSDMainnetStableVision.sol#L131
Then, the callback function is called on the receiver address:
https://github.com/code-423n4/2023-06-lybra/blob/7b73ef2fbb542b569e182d9abf79be643ca883ee/contracts/lybra/token/PeUSDMainnetStableVision.sol#L132
Then, the same lent out fund will be transferred from the receiver to the protocol:
https://github.com/code-423n4/2023-06-lybra/blob/7b73ef2fbb542b569e182d9abf79be643ca883ee/contracts/lybra/token/PeUSDMainnetStableVision.sol#L133
Finally, the fee of the flashloan is burned from the receiver.
https://github.com/code-423n4/2023-06-lybra/blob/7b73ef2fbb542b569e182d9abf79be643ca883ee/contracts/lybra/token/PeUSDMainnetStableVision.sol#L137
The problem is that anyone can call this function to borrow flashloan on behalf of
FlashloanBorrower.sol
, and finally the fee will be deducted fromFlashloanBorrower.sol
.Let's say Bob (a malicious user) calls
executeFlashloan(FlashBorrower(address(FlashloanBorrower)), 1_000_000e18, "")
. In this case,1_000_000e18
will be transferred toFlashloanBorrower
contract, then the callback is called, then it is transferred fromFlashloanBorrower
to the protocol, and finally the fee is deducted fromFlashloanBorrower
(assumingFlashloanBorrower
has enough eUSD to pay the fee). As a result,FlashloanBorrower
loses the fee of the unwanted flashloan.Tools Used
Recommended Mitigation Steps
There are two recommendations as other protocol's flashloan is working:
msg.sender
, not thereceiver
. In other words, burning the shares ofmsg.sender
as fee.EUSD.transferFrom(...)
, it is better to track thebalanceBefore
andbalanceAfter
, so thatbalanceAfter - balanceBefore >= getFee(shareAmount)
.Assessed type
Context
The text was updated successfully, but these errors were encountered: