Alluo Explained
  • Welcome
    • 🧭 The Basics
  • Getting Started
    • πŸ’» The DeFi Web App
      • ❓ Connecting to the app
      • 🚜 Depositing into the farms
      • πŸ™Œ Other basics
      • 🏦 Importing your Mobile app wallet to Metamask
      • 🧬 Add the polygon network manually in Metamask.
      • ⛓️ Bridging Stablecoins from another chain
    • πŸ“±The Mobile app
      • πŸ—οΈ Setting up your account
      • 🏦 Depositing money into the app
      • πŸ™Œ Other basics
      • πŸ” Exporting your private key
    • πŸ“–Tech deep dive: Contract Address Library
  • Understanding Alluo
    • πŸ’΅ How does Alluo get the yield?
      • 🐰 Going deeper into the Alluo protocol rabbit hole
    • 🧐 FAQ
  • Tokens & Tokenomics
    • πŸͺ™ The tokens
    • πŸ‘¨β€πŸ”¬Tech deep dive: Interest Bearing {asset} token
      • Depositing
      • Withdrawals
      • IbAlluo on different chains
      • StIbAlluo and Superfluid
        • A closer look at the integration between IbAlluo and StIbAlluo
      • Using the IbAlluo contract directly to create streams
      • Liquidity Handler and adapters
        • Deposit process with the Liquidity Handler
        • Withdraw process with the Liquidity Handler
    • πŸ“ˆ Tokenomics
    • πŸ‘¨β€πŸ”¬Tech deep dive: Boosting yield by compounding rewards
      • Deposit into the Vault
      • Withdraw from the Vault
      • Redeem rewards
      • Automatic boosting with Alluo
      • FraxConvex Vaults
      • Managing withdrawal requests in IERC4626
  • Decentralisation and Trust
    • πŸ—³οΈ Trustless governance and execution
    • πŸ‘¨β€πŸ”¬Tech deep dive: Vote Executor Architecture
      • Off chain votes to on chain data
      • Onchain data verifcation
      • Automated execution of votes
        • Tokenomics
        • Liquidity Direction
        • Setting APYs on farms
      • Cross chain execution of votes
      • Manually submitting vote results onchain
    • ↔️Alluo Exchange
      • Interacting with the Exchange
    • vlAlluo Architecture
    • Contracts upgrades
    • Investment strategies
      • πŸ“ˆFrax Convex Finance
        • Adding new pools into the strategy
        • Investing into a pool
  • More Advanced Features
    • πŸ” Repeat payments, streaming IbAlluo
  • Product Updates
    • πŸ‘Œ Product Roadmap: Building the right products
    • πŸ’» Web App releases
    • πŸ“± Mobile App releases
    • 🏎️ Alluo Boost
  • tutorial projects
    • Example: USDC to streaming 1 IbAlluo per second
    • Example: Using IbAlluoUSD and Ricochet to do capital efficient DCA into ETH
Powered by GitBook
On this page
  • 1. Grant Permissions first!
  • 2. Once permissions are granted, now call the createFlow function
  1. Tokens & Tokenomics
  2. Tech deep dive: Interest Bearing {asset} token

Using the IbAlluo contract directly to create streams

Creating a stream directly through the IbAlluo contract allows you to bypass manually wrapping and approving the StIbAlluo contract.

1. Grant Permissions first!

To do so, you must grant permissions to the IbAlluo contract as a stream operator for your account. One way you can do this is through hardhat by instantiating an IbAlluo contract, using formatPermissions to get the callData and then calling the Superfluid Host contract with the following parameters. This only needs to be done once for each IbAlluo contract when initially making a stream.

