# NotionalModule ## Overview Notional V2 is building a wrapped fCash token to allow Set Protocol V2 indices to hold Notional's bonds (fCash). While this wrapper should allow us to trade fCash using an adapter for the standard `TradeModule`, we would need to build a complex manager extension and issuance hook system to allow the redemption of matured fCash positions before issuance and redemption. Because of this, we plan to write the `NotionModule`, which will be a fork of the `TradeModule`, with two differences. `NotionalModule` will not support trade adapters since we only need to interact with Notional's internal AMM. `NotionalModule` will have module issuance and redeem hooks which automatically checks if an fCash position has matured, and redeem it to the underlying token. ## Important Links - Wrapped fCash - https://github.com/notional-finance/notional-solidity-sdk/pull/6 - TradeModule - https://github.com/SetProtocol/set-protocol-v2/blob/master/contracts/protocol/modules/v1/TradeModule.sol - DebtIssuanceModule - https://github.com/SetProtocol/set-protocol-v2/blob/master/contracts/protocol/modules/v1/DebtIssuanceModule.sol - AaveLeverageModule (for examples of hook usage) - https://github.com/SetProtocol/set-protocol-v2/blob/master/contracts/protocol/modules/v1/AaveLeverageModule.sol ## Specification *trade(ISetToken, address, uint256, address, uint256)* Performs a trade via the notional fCash wrapper. - ISetToken _setToken - Set to trade with - address _sendToken - token to be sold in trade - this may be either a wrapped fCash, cToken, or underlying token - at least one of _sendToken or _receiveToken must be fCash - _sendToken and _receiveToken must have the same underlying asset / cToken - uint256 _sendQuantity - amount of _sendToken to sell - address _receiveToken - token to be purchased in trade - this may be either a wrapped fCash, cToken, or underlying token - at least one of _sendToken or _receiveToken must be fCash - _sendToken and _receiveToken must have the same underlying asset / cToken - uint256 _minReceiveQuantity - minimum amount of _receiveToken to receive post trade *moduleIssueHook(ISetToken, uint256)* Called by `DebtIssuanceModule` and `DebtIssuanceModuleV2` prior to issuance. This function will iterate over each component, check if it is a matured fCash position, and if it is, redeem it for its underlying cToken (or the cToken's underlying if the redeemToUnderlying flag has been set). - ISetToken _setToken - the Set being issued - the issuance amount - this paramter is unused, but is needed to be compliant with the IModuleIssuanceHook interface *moduleRedeemHook(ISetToken, uint256)* Called by `DebtIssuanceModule` and `DebtIssuanceModuleV2` prior to redemption. This function will iterate over each component, check if it is a matured fCash position, and if it is, redeem it for its underlying cToken (or the cToken's underlying if the redeemToUnderlying flag has been set). - ISetToken _setToken - the Set being redeemed - the redeem amount - this paramter is unused, but is needed to be compliant with the IModuleIssuanceHook interface *setRedeemToUnderlying(ISetToken, bool)* Change the redeemToUnderlying flag for this SetToken. If redeemToUnderlying is false, matured fCash positions are redeemed to the cToken. If it is true, they are instead redeemed to the cToken's underlying. - ISetToken _setToken - the SetToken to set the flag for - bool _redeemUnderlying - the new value of redeemToUnderlying ## Open Questions - Should trade adapters be used? - Since we only intend to use this for Notional for now, we don't strictly need adapters. - Adapters would allow us to extend to different fixed interest protocols. - Redeem logic likely does not port over well to an adapter - Could add isMatured and getRedeemCalldata functions - Possible that other fixed interest protocols don't have similar concepts so would need to write a new module anyway - Leverage modules don't use adapters since a lot of the concepts between different lending markets don't port over. - Leaning towards following this pattern of using a different module if we ever want to integrate new fixed interest markets. - Will the component makeup being modified during issuance need to be handled on the TokenSets frontend? - If a matured fCash position is in the set when a user tries to issue, tokensets will ask them to approve this token, or even tell them they do not have this token. - The hook will take care of redeeming it, so in actually they don't need the token and instead need to match the cToken/underyling token balance that would be created by the redemption. - Without modifying the frotend, users will likely experience quite a bit of frustration by this.