Helio Docs
English
Search…
⌃K

Helio mechanics

Helio mechanics

The key components of Helio functions lie between a set of smart contracts that interact across blockchains and existing contracts. Helio created its customized smart contracts based on a fork of MakerDAO smart contract set.

Modules

Helio consists of 2 main modules:
  • Core module (a MakerDAO fork and Helio's Interaction contract) — provide collateral, borrow HAY, repay HAY, withdraw collateral, liquidate collateralized assets.
  • Rewards module — claim rewards in HELIO.

Requirements

  • Minimum deposit amount — 0.5021 BNB.
  • Minimum withdrawal amount — 0.5 BNB.
  • Minimum borrowing amount of HAY — 100 HAY.
  • Loan cannot go under 100 HAY, so the user may either choose to repay it to 100 HAY or in full.

Fees

  • Borrowing interest — an interest paid to Helio for borrowing HAY. The rate is a fixed number set by Helio governance platform.
  • Liquidation penalty — percentage subtracted in the form of HAY when selling user's collateral in a Dutch action during the liquidation process.

Ratios

Collateral ratio — a percentage of the user's collateral value that determines the maximum borrowing limit for the user; it is calculated as follows: (total amount of HAY minted / total value of the collateral * 100). Different assets will have different collateral ratios, depending on asset volatility. Collateral ratio is used as a liquidation bar to decide when a liquidation event should happen.

Rewards

  • Borrowing reward — users get rewards for borrowing HAY, in HELIO — the Helio token. Rewards are calculated dynamically and are the product of rewards rate and total user’s debt in HAY. The rewards rate is a fixed amount set by Helio.
  • Auction start reward — anybody who triggers the liquidation event of a CDP, i.e. start of a Dutch auction, receives a flat fee (tip) and a percentage fee (chip) for just initiating the process. Tip and chip are paid by Helio from Helio reserves.
  • Auction restart reward — anybody who restarts the Dutch auction, which is part of the liquidation process, receives a flat fee (tip) and a percentage fee (chip). An EOA can restart the auction when the auction time limit is reached or the price decrease has reached a certain threshold. These two limits are set by Helio governance. Tip and chip are paid by Helio from Helio reserves.

Liquidation model

Variable/Step
Value/Formula
Price of 1 unit of collateral
$2
Liquidation ratio
66%
Collateral price based on liquidation ratio
$1.32
Assume User deposit 10 units collateral
10 * 2 = $20
Borrow limit
user_deposit * liquidation_ratio = 20 * 0.66 = $13.2
Assume User borrows $13.2 of HAY
13.2 HAY
Assume Price of 1 unit of collateral decreases to
$1.8
Collateral unit price with safety margin
current_collateral_unit_price * liquidation_ratio = 1.8 * 0.66 = $1.188
Current worth of collateral with safety margin
price_of_colatteral * amount_of_collateral= 1.188 * 10 = $11.88
Positive diff puts user under liquidation line
borrowed_amount - current_total_colateral_borrow_limit = 13.2 - 11.88 = $1.32
Amount of collateral that goes to Dutch auction
10
Liquidation penalty (fixed by Helio governance)
13% of the debt
Debt to cover in the auction
borrowed_amount * liquidation penalty = 13.2 * 1.13 = $14.916
buf (percentage similar to liquidation penalty, fixed by Helio governance)
2%
Starting auction price (top)
current_collaterral_unit_price * buf = 1.8 * 1.02 = $1.836
Somebody triggers auction and gets tip + chip as a reward for doing it (described later)
Auction starts and the price gradually decreases. Liquidator can participate to buy customized amount of liquidated collateral
tau (time until price is 0; fixed by Helio governance))
e.g. 3600
dur (fixed by Helio governance)
time in seconds elapsed since the auction start, e.g. 600
Linear decrease of price (subject to be disrupted at the below event)
top * ((tau - dur) / tau) = 1.836 * ((3600 - 600) / 3600) = $1.53
Pause auction because of one of two conditions: — tail (specific amount of time elapsed; fixed by Helio governance) OR — cusp (% of price drop; 40% start auction price; fixed by Helio governance)
either requirement is met, the auction will be restarted
Wait till someone restarts auction
tip (flat fee; fixed by Helio governance))
$300
chip (dynamic fee; fixed by Helio governance))
%0.1 of amount of debt in the auction
Restarter gets tip + chip as a reward

Smart contracts

