Manage Account Assets
How to manage Notional account fCash, nToken and cash assets
Notional keeps track of all assets related to an account (one Ethereum address) in the main Notional proxy storage. This page will describe the different ways an account can manage their assets.

Key Concepts

  • Currency ID: every currency in Notional is identified by a unique currency number. A currency on Notional can be represented by two tokens, an asset cash token (interest bearing yield token, like a cToken or aToken) and an underlying token (such as DAI, USDC, etc).
  • Asset Cash: whenever possible, cash balances held in Notional as collateral are held as interest bearing yield tokens (aka asset cash).
  • nTokens: asset cash can be further wrapped into nTokens which provide the account even higher yield from trading fees on fCash markets and NOTE incentives. nTokens are not risk free because they can experience market to market losses due to interest rate fluctuations. nTokens are perpetual (never maturing) claims on liquidity in fCash markets.
  • Settlement: fCash is a promise of a fixed amount of underlying at maturity. After maturity, fCash will be deleted from the portfolio and settled into asset cash. Since asset cash continues to earn a variable yield, fCash holders will not give up yield after maturity. Settlement (if required) happens automatically on every transaction.
  • Array Portfolio: accounts can lend and borrow in multiple currencies on Notional. Their positions are tracked in a storage array. Since array iteration and free collateral checks get more expensive as an account adds assets, these portfolios are limited to a maximum of 7 fCash assets in multiple currencies.
  • Bitmap Portfolio: some accounts may want to hold more fCash assets than an array portfolio allows for. In this case, we can reduce gas costs by limiting them to a single currency and holding their fCash assets in a more gas efficient manner. Converting an account to a bitmap portfolio is a one way action for an account. The current limit is 20 fCash assets for this portfolio type.
  • Has Debt: if an account has negative fCash or cash, then it has debts that require a free collateral check. If an account only ever lends fCash it will never have risk and therefore never requires a free collateral check.
  • Wrapped fCash ERC20: some protocols require integration with ERC20 so this is provided externally via wrapped fCash. Users can mint and redeem fCash directly on the Wrapped fCash contract and transfer them just like any other ERC20 token. Importantly, fCash held in wrapped fCash is lend only and cannot be used as collateral for borrowing on Notional. Every Wrapped fCash contract represents a single currency and maturity of fCash and new wrappers can be deployed by anyone (although the factory contract will ensure that only 1 version of Wrapped fCash exists for every currency and maturity). A user may hold any number of Wrapped fCash assets, there is no upper limit.

Choosing a Portfolio Type

  • If you want to lend, borrow and provide liquidity (mint nTokens) in multiple currencies use the array portfolio. This is the default choice, it is flexible, and appropriate for most users.
  • If you want to lend and borrow at many different maturities you can use a bitmap portfolio. An account can hold many different idiosyncratic fCash positions (illiquid positions on chain) and still borrow against them using a bitmap portfolio. For example, if an account holds 9 month idiosyncratic fCash it will be unable to convert it to cash on fCash markets. It could, however, borrow cash at the 6 month or 1 year markets using the 9 month idiosyncratic fCash asset as collateral. As Notional extends to longer dated maturities, bitmap portfolios will play an important market making role in the system.
  • If you will only ever lend but want to do so on an unlimited number of maturities, consider using Wrapped fCash. Be aware that automatic settlement does not occur in Wrapped fCash, so users will need to redeem their Wrapped fCash tokens manually after maturity. Note that Wrapped fCash can be transferred into a bitmap portfolio at later date if you do decide that you want to borrow against fCash assets.

Withdrawing Lending Early

If an account is lending fCash they have "purchased" fCash at a discount prior to maturity. The account may chose to withdraw their lending position early by selling the fCash they have purchased on a matching fCash market (if there is no matching market then this fCash asset is idiosyncratic and can only be sold OTC).
Selling fCash is equivalent to "borrowing" except that the user will sell their fCash balance down to a floor of 0 so they will not incur debts. See Lend and Borrow fCash for an overview on trade execution mechanics.

Repaying Debts

Debts can be repaid in two ways:
  1. 1.
    Lending (or purchasing) enough fCash to repay a debt prior to maturity. This similar to Withdrawing Lending Early except in the opposite direction. See Lend and Borrow fCash for an overview on trade execution mechanics.
  2. 2.
    Deposit sufficient cash to repay the debt prior to maturity. While lending is economically more efficient for the borrower since they can repay at a discount, trade execution may not always be possible. Depositing cash to repay debts will always succeed and net off 1-1 against debts at maturity. Call depositAssetToken and depositUnderlyingToken to deposit cash into an account.

Rolling Assets Forward

As an fCash position gets closer to maturity, borrowers and lenders may want to "roll" their positions to longer dated maturities at new, fixed rates. What this amounts to is two trades on Notional fCash markets. One trade to sell or repay their current fCash asset and another to lend or borrow fCash at the new maturity. Generally, users will want to roll their assets to longer dated maturities but nothing prevents a user from executing trade to shorter dated maturities.
The new fixed rates after rolling their assets forward will not be the same as the account's previous fixed rate. The new fixed rates will be reflected by current market interest rates.
BatchBalanceAndTradeAction[] actions = new BatchBalanceAndTradeAction[](1);
actions[0] = BatchBalanceAndTradeAction({
actionType: None,
currencyId: 2, // DAI
depositAmount: 0,
withdrawAmountInternalPrecision: 0,
withdrawEntireCashBalance: false,
redeemToUnderlying: false,
trades: new bytes32(2)
// Sell 100e8 fCash at the current 3 month market (assuming the account has
// a 100e8 fCash balance already)
action[0].trades[0] = encodeBorrowTrade(
1, // 3 month market
100e8, // Sell 100 fCash
0.05e9 // Do not sell at a higher rate than 5% annualized
// Purchase (lend) 100e8 fCash at the 6 month market using the proceeds of
// what was sold in the previous trade.
action[0].trades[0] = encodeLendTrade(
2, // 6 month market
100e8, // Purchase 100 fCash at 6 months
0.05e9 // Do not lend at a lower rate than 5% annualized
// Submit trade, roll a 100 fDAI position from 3 months to 6 months.
NotionalProxy.batchBalanceAndTradeAction{value: 1e18}(account, actions);