Skip to content
Open
Show file tree
Hide file tree
Changes from 86 commits
Commits
Show all changes
150 commits
Select commit Hold shift + click to select a range
dba9c60
feat: flash loan contracts
Debugger022 Jan 7, 2025
dcd4f1f
feat: single asset flash loan
Debugger022 Jan 7, 2025
aba2937
feat: multiple asset flash loan
Debugger022 Jan 7, 2025
fb92c44
feat: add mock contracts for flash loan receiver
Debugger022 Jan 20, 2025
4112b43
test: add tests for the multi asset flash loan
Debugger022 Jan 20, 2025
12583d2
test: add tests for the single asset flash loan
Debugger022 Jan 20, 2025
adb7d8b
refactor: reduce vToken size to keep it under 24kb
Debugger022 Jan 21, 2025
212c067
test: refactor tests as per flashloan feature
Debugger022 Jan 21, 2025
1c60161
test: add fork test for single asset flash loan
Debugger022 Jan 21, 2025
26f5663
test: add fork test for multi asset flash loan
Debugger022 Jan 21, 2025
558b0f5
fix: ci/cd issues
Debugger022 Jan 24, 2025
b88270c
Merge branch 'develop' into feat/VEN-2985
Debugger022 Jan 28, 2025
27f3047
fix: evilXToken test
Debugger022 Jan 29, 2025
7b5d653
fix: pr comments
Debugger022 Mar 12, 2025
bce9a10
fix: pr comments
Debugger022 Mar 18, 2025
c0fd071
refactor: introduced two fees for flash loans
Debugger022 Mar 18, 2025
e5c1d0d
refactor: use approve instead of transfer funds in flash loan
Debugger022 Mar 18, 2025
041c3ba
Merge branch 'develop' into feat/VEN-2985
Debugger022 Mar 18, 2025
44d26f5
chore: update yarn.lock
Debugger022 Mar 18, 2025
47b2acf
fix: lint issues
Debugger022 Mar 18, 2025
558e868
refactor: transfer funds to PSR
Debugger022 Mar 28, 2025
b2bcfc6
Merge branch 'develop' into feat/VEN-2985
Debugger022 Jun 20, 2025
912e590
refactor: update helper files for flashloan configs
Debugger022 Jun 20, 2025
3ee9e28
refactor: update flashLoan parameters to use vTokens and underlying a…
Debugger022 Jul 28, 2025
8a47ea4
refactor: update flashLoan fee parameters in VToken contract
Debugger022 Jul 28, 2025
317115a
refactor: simplify VToken initialization by removing unused flashLoan…
Debugger022 Jul 28, 2025
ddf975f
refactor: update flashLoan receiver initialization and remove unused …
Debugger022 Jul 28, 2025
3c36cab
fix : prettier
Debugger022 Jul 28, 2025
7ceed8c
feat : add initiator parameter to flash loan functions and implement …
Debugger022 Jul 28, 2025
13db780
refactor: rename _setWhiteListFlashLoanAccount to setWhiteListFlashLo…
Debugger022 Jul 29, 2025
8192bab
refactor: update ensureAllowed parameter for setWhiteListFlashLoanAcc…
Debugger022 Jul 29, 2025
8fde88f
feat: add initiator parameter to executeFlashLoan function
Debugger022 Jul 30, 2025
3c282eb
test: add checks for whitelisted users in flash loan requests
Debugger022 Aug 5, 2025
41390b3
refactor: enhance flash loan functionality with delegate authorizatio…
Debugger022 Aug 5, 2025
1519e3b
Merge branch 'develop' into feat/VEN-2985
Debugger022 Aug 8, 2025
335f8b2
test: add tests for modes in flashloan
Debugger022 Aug 8, 2025
2759ead
fix: lint and prettier
Debugger022 Aug 8, 2025
1ff666e
Merge branch 'feat/solidity-0.8' into feat/VEN-2985
Debugger022 Aug 12, 2025
d35e3c8
fix: reduce vToken size
Debugger022 Aug 22, 2025
4879942
fix: minor fixes
Debugger022 Aug 22, 2025
ea80325
fix: minor fixes
Debugger022 Aug 25, 2025
0e472e2
Merge branch 'feat/solidity-0.8' into feat/VEN-2985
Debugger022 Aug 25, 2025
1b29e85
Merge branch 'feat/VEN-3361' into feat/VEN-2985
Debugger022 Aug 27, 2025
7c64dc3
refactor: update flashloan unit and fork tests
Debugger022 Aug 27, 2025
0dcca21
fix: minor fix
Debugger022 Aug 27, 2025
11cf73a
feat: add BadFlashLoanReceiver contract and related tests
Debugger022 Sep 1, 2025
a8ee3fc
Merge branch 'feat/VEN-2985' into feat/VEN-3343
Debugger022 Sep 1, 2025
ad249ae
refactor: replace string reverts with custom error types in VToken co…
Debugger022 Sep 2, 2025
7c7ddfb
fix: update comptroller storage
Debugger022 Sep 3, 2025
f7c1829
refactor: update unit and fork tests of flashloan
Debugger022 Sep 3, 2025
936d774
refactor: update _handleFlashLoanMode1 in policyfacet
Debugger022 Sep 4, 2025
1637457
fix: minor fix
Debugger022 Sep 4, 2025
48b8d77
fix: update balanceBefore to balanceBeforeRepayFlashloan
Debugger022 Sep 4, 2025
49b3759
refactor: update tests supporting modes of flashloan
Debugger022 Sep 5, 2025
fca0756
feat: add deployments for flashloan functionality in bsctestnet
Debugger022 Sep 8, 2025
e4d512e
feat: add deployments for market and reward facet in bsctestnet
Debugger022 Sep 8, 2025
86f9478
feat: updating deployment files
Debugger022 Sep 8, 2025
d67c78b
fix: minor fix
Debugger022 Sep 8, 2025
7ffb17a
fix: lint
Debugger022 Sep 8, 2025
6ffbf15
fix: update natspec for executeFlashloan in vtoken
Debugger022 Sep 9, 2025
33cbd99
refactor: using custom errors for flashLoan functionality
Debugger022 Sep 15, 2025
8aefaa9
refactor: using calldata consistently
Debugger022 Sep 15, 2025
b0dec3a
refactor: removed initiator param in executeFlashLoan
Debugger022 Sep 16, 2025
d849599
refactor: consolidate borrow logic with transfer flag
Debugger022 Sep 16, 2025
840f996
refactor: remove flashLoanAmount from calculations
Debugger022 Sep 16, 2025
7129c29
revert: remove flashLoanAmount from calculations
Debugger022 Sep 16, 2025
d6a3620
fix: minor changes
Debugger022 Sep 16, 2025
0b9aec1
refactor: update flashLoan fee structure
Debugger022 Sep 16, 2025
228cdeb
refactor: remove modes and introduce partial repayments in flashloan
Debugger022 Sep 17, 2025
e90e502
refactor: update unit and fork tests of flashloan
Debugger022 Sep 17, 2025
d75ef99
Merge branch 'feat/VEN-3361' into feat/VEN-2985
Debugger022 Sep 17, 2025
54f8427
Merge branch 'feat/VEN-3343' into feat/VEN-2985
Debugger022 Sep 17, 2025
2efdca4
fix: minor fix
Debugger022 Sep 17, 2025
0b410f7
refactor: update unit and fork tests of flashloan
Debugger022 Sep 17, 2025
e7e5cf7
fix: lint and prettier
Debugger022 Sep 17, 2025
8ef62a9
Merge branch 'feat/VEN-3361' into feat/VEN-2985
Debugger022 Sep 18, 2025
049c515
refactor: rename _toggleFlashLoan to toggleFlashLoan
Debugger022 Sep 18, 2025
0fd47b9
test: add more test scenarios for flashLoan
Debugger022 Sep 18, 2025
5ec249d
feat: add deployments for Facets, Diamond and VBep20Delegate in bscte…
Debugger022 Sep 18, 2025
e921530
fix: minor fixes
Debugger022 Sep 22, 2025
95e539d
refactor: update comptroller storage
Debugger022 Sep 22, 2025
5e6e4d6
fix: minor fix
Debugger022 Sep 22, 2025
544dcf1
fix: fixed _gap value
Debugger022 Sep 22, 2025
eaddc40
feat: add deployments for Facets, Diamond, ComptrollerLens and VBep20…
Debugger022 Sep 22, 2025
6957892
Merge branch 'feat/VEN-3361' into feat/VEN-2985
Debugger022 Sep 24, 2025
ed08f16
refactor: update enum IncomeType in IProtocolShareReserve
Debugger022 Sep 24, 2025
8ed2d89
fix: minor fixes
Debugger022 Sep 25, 2025
01d36ee
fix: resolve comments
Debugger022 Sep 25, 2025
2bc16e6
refactor: replace toggleFlashLoan with setFlashLoanEnabled function
Debugger022 Sep 25, 2025
08ca797
refactor: update flash loan parameters to use 'onBehalf' instead of '…
Debugger022 Sep 25, 2025
d3bf53c
refactor: remove checkAccrueInterest function
Debugger022 Sep 25, 2025
18eb4c8
feat: move flashLoan functions to new FlashLoanFacet
Debugger022 Sep 25, 2025
f511491
fix: small optimization
Debugger022 Sep 25, 2025
e313deb
fix: minor fixes
Debugger022 Sep 25, 2025
947e632
refactor: update repayment handling in flashloan
Debugger022 Sep 26, 2025
243fc8c
fix: minor fixes
Debugger022 Sep 26, 2025
3ec2d14
Refactor: removed PSR check transferOutUnderlyingFlashLoan
Debugger022 Sep 26, 2025
e570b0b
fix: Lint
Debugger022 Sep 26, 2025
9445b3a
feat: add deployments for new flashLoan changes
Debugger022 Sep 29, 2025
09024d5
fix: fix comments
Debugger022 Sep 29, 2025
bb75513
refactor: removed simple flashLoan functionality
Debugger022 Sep 29, 2025
12bccb7
fix: minor fixes
Debugger022 Sep 30, 2025
b312653
refactor: revert some changes
Debugger022 Sep 30, 2025
fad2194
fix: remove unused errors
Debugger022 Sep 30, 2025
c9f1d56
feat: add reentrancy guard in executeFlashloan
Debugger022 Oct 6, 2025
869afd8
feat: vlw-14
Debugger022 Oct 6, 2025
cf4e131
feat: updating deployment files
Debugger022 Oct 6, 2025
f05bf54
feat: vlw-04
Debugger022 Oct 6, 2025
9f05cca
feat: vlw-01,03,15,17
Debugger022 Oct 6, 2025
9821c49
feat: vlw-11
Debugger022 Oct 6, 2025
1c9dbd1
feat: vlw-06
Debugger022 Oct 6, 2025
c249297
feat: vlw-09
Debugger022 Oct 6, 2025
3f6077b
feat: vlw-12
Debugger022 Oct 6, 2025
f7b5ff8
refactor: add event for partial repayments
Debugger022 Oct 7, 2025
46110a6
refactor: rename borrowDebtPosition to flashLoanDebtPosition
Debugger022 Oct 7, 2025
d415fab
fix: tests
Debugger022 Oct 7, 2025
9945c5f
fix: vlw-12
Debugger022 Oct 7, 2025
e899c25
refactor: update FlashLoanPartiallyRepaid event to FlashLoanRepaid
Debugger022 Oct 8, 2025
1ad53f6
refactor: add event verifications for repayments in flashLoan fork tests
Debugger022 Oct 8, 2025
757e323
fix: vlw-13
Debugger022 Oct 8, 2025
865ff7f
revert: getCash modification
Debugger022 Oct 8, 2025
49382e4
feat: vlw-05
Debugger022 Oct 8, 2025
f69858b
fix: vlw-09
Debugger022 Oct 8, 2025
194b387
feat: add _getCashPriorWithFlashLoan function
Debugger022 Oct 8, 2025
242ab2b
fix: minor fixes
Debugger022 Oct 8, 2025
c2e44d4
fix: vlw-11
GitGuru7 Oct 8, 2025
4bb366a
fix: I04
GitGuru7 Oct 8, 2025
a1311c5
fix: add missing natSpec
GitGuru7 Oct 8, 2025
1d1fa04
fix: use oz ReentrancyGuard
GitGuru7 Oct 9, 2025
c940eae
fixup! fix: add missing natSpec
chechu Oct 9, 2025
88872eb
Revert "fix: use oz ReentrancyGuard"
GitGuru7 Oct 10, 2025
19e135a
fix: add ref to OZ ReentrancyGuardTransient
GitGuru7 Oct 10, 2025
a89c5fc
fix: use actual cash for transfering reserve
GitGuru7 Oct 10, 2025
68a5a21
Merge branch 'feat/VEN-2985' into fix/certik-audit
GitGuru7 Oct 10, 2025
bc9e4c1
Merge pull request #638 from VenusProtocol/fix/certik-audit
chechu Oct 10, 2025
fba0819
test: fix EvilXDelegator test and the build step
chechu Oct 10, 2025
bcbd24d
Merge branch 'develop' into feat/VEN-2985
chechu Oct 10, 2025
76eebd4
feat: add deployments for Facets, Diamond, ComptrollerLens and VBep20…
Debugger022 Oct 13, 2025
5f264f6
feat: updating deployment files
Debugger022 Oct 13, 2025
2932de2
feat: add deployments for Facets, Diamond, ComptrollerLens and VBep20…
Debugger022 Oct 17, 2025
7fd685c
feat: updating deployment files
Debugger022 Oct 17, 2025
cc4b4f2
feat: s1
Debugger022 Oct 23, 2025
64c04cf
feat: s3
Debugger022 Oct 23, 2025
bb6db03
refactor: update max vTokens length
Debugger022 Oct 24, 2025
ec80cec
refactor: remove isFlashLoanPaused function
Debugger022 Oct 24, 2025
bfde12e
Merge pull request #642 from VenusProtocol/feat/quantstamp-audit-miti…
Debugger022 Oct 27, 2025
a58624d
feat: update bsctestnet deployments
Debugger022 Oct 27, 2025
7ba8333
feat: updating deployment files
Debugger022 Oct 27, 2025
514220a
feat: update bscmainnet deployments
Debugger022 Oct 29, 2025
43a4fec
feat: updating deployment files
Debugger022 Oct 29, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions contracts/Comptroller/ComptrollerInterface.sol
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,14 @@ interface ComptrollerInterface {

function borrowVerify(address vToken, address borrower, uint borrowAmount) external;

function executeFlashLoan(
address payable initiator,
address payable receiver,
VToken[] calldata vTokens,
uint256[] calldata amounts,
bytes calldata param
) external;

function repayBorrowAllowed(
address vToken,
address payer,
Expand Down Expand Up @@ -160,6 +168,8 @@ interface ComptrollerInterface {

function vaiMintRate() external view returns (uint);

function authorizedFlashLoan(address account) external view returns (bool);

function userPoolId(address account) external view returns (uint96);

function getLiquidationIncentive(address vToken) external view returns (uint256);
Expand Down
13 changes: 13 additions & 0 deletions contracts/Comptroller/ComptrollerStorage.sol
Original file line number Diff line number Diff line change
Expand Up @@ -320,3 +320,16 @@ contract ComptrollerV17Storage is ComptrollerV16Storage {
*/
uint96 public lastPoolId;
}

contract ComptrollerV18Storage is ComptrollerV17Storage {
struct FlashLoanData {
uint256[] totalFees;
uint256[] protocolFees;
uint256[] balanceAfterTransfer;
uint256[] actualRepayments;
uint256[] remainingDebts;
}

/// @notice Mapping of accounts authorized to execute flash loans
mapping(address => bool) public authorizedFlashLoan;
}
6 changes: 3 additions & 3 deletions contracts/Comptroller/Diamond/Diamond.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ pragma solidity 0.8.25;

import { IDiamondCut } from "./interfaces/IDiamondCut.sol";
import { Unitroller } from "../Unitroller.sol";
import { ComptrollerV17Storage } from "../ComptrollerStorage.sol";
import { ComptrollerV18Storage } from "../ComptrollerStorage.sol";

/**
* @title Diamond
* @author Venus
* @notice This contract contains functions related to facets
*/
contract Diamond is IDiamondCut, ComptrollerV17Storage {
contract Diamond is IDiamondCut, ComptrollerV18Storage {
/// @notice Emitted when functions are added, replaced or removed to facets
event DiamondCut(IDiamondCut.FacetCut[] _diamondCut);

Expand Down Expand Up @@ -72,7 +72,7 @@ contract Diamond is IDiamondCut, ComptrollerV17Storage {
*/
function facetAddress(
bytes4 functionSelector
) external view returns (ComptrollerV17Storage.FacetAddressAndPosition memory) {
) external view returns (ComptrollerV18Storage.FacetAddressAndPosition memory) {
return _selectorToFacetAndPosition[functionSelector];
}

Expand Down
4 changes: 2 additions & 2 deletions contracts/Comptroller/Diamond/facets/FacetBase.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { VToken } from "../../../Tokens/VTokens/VToken.sol";
import { ComptrollerErrorReporter } from "../../../Utils/ErrorReporter.sol";
import { ExponentialNoError } from "../../../Utils/ExponentialNoError.sol";
import { IVAIVault, Action } from "../../../Comptroller/ComptrollerInterface.sol";
import { ComptrollerV17Storage } from "../../../Comptroller/ComptrollerStorage.sol";
import { ComptrollerV18Storage } from "../../../Comptroller/ComptrollerStorage.sol";
import { PoolMarketId } from "../../../Comptroller/Types/PoolMarketId.sol";
import { IFacetBase, WeightFunction } from "../interfaces/IFacetBase.sol";

Expand All @@ -19,7 +19,7 @@ import { IFacetBase, WeightFunction } from "../interfaces/IFacetBase.sol";
* @author Venus
* @notice This facet contract contains functions related to access and checks
*/
contract FacetBase is IFacetBase, ComptrollerV17Storage, ExponentialNoError, ComptrollerErrorReporter {
contract FacetBase is IFacetBase, ComptrollerV18Storage, ExponentialNoError, ComptrollerErrorReporter {
using SafeERC20 for IERC20;

/// @notice The initial Venus index for a market
Expand Down
204 changes: 204 additions & 0 deletions contracts/Comptroller/Diamond/facets/PolicyFacet.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,12 @@ import { Action } from "../../ComptrollerInterface.sol";
import { IPolicyFacet } from "../interfaces/IPolicyFacet.sol";

import { XVSRewardsHelper } from "./XVSRewardsHelper.sol";
import { IFlashLoanReceiver } from "../../../FlashLoan/interfaces/IFlashLoanReceiver.sol";
import { PoolMarketId } from "../../../Comptroller/Types/PoolMarketId.sol";
import { WeightFunction } from "../interfaces/IFacetBase.sol";

import { IProtocolShareReserve } from "../../../external/IProtocolShareReserve.sol";

/**
* @title PolicyFacet
* @author Venus
Expand All @@ -23,6 +26,9 @@ contract PolicyFacet is IPolicyFacet, XVSRewardsHelper {
/// @notice Emitted when a new supply-side XVS speed is calculated for a market
event VenusSupplySpeedUpdated(VToken indexed vToken, uint256 newSpeed);

// @notice Emitted When the flash loan is successfully executed
event FlashLoanExecuted(address receiver, VToken[] assets, uint256[] amounts);

/**
* @notice Checks if the account should be allowed to mint tokens in the given market
* @param vToken The market to verify the mint against
Expand All @@ -42,6 +48,7 @@ contract PolicyFacet is IPolicyFacet, XVSRewardsHelper {
uint256 vTokenSupply = VToken(vToken).totalSupply();
Exp memory exchangeRate = Exp({ mantissa: VToken(vToken).exchangeRateStored() });
uint256 nextTotalSupply = mul_ScalarTruncateAddUInt(exchangeRate, vTokenSupply, mintAmount);

require(nextTotalSupply <= supplyCap, "market supply cap reached");

// Keep the flywheel moving
Expand Down Expand Up @@ -147,6 +154,7 @@ contract PolicyFacet is IPolicyFacet, XVSRewardsHelper {
if (err != Error.NO_ERROR) {
return uint256(err);
}

if (shortfall != 0) {
return uint256(Error.INSUFFICIENT_LIQUIDITY);
}
Expand Down Expand Up @@ -370,6 +378,202 @@ contract PolicyFacet is IPolicyFacet, XVSRewardsHelper {
}
}

/**
* @notice Executes a flashLoan operation with the requested assets.
* @dev Transfer the specified assets to the receiver contract and handles repayment.
* @param initiator The address of the EOA who initiated the flash loan.
* @param receiver The address of the contract that will receive the flashLoan amount and execute the operation.
* @param vTokens The addresses of the vToken assets to be loaned.
* @param underlyingAmounts The amounts of each underlying assets to be loaned.
* @param param The bytes passed in the executeOperation call.
* @custom:error FlashLoanNotEnabled is thrown if the flash loan is not enabled for the asset.
* @custom:error InvalidAmount is thrown if the requested amount is zero.
* @custom:error NoAssetsRequested is thrown if no assets are requested for the flash loan.
* @custom:error InvalidFlashLoanParams is thrown if the flash loan params are invalid.
* @custom:error SenderNotAuthorizedForFlashLoan is thrown if the sender is not authorized to use flashloan.
* @custom:event Emits FlashLoanExecuted on success
*/
function executeFlashLoan(
address payable initiator,
address payable receiver,
VToken[] memory vTokens,
uint256[] memory underlyingAmounts,
bytes memory param
) external {
for (uint256 i; i < vTokens.length; i++) {
if (!(vTokens[i]).isFlashLoanEnabled()) revert FlashLoanNotEnabled();
if (underlyingAmounts[i] == 0) revert InvalidAmount();
}
// vTokens array must not be empty
if (vTokens.length == 0) {
revert NoAssetsRequested();
}
// All arrays must have the same length and not be zero
if (vTokens.length != underlyingAmounts.length) {
revert InvalidFlashLoanParams();
}

ensureNonzeroAddress(receiver);

if (!authorizedFlashLoan[initiator]) {
revert SenderNotAuthorizedForFlashLoan(initiator);
}

// Execute flash loan phases
_executeFlashLoanPhases(initiator, receiver, vTokens, underlyingAmounts, param);

emit FlashLoanExecuted(receiver, vTokens, underlyingAmounts);
}

/**
* @notice Executes all flash loan phases
*/
function _executeFlashLoanPhases(
address payable initiator,
address payable receiver,
VToken[] memory vTokens,
uint256[] memory underlyingAmounts,
bytes memory param
) internal returns (FlashLoanData memory flashLoanData) {
// Initialize arrays
flashLoanData.totalFees = new uint256[](vTokens.length);
flashLoanData.protocolFees = new uint256[](vTokens.length);
flashLoanData.balanceAfterTransfer = new uint256[](vTokens.length);
flashLoanData.actualRepayments = new uint256[](vTokens.length);
flashLoanData.remainingDebts = new uint256[](vTokens.length);

// Phase 1: Calculate fees and transfer assets
_executePhase1(receiver, vTokens, underlyingAmounts, flashLoanData);
// Phase 2: Execute operations on receiver contract
uint256[] memory tokensApproved = _executePhase2(
initiator,
receiver,
vTokens,
underlyingAmounts,
flashLoanData.totalFees,
param
);
// Phase 3: Handles repayment
_executePhase3(initiator, receiver, vTokens, tokensApproved, flashLoanData);

return flashLoanData;
}

/**
* @notice Phase 1: Calculate fees and transfer assets to receiver
*/
function _executePhase1(
address payable receiver,
VToken[] memory vTokens,
uint256[] memory underlyingAmounts,
FlashLoanData memory flashLoanData
) internal {
for (uint256 j = 0; j < vTokens.length; j++) {
(flashLoanData.totalFees[j], flashLoanData.protocolFees[j]) = vTokens[j].calculateFlashLoanFee(
underlyingAmounts[j]
);

// Transfer the asset to receiver
flashLoanData.balanceAfterTransfer[j] = vTokens[j].transferOutUnderlying(receiver, underlyingAmounts[j]);
}
}

/**
* @notice Phase 2: Execute operations on receiver contract
*/
function _executePhase2(
address payable initiator,
address payable receiver,
VToken[] memory vTokens,
uint256[] memory underlyingAmounts,
uint256[] memory totalFees,
bytes memory param
) internal returns (uint256[] memory) {
(bool success, uint256[] memory tokensApproved) = IFlashLoanReceiver(receiver).executeOperation(
vTokens,
underlyingAmounts,
totalFees,
initiator,
param
);

if (!success) {
revert ExecuteFlashLoanFailed();
}
return tokensApproved;
}

/**
* @notice Phase 3: Handles repayment based on full or partial repayment
* @dev If full repayment is made, transfer protocol fee to protocol share reserve and update state.
* If partial repayment is made, create an ongoing debt position for the unpaid balance.
*/
function _executePhase3(
address payable initiator,
address payable receiver,
VToken[] memory vTokens,
uint256[] memory underlyingAmounts,
FlashLoanData memory flashLoanData
) internal {
for (uint256 k = 0; k < vTokens.length; k++) {
_handleFlashLoan(
vTokens[k],
initiator,
receiver,
underlyingAmounts[k],
flashLoanData.totalFees[k],
flashLoanData.protocolFees[k]
);
}
}

/**
* @notice Handles the repayment and fee logic for a flash loan.
* @dev Transfers the repaid amount from the receiver, checks if the full amount plus fee is repaid,
* and either settles the protocol fee or creates an ongoing debt position for any unpaid balance.
* Updates the protocol share reserve state if the protocol fee is transferred.
* @param vToken The vToken contract for the asset being flash loaned.
* @param initiator The address of the EOA who initiated the flash loan.
* @param receiver The address that received the flash loan and is repaying.
* @param amountRepayed The amount repaid by the receiver (principal + fee).
* @param totalFee The total fee charged for the flash loan.
* @param protocolFee The portion of the total fee allocated to the protocol.
*/
function _handleFlashLoan(
VToken vToken,
address payable initiator,
address payable receiver,
uint256 amountRepayed,
uint256 totalFee,
uint256 protocolFee
) internal {
uint256 borrowedFlashLoanAmount = vToken.flashLoanAmount();
// Must repay full amount + fee
vToken.transferInUnderlyingAndVerify(receiver, amountRepayed);

if (borrowedFlashLoanAmount + totalFee > amountRepayed) {
// If there is any unpaid balance, it becomes an ongoing debt
uint256 leftUnpaidBalance = (borrowedFlashLoanAmount + totalFee) - amountRepayed;
uint256 accrueResult = vToken.accrueInterest();
require(accrueResult == 0, "Failed to accrue interest");

uint256 debtError = vToken.borrowDebtPosition(initiator, leftUnpaidBalance);
if (debtError != 0) {
revert FailedToCreateDebtPosition();
}
} else {
// Transfer protocol fee to protocol share reserve
vToken.transferOutUnderlying(vToken.protocolShareReserve(), protocolFee);

// Update protocol share reserve state
IProtocolShareReserve(vToken.protocolShareReserve()).updateAssetsState(
address(vToken.comptroller()),
address(vToken.underlying()),
IProtocolShareReserve.IncomeType.FLASHLOAN
);
}
}

/**
* @notice Checks if the account should be allowed to transfer tokens in the given market
* @param vToken The market to verify the transfer against
Expand Down
16 changes: 16 additions & 0 deletions contracts/Comptroller/Diamond/facets/SetterFacet.sol
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,9 @@ contract SetterFacet is ISetterFacet, FacetBase {
/// @notice Emitted when XVS vToken address is changed
event NewXVSVToken(address indexed oldXVSVToken, address indexed newXVSVToken);

/// @notice Emitted when an account's flash loan whitelist status is updated
event IsAccountFlashLoanWhitelisted(address indexed account, bool indexed isWhitelisted);

/// @notice Emitted when liquidation threshold for a market in a pool is changed by admin
event NewLiquidationThreshold(
uint96 indexed poolId,
Expand Down Expand Up @@ -618,6 +621,19 @@ contract SetterFacet is ISetterFacet, FacetBase {
xvsVToken = xvsVToken_;
}

/**
* @notice Adds/Removes an account to the flash loan whitelist
* @param account The account to authorize for flash loans
* @param _isWhiteListed True to whitelist the account for flash loans, false to remove from whitelist
*/
function setWhiteListFlashLoanAccount(address account, bool _isWhiteListed) external {
ensureAllowed("setWhiteListFlashLoanAccount(address,bool)");
ensureNonzeroAddress(account);

authorizedFlashLoan[account] = _isWhiteListed;
emit IsAccountFlashLoanWhitelisted(account, _isWhiteListed);
}

/**
* @notice Updates the label for a specific pool (excluding the Core Pool)
* @param poolId ID of the pool to update
Expand Down
8 changes: 8 additions & 0 deletions contracts/Comptroller/Diamond/interfaces/IPolicyFacet.sol
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,14 @@ interface IPolicyFacet {
uint256[] calldata borrowSpeeds
) external;

function executeFlashLoan(
address payable initiator,
address payable receiver,
VToken[] calldata vTokens,
uint256[] calldata amounts,
bytes calldata param
) external;

function getBorrowingPower(
address account
) external view returns (uint256 error, uint256 liquidity, uint256 shortfall);
Expand Down
2 changes: 2 additions & 0 deletions contracts/Comptroller/Diamond/interfaces/ISetterFacet.sol
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ interface ISetterFacet {

function _setXVSVToken(address xvsVToken_) external;

function setWhiteListFlashLoanAccount(address account, bool _isWhiteListed) external;

function setIsBorrowAllowed(uint96 poolId, address vToken, bool borrowAllowed) external;

function setPoolActive(uint96 poolId, bool active) external;
Expand Down
Loading