The smart contracts that implement Helio are:
  • MakerDAO set — the Maker Protocol, also known as the Multi-Collateral Dai (MCD) system, allowing users to generate HAY by leveraging collateralized assets. HAY is a decentralized, unbiased, collateral-backed cryptocurrency soft-pegged to the US Dollar.
    • ABACI — price decrease function for Dutch auctions during the liquidation process of user's assets.
    • CLIP — liquidation v2.0 mechanics.
    • DOG — starts Dutch auctions during the liquidation process of user's assets.
    • JUG — collects Helio's borrowing interest for lending HAY to the user.
    • JAR — stakes and unstakes HAY, mints and burn hHAY token (token–deposit receipt for staked HAY).
    • JOIN — BEP-20 token adapters:
      • HayJoin — adapter between MakerDAO and HAY via which adapter which withdraws internal HAY from the system into a standard ERC20 token when user borrows HAY tokens or burns ERC20 when user repays their HAY loan to Helio.
      • ceaBNBcJoin — adapter between MakerDAO and HelioProvider that allows user assets to be deposited in the system for collateralization.
    • SPOT — oracle that fetches the price of aBNBc, which is an intermediate token used during the process of collateralizing user's assets.
    • VAT — сore vault for collateralized debt positions (CDP).
    • VOW — vault balance sheet. Keeps track of debt or surplus of HAY.
  • CurveProxyForDeposit — add liquidity to the StableSwap pool, get LP tokens, deposit LP tokens for Farming smart contract.
  • Farming — deposit or withdraw farmed tokens, distribute rewards in HAY to the depositors.
  • IncentiveVoting — distribute rewards among the internat pools (in the Farming contract) or external pools (e.g. Ellipsis, Wombat, and so on), depending on the votes, which depend on the staked HELIO governance tokens (future functionality).
  • StableCoinStrategyCurve — swap PancakeSwap farming rewards (CAKE) into HAY and BUSD, add them to the StableSwap liquidity pool, get LP tokens, add these LP tokens to the user share in the pool.
  • HelioRewards — rewards distribution, in the HELIO rewards token.
  • HelioToken — BEP-20 compatible rewards token given to the user for borrowing HAY.
  • HelioOracle — oracle for the HELIO rewards token.
  • HelioProvider — wraps BNB into ceABNBc via cerosRouter.
  • cerosRouter — finds the best way to obtain aBNBc, which is an intermediate token used during the process of collateralizing user's assets.
  • CeToken — ceABNBc, which is the underlying collateral token inside MakerDAO.
  • CeVault — stores obtained aBNBc, which is an intermediate token used during the process of collateralizing user's assets.
  • Interaction — proxy for the MakerDAO contracts. Provides deposit, withdraw, borrow, payback, and liquidation functions to the end users.
  • AuctionProxy — entrypoint for Dutch auction methods, which is part of the liquidation process of user's assets. Allow users to start and participate in auctions.
  • aBNBc — liquid yield-bearing token used during the process of collateralizing user's assets.
  • hBNB — token minted for the user as a deposit receipt for their collateral.
For the addresses, refer to smart contracts addresses table. For the codebase, refer to the smart contracts repo on GitHub.

Workflow

Here are the main Helio's operations described in high-level detail.

Collateralize user’s assets to borrow HAY

When a user initiates a deposit action, the following sequence of events will occur.
  1. 1.
    User transfers BNB to Helio via HelioProvider::provide().
  2. 2.
    HelioProvider mints hBNB for the user as a deposit receipt for their collateral.
  3. 3.
    HelioProvider gets ceABNBc, running the following logic inside:
    1. 1.
      Exchanges BNB for aBNBc via cerosRouter::deposit({value: msg.value}). During this step, cerosRouter weighs the method profitability and choose 1 from the following 2 options:
      1. 1.
        Option 1: swap BNB on DEX for aBNBc.
      2. 2.
        Option 2: stake BNB in Binance Liquid Staking via the BinancePool smart contract and exchange BNB for aBNBc.
    2. 2.
      cerosRouter sends aBNBc to CeVault for storing the amount of exchanged aBNBc. This is done via CeVault::depositFor(msg.sender, amount after exchange), where msg.sender — HelioProvider address and amount after exchange — the amount of exchanged aBNBc.
    3. 3.
      CeVault mints ceABNBc for HelioProvider.
  4. 4.
    HelioProvider collateralizes ceABNBc via Interaction::deposit(account, address(ceABNBc), amount), where account — user's account address, address(ceABNBc) — address of ceABNBc smart contract, amount — BNB initially collateralized by the user minus fees (relayer fee from BinancePool). Interaction runs the following logic inside:
    1. 1.
      Transfers ceABNBc (BEP-20 token) to the Interaction smart contract, via the transfer() function of the BEP-20 token smart contract.
    2. 2.
      Transfers the assets to the MakerDAO vault via gem::join(). For more information, refer to the Join docs.
    3. 3.
      Makes the VAT smart contract fully trust the Interaction smart contract via VAT::behalf().
    4. 4.
      Locks the assets inside MakerDAO via VAT::frob(), effectively collateralizing them. For more information, refer to the VAT docs.
    5. 5.
      Emits a Deposit event.

