Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[VEN-2356]: NativeTokenGateway Contract #361

Merged
merged 83 commits into from
Mar 19, 2024
Merged
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
83 commits
Select commit Hold shift + click to select a range
9f131f9
feat: add borrowBehalf, redeemBehalf and redeemUnderlyingBehalf funct…
Debugger022 Feb 1, 2024
649189a
feat: add NativeTokenGateway contract
Debugger022 Feb 1, 2024
4e3a2c1
fix: set approval to zero in wrapAndRepay
Debugger022 Feb 1, 2024
830b988
fixup! feat: add borrowBehalf, redeemBehalf and redeemUnderlyingBehal…
kkirka Feb 1, 2024
01123c2
fixup! feat: add borrowBehalf, redeemBehalf and redeemUnderlyingBehal…
kkirka Feb 1, 2024
91bd528
Merge pull request #362 from VenusProtocol/feat/fixup-VEN-2356
Debugger022 Feb 2, 2024
c393374
fix: add reentrancy check and minor gas optimizations
Debugger022 Feb 2, 2024
4af2569
fix: tests
Debugger022 Feb 2, 2024
19c676e
fix: minor fixes
Debugger022 Feb 2, 2024
d66cf83
tests: add fork tests
Debugger022 Feb 2, 2024
8fb63cc
refactor: use BSD-3-Clause license identifier
Debugger022 Feb 5, 2024
04c3c96
feat: add deployment files for sepolia and bsctestnet
Debugger022 Feb 12, 2024
bb6a212
feat: updating deployment files
Debugger022 Feb 12, 2024
c6c1d16
fix: pr comments
Debugger022 Feb 12, 2024
3c33508
fix: NTG-01
Debugger022 Feb 15, 2024
c051289
fix: NTG-07
Debugger022 Feb 15, 2024
bfe2c2f
fix: NTG-05
Debugger022 Feb 15, 2024
18f16c3
fix: VBV-01
Debugger022 Feb 15, 2024
dfaef87
fix: VPB-01
Debugger022 Feb 15, 2024
119cd12
fix: NTG-06
Debugger022 Feb 15, 2024
e477182
fix: imports in NativeTokenGateway.sol
Debugger022 Feb 15, 2024
2c786a0
fixup! fix: NTG-06 variable passing
Debugger022 Feb 16, 2024
48d6b45
fix: fork tests for gateway contract
Debugger022 Feb 16, 2024
85271d2
refractor: removed wrappedNativeToken from constructor argument
Debugger022 Feb 19, 2024
bb12776
feat: remove unneeded fallback and checks, and review tests
chechu Feb 19, 2024
70f74e2
feat: add deployment script for NativeTokenGateway
Debugger022 Feb 20, 2024
ae0b770
fix: deployment script to run for hardhat
Debugger022 Feb 20, 2024
4b9f7f4
refactor: update deployment addresses
Debugger022 Feb 22, 2024
6e1d240
feat: updating deployment files
Debugger022 Feb 22, 2024
b508cb1
fix: pr comments
Debugger022 Feb 22, 2024
eb09199
Merge branch 'develop' into VEN-2356
Debugger022 Feb 22, 2024
2e055e0
fix: failing deploy check
Debugger022 Feb 22, 2024
f1c7e98
fix: VPB-01
Debugger022 Feb 22, 2024
eed3a61
fix: NTV-01
Debugger022 Feb 22, 2024
a6af33c
refactor: take input token address in sweepToken
Debugger022 Feb 22, 2024
4d414cc
feat: add sepolia deployment for NativeTokenGateway, VToken and Compt…
Debugger022 Feb 22, 2024
772880c
feat: updating deployment files
Debugger022 Feb 22, 2024
78a4c50
refactor: deployment script and remove NativeTokenGateway old deploym…
Debugger022 Feb 23, 2024
f4e7a3e
feat: updating deployment files
Debugger022 Feb 23, 2024
5f494a9
fix: L01
Debugger022 Feb 23, 2024
3eaf534
fix: L02
Debugger022 Feb 23, 2024
0a037b9
fix: spelling
Debugger022 Feb 23, 2024
6580956
docs: fix comment of _redeemFresh (VPB-01)
chechu Feb 23, 2024
4211d2d
refactor: deployment script to use vToken symbol
Debugger022 Feb 26, 2024
698a1ee
feat: update deployment files for sepolia
Debugger022 Feb 26, 2024
9fe398b
feat: updating deployment files
Debugger022 Feb 26, 2024
652459f
docs: add audit reports for the NativeTokenGateway contract by certik…
chechu Feb 29, 2024
4eb9877
Merge branch 'develop' into VEN-2356
Debugger022 Mar 4, 2024
d0085e2
refactor: deployment script
Debugger022 Mar 4, 2024
f8c5804
fix: VEN-GATE-5
Debugger022 Mar 4, 2024
3204553
feat: update deployments and add gateway deployment for LST pool vWET…
Debugger022 Mar 5, 2024
2b28492
feat: add support for opbnbtestnet and opbnbmainnet in deployment script
Debugger022 Mar 5, 2024
5b691d3
feat: updating deployment files
Debugger022 Mar 5, 2024
6c9d6e2
feat: update deployments for bsctestnet
Debugger022 Mar 5, 2024
e52f83a
feat: updating deployment files
Debugger022 Mar 5, 2024
1adf7e1
feat: update deployments for opbnbtestnet
Debugger022 Mar 6, 2024
38da937
feat: updating deployment files
Debugger022 Mar 6, 2024
6b88e7a
feat: add deployment files for bscmainnet
Debugger022 Mar 7, 2024
e6a170d
feat: updating deployment files
Debugger022 Mar 7, 2024
e8bfdad
feat: update deployment files for opbnbmainnet
Debugger022 Mar 7, 2024
0e833ee
feat: updating deployment files
Debugger022 Mar 7, 2024
52a2a87
feat: add ethereum configuration to hardhat config
Debugger022 Mar 8, 2024
f8899ed
feat: add deployment files for ethereum
Debugger022 Mar 8, 2024
73e2b74
feat: updating deployment files
Debugger022 Mar 8, 2024
e6bab68
feat: add redeemAndUnwrap functionality
Debugger022 Mar 11, 2024
4d083c8
tests: add unit and fork tests for redeemAndUnwrap
Debugger022 Mar 11, 2024
44bd213
refactor: move non zero value check to _redeemAndUnwrap internal func…
Debugger022 Mar 11, 2024
adbdb96
Merge branch 'develop' into VEN-2356
Debugger022 Mar 12, 2024
98d1d27
feat: update deployment files for bsctestnet
Debugger022 Mar 12, 2024
8bd0e5a
feat: updating deployment files
Debugger022 Mar 12, 2024
74de379
feat update deployment files for opbnbtestnet and sepolia
Debugger022 Mar 12, 2024
7932ed2
feat: updating deployment files
Debugger022 Mar 12, 2024
d2e2b8f
feat: update deployment files for opbnbmainnet
Debugger022 Mar 14, 2024
942135e
Merge branch 'develop' into VEN-2356
Debugger022 Mar 14, 2024
e2dfe75
feat: updating deployment files
Debugger022 Mar 14, 2024
4957a2c
feat: update deployment files for bscmainnet
Debugger022 Mar 14, 2024
7658f72
feat: updating deployment files
Debugger022 Mar 14, 2024
e7dcbb2
chore: add VWETH_LiquidStakedETH token gateway deployment
0xlucian Mar 15, 2024
60f9953
feat: updating deployment files
0xlucian Mar 15, 2024
28fba90
chore: add deployment file for vWETH_Core gateway contract
Debugger022 Mar 16, 2024
6199a15
feat: updating deployment files
Debugger022 Mar 16, 2024
0ec94f4
docs: add quantstamp audit report for the NativeTokenGateway feature
chechu Mar 17, 2024
d18285b
fix: GVP-01
Debugger022 Mar 18, 2024
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
22 changes: 22 additions & 0 deletions contracts/Comptroller.sol
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
{
// PoolRegistry, immutable to save on gas
/// @custom:oz-upgrades-unsafe-allow state-variable-immutable
address public immutable poolRegistry;

Check warning on line 50 in contracts/Comptroller.sol

View workflow job for this annotation

GitHub Actions / Lint

Immutable variables name are set to be in capitalized SNAKE_CASE

/// @notice Emitted when an account enters a market
event MarketEntered(VToken indexed vToken, address indexed account);
Expand Down Expand Up @@ -98,6 +98,9 @@
/// @notice Emitted when forced liquidation is enabled or disabled for a market
event IsForcedLiquidationEnabledUpdated(address indexed vToken, bool enable);

/// @notice Emitted when the delegate rights are updated for an account
event DelegateUpdated(address indexed user, address indexed delegate, bool allowDelegate);

/// @notice Thrown when collateral factor exceeds the upper bound
error InvalidCollateralFactor();

Expand Down Expand Up @@ -199,6 +202,25 @@
return results;
}

/**
* @notice Grants or revokes the borrowing delegate rights to / from an account
* If allowed, the delegate will be able to borrow/redeem funds on behalf of the sender
* Upon a delegated borrow, the delegate will receive the funds, and the borrower
* will see the debt on their account
* Upon a delegated redeem, the delegate will redeem the vTokens or the underlying,
* will receive the redeemed amount on behalf of the approver(redeemer)
* @param delegate The address to update the rights for
* @param allowBorrows Whether to grant (true) or revoke (false) the rights
* @custom:event DelegateUpdated emits on success
* @custom:error ZeroAddressNotAllowed is thrown when delegate address is zero
* @custom:access Not restricted
*/
function updateDelegate(address delegate, bool allowBorrows) external {
kkirka marked this conversation as resolved.
Show resolved Hide resolved
ensureNonzeroAddress(delegate);
approvedDelegates[msg.sender][delegate] = allowBorrows;
emit DelegateUpdated(msg.sender, delegate, allowBorrows);
}

/**
* @notice Removes asset from sender's account liquidity calculation; disabling them as collateral
* @dev Sender must not have an outstanding borrow balance in the asset,
Expand Down Expand Up @@ -352,7 +374,7 @@
* @param redeemAmount The amount of the underlying asset being redeemed
* @param redeemTokens The number of tokens being redeemed
*/
function redeemVerify(address vToken, address redeemer, uint256 redeemAmount, uint256 redeemTokens) external {

Check warning on line 377 in contracts/Comptroller.sol

View workflow job for this annotation

GitHub Actions / Lint

Variable "redeemAmount" is unused

Check warning on line 377 in contracts/Comptroller.sol

View workflow job for this annotation

GitHub Actions / Lint

Variable "redeemTokens" is unused
if (address(prime) != address(0)) {
prime.accrueInterestAndUpdateScore(redeemer, vToken);
}
Expand Down Expand Up @@ -835,7 +857,7 @@

for (uint256 i; i < marketsCount; ++i) {
(, uint256 borrowBalance, ) = _safeGetAccountSnapshot(borrowMarkets[i], borrower);
require(borrowBalance == 0, "Nonzero borrow balance after liquidation");

Check warning on line 860 in contracts/Comptroller.sol

View workflow job for this annotation

GitHub Actions / Lint

Use Custom Errors instead of require statements
}
}

Expand All @@ -847,8 +869,8 @@
*/
function setCloseFactor(uint256 newCloseFactorMantissa) external {
_checkAccessAllowed("setCloseFactor(uint256)");
require(MAX_CLOSE_FACTOR_MANTISSA >= newCloseFactorMantissa, "Close factor greater than maximum close factor");

Check warning on line 872 in contracts/Comptroller.sol

View workflow job for this annotation

GitHub Actions / Lint

Use Custom Errors instead of require statements
require(MIN_CLOSE_FACTOR_MANTISSA <= newCloseFactorMantissa, "Close factor smaller than minimum close factor");

Check warning on line 873 in contracts/Comptroller.sol

View workflow job for this annotation

GitHub Actions / Lint

Use Custom Errors instead of require statements

uint256 oldCloseFactorMantissa = closeFactorMantissa;
closeFactorMantissa = newCloseFactorMantissa;
Expand Down Expand Up @@ -923,7 +945,7 @@
* @custom:access Controlled by AccessControlManager
*/
function setLiquidationIncentive(uint256 newLiquidationIncentiveMantissa) external {
require(newLiquidationIncentiveMantissa >= MANTISSA_ONE, "liquidation incentive should be greater than 1e18");

Check warning on line 948 in contracts/Comptroller.sol

View workflow job for this annotation

GitHub Actions / Lint

Use Custom Errors instead of require statements

_checkAccessAllowed("setLiquidationIncentive(uint256)");

Expand Down
2 changes: 2 additions & 0 deletions contracts/ComptrollerInterface.sol
Original file line number Diff line number Diff line change
Expand Up @@ -116,4 +116,6 @@ interface ComptrollerViewInterface {
function borrowCaps(address) external view returns (uint256);

function supplyCaps(address) external view returns (uint256);

function approvedDelegates(address borrower, address receiver) external view returns (bool);
chechu marked this conversation as resolved.
Show resolved Hide resolved
}
6 changes: 5 additions & 1 deletion contracts/ComptrollerStorage.sol
Original file line number Diff line number Diff line change
Expand Up @@ -125,10 +125,14 @@ contract ComptrollerStorage {
/// Prime token address
IPrime public prime;

/// @notice Whether the delegate is allowed to borrow or redeem on behalf of the user
//mapping(address user => mapping (address delegate => bool approved)) public approvedDelegates;
mapping(address => mapping(address => bool)) public approvedDelegates;

/**
* @dev This empty reserved space is put in place to allow future versions to add new
* variables without shifting down storage in the inheritance chain.
* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
*/
uint256[48] private __gap;
uint256[47] private __gap;
}
1 change: 1 addition & 0 deletions contracts/ErrorReporter.sol
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ contract TokenErrorReporter {

error BorrowFreshnessCheck();
error BorrowCashNotAvailable();
error DelegateNotApproved();

error RepayBorrowFreshnessCheck();

Expand Down
87 changes: 87 additions & 0 deletions contracts/Gateway/INativeTokenGateway.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
// SPDX-License-Identifier: BSD-3-Clause
pragma solidity 0.8.20;

/**
* @title INativeTokenGateway
* @author Venus
* @notice Interface for NativeTokenGateway contract
*/
interface INativeTokenGateway {
/**
* @dev Emitted when native currency is supplied
*/
event TokensWrappedAndSupplied(address indexed sender, address indexed vToken, uint256 amount);

/**
* @dev Emitted when tokens are redeemed and then unwrapped to be sent to user
*/
event TokensRedeemedAndUnwrapped(address indexed sender, address indexed vToken, uint256 amount);

/**
* @dev Emitted when native tokens are borrowed and unwrapped
*/
event TokensBorrowedAndUnwrapped(address indexed sender, address indexed vToken, uint256 amount);

/**
* @dev Emitted when native currency is wrapped and repaid
*/
event TokensWrappedAndRepaid(address indexed sender, address indexed vToken, uint256 amount);

/**
* @dev Emitted when wNativeToken is swept from the contract
*/
event SweepToken(address indexed sender, uint256 amount);

/**
* @dev Emitted when native asset is swept from the contract
*/
event SweepNative(address indexed sender, uint256 amount);

/**
* @notice Thrown if transfer of native token fails
*/
error NativeTokenTransferFailed();

/**
* @notice Thrown if the supplied address is a zero address where it is not allowed
*/
error ZeroAddressNotAllowed();

/**
* @notice Thrown if the supplied value is 0 where it is not allowed
*/
error ZeroValueNotAllowed();

/**
* @dev Wrap Native Token, get wNativeToken, mint vWNativeTokens, and supply to the market
* @param minter The address on behalf of whom the supply is performed
*/
function wrapAndSupply(address minter) external payable;

/**
* @dev Redeem vWNativeTokens, unwrap to Native Token, and send to the user
* @param redeemAmount The amount of underlying tokens to redeem
*/
function redeemUnderlyingAndUnwrap(uint256 redeemAmount) external;

/**
* @dev Borrow wNativeToken, unwrap to Native Token, and send to the user
* @param amount The amount of underlying tokens to borrow
*/
function borrowAndUnwrap(uint256 amount) external;

/**
* @dev Wrap Native Token, repay borrow in the market, and send remaining Native Token to the user
*/
function wrapAndRepay() external payable;

/**
* @dev Sweeps wNativeToken tokens from the contract and sends them to the owner
*/
function sweepToken() external;

/**
* @dev Sweeps native assets (Native Token) from the contract and sends them to the owner
*/
function sweepNative() external;
}
22 changes: 22 additions & 0 deletions contracts/Gateway/Interfaces/IVToken.sol
web3rover marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// SPDX-License-Identifier: BSD-3-Clause
pragma solidity 0.8.20;

interface IVToken {
function mintBehalf(address receiver, uint256 mintAmount) external returns (uint256);

function redeemUnderlyingBehalf(address redeemer, uint256 redeemAmount) external returns (uint256);

function repayBorrowBehalf(address borrower, uint256 repayAmount) external returns (uint256);

function borrowBalanceCurrent(address account) external returns (uint256);

function borrowBehalf(address borrower, uint256 borrowAmount) external returns (uint256);

function underlying() external returns (address);

function exchangeRateCurrent() external returns (uint256);

function transferFrom(address from, address to, uint256 amount) external returns (bool);

function redeem(uint256 redeemTokens) external returns (uint256);
}
16 changes: 16 additions & 0 deletions contracts/Gateway/Interfaces/IWrappedNative.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// SPDX-License-Identifier: BSD-3-Clause
pragma solidity 0.8.20;

interface IWrappedNative {
function deposit() external payable;

function withdraw(uint256) external;

function approve(address guy, uint256 wad) external returns (bool);

function transferFrom(address src, address dst, uint256 wad) external returns (bool);

function transfer(address dst, uint256 wad) external returns (bool);

function balanceOf(address account) external view returns (uint256);
}
200 changes: 200 additions & 0 deletions contracts/Gateway/NativeTokenGateway.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
// SPDX-License-Identifier: BSD-3-Clause
pragma solidity 0.8.20;

import { Ownable2Step } from "@openzeppelin/contracts/access/Ownable2Step.sol";
import { SafeERC20, IERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import { ReentrancyGuard } from "@openzeppelin/contracts/security/ReentrancyGuard.sol";

import { IWrappedNative } from "./Interfaces/IWrappedNative.sol";
import { INativeTokenGateway } from "./INativeTokenGateway.sol";
import { IVToken } from "./Interfaces/IVToken.sol";

/**
* @title NativeTokenGateway
* @author Venus
* @notice NativeTokenGateway contract facilitates interactions with a vToken market for native tokens (Native or wNativeToken)
*/
contract NativeTokenGateway is INativeTokenGateway, Ownable2Step, ReentrancyGuard {
using SafeERC20 for IERC20;

/**
* @notice Address of wrapped native token contract
*/
IWrappedNative public immutable wNativeToken;

/**
* @notice Address of wrapped native token market
*/
IVToken public immutable vWNativeToken;

/**
* @notice Constructor for NativeTokenGateway
* @param vWrappedNativeToken Address of wrapped native token market
*/
constructor(IVToken vWrappedNativeToken) {
ensureNonzeroAddress(address(vWrappedNativeToken));

vWNativeToken = vWrappedNativeToken;
wNativeToken = IWrappedNative(vWNativeToken.underlying());
}

/**
* @notice To receive Native when msg.data is empty
*/
receive() external payable {}

/**
* @notice To receive Native when msg.data is not empty
*/
fallback() external payable {}
chechu marked this conversation as resolved.
Show resolved Hide resolved

/**
* @notice Wrap Native, get wNativeToken, mint vWNativeToken, and supply to the market.
* @param minter The address on behalf of whom the supply is performed.
* @custom:error ZeroAddressNotAllowed is thrown if address of minter is zero address
* @custom:error ZeroValueNotAllowed is thrown if mintAmount is zero
* @custom:event TokensWrappedAndSupplied is emitted when assets are supplied to the market
*/
function wrapAndSupply(address minter) external payable nonReentrant {
ensureNonzeroAddress(minter);

uint256 mintAmount = msg.value;
ensureNonzeroValue(mintAmount);

wNativeToken.deposit{ value: mintAmount }();
IERC20(address(wNativeToken)).safeApprove(address(vWNativeToken), mintAmount);
kkirka marked this conversation as resolved.
Show resolved Hide resolved

vWNativeToken.mintBehalf(minter, mintAmount);

IERC20(address(wNativeToken)).safeApprove(address(vWNativeToken), 0);
emit TokensWrappedAndSupplied(minter, address(vWNativeToken), mintAmount);
}

/**
* @notice Redeem vWNativeToken, unwrap to Native Token, and send to the user
* @param redeemAmount The amount of underlying tokens to redeem
* @custom:error ZeroValueNotAllowed is thrown if redeemAmount is zero
* @custom:event TokensRedeemedAndUnwrapped is emitted when assets are redeemed from a market and unwrapped
*/
function redeemUnderlyingAndUnwrap(uint256 redeemAmount) external nonReentrant {
ensureNonzeroValue(redeemAmount);

uint256 balanceBefore = wNativeToken.balanceOf(address(this));
vWNativeToken.redeemUnderlyingBehalf(msg.sender, redeemAmount);
uint256 balanceAfter = wNativeToken.balanceOf(address(this));

uint256 redeemedAmount = balanceAfter - balanceBefore;
wNativeToken.withdraw(redeemedAmount);

_safeTransferNativeTokens(msg.sender, redeemedAmount);
emit TokensRedeemedAndUnwrapped(msg.sender, address(vWNativeToken), redeemedAmount);
}

/**
* @dev Borrow wNativeToken, unwrap to Native, and send to the user
* @param borrowAmount The amount of underlying tokens to borrow
* @custom:error ZeroValueNotAllowed is thrown if borrowAmount is zero
* @custom:event TokensBorrowedAndUnwrapped is emitted when assets are borrowed from a market and unwrapped
*/
function borrowAndUnwrap(uint256 borrowAmount) external nonReentrant {
ensureNonzeroAddress(address(vWNativeToken));
GitGuru7 marked this conversation as resolved.
Show resolved Hide resolved
ensureNonzeroValue(borrowAmount);

vWNativeToken.borrowBehalf(msg.sender, borrowAmount);

wNativeToken.withdraw(borrowAmount);
_safeTransferNativeTokens(msg.sender, borrowAmount);
emit TokensBorrowedAndUnwrapped(msg.sender, address(vWNativeToken), borrowAmount);
}

/**
* @notice Wrap Native, repay borrow in the market, and send remaining Native to the user
* @custom:error ZeroValueNotAllowed is thrown if repayAmount is zero
* @custom:event TokensWrappedAndRepaid is emitted when assets are repaid to a market and unwrapped
*/
function wrapAndRepay() external payable nonReentrant {
uint256 repayAmount = msg.value;
ensureNonzeroValue(repayAmount);

wNativeToken.deposit{ value: repayAmount }();
kkirka marked this conversation as resolved.
Show resolved Hide resolved
IERC20(address(wNativeToken)).safeApprove(address(vWNativeToken), repayAmount);

uint256 borrowBalanceBefore = vWNativeToken.borrowBalanceCurrent(msg.sender);
vWNativeToken.repayBorrowBehalf(msg.sender, repayAmount);
uint256 borrowBalanceAfter = vWNativeToken.borrowBalanceCurrent(msg.sender);

IERC20(address(wNativeToken)).safeApprove(address(vWNativeToken), 0);

if (borrowBalanceAfter == 0 && (repayAmount > borrowBalanceBefore)) {
uint256 dust = repayAmount - borrowBalanceBefore;
GitGuru7 marked this conversation as resolved.
Show resolved Hide resolved

wNativeToken.withdraw(dust);
_safeTransferNativeTokens(msg.sender, dust);
}
emit TokensWrappedAndRepaid(msg.sender, address(vWNativeToken), borrowBalanceBefore - borrowBalanceAfter);
}

/**
* @notice Sweeps native assets (Native) from the contract and sends them to the owner
* @custom:event SweepNative is emitted when assets are swept from the contract
* @custom:access Controlled by Governance
*/
function sweepNative() external onlyOwner {
uint256 balance = address(this).balance;

if (balance > 0) {
_safeTransferNativeTokens((owner()), balance);
emit SweepNative((owner()), balance);
kkirka marked this conversation as resolved.
Show resolved Hide resolved
}
}

/**
* @notice Sweeps wNativeToken tokens from the contract and sends them to the owner
* @custom:event SweepToken emits on success
* @custom:access Controlled by Governance
*/
function sweepToken() external onlyOwner {
kkirka marked this conversation as resolved.
Show resolved Hide resolved
uint256 balance = wNativeToken.balanceOf(address(this));

if (balance > 0) {
IERC20(address(wNativeToken)).safeTransfer(owner(), balance);
emit SweepToken(owner(), balance);
}
}

/**
* @dev transfer Native tokens to an address, revert if it fails
* @param to recipient of the transfer
* @param value the amount to send
* @custom:error NativeTokenTransferFailed is thrown if the Native token transfer fails
*/
function _safeTransferNativeTokens(address to, uint256 value) internal {
(bool success, ) = to.call{ value: value }(new bytes(0));

if (!success) {
revert NativeTokenTransferFailed();
}
}

/**
* @dev Checks if the provided address is nonzero, reverts otherwise
* @param address_ Address to check
* @custom:error ZeroAddressNotAllowed is thrown if the provided address is a zero address
**/
function ensureNonzeroAddress(address address_) internal pure {
if (address_ == address(0)) {
revert ZeroAddressNotAllowed();
}
}

/**
* @dev Checks if the provided value is nonzero, reverts otherwise
* @param value_ Value to check
* @custom:error ZeroValueNotAllowed is thrown if the provided value is 0
*/
function ensureNonzeroValue(uint256 value_) internal pure {
if (value_ == 0) {
revert ZeroValueNotAllowed();
}
}
}
Loading
Loading