IbAlluo.sol
/// @notice Formats permissios so users can approve the ibAlluo contract as an operator of streams
/// @dev This can be removed once the frontend hardcodes the function call / does it inside ethers.js.
function formatPermissions() public view returns (bytes memory) {
     return abi.encodeCall(
            cfaV1Lib.cfa.authorizeFlowOperatorWithFullControl,
            (
                ISuperfluidToken(superToken),
                address(this),
                new bytes(0)
            )
        );
}
Example on polygon
let encodeData = await ibAlluoCurrent.formatPermissions();
let superhost = await ethers.getContractAt("Superfluid", "0x3E14dC1b13c488a8d5D310918780c983bD5982E7");
await superhost.callAgreement(
    "0x6EeE6060f715257b970700bc2656De21dEdF074C",
    encodeData,
    "0x"
)

2. Once permissions are granted, now call the createFlow function

IbAlluo.sol
/// @notice Wraps and creates flow 
/// @dev Forces transfer of ibAlluo to the StIbAlluo contract then mints StIbAlluos to circumvent having to sign multiple transactions to create streams
/// @param receiver The recipient of the streamed flow
/// @param flowRate The amount of ibAlluos per second to be streamed (decimals 10**18)
/// @param toWrap The amount of ibAlluos to automatically wrap (recommend wrapping entire ibALluo balance initially)
function createFlow(address receiver, int96 flowRate, uint256 toWrap) external {
    _transfer(msg.sender, address(this), toWrap);
    _approve(address(this), superToken, toWrap);
    IAlluoSuperToken(superToken).upgradeTo(msg.sender, toWrap, "");
    cfaV1Lib.createFlowByOperator( msg.sender, receiver, ISuperfluidToken(superToken), flowRate);
    ISuperfluidResolver(superfluidResolver).addToChecker(msg.sender, receiver);
    emit CreateFlow(msg.sender, receiver, flowRate);
}
function stopFlowWhenCritical(address sender, address receiver) external onlyRole(DEFAULT_ADMIN_ROLE) {
    cfaV1Lib.deleteFlowByOperator(sender, receiver, ISuperfluidToken(superToken));
    emit DeletedFlow(sender, receiver);
}
    
function forceWrap(address sender) external onlyRole(DEFAULT_ADMIN_ROLE) {
    uint256 balance = balanceOf(address(sender));
    _transfer(sender, address(this), balance);
    _approve(address(this), superToken, balance);
    IAlluoSuperToken(superToken).upgradeTo(sender, balance, "");
}

Calling createFlow will force transfer IbAlluos and then the IbAlluo contract will upgrade on your behalf and mint you StIbAlluos. Then, a flow will be created with the parameters you specified.

When creating a stream through the IbAlluo contract, the Alluo protocol protects you from liquidations: addToChecker() adds you to a list of users that a gelato resolver will check for liquidation risk. This means that whenever your StIbAlluo balance is low, a resolver will either call forceWrap() so you don't get accidentally liquidated, or close the stream entirely using stopFlowWhenCritical().

To illustrate this with examples:

  • Case 1: Stream close to liquidation but with enough IbAlluo balance to cover it.

You have 100 IbAlluos and 100 StIbAlluos with an outgoing stream of 20 IbAlluos per hour. You are 1 hour away from being liquidated by the superfluid protocol (including the deposit initially taken).

The Alluo resolver will realise that you have 100 IbAlluo to continue the stream and therefore wrap the IbAlluo to StIbAlluo - leaving you with 0 IbAlluo and 200 StIbAlluo to continue the stream.

  • Case 2: Stream close to liquidation but without enough IbAlluo balance to cover it.

You have 0 IbAlluos and 100 StIbAlluos with an outgoing stream of 20 IbAlluos per hour. You are 1 hour away from being liquidated by the superfluid protocol (including the deposit initially taken). The Alluo protocol will close your stream 1 hour prematurely to prevent your 80 StIbAlluos from being taken as a liquidation fee.

PreviousA closer look at the integration between IbAlluo and StIbAlluoNextLiquidity Handler and adapters

Last updated 2 years ago

πŸ‘¨β€πŸ”¬