Borrow HAY

When a user initiates a borrowing action, the following sequence of events will occur.
  1. 1.
    Borrow HAY via Interaction::borrow(). Interaction runs the following logic inside:
    1. 1.
      Calculate the current HAY value inside Helio. Calculation takes into consideration the borrowing limit, which is the price of the total assets collateralized by the user * collateral ratio (fixed amount set by Helio).
    2. 2.
      The user is indebted for an amount equivalent to the borrowed HAY via VAT::frob(). For more information, refer to the VAT docs.
    3. 3.
      Transfer the borrowed HAY via HAYJoin::exit(). For more information, refer to the Join docs.
    4. 4.
      Emit a Borrow event.

Farm HAY–BUSD (LP) (PancakeSwap — StableSwap pool)

There are two cases:
  • User doesn't yet have LP tokens.
  • User already has LP tokens.
When a user doesn't yet have LP tokens and initiates a farming action, the following sequence of events will occur.
  1. 1.
    Let CurveProxyForDeposit access HAY tokens via hay::approve(spender, amount) and BUSD tokens via busd::approve(spender, amount), where spender — address of the CurveProxyForDeposit smart contract, amount — amount to approve access to.
  2. 2.
    CurveProxyForDeposit adds the approved tokens to the StableSwap liquidity pool via CurveProxyForDeposit::depositToFarming(stableSwap, amount0, amount1, minMintAmount), where stableSwap — address of the StableSwap pool, amount0 — amount of HAY tokens to add, amount1 — amount of BUSD tokens to add, minMintAmount — minimum amount of LP tokens to mint from the added liquidity.
  3. 3.
    CurveProxyForDeposit deposits the minted LP tokens from #2 to Farming via Farming::deposit(uint256 _pid, uint256 _wantAmt, bool _claimRewards, address _userAddress), where _pid — pool ID in Farming, _wantAmt — amount of LP tokens, _claimRewards — auto-claim of rewards (def. value — false), _userAddress — address of the user who called the function.
  4. 4.
    Farming transfer the received LP tokens to StableCoinStrategyCurve via StableCoinStrategyCurve::deposit(address _userAddress, uint256 _wantAmt), where _userAddress — address of the user who called the function, _wantAmt — amount of sent LP tokens.
  5. 5.
    StableCoinStrategyCurve deposits LP tokens to MasterChefV2 via MasterChefV2::deposit(uint256 _pid, uint256 _wantAmt), where _pid — pool ID in MasterChefV2, _wantAmt — amount of deposited LP tokens.
When a user has LP tokens and initiates a farming action, the following sequence of events will occur.
  1. 1.
    Let Farming access the LP tokens via PancakeStableSwapLP::approve(spender, amount), where lp is a PancakeSwap LP token smart contract, spender — address of Farming, amount — amount of LP tokens to give access to.
  2. 2.
    Deposit the LP tokens to Farming via Farming::deposit(uint256 _pid, uint256 _wantAmt, bool _claimRewards, address _userAddress), where _pid — pool ID in Farming, _wantAmt — amount of LP tokens, _claimRewards — auto-claim of rewards (def. value — false), _userAddress — address of the user who called the function.
  3. 3.
    Farming transfers the received LP tokens to StableCoinStrategyCurve via StableCoinStrategyCurve::deposit(address _userAddress, uint256 _wantAmt), where _userAddress — address of the user who called the function, _wantAmt — amount of sent LP tokens.
  4. 4.
    StableCoinStrategyCurve deposits LP tokens to MasterChefV2 via MasterChefV2::deposit(uint256 _pid, uint256 _wantAmt), where _pid — pool ID in MasterChefV2, _wantAmt — amount of deposited LP tokens.

Compound farming rewards

When Helio creates compound rewards, the following sequence of events will occur.
  1. 1.
    Harvest the rewards via StableCoinStrategyCurve::harvest() . StableCoinStrategyCurve runs the following logic inside:
    1. 1.
      Gets rewards in the CAKE token via MasterChefV2.withdraw(pid, _wantAmt), where pid — pool ID in MasterChefV2, and _wantAmt — 0.
    2. 2.
      If CAKE_amount > minEarnAmount, swap all CAKE to BUSD via IPancakeRouter02(_uniRouterAddress).swapExactTokensForTokens( _amountIn, 0, _path, _to, _deadline ), where _amountIn — amount of CAKE, 0 — no min amount of BUSD to get, _path — array (CAKE address, BUSD address), _to — address of StableCoinStrategyCurve, _deadline — block timestamp + 700. Else, finish the workflow.
    3. 3.
      Swap half of the swapped BUSD for HAY via StableSwap.exchange(_i, _j, _dx, 0), where _i — 1 (BUSD), _j — 0 (HAY), _dx — amount of BUSD, 0 — no min amount of HAY to get.
    4. 4.
      Add liquidity via StableSwap::add_liquidity(amounts, 0), where amounts — array (amount of HAY, amount of BUSD), 0 — no min amount of LP tokens to mint from the added liquidity.
    5. 5.
      Farm the obtained LP tokens via MasterChefV2.deposit(pid, wantAmt), where pid — pool ID in MasterChefV2, wantAmt — amount of LP tokens obtained at #4.

Claim farming rewards

When a user initiates a reward-claiming action, the following sequence of events will occur.
  1. 1.
    Claim rewards in HAY via Farming::claim(address _user, uint256[] _pids), where _user — address to claim rewards for, _pids — array of pool IDs to get rewards for.

Withdraw HAY–BUSD (LP) (PancakeSwap — StableSwap pool)

When a user initiates an unfarming action, the following sequence of events will occur.
  1. 1.
    User withdraws LP tokens via Farming::withdraw(uint256 _pid, uint256 _wantAmt, bool _claimRewards), where _pid — pool ID in Farming, _wantAmt — amount of LP tokens to withdraw (set to max value of uint256 to withdraw all user's LP tokens), _claimRewards — auto-claim rewards. Farming runs the following logic inside:
    1. 1.
      Farming withdraws LP tokens from StableCoinStrategyCurve via StableCoinStrategyCurve::withdraw(address _userAddress, uint256 _wantAmt), where _userAddress — address of the user who called the function, _wantAmt — amount of LP tokens to withdraw.
    2. 2.
      StableCoinStrategyCurve withdraws LP tokens to MasterChefV2 via MasterChefV2::withdraw(uint256 _pid, uint256 _wantAmt), where _pid — pool ID in MasterChefV2, _wantAmt — amount of withdrawn LP tokens.
You can also use withdrawAll(uint256 _pid, bool _claimRewards) at #1.1 to withdraw all the user's LP tokens.

Withdraw HAY–BUSD (PancakeSwap — StableSwap pool)

User visit the StableSwap pool on PancakeSwap and withdraws the liquidity (HAY and BUSD) manually.

Stake HAY

When a user initiates a staking action, the following sequence of events will occur.
  1. 1.
    Deposit HAY via JAR::join(). JAR runs the following logic inside:
    1. 1.
      Mint hHAY token in 1:1 ratio to the deposited HAY amount.
    2. 2.
      Emit a Join event.

Unstake HAY

When a user initiates an unstaking action, the following sequence of events will occur.
  1. 1.
    Withdraw HAY via JAR::exit(). JAR runs the following logic inside:
    1. 1.
      Burn hHAY token in 1:1 ratio to the deposited HAY amount.
    2. 2.
      Emit an Exit event.

Repay HAY

When a user initiates a repayment action, the following sequence of events will occur.
  1. 1.
    Repay Helio the borrowed HAY via Interaction::payback(). Interaction runs the following logic inside:
    1. 1.
      Transfer the HAY (BEP-20 token) to the Interaction smart contract via the transfer() function of the BEP-20 token smart contract.
    2. 2.
      Transfer the HAY to the MakerDAO vault via HAYJoin::join(). For more information, refer to the Join docs.
    3. 3.
      Calculate the current HAY value inside Helio.
    4. 4.
      Subtract the repaid HAY amount from the user’s debt via VAT::frob(). For more information, refer to the VAT docs.
    5. 5.
      Emit a Payback event.

Withdraw collateral

When a user initiates a withdrawal action and supplies with their hBNB, the following sequence of events will occur.
  1. 1.
    Platform burn user's hBNB via HelioProvider::release().
  2. 2.
    HelioProvider gets ceABNBc back via Interaction::withdraw(account, address(ceABNBc), amount), where account — user's account address, address(ceABNBc) — address of ceABNBc smart contract, amount — BNB initiallly collateralized by the user - fees (relayer fee from BinancePool). Interaction runs the following logic inside:
    1. 1.
      Unlock the assets via VAT::frob(). For more information, refer to the VAT docs.
    2. 2.
      Transfer the assets from the CDP engine to the MakerDAO vault via VAT::flux(). For more information, refer to the VAT docs.
    3. 3.
      Transfer the assets to the user’s wallet via gem::exit(). For more information, refer to the Join docs.
    4. 4.
      Emit a withdraw event.
  3. 3.
    Exchange ceABNBc to BNB.
    1. 1.
      HelioProvider exchanges ceABNBc for aBNBc via cerosRouter::withdraw(address recipient, uint256 amount), where address recipient — desired user's address to release BNB to in the future, amount — amount ceABNBc to exchange to BNB.
    2. 2.
      cerosRouter in turn calls CeVault::withdrawFor(msg.sender, address(this), amount) to exchange aBNBc for BNB, where address(this) — address of cerosRouter, amount — amount ceABNBc to exchange to aBNBc, msg.sender — address of the HelioProvider smart contract.
    3. 3.
      CeVault burns aBNBc and unstakes BNB via BinancePool::unstakeCerts(recipient, realAmount), where recipient — user's address, realAmount — amount of BNB * aBNBC.ratio().

Claim rewards

Borrowers can claim rewards in the form of HELIO for borrowing HAY. When a user initiates a claim rewards action, the following sequence of events will occur.
  1. 1.
    Claim a reward for the borrowed HAY to the user’s wallet via HelioRewards::claim(). HelioRewards runs the following logic inside:
    1. 1.
      Update the rewards pool size and rewards rate.
    2. 2.
      Transfer the pending user rewards to the user’s wallet via HelioToken::transfer().

Liquidation

When liquidation of assets is possible and when a user initiates a liquidation action, the following sequence of events will occur.
For explanation of specific parameters and their current values, refer to the liquidation model earlier on this page.
  1. 1.
    When the current worth of collateral with safety margin < borrowed amount of HAY, a user (anybody) triggers the liquidation process via Interaction::startAuction(token, user, keeper), where token — address of the liquidated assets, user — address of user whose collateral is being liquidated, keeper — address of the user who gets a reward (tip + chip) for starting the auction. Interaction runs the following logic inside:
    1. 1.
      Start a Dutch auction:
      1. 1.
        Set the starting auction price for the liquidated collateral to be equal (current_collaterral_unit_price * buf).
      2. 2.
        Let anybody come and buy via buyFromAuction(token, auctionId, collateralAmount, maxPrice, receiverAddress) to buy any amount > than dust (currently 1 USD). token — address of the liquidated assets, auctionId — ID of the auction, collateralAmount — amount to buy, maxPrice — price to pay , receiverAddress — address of the buyer.
      3. 3.
        If the maxPirce is > current_ auction_collateral_unit_price, sell the requested amount of the user's collateral to the buyer.
      4. 4.
        Else, incrementally lower the auction price and let anybody buy still. The reason for decreasing from a higher price is because of bots and change of collateral price from oracle to avoid any sudden loss. The auction lasts a fixed amount of time (tau) set by Helio governance. The price is recalculated every second of the auction.
      5. 5.
        When the auction time limit is reached or the price decrease has reached a certain threshold (the limits are set by Helio governance; currently the time limit is 21600s and price limit is 40%), let anybody come and restart the auction and get a reward (tip + chip) for doing it.
    2. 2.
      Transfer the price paid in 1.3, in HAY, from the buyer's wallet to Helio.
    3. 3.
      Exchange ceABNBc for aBNBc and send aBNBc to the buyer's wallet. Effectively, buyer buys aBNBc that they can later exchange for BNB.
    4. 4.
      Cover debt and keep profit (borrowed amount + (borrow interest + liquidation penalty)).
    5. 5.
      Calculate the remainder (price paid - debt - profit). Send the remainder to the user’s wallet.