dsa-connectors/contracts/mainnet/connectors/notional/main.sol

814 lines
26 KiB
Solidity

// SPDX-License-Identifier: MIT
pragma solidity ^0.7.6;
pragma abicoder v2;
/**
* @title Notional
* @dev Fixed Rate Lending and Borrowing
*/
import { Helpers } from "./helpers.sol";
import { Events } from "./events.sol";
import { DepositActionType, BalanceActionWithTrades, BalanceAction } from "./interface.sol";
import { TokenInterface } from "../../common/interfaces.sol";
abstract contract NotionalResolver is Events, Helpers {
/**
* @notice Deposit collateral into Notional, this should only be used for reducing risk of
* liquidation.
* @dev Deposits into Notional are not earning fixed rates, they are earning the cToken
* lending rate. In order to lend at fixed rates use `depositAndLend`
* @param currencyId notional defined currency id to deposit
* @param useUnderlying if true, will accept a deposit in the underlying currency (i.e DAI), if false
* will use the asset currency (i.e. cDAI)
* @param depositAmount amount of tokens to deposit
* @param getId id of depositAmount
* @param setId id to set the value of notional cash deposit increase (denominated in asset cash, i.e. cDAI)
*/
function depositCollateral(
uint16 currencyId,
bool useUnderlying,
uint256 depositAmount,
uint256 getId,
uint256 setId
)
external
payable
returns (string memory _eventName, bytes memory _eventParam)
{
depositAmount = getDepositAmountAndSetApproval(
getId,
currencyId,
useUnderlying,
depositAmount
);
uint256 assetCashDeposited;
if (useUnderlying && currencyId == ETH_CURRENCY_ID) {
assetCashDeposited = notional.depositUnderlyingToken{
value: depositAmount
}(address(this), currencyId, depositAmount);
} else if (useUnderlying) {
assetCashDeposited = notional.depositUnderlyingToken(
address(this),
currencyId,
depositAmount
);
} else {
assetCashDeposited = notional.depositAssetToken(
address(this),
currencyId,
depositAmount
);
}
setUint(setId, assetCashDeposited);
_eventName = "LogDepositCollateral(address,uint16,bool,uint256,uint256)";
_eventParam = abi.encode(
address(this),
currencyId,
useUnderlying,
depositAmount,
assetCashDeposited
);
}
/**
* @notice Withdraw collateral from Notional
* @dev This spell allows users to withdraw collateral from Notional
* @param currencyId notional defined currency id to withdraw
* @param redeemToUnderlying if true, will redeem the amount withdrawn to the underlying currency (i.e. DAI),
* if false, will simply withdraw the asset token (i.e. cDAI)
* @param withdrawAmount amount of tokens to withdraw, denominated in asset tokens (i.e. cDAI)
* @param getId id of withdraw amount
* @param setId id to set the value of amount withdrawn, if redeemToUnderlying this amount will be in underlying
* (i.e. DAI), if not redeemToUnderlying this amount will be asset tokens (i.e. cDAI)
*/
function withdrawCollateral(
uint16 currencyId,
bool redeemToUnderlying,
uint256 withdrawAmount,
uint256 getId,
uint256 setId
)
external
payable
returns (string memory _eventName, bytes memory _eventParam)
{
withdrawAmount = getUint(getId, withdrawAmount);
uint88 amountInternalPrecision = withdrawAmount == type(uint256).max
? toUint88(getCashOrNTokenBalance(currencyId, false))
: toUint88(convertToInternal(currencyId, withdrawAmount));
uint256 amountWithdrawn = notional.withdraw(
currencyId,
amountInternalPrecision,
redeemToUnderlying
);
// Sets the amount of tokens withdrawn to address(this), Notional returns this value
// in the native precision of the token that was withdrawn
setUint(setId, amountWithdrawn);
_eventName = "LogWithdrawCollateral(address,uint16,bool,uint256)";
_eventParam = abi.encode(
address(this),
currencyId,
redeemToUnderlying,
amountWithdrawn
);
}
/**
* @notice Claims NOTE tokens and transfers to the address
* @dev This spell allows users to claim nToken incentives
* @param setId the id to set the balance of NOTE tokens claimed
*/
function claimNOTE(uint256 setId)
external
payable
returns (string memory _eventName, bytes memory _eventParam)
{
uint256 notesClaimed = notional.nTokenClaimIncentives();
setUint(setId, notesClaimed);
_eventName = "LogClaimNOTE(address,uint256)";
_eventParam = abi.encode(address(this), notesClaimed);
}
/**
* @notice Redeem nTokens allowing for accepting of fCash residuals
* @dev This spell allows users to redeem nTokens even when there are fCash residuals that
* cannot be sold when markets are at extremely high utilization
* @param currencyId notional defined currency id of nToken
* @param sellTokenAssets set to false to accept fCash residuals into portfolio, set to true will
* sell fCash residuals back to cash
* @param tokensToRedeem amount of nTokens to redeem
* @param getId id of amount of tokens to redeem
* @param setId id to set amount of asset cash from redeem
*/
function redeemNTokenRaw(
uint16 currencyId,
bool sellTokenAssets,
uint96 tokensToRedeem,
bool acceptResidualAssets,
uint256 getId,
uint256 setId
)
external
payable
returns (string memory _eventName, bytes memory _eventParam)
{
tokensToRedeem = getNTokenRedeemAmount(
currencyId,
tokensToRedeem,
getId
);
int256 _assetCashChange = notional.nTokenRedeem(
address(this),
currencyId,
tokensToRedeem,
sellTokenAssets,
acceptResidualAssets
);
// Floor asset cash change at zero in order to properly set the uint. If the asset cash change is negative
// (this will almost certainly never happen), then no withdraw is possible.
uint256 assetCashChange = _assetCashChange > 0
? uint256(_assetCashChange)
: 0;
setUint(setId, assetCashChange);
_eventName = "LogRedeemNTokenRaw(address,uint16,bool,uint96,int256)";
_eventParam = abi.encode(
address(this),
currencyId,
sellTokenAssets,
tokensToRedeem,
assetCashChange
);
}
/**
* @notice Redeems nTokens to cash and withdraws the resulting cash
* @dev Also possible to use redeemNTokenRaw and withdrawCollateral to achieve the same
* result but this is more gas efficient, it does it in one call to Notional
* @param currencyId notional defined currency id of nToken
* @param tokensToRedeem amount of nTokens to redeem
* @param amountToWithdraw amount of asset cash to withdraw, if set to uint(-1) then will withdraw the
* entire cash balance in notional
* @param redeemToUnderlying if true, will redeem the asset cash withdrawn to underlying tokens
* @param getId id of amount of tokens to redeem
* @param setId id to set amount of asset cash or underlying tokens withdrawn
*/
function redeemNTokenAndWithdraw(
uint16 currencyId,
uint96 tokensToRedeem,
uint256 amountToWithdraw,
bool redeemToUnderlying,
uint256 getId,
uint256 setId
)
external
payable
returns (string memory _eventName, bytes memory _eventParam)
{
tokensToRedeem = getNTokenRedeemAmount(
currencyId,
tokensToRedeem,
getId
);
BalanceAction[] memory action = new BalanceAction[](1);
action[0].actionType = DepositActionType.RedeemNToken;
action[0].currencyId = currencyId;
action[0].depositActionAmount = tokensToRedeem;
action[0].redeemToUnderlying = redeemToUnderlying;
if (amountToWithdraw == type(uint256).max) {
// This setting will override the withdrawAmountInternalPrecision
action[0].withdrawEntireCashBalance = true;
} else {
action[0].withdrawAmountInternalPrecision = amountToWithdraw;
}
executeActionWithBalanceChange(
action,
0,
currencyId,
redeemToUnderlying,
setId
);
_eventName = "LogRedeemNTokenWithdraw(address,uint16,uint96,uint256,bool)";
_eventParam = abi.encode(
address(this),
currencyId,
tokensToRedeem,
amountToWithdraw,
redeemToUnderlying
);
}
/**
* @notice Redeems nTokens and uses the cash to repay a borrow.
* @dev When specifying fCashAmount be sure to calculate it such that the account
* has enough cash after redeeming nTokens to pay down the debt. This can be done
* off-chain using the Notional SDK.
* @param currencyId notional defined currency id of nToken
* @param tokensToRedeem amount of nTokens to redeem
* @param marketIndex the market index that references where the account will lend
* @param fCashAmount amount of fCash to lend into the market (this has the effect or repaying
* the borrowed cash at current market rates), the corresponding amount of cash will be taken
* from the account after redeeming nTokens.
* @param minLendRate minimum rate where the user will lend, if the rate is lower will revert
* @param getId id of amount of tokens to redeem
*/
function redeemNTokenAndDeleverage(
uint16 currencyId,
uint96 tokensToRedeem,
uint8 marketIndex,
uint88 fCashAmount,
uint32 minLendRate,
uint256 getId
)
external
payable
returns (string memory _eventName, bytes memory _eventParam)
{
tokensToRedeem = getNTokenRedeemAmount(
currencyId,
tokensToRedeem,
getId
);
BalanceActionWithTrades[] memory action = new BalanceActionWithTrades[](
1
);
action[0].actionType = DepositActionType.RedeemNToken;
action[0].currencyId = currencyId;
action[0].depositActionAmount = tokensToRedeem;
// Withdraw amount, withdraw cash balance and redeemToUnderlying are all 0 or false
bytes32[] memory trades = new bytes32[](1);
trades[0] = encodeLendTrade(marketIndex, fCashAmount, minLendRate);
action[0].trades = trades;
notional.batchBalanceAndTradeAction(address(this), action);
_eventName = "LogRedeemNTokenAndDeleverage(address,uint16,uint96,uint8,uint88)";
_eventParam = abi.encode(
address(this),
currencyId,
tokensToRedeem,
marketIndex,
fCashAmount
);
}
/**
* @notice Deposit asset or underlying tokens and mint nTokens in a single transaction
* @dev This spell allows users to deposit and mint nTokens (providing liquidity)
* @param currencyId notional defined currency id to deposit
* @param depositAmount amount of tokens to deposit
* @param useUnderlying if true, will accept a deposit in the underlying currency (i.e DAI), if false
* will use the asset currency (i.e. cDAI)
* @param getId id of depositAmount
* @param setId id to set the value of nToken balance change
*/
function depositAndMintNToken(
uint16 currencyId,
uint256 depositAmount,
bool useUnderlying,
uint256 getId,
uint256 setId
)
external
payable
returns (string memory _eventName, bytes memory _eventParam)
{
depositAmount = getDepositAmountAndSetApproval(
getId,
currencyId,
useUnderlying,
depositAmount
);
BalanceAction[] memory action = new BalanceAction[](1);
action[0].actionType = useUnderlying
? DepositActionType.DepositUnderlyingAndMintNToken
: DepositActionType.DepositAssetAndMintNToken;
action[0].currencyId = currencyId;
action[0].depositActionAmount = depositAmount;
// withdraw amount, withdraw cash and redeem to underlying are all 0 and false
uint256 nTokenBefore = getCashOrNTokenBalance(currencyId, true);
uint256 msgValue = getMsgValue(
currencyId,
useUnderlying,
depositAmount
);
notional.batchBalanceAction{ value: msgValue }(address(this), action);
uint256 nTokenBalanceChange = sub(
getCashOrNTokenBalance(currencyId, true),
nTokenBefore
);
if (setId != 0) {
// Set the amount of nTokens minted
setUint(setId, uint256(nTokenBalanceChange));
}
_eventName = "LogDepositAndMintNToken(address,uint16,bool,uint256,int256)";
_eventParam = abi.encode(
address(this),
currencyId,
useUnderlying,
depositAmount,
nTokenBalanceChange
);
}
/**
* @notice Uses existing Notional cash balance (deposits in Notional held as cTokens) and uses them to mint
* nTokens.
* @dev This spell allows users to mint nTokens (providing liquidity) from existing cash balance.
* @param currencyId notional defined currency id of the cash balance
* @param cashBalanceToMint amount of account's cash balance to convert to nTokens
* @param getId id of cash balance
* @param setId id to set the value of nToken increase
*/
function mintNTokenFromCash(
uint16 currencyId,
uint256 cashBalanceToMint,
uint256 getId,
uint256 setId
)
external
payable
returns (string memory _eventName, bytes memory _eventParam)
{
cashBalanceToMint = getUint(getId, cashBalanceToMint);
if (cashBalanceToMint == type(uint256).max)
cashBalanceToMint = getCashOrNTokenBalance(currencyId, false);
BalanceAction[] memory action = new BalanceAction[](1);
action[0].actionType = DepositActionType.ConvertCashToNToken;
action[0].currencyId = currencyId;
action[0].depositActionAmount = cashBalanceToMint;
// NOTE: withdraw amount, withdraw cash and redeem to underlying are all 0 and false
uint256 nTokenBefore = getCashOrNTokenBalance(currencyId, true);
notional.batchBalanceAction(address(this), action);
uint256 nTokenBalanceChange = sub(
getCashOrNTokenBalance(currencyId, true),
nTokenBefore
);
if (setId != 0) {
// Set the amount of nTokens minted
setUint(setId, uint256(nTokenBalanceChange));
}
_eventName = "LogMintNTokenFromCash(address,uint16,uint256,int256)";
_eventParam = abi.encode(
address(this),
currencyId,
cashBalanceToMint,
nTokenBalanceChange
);
}
/**
* @notice Deposits some amount of tokens and lends them in the specified market. This method can also be used to repay a
* borrow early by specifying the corresponding market index of an existing borrow.
* @dev Setting the fCash amount and minLendRate are best calculated using the Notional SDK off chain. They can
* be calculated on chain but there is a significant gas cost to doing so. If there is insufficient depositAmount for the
* fCashAmount specified Notional will revert. In most cases there will be some dust amount of cash left after lending and
* this method will withdraw that dust back to the account.
* @param currencyId notional defined currency id to lend
* @param depositAmount amount of cash to deposit to lend
* @param useUnderlying if true, will accept a deposit in the underlying currency (i.e DAI), if false
* will use the asset currency (i.e. cDAI)
* @param marketIndex the market index to lend to. This is a number from 1 to 7 which corresponds to the tenor
* of the fCash asset to lend. Tenors are described here: https://docs.notional.finance/notional-v2/quarterly-rolls/tenors
* @param fCashAmount amount of fCash for the account to receive, this is equal to how much the account will receive
* at maturity (principal plus interest).
* @param minLendRate the minimum interest rate that the account is willing to lend at, if set to zero the account will accept
* any lending rate
* @param getId returns the deposit amount
*/
function depositAndLend(
uint16 currencyId,
uint256 depositAmount,
bool useUnderlying,
uint8 marketIndex,
uint88 fCashAmount,
uint32 minLendRate,
uint256 getId
)
external
payable
returns (string memory _eventName, bytes memory _eventParam)
{
depositAmount = getDepositAmountAndSetApproval(
getId,
currencyId,
useUnderlying,
depositAmount
);
BalanceActionWithTrades[] memory action = new BalanceActionWithTrades[](
1
);
action[0].actionType = useUnderlying
? DepositActionType.DepositUnderlying
: DepositActionType.DepositAsset;
action[0].currencyId = currencyId;
action[0].depositActionAmount = depositAmount;
// Withdraw any residual cash from lending back to the token that was used
action[0].withdrawEntireCashBalance = true;
action[0].redeemToUnderlying = useUnderlying;
bytes32[] memory trades = new bytes32[](1);
trades[0] = encodeLendTrade(marketIndex, fCashAmount, minLendRate);
action[0].trades = trades;
uint256 msgValue = getMsgValue(
currencyId,
useUnderlying,
depositAmount
);
notional.batchBalanceAndTradeAction{ value: msgValue }(
address(this),
action
);
_eventName = "LogDepositAndLend(address,uint16,bool,uint256,uint8,uint88,uint32)";
_eventParam = abi.encode(
address(this),
currencyId,
useUnderlying,
depositAmount,
marketIndex,
fCashAmount,
minLendRate
);
}
/**
* @notice Deposits some amount of tokens as collateral and borrows. This can be achieved by combining multiple spells but this
* method is more gas efficient by only making a single call to Notional.
* @dev Setting the fCash amount and maxBorrowRate are best calculated using the Notional SDK off chain. The amount of fCash
* when borrowing is more forgiving compared to lending since generally accounts will over collateralize and dust amounts are
* less likely to cause reverts. The Notional SDK will also provide calculations to tell the user what their LTV is for a given
* borrowing action.
* @param depositCurrencyId notional defined currency id of the collateral to deposit
* @param depositAction one of the following values which will define how the collateral is deposited:
* - None: no collateral will be deposited
* - DepositAsset: deposit amount will be specified in asset tokens (i.e. cTokens)
* - DepositUnderlying: deposit amount will be specified in underlying tokens (i.e. DAI)
* - DepositAssetAndMintNToken: deposit amount will be converted to nTokens
* - DepositUnderlyingAndMintNToken: deposit amount will be converted to nTokens
*
* Technically these two deposit types can be used, but there is not a clear reason why they would be used in combination
* with borrowing:
* - RedeemNToken
* - ConvertCashToNToken
*
* @param depositAmount amount of cash to deposit as collateral
* @param borrowCurrencyId id of the currency to borrow
* @param marketIndex the market index to borrow from. This is a number from 1 to 7 which corresponds to the tenor
* of the fCash asset to borrow. Tenors are described here: https://docs.notional.finance/notional-v2/quarterly-rolls/tenors
* @param fCashAmount amount of fCash for the account to borrow, this is equal to how much the account must pay
* at maturity (principal plus interest).
* @param maxBorrowRate the maximum interest rate that the account is willing to borrow at, if set to zero the account will accept
* any borrowing rate
* @param redeemToUnderlying if true, redeems the borrowed balance from cTokens down to the underlying token before transferring
* to the account
* @param getId returns the collateral deposit amount
* @param setId sets the amount that the account borrowed (i.e. how much of borrowCurrencyId it has received)
*/
function depositCollateralBorrowAndWithdraw(
uint16 depositCurrencyId,
DepositActionType depositAction,
uint256 depositAmount,
uint16 borrowCurrencyId,
uint8 marketIndex,
uint88 fCashAmount,
uint32 maxBorrowRate,
bool redeemToUnderlying,
uint256 getId,
uint256 setId
)
external
payable
returns (string memory _eventName, bytes memory _eventParam)
{
bool useUnderlying = (depositAction ==
DepositActionType.DepositUnderlying ||
depositAction == DepositActionType.DepositUnderlyingAndMintNToken);
depositAmount = getDepositAmountAndSetApproval(
getId,
depositCurrencyId,
useUnderlying,
depositAmount
);
BalanceActionWithTrades[]
memory actions = getDepositCollateralBorrowAndWithdrawActions(
depositCurrencyId,
depositAction,
depositAmount,
borrowCurrencyId,
marketIndex,
fCashAmount,
maxBorrowRate,
redeemToUnderlying
);
uint256 msgValue = getMsgValue(
depositCurrencyId,
useUnderlying,
depositAmount
);
executeTradeActionWithBalanceChange(
actions,
msgValue,
borrowCurrencyId,
redeemToUnderlying,
setId
);
_eventName = "LogDepositCollateralBorrowAndWithdraw(address,bool,uint256,uint16,uint8,uint88,uint32,bool)";
_eventParam = abi.encode(
address(this),
useUnderlying,
depositAmount,
borrowCurrencyId,
marketIndex,
fCashAmount,
maxBorrowRate,
redeemToUnderlying
);
}
/**
* @notice Allows an account to withdraw from a fixed rate lend by selling the fCash back to the market. Equivalent to
* borrowing from the Notional perspective.
* @dev Setting the fCash amount and maxBorrowRate are best calculated using the Notional SDK off chain. Similar to borrowing,
* setting these amounts are a bit more forgiving since there is no change of reverts due to dust amounts.
* @param currencyId notional defined currency id of the lend asset to withdraw
* @param marketIndex the market index of the fCash asset. This is a number from 1 to 7 which corresponds to the tenor
* of the fCash asset. Tenors are described here: https://docs.notional.finance/notional-v2/quarterly-rolls/tenors
* @param fCashAmount amount of fCash at the marketIndex that should be sold
* @param maxBorrowRate the maximum interest rate that the account is willing to sell fCash at at, if set to zero the
* account will accept any rate
* @param setId sets the amount that the account has received when withdrawing its lend
*/
function withdrawLend(
uint16 currencyId,
uint8 marketIndex,
uint88 fCashAmount,
uint32 maxBorrowRate,
uint256 setId
)
external
payable
returns (string memory _eventName, bytes memory _eventParam)
{
bool useUnderlying = currencyId != ETH_CURRENCY_ID;
BalanceActionWithTrades[] memory action = new BalanceActionWithTrades[](
1
);
action[0].actionType = DepositActionType.None;
action[0].currencyId = currencyId;
// Withdraw borrowed amount to wallet
action[0].withdrawEntireCashBalance = true;
action[0].redeemToUnderlying = useUnderlying;
bytes32[] memory trades = new bytes32[](1);
trades[0] = encodeBorrowTrade(marketIndex, fCashAmount, maxBorrowRate);
action[0].trades = trades;
executeTradeActionWithBalanceChange(
action,
0,
currencyId,
useUnderlying,
setId
);
_eventName = "LogWithdrawLend(address,uint16,uint8,uint88,uint32)";
_eventParam = abi.encode(
address(this),
currencyId,
marketIndex,
fCashAmount,
maxBorrowRate
);
}
/// @notice Mints sNOTE from the underlying BPT token.
/// @dev Mints sNOTE from the underlying BPT token.
/// @param bptAmount is the amount of BPT to transfer from the msg.sender.
function mintSNoteFromBPT(uint256 bptAmount)
external
payable
returns (string memory _eventName, bytes memory _eventParam)
{
if (bptAmount == type(uint256).max)
bptAmount = bpt.balanceOf(address(this));
approve(bpt, address(staking), bptAmount);
staking.mintFromBPT(bptAmount);
_eventName = "LogMintSNoteFromBPT(address,uint256)";
_eventParam = abi.encode(address(this), bptAmount);
}
/// @notice Mints sNOTE from some amount of NOTE and ETH
/// @dev Mints sNOTE from some amount of NOTE and ETH
/// @param noteAmount amount of NOTE to transfer into the sNOTE contract
/// @param minBPT slippage parameter to prevent front running
function mintSNoteFromETH(
uint256 noteAmount,
uint256 ethAmount,
uint256 minBPT,
uint256 getId
)
external
payable
returns (string memory _eventName, bytes memory _eventParam)
{
noteAmount = getUint(getId, noteAmount);
if (noteAmount == type(uint256).max)
noteAmount = note.balanceOf(address(this));
if (ethAmount == type(uint256).max) ethAmount = address(this).balance;
approve(note, address(staking), noteAmount);
staking.mintFromETH{ value: ethAmount }(noteAmount, minBPT);
_eventName = "LogMintSNoteFromETH(address,uint256,uint256,uint256)";
_eventParam = abi.encode(address(this), ethAmount, noteAmount, minBPT);
}
/// @notice Mints sNOTE from some amount of NOTE and WETH
/// @dev Mints sNOTE from some amount of NOTE and WETH
/// @param noteAmount amount of NOTE to transfer into the sNOTE contract
/// @param wethAmount amount of WETH to transfer into the sNOTE contract
/// @param minBPT slippage parameter to prevent front running
function mintSNoteFromWETH(
uint256 noteAmount,
uint256 wethAmount,
uint256 minBPT,
uint256 getId
)
external
payable
returns (string memory _eventName, bytes memory _eventParam)
{
noteAmount = getUint(getId, noteAmount);
if (noteAmount == type(uint256).max)
noteAmount = note.balanceOf(address(this));
if (wethAmount == type(uint256).max)
wethAmount = weth.balanceOf(address(this));
approve(note, address(staking), noteAmount);
approve(weth, address(staking), wethAmount);
staking.mintFromWETH(noteAmount, wethAmount, minBPT);
_eventName = "LogMintSNoteFromWETH(address,uint256,uint256,uint256)";
_eventParam = abi.encode(address(this), noteAmount, wethAmount, minBPT);
}
/// @notice Begins a cool down period for the sender
/// @dev This is required to redeem tokens
function startCoolDown()
external
payable
returns (string memory _eventName, bytes memory _eventParam)
{
staking.startCoolDown();
_eventName = "LogStartCoolDown(address)";
_eventParam = abi.encode(address(this));
}
/// @notice Stops a cool down for the sender
/// @dev User must start another cool down period in order to call redeemSNote
function stopCoolDown()
external
payable
returns (string memory _eventName, bytes memory _eventParam)
{
staking.stopCoolDown();
_eventName = "LogStopCoolDown(address)";
_eventParam = abi.encode(address(this));
}
/// @notice Redeems some amount of sNOTE to underlying constituent tokens (ETH and NOTE).
/// @dev An account must have passed its cool down expiration before they can redeem
/// @param sNOTEAmount amount of sNOTE to redeem
/// @param minWETH slippage protection for ETH/WETH amount
/// @param minNOTE slippage protection for NOTE amount
/// @param redeemWETH true if redeeming to WETH to ETH
function redeemSNote(
uint256 sNOTEAmount,
uint256 minWETH,
uint256 minNOTE,
bool redeemWETH
)
external
payable
returns (string memory _eventName, bytes memory _eventParam)
{
if (sNOTEAmount == type(uint256).max)
sNOTEAmount = staking.balanceOf(address(this));
staking.redeem(sNOTEAmount, minWETH, minNOTE, redeemWETH);
_eventName = "LogRedeemSNote(address,uint256,uint256,uint256,bool)";
_eventParam = abi.encode(
address(this),
sNOTEAmount,
minWETH,
minNOTE,
redeemWETH
);
}
/**
* @notice Executes a number of batch actions on the account without getId or setId integration
* @dev This method will allow the user to take almost any action on Notional but does not have any
* getId or setId integration. This can be used to roll lends and borrows forward.
* @param actions a set of BatchActionWithTrades that will be executed for this account
*/
function batchActionRaw(BalanceActionWithTrades[] memory actions)
external
payable
returns (string memory _eventName, bytes memory _eventParam)
{
notional.batchBalanceAndTradeAction(address(this), actions);
_eventName = "LogBatchActionRaw(address)";
_eventParam = abi.encode(address(this));
}
}
contract ConnectV2Notional is NotionalResolver {
string public name = "Notional-v1.1";
}