# Alpha Homora contract documentation Alpha Homora is a decentralize leverage yield farming product. We allow users to lever up their yield farming position by borrowing external liquidity from the lending protocol. Users can open leveraged positions, add more liquidity, harvest their positions, and remove their liquidity. # Alpha Homora Components Alpha Homora product is mainly composed of 5 components 1. Homora Bank Contract - is the main contract where stores user's positions and tracks the borrowing tokens. 2. Homora Wrapper Contracts - handle the farming process (i.e. deposit into Masterchef contract). 3. Homora Spell Contracts - interact with DEX and the wrapper contract to open/add/remove/close users' positions. 4. Homora Oracle Contracts - Identify position values and token price 5. Homora SafeBox Contracts - allow users to lend tokens and earn lending interest (interest rate is reflected from how much user borrow the token). # Interact with Alpha Homora Product Farming on different DEX protocols uses different spell contracts. To interact with HomoraBank, you need to know which DEX protocol to farm (i.e. Uniswap, Sushiswap or Curve) and correctly map with the spell contract. ![](https://i.imgur.com/cizves9.png) See all contract addresses and download abi file [ABI](https://drive.google.com/drive/folders/1bAYYGEeVfkNoq9dzaDqzqy2-ZprxUHB6?usp=sharing) | Description | Contract Address | ABI | | ---------------------- |:------------------------------------------ |:--- | | HomoraBank | 0xba5eBAf3fc1Fcca67147050Bf80462393814E54B | | | SushiswapSpellV1 | 0xdc9c7a2bae15dd89271ae5701a6f4db147baa44c | | | UniswapV2SpellV1 | 0x00b1a4e7f217380a7c9e6c12f327ac4a1d9b6a14 | | | CurveSpellV1 | 0x8b947D8448CFFb89EF07A6922b74fBAbac219795 | | | WMasterChef | 0xA2caEa05fF7B98f10Ad5ddc837F15905f33FEb60 | | | WLiquidityGauge | 0xf1F32C8EEb06046d3cc3157B8F9f72B09D84ee5b | | | WStakingRewards(INDEX) | 0x011535FD795fD28c749363E080662D62fBB456a7 | | | IMasterChef | - | | | IStakingRewards | - | | Available pools https://api.homora.alphaventuredao.io/v2/1/pools ### Steps - Choose a spell that you want to farm | Chain | Protocol | Spell | Address | | -------- |:--------- |:---------------- |:------------------------------------------ | | Ethereum | Uniswap | UniswapV2SpellV1 | 0x00b1a4e7f217380a7c9e6c12f327ac4a1d9b6a14 | | | Sushiswap | SushiswapSpellV1 | 0xdc9c7a2bae15dd89271ae5701a6f4db147baa44c | | | Curve | CurveSpellV1 | 0x8b947D8448CFFb89EF07A6922b74fBAbac219795 | - Choose an action you want to interact with HomoraBank For example, you want to integrate with Sushiswap leverage farm, you choose SushiswapSpellV1 and then decide which action/function you want to interact to HomoraBank from the list [here](#SushiswapSpellV1). - For yield farming, you need to add more additional argument to function (i.e. pool id for Sushiswap, wrapped staking contract for UniswapV2, gauge id for Curve). You will see how to find it in the examples below > Scenario: User opens new position to farm DEI-WETH LP on UniswapV2 with staking contract > - choose spell -> UniswapV2SpellV1 > - choose action -> addLiquidityWStakingRewards The followings are example of how to interact with the product. ## Example [actions](#SushiswapSpellV1) for Sushiswap leverage farm - To find available leverage pools for Sushiswap, visit https://api.homora.alphaventuredao.io/v2/1/pools and then filter only pool that `exchange.name` is Sushiswap. ### Yield Farming: Assume a user farms on Masterchef of Sushiswap 1. open position ```python= bank = HomoraBank.at("0xba5eBAf3fc1Fcca67147050Bf80462393814E54B") spell = SushiswapSpellV1.at("0xdc9c7a2bae15dd89271ae5701a6f4db147baa44c") # spell token0 = "0x.." # token 0 token1 = "0x.." # token 1 amount0 = 10000 # supply token0 amount1 = 10000 # supply token1 amount_lp = # supply LP amount0_borrow = 10000 # borrow token0 amount1_borrow = 10000 # borrow token1 pid = 20 # pool id bank.execute( 0, # (0 is reserved for opening new position) spell, spell.addLiquidityWMasterChef.encode_input( token0, # token 0 token1, # token 1 [ amount0, # supply token0 amount1, # supply token1 amount_lp, # supply LP amount0_borrow, # borrow token0 amount1_borrow, # borrow token1 0, # borrow LP tokens (always 0 since LP for borrowing is disabled) 0, # min token0 0, # min token1 ], pid, # pool id to farm on MasterChef ), # data {"from": user}, ) ``` 2. increase position ```python= bank = HomoraBank.at("0xba5eBAf3fc1Fcca67147050Bf80462393814E54B") spell = SushiswapSpellV1.at("0xdc9c7a2bae15dd89271ae5701a6f4db147baa44c") pos_id = 123 # position to increase token0 = "0x.." # token 0 token1 = "0x.." # token 1 amount0 = 10000 # supply token0 amount1 = 10000 # supply token1 amount_lp = 0 # supply LP amount0_borrow = 10000 # borrow token0 amount1_borrow = 10000 # borrow token1 pid = 20 # pool id bank.execute( pos_id, # position id spell, # spell spell.addLiquidityWMasterChef.encode_input( token0, # token 0 token1, # token 1 [ amount0, # supply token0 amount1, # supply token1 amount_lp, # supply LP amount0_borrow, # borrow token0 amount1_borrow, # borrow token1 0, # borrow LP tokens (always 0 since LP for borrowing is disabled) 0, # min token0 0, # min token1 ], pid, # pool id to farm on MasterChef ), # data {"from": user}, ) ``` 3. reduce position (and repay debt if any) ```python= bank = HomoraBank.at("0xba5eBAf3fc1Fcca67147050Bf80462393814E54B") spell = SushiswapSpellV1.at("0xdc9c7a2bae15dd89271ae5701a6f4db147baa44c") pos_id = 123 # position to increase token0 = "0x.." # token 0 token1 = "0x.." # token 1 amt_a_repay = 100000 # amtARepay amt_b_repay = 200000 # amtBRepay # fetch remaining collateral amount in the position _, _, _, coll_amt = bank.getPositionInfo(pos_id) debt_tokens, debt_amts = bank.getPositionDebts(pos_id) remove_wmasterchef_amt = coll_amt remove_lp_amt = coll_amt bank.execute( pos_id, spell, spell.removeLiquidityWMasterChef.encode_input( token0, # token0 token1, # token1 [ remove_wmasterchef_amt, # amtLPTake remove_lp_amt, # amtLPWithdraw amt_a_repay, # amtARepay amt_b_repay, # amtBRepay 0, # amtLPRepay 0, # amtAMin 0 # amtBMin ], ), {"from": user}, ) ``` 4. harvest rewards ```python= bank = HomoraBank.at("0xba5eBAf3fc1Fcca67147050Bf80462393814E54B") spell = SushiswapSpellV1.at("0xdc9c7a2bae15dd89271ae5701a6f4db147baa44c") pos_id = 123 bank.execute( pos_id, spell, spell.harvestWMasterChef.encode_input(), {"from": user}, ) ``` 5. get pending rewards ```python= bank = HomoraBank.at("0xba5eBAf3fc1Fcca67147050Bf80462393814E54B") pos_id = 10 # position id to calculate pending rewards _, coll_token_addr, coll_id, coll_amt = bank.getPositionInfo(pos_id) # for sushiswap, choose wmasterchef contract wrapper = WMasterChef.at(coll_token_addr) # use interface contract from MasterChef chef = interface.IMasterChef(wrapper.chef()) # find start token per share pid, start_token_per_share = wrapper.decodeId(coll_id) # find current token per share _, _, _, end_token_per_share = chef.poolInfo(pid) acc_token_per_share_precision = 12 # depend on staking contract implementation # calculate pending rewards pending_rewards = ( coll_amt * (end_token_per_share - start_token_per_share) // 10 ** (acc_token_per_share_precision) ) ``` ## Example [actions](#UniswapV2SpellV1) for UniswapV2 leverage farm - To find available leverage pools for UniswapV2, visit https://api.homora.alphaventuredao.io/v2/1/pools and then filter only pool that `exchange.name` is Uniswap V2. ### Liquidity Providing: Assume a user adds liquidity to Uniswap pool without staking rewards 1. open position ```python= bank = HomoraBank.at("0xba5eBAf3fc1Fcca67147050Bf80462393814E54B") spell = UniswapV2SpellV1.at("0x00b1a4e7f217380a7c9e6c12f327ac4a1d9b6a14") # spell token0 = "0x.." # token 0 token1 = "0x.." # token 1 amount0 = 10000 # supply token0 amount1 = 10000 # supply token1 amount_lp = # supply LP amount0_borrow = 10000 # borrow token0 amount1_borrow = 10000 # borrow token1 bank.execute( 0, # (0 is reserved for opening new position) spell, spell.addLiquidityWERC20.encode_input( token0, # token 0 token1, # token 1 [ amount0, # supply token0 amount1, # supply token1 amount_lp, # supply LP amount0_borrow, # borrow token0 amount1_borrow, # borrow token1 0, # borrow LP tokens (always 0 since LP for borrowing is disabled) 0, # min token0 0, # min token1 ], ), # data {"from": user}, ) ``` 2. increase position ```python= bank = HomoraBank.at("0xba5eBAf3fc1Fcca67147050Bf80462393814E54B") spell = UniswapV2SpellV1.at("0x00b1a4e7f217380a7c9e6c12f327ac4a1d9b6a14") pos_id = 123 # position to increase token0 = "0x.." # token 0 token1 = "0x.." # token 1 amount0 = 10000 # supply token0 amount1 = 10000 # supply token1 amount_lp = 0 # supply LP amount0_borrow = 10000 # borrow token0 amount1_borrow = 10000 # borrow token1 bank.execute( pos_id, # position id spell, # spell spell.addLiquidityWERC20.encode_input( token0, # token 0 token1, # token 1 [ amount0, # supply token0 amount1, # supply token1 amount_lp, # supply LP amount0_borrow, # borrow token0 amount1_borrow, # borrow token1 0, # borrow LP tokens (always 0 since LP for borrowing is disabled) 0, # min token0 0, # min token1 ], ), # data {"from": user}, ) ``` 3. reduce position (and repay debt if any) ```python= bank = HomoraBank.at("0xba5eBAf3fc1Fcca67147050Bf80462393814E54B") spell = UniswapV2SpellV1.at("0x00b1a4e7f217380a7c9e6c12f327ac4a1d9b6a14") pos_id = 123 # position to increase token0 = "0x.." # token 0 token1 = "0x.." # token 1 amt_a_repay = 100000 # amtARepay amt_b_repay = 200000 # amtBRepay # fetch remaining collateral amount in the position _, _, _, coll_amt = bank.getPositionInfo(pos_id) debt_tokens, debt_amts = bank.getPositionDebts(pos_id) remove_lp_amt = coll_amt bank.execute( pos_id, spell, spell.removeLiquidityWERC20.encode_input( token0, # token0 token1, # token1 [ remove_lp_amt, # amtLPTake remove_lp_amt, # amtLPWithdraw amt_a_repay, # amtARepay amt_b_repay, # amtBRepay 0, # amtLPRepay 0, # amtAMin 0 # amtBMin ], ), {"from": user}, ) ``` ### Yield Farming: Assume a user adds liquidity to Uniswap pool with staking rewards - Find wrapped staking contract whose underlying token address matches LP address that you want to farm - Currently there is only one pool that allows user to use wstaking contract for UniswapV2 | Farm | WStakingRewards address | Underlying token address | | -------- |:------------------------------------------ |:------------------------------------------ | | DPI-WETH | 0x011535FD795fD28c749363E080662D62fBB456a7 | 0x4d5ef58aAc27d99935E5b6B4A6778ff292059991 | 1. open position ```python= bank = HomoraBank.at("0xba5eBAf3fc1Fcca67147050Bf80462393814E54B") spell = UniswapV2SpellV1.at("0x00b1a4e7f217380a7c9e6c12f327ac4a1d9b6a14") # spell wstaking = WStakingRewards.at("0x011535FD795fD28c749363E080662D62fBB456a7") # please make sure that received LP address after providing token0 and token1 # is the same as underlying token address from wrapped staking contract token0 = "0x.." # token 0 token1 = "0x.." # token 1 amount0 = 10000 # supply token0 amount1 = 10000 # supply token1 amount_lp = # supply LP amount0_borrow = 10000 # borrow token0 amount1_borrow = 10000 # borrow token1 bank.execute( 0, # (0 is reserved for opening new position) spell, spell.addLiquidityWStakingRewards.encode_input( token0, # token 0 token1, # token 1 [ amount0, # supply token0 amount1, # supply token1 amount_lp, # supply LP amount0_borrow, # borrow token0 amount1_borrow, # borrow token1 0, # borrow LP tokens (always 0 since LP for borrowing is disabled) 0, # min token0 0, # min token1 ], wstaking ), # data {"from": user}, ) ``` 2. increase position ```python= bank = HomoraBank.at("0xba5eBAf3fc1Fcca67147050Bf80462393814E54B") spell = UniswapV2SpellV1.at("0x00b1a4e7f217380a7c9e6c12f327ac4a1d9b6a14") wstaking = WStakingRewards.at("0x011535FD795fD28c749363E080662D62fBB456a7") pos_id = 123 # position to increase # please make sure that received LP address after providing token0 and token1 # is the same as underlying token address from wrapped staking contract token0 = "0x.." # token 0 token1 = "0x.." # token 1 amount0 = 10000 # supply token0 amount1 = 10000 # supply token1 amount_lp = 0 # supply LP amount0_borrow = 10000 # borrow token0 amount1_borrow = 10000 # borrow token1 bank.execute( pos_id, # position id spell, # spell spell.addLiquidityWStakingRewards.encode_input( token0, # token 0 token1, # token 1 [ amount0, # supply token0 amount1, # supply token1 amount_lp, # supply LP amount0_borrow, # borrow token0 amount1_borrow, # borrow token1 0, # borrow LP tokens (always 0 since LP for borrowing is disabled) 0, # min token0 0, # min token1 ], wstaking ), # data {"from": user}, ) ``` 3. reduce position (and repay debt if any) ```python= bank = HomoraBank.at("0xba5eBAf3fc1Fcca67147050Bf80462393814E54B") spell = UniswapV2SpellV1.at("0x00b1a4e7f217380a7c9e6c12f327ac4a1d9b6a14") wstaking = WStakingRewards.at("0x011535FD795fD28c749363E080662D62fBB456a7") pos_id = 123 # position to increase token0 = "0x.." # token 0 token1 = "0x.." # token 1 amt_a_repay = 100000 # amtARepay amt_b_repay = 200000 # amtBRepay # fetch remaining collateral amount in the position _, _, _, coll_amt = bank.getPositionInfo(pos_id) remove_wstaking_amt = coll_amt remove_lp_amt = coll_amt bank.execute( pos_id, spell, spell.removeLiquidityWStakingRewards.encode_input( token0, # token0 token1, # token1 [ remove_wstaking_amt, # amtLPTake remove_lp_amt, # amtLPWithdraw amt_a_repay, # amtARepay amt_b_repay, # amtBRepay 0, # amtLPRepay 0, # amtAMin 0 # amtBMin ], wstaking, ), {"from": user}, ) ``` 4. harvest rewards ```python= bank = HomoraBank.at("0xba5eBAf3fc1Fcca67147050Bf80462393814E54B") spell = UniswapV2SpellV1.at("0x00b1a4e7f217380a7c9e6c12f327ac4a1d9b6a14") wstaking = WStakingRewards.at("0x011535FD795fD28c749363E080662D62fBB456a7") pos_id = 123 bank.execute( pos_id, spell, spell.harvestWStakingRewards.encode_input(wstaking), {"from": user}, ) ``` 5. get pending rewards ```python= bank = HomoraBank.at("0xba5eBAf3fc1Fcca67147050Bf80462393814E54B") pos_id = 454 _, coll_token_addr, coll_id, coll_amt = bank.getPositionInfo(pos_id) # for uniswapV2, use wstaking contract wrapper = WStakingRewards.at(coll_token_addr) staking = interface.IStakingRewards(wrapper.staking()) # find start token per share # NOTE: for wstaking contract, coll_id is reward token per share start_token_per_share = coll_id # find current token per share end_token_per_share = staking.rewardPerToken() acc_token_per_share_precision = 18 # depend on staking contract implementation pending_rewards = ( coll_amt * (end_token_per_share - start_token_per_share) // 10 ** (acc_token_per_share_precision) ) ``` ## Example [actions](#CurveSpellV1) for Curve leverage farm ### Yield Farming: Assume a user adds liquidity to Curve pool with gauge | Farm | pool id | gauge id | WLiquidity | | ------ |:------- |:-------- | ------------------------------------------ | | 3-pool | 0 | 0 | 0xf1f32c8eeb06046d3cc3157b8f9f72b09d84ee5b | - To find available leverage pools for Curve, visit https://api.homora.alphaventuredao.io/v2/1/pools and then filter only pool that `wTokenType` is WLiquidityGauge. To find all tokens (token0, token1, ...) in that pool, you can see through `tokens` key 1. open position ```python= bank = HomoraBank.at("0xba5eBAf3fc1Fcca67147050Bf80462393814E54B") spell = CurveSpellV1.at("0x8b947D8448CFFb89EF07A6922b74fBAbac219795") # spell lp = "0x6c3f90f043a72fa612cbac8115ee7e52bde6e490" # token0 = "0x6b175474e89094c44da98b954eedeac495271d0f" # token1 = "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48" # token2 = "0xdac17f958d2ee523a2206206994597c13d831ec7" amount0 = 10000 # supply token0 amount1 = 10000 # supply token1 amount2 = 10000 # supply token2 amount_lp = 0 # supply LP amount0_borrow = 10000 # borrow token0 amount1_borrow = 10000 # borrow token1 amount2_borrow = 10000 # borrow token2 min_lp_mint = 0 # min LP mint pid = 0 # pool id gid = 0 # gauge id bank.execute( 0, spell, spell.addLiquidity3.encode_input( lp, # LP [amount0, amount1, amount2], # supply tokens amount_lp, # supply LP [amount0_borrow, amount1_borrow, amount2_borrow], # borrow tokens 0, # borrow LP (always 0 since LP for borrowing is disabled) min_lp_mint, # min LP mint pid, gid, ), {"from": user}, ) ``` 2. increase position ```python= bank = HomoraBank.at("0xba5eBAf3fc1Fcca67147050Bf80462393814E54B") spell = CurveSpellV1.at("0x8b947D8448CFFb89EF07A6922b74fBAbac219795") # spell pos_id = 100 lp = "0x6c3f90f043a72fa612cbac8115ee7e52bde6e490" # token0 = "0x6b175474e89094c44da98b954eedeac495271d0f" # token1 = "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48" # token2 = "0xdac17f958d2ee523a2206206994597c13d831ec7" amount0 = 10000 # supply token0 amount1 = 10000 # supply token1 amount2 = 10000 # supply token2 amount_lp = 0 # supply LP amount0_borrow = 10000 # borrow token0 amount1_borrow = 10000 # borrow token1 amount2_borrow = 10000 # borrow token2 min_lp_mint = 0 # min LP mint pid = 0 # pool id gid = 0 # gauge id bank.execute( pos_id, spell, spell.addLiquidity3.encode_input( lp, # LP [amount0, amount1, amount2], # supply tokens amount_lp, # supply LP [amount0_borrow, amount1_borrow, amount2_borrow], # borrow tokens 0, # borrow LP (always 0 since LP for borrowing is disabled) min_lp_mint, # min LP mint pid, gid, ), {"from": user}, ) ``` 3. reduce position (and repay debt if any) ```python= bank = HomoraBank.at("0xba5eBAf3fc1Fcca67147050Bf80462393814E54B") spell = CurveSpellV1.at("0x8b947D8448CFFb89EF07A6922b74fBAbac219795") # spell pos_id = 100 lp = "0x6c3f90f043a72fa612cbac8115ee7e52bde6e490" # token0 = "0x6b175474e89094c44da98b954eedeac495271d0f" # token1 = "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48" # token2 = "0xdac17f958d2ee523a2206206994597c13d831ec7" # fetch remaining collateral amount in the position _, _, _, coll_amt = bank.getPositionInfo(pos_id) debt_tokens, debt_amts = bank.getPositionDebts(pos_id) lp_take_amt = coll_amt # LP amount to take out lp_want = coll_amt // 2 # LP amount to withdraw to wallet amount_lp = 0 # supply LP repay_token0 = 10000 # repay token0 repay_token1 = 10000 # repay token1 repay_token2 = 10000 # repay token2 lp_repay = 0 min_amt0 = 0 # min amount token0 min_amt1 = 0 # min amount token1 min_amt2 = 0 # min amount token2 bank.execute( pos_id, spell, curve_spell.removeLiquidity3.encode_input( lp, # LP token lp_take_amt, # LP amount to take out lp_want, # LP amount to withdraw to wallet [repay_token0, repay_token1, repay_token2], # repay amounts lp_repay, # repay LP amount [min_amt0, min_amt1, min_amt2], # min amounts ), {"from": user}, ) ``` 4. harvest rewards ```python= bank = HomoraBank.at("0xba5eBAf3fc1Fcca67147050Bf80462393814E54B") spell = CurveSpellV1.at("0x8b947D8448CFFb89EF07A6922b74fBAbac219795") # spell pos_id = 123 bank.execute( pos_id, spell, spell.harvest.encode_input(), {"from": user} ) ``` 5. get pending rewards ```python= bank = HomoraBank.at("0xba5eBAf3fc1Fcca67147050Bf80462393814E54B") pos_id = 1570 pid = 0 gid = 0 _, coll_token_addr, coll_id, coll_amt = bank.getPositionInfo(pos_id) # for curve, use wrapped liquidity gauge contract wrapper = WLiquidityGauge.at(coll_token_addr) # find start token per share _, _, start_token_per_share = wrapper.decodeId(coll_id) # find current token per share _, end_token_per_share = wrapper.gauges(pid, gid) acc_token_per_share_precision = 18 # depend on staking contract implementation pending_rewards = ( coll_amt * (end_token_per_share - start_token_per_share) // 10 ** (acc_token_per_share_precision) ) ``` # HomoraBank ## Execute This function passes the bytes data to the given spell address and execute on that contract. In order to correctly encode bytes data, you may need to know function abis on the target spell. | action | function | | ------------------------------------- |:--------------- | | open new position / increase position | addLiquidity | | decrease position / close postiion | removeLiquidity | | harvest rewards | harvest | ```solidity function execute( uint positionId, address spell, bytes memory data ) external payable lock onlyEOAEx returns (uint) ``` - `positionId`: The position id to execute the action, or zero for new position. - `spell`: The spell contract address which is an agent to handle user's tokens - `data`: The encoded function and its arguments which Homora bank will call to - `RETURN`: The position id of execution (new position id for new position) ## Query function ### borrowBalanceStored Return the borrow balance for given position and token without triggering interest accrual. ```solidity= function borrowBalanceStored(uint positionId, address token) public view override returns (uint) ``` - `positionId`: The position to query for borrow balance. - `token`: The token to query for borrow balance. > Example > ```solidity= > bank = HomoraBank.at("0xba5eBAf3fc1Fcca67147050Bf80462393814E54B") > token = "0x.." > position_id = 10 > debt = bank.borrowBalanceStored(position_id, token) ### borrowBalanceCurrent Trigger interest accrual and return the current borrow balance. ```solidity= function borrowBalanceCurrent(uint positionId, address token) public view override returns (uint) ``` - `positionId`: The position to query for borrow balance. - `token`: The token to query for borrow balance. > Example > ```solidity= > bank = HomoraBank.at("0xba5eBAf3fc1Fcca67147050Bf80462393814E54B") > token = "0x.." > position_id = 10 > debt = bank.borrowBalanceCurrent(position_id, token) > ``` ### getBankInfo Return bank information for the given token. ```solidity= function getBankInfo(address token) external view override returns ( bool isListed, address cToken, uint reserve, uint totalDebt, uint totalShare ) ``` - `token`: The token address to query for bank information. - `isListed`: The flag whether this market exists. - `cToken`: The CToken to draw liquidity from. - `reserve`: The reserve portion allocated to Homora protocol. - `totalDebt`: The last recorded total debt since last action. - `totalShare`: The total debt share count across all open positions. > Example > ```solidity= > bank = HomoraBank.at("0xba5eBAf3fc1Fcca67147050Bf80462393814E54B") > token = "0x.." > is_listed, c_token_addr, reserve, total_debt, total_share = bank.getBankInfo(token) > ``` ### getPositionInfo Return position information for the given position id. ```solidity= function getPositionInfo(uint positionId) public view override returns ( address owner, address collToken, uint collId, uint collateralSize ) ``` - `positionId`: The position id to query for position information. - `owner`: The owner of this position. - `collToken`: The ERC1155 token used as collateral for this position. - `collId`: The token id used as collateral. - `collateralSize`: The size of collateral token for this position. > Example > ```solidity= > bank = HomoraBank.at("0xba5eBAf3fc1Fcca67147050Bf80462393814E54B") > position_id = 1 > owner, coll_token_addr, coll_id, coll_size = bank.getPositionInfo(position_id) > ``` ### getPositionDebtShareOf Return the debt share of the given bank token for the given position id. ```solidity= function getPositionDebtShareOf(uint positionId, address token) external view returns (uint) ``` - `positionId`: position id to get debt of - `token`: ERC20 debt token to query > Example > ```solidity= > bank = HomoraBank.at("0xba5eBAf3fc1Fcca67147050Bf80462393814E54B") > token = "0x.." > position_id = 1 > debt_share = bank.getPositionDebtShareOf(position_id, token) > ``` ### getPositionDebts Return the list of all debts for the given position id. ```solidity= function getPositionDebts(uint positionId) external view returns (address[] memory tokens, uint[] memory debts) ``` - `positionId`: The position id to get debts of - `tokens`: The list of all token addresses - `debts`: The list of all debts (the list is same order as `tokens`) > Example > ```solidity= > bank = HomoraBank.at("0xba5eBAf3fc1Fcca67147050Bf80462393814E54B") > token = "0x.." > position_id = 1 > debt_tokens, debt_amts = bank.getPositionDebts(position_id) > ``` ### getCollateralETHValue Return the total collateral value of the given position in ETH. ```solidity= function getCollateralETHValue(uint positionId) public view returns (uint) ``` - `positionId`: The position ID to query for the collateral value. > Example > ```solidity= > bank = HomoraBank.at("0xba5eBAf3fc1Fcca67147050Bf80462393814E54B") > position_id = 1 > coll_in_eth = bank.getCollateralETHValue(position_id) > ``` ### getBorrowETHValue Return the total borrow value of the given position in ETH. ```solidity= function getBorrowETHValue(uint positionId) public view returns (uint) ``` - `positionId`: The position ID to query for the borrow value. > Example > ```solidity= > bank = HomoraBank.at("0xba5eBAf3fc1Fcca67147050Bf80462393814E54B") > position_id = 1 > borrow_in_eth = bank.getBorrowETHValue(position_id) > ``` # Spell To use spell functionality, you cannot call following functions directly so you must encode function and its input as `data` and execute it through HomoraBank contract [example here](#Execute) ```solidity= struct Amounts { uint amtAUser; // Supplied tokenA amount uint amtBUser; // Supplied tokenB amount uint amtLPUser; // Supplied LP token amount uint amtABorrow; // Borrow tokenA amounthttps://hackmd.io/MauBEDLlSdaMrYslhAln4Q?both# uint amtBBorrow; // Borrow tokenB amount uint amtLPBorrow; // Borrow LP token amount uint amtAMin; // Desired tokenA amount (slippage control) uint amtBMin; // Desired tokenB amount (slippage control) } struct RepayAmounts { uint amtLPTake; // Take out LP token amount (from Homora) uint amtLPWithdraw; // Withdraw LP token amount (back to caller) uint amtARepay; // Repay tokenA amount uint amtBRepay; // Repay tokenB amount uint amtLPRepay; // Repay LP token amount uint amtAMin; // Desired tokenA amount uint amtBMin; // Desired tokenB amount } ``` ## Ethereum ### UniswapV2SpellV1 | Leverage mode | action | function | | ------------------- | ------------------------ |:------------------------------ | | Liquidity Providing | open / increase position | addLiquidityWERC20 | | Liquidity Providing | reduce / close position | removeLiquidityWERC20 | | Yield Farming | open / increase position | addLiquidityWStakingRewards | | Yield Farming | reduce / close position | removeLiquidityWStakingRewards | | Yield Farming | harvest | harvestWStakingRewards | #### addLiquidityWERC20 Add liquidity to Uniswap pool, with no staking rewards (use WERC20 wrapper) ```solidity= function addLiquidityWERC20( address tokenA, address tokenB, Amounts calldata amt ) external payable ``` - `tokenA`: Token A for the pair - `tokenB`: Token B for the pair - `amt`: Amounts of tokens to supply, borrow, and get. #### addLiquidityWStakingRewards Add liquidity to Uniswap pool, with staking rewards ```solidity= function addLiquidityWStakingRewards( address tokenA, address tokenB, Amounts calldata amt, address wstaking ) external payable ``` - `tokenA`: Token A for the pair - `tokenB`: Token B for the pair - `amt`: Amounts of tokens to supply, borrow, and get. - `wstaking`: Wrapped staking contract address #### removeLiquidityWERC20 Remove liquidity from Uniswap pool, with no staking rewards (use WERC20 wrapper) ```solidity= function removeLiquidityWERC20( address tokenA, address tokenB, RepayAmounts calldata amt ) external ``` - `tokenA`: Token A for the pair - `tokenB`: Token B for the pair - `amt`: Amounts of tokens to take out, withdraw, repay, and get. #### removeLiquidityWStakingRewards Remove liquidity from Uniswap pool, from staking rewards ```solidity= function removeLiquidityWStakingRewards( address tokenA, address tokenB, RepayAmounts calldata amt, address wstaking ) external ``` - `tokenA`: Token A for the pair - `tokenB`: Token B for the pair - `amt`: Amounts of tokens to take out, withdraw, repay, and get. - `wstaking`: Wrapped staking contract address #### harvestWStakingRewards Harvest staking reward tokens to in-exec position's owner ```solidity= function harvestWStakingRewards(address wstaking) external ``` ### SushiswapSpellV1 | Leverage mode | action | function | | ------------- | ------------------------ |:-------------------------- | | Yield Farming | open / increase position | addLiquidityWMasterChef | | Yield Farming | reduce / close position | removeLiquidityWMasterChef | | Yield Farming | harvest | harvestWMasterChef | #### addLiquidityWMasterChef Add liquidity to TraderJoe pool, with staking to masterChef ```solidity= function addLiquidityWMasterChef( address tokenA, address tokenB, Amounts calldata amt, uint pid ) external payable ``` - `tokenA`: Token A for the pair - `tokenB`: Token B for the pair - `amt`: Amounts of tokens to supply, borrow, and get. - `pid`: Pool id #### removeLiquidityWMasterChef Remove liquidity from TraderJoe pool, from masterChef staking ```solidity= function removeLiquidityWMasterChef( address tokenA, address tokenB, RepayAmounts calldata amt ) external ``` - `tokenA`: Token A for the pair - `tokenB`: Token B for the pair - `amt`: Amounts of tokens to take out, withdraw, repay, and get. #### harvestWMasterChef Harvest Joe reward tokens to in-exec position's owner ```solidity= function harvestWMasterChef() external ``` ### CurveSpellV1 | Leverage mode | action | function | | ------------- | ------------------------ |:--------------- | | Yield Farming | open / increase position | addLiquidity | | Yield Farming | reduce / close position | removeLiquidity | | Yield Farming | harvest | harvest | #### addLiquidity2 Add liquidity to Curve pool with 2 underlying tokens, with staking to Curve gauge ```solidity= function addLiquidity2( address lp, uint[2] calldata amtsUser, uint amtLPUser, uint[2] calldata amtsBorrow, uint amtLPBorrow, uint minLPMint, uint pid, uint gid ) external ``` - `lp`: LP token for the pool - `amtsUser`: Supplied underlying token amounts - `amtLPUser`: Supplied LP token amount - `amtsBorrow`: Borrow underlying token amounts - `amtLPBorrow`: Borrow LP token amount - `minLPMint`: Desired LP token amount (slippage control) - `pid`: Curve pool id for the pool - `gid`: Curve gauge id for the pool #### addLiquidity3 Add liquidity to Curve pool with 3 underlying tokens, with staking to Curve gauge ```solidity= function addLiquidity3( address lp, uint[3] calldata amtsUser, uint amtLPUser, uint[3] calldata amtsBorrow, uint amtLPBorrow, uint minLPMint, uint pid, uint gid ) external ``` - `lp`: LP token for the pool - `amtsUser`: Supplied underlying token amounts - `amtLPUser`: Supplied LP token amount - `amtsBorrow`: Borrow underlying token amounts - `amtLPBorrow`: Borrow LP token amount - `minLPMint`: Desired LP token amount (slippage control) - `pid`: Curve pool id for the pool - `gid`: Curve gauge id for the pool #### addLiquidity4 Add liquidity to Curve pool with 4 underlying tokens, with staking to Curve gauge ```solidity= function addLiquidity4( address lp, uint[4] calldata amtsUser, uint amtLPUser, uint[4] calldata amtsBorrow, uint amtLPBorrow, uint minLPMint, uint pid, uint gid ) external ``` - `lp`: LP token for the pool - `amtsUser`: Supplied underlying token amounts - `amtLPUser`: Supplied LP token amount - `amtsBorrow`: Borrow underlying token amounts - `amtLPBorrow`: Borrow LP token amount - `minLPMint`: Desired LP token amount (slippage control) - `pid`: Curve pool id for the pool - `gid`: Curve gauge id for the pool #### removeLiquidity2 Remove liquidity from Curve pool with 2 underlying tokens ```solidity= function removeLiquidity2( address lp, uint amtLPTake, uint amtLPWithdraw, uint[2] calldata amtsRepay, uint amtLPRepay, uint[2] calldata amtsMin ) external ``` - `lp`: LP token for the pool - `amtLPTake`: Take out LP token amount (from Homora) - `amtLPWithdraw`: Withdraw LP token amount (back to caller) - `amtsRepay`: Repay underlying token amounts - `amtLPRepay`: Repay LP token amount - `amtsMin`: Desired underlying token amounts (slippage control) #### removeLiquidity3 Remove liquidity from Curve pool with 3 underlying tokens ```solidity= function removeLiquidity3( address lp, uint amtLPTake, uint amtLPWithdraw, uint[3] calldata amtsRepay, uint amtLPRepay, uint[3] calldata amtsMin ) external ``` - `lp`: LP token for the pool - `amtLPTake`: Take out LP token amount (from Homora) - `amtLPWithdraw`: Withdraw LP token amount (back to caller) - `amtsRepay`: Repay underlying token amounts - `amtLPRepay`: Repay LP token amount - `amtsMin`: Desired underlying token amounts (slippage control) #### removeLiquidity4 Remove liquidity from Curve pool with 4 underlying tokens ```solidity= function removeLiquidity4( address lp, uint amtLPTake, uint amtLPWithdraw, uint[4] calldata amtsRepay, uint amtLPRepay, uint[4] calldata amtsMin ) external ``` - `lp`: LP token for the pool - `amtLPTake`: Take out LP token amount (from Homora) - `amtLPWithdraw`: Withdraw LP token amount (back to caller) - `amtsRepay`: Repay underlying token amounts - `amtLPRepay`: Repay LP token amount - `amtsMin`: Desired underlying token amounts (slippage control) #### harvest Harvest CRV reward tokens to in-exec position's owner ```solidity= function harvest() external ``` ########################## ## Avalanche ### TraderJoeSpellV2 #### addLiquidityWMasterChef Add liquidity to TraderJoe pool, with staking to masterChef ```solidity= function addLiquidityWMasterChef( address tokenA, address tokenB, Amounts calldata amt, uint pid ) external payable ``` - `tokenA`: Token A for the pair - `tokenB`: Token B for the pair - `amt`: Amounts of tokens to supply, borrow, and get. - `pid`: Pool id #### removeLiquidityWMasterChef Remove liquidity from TraderJoe pool, from masterChef staking ```solidity= function removeLiquidityWMasterChef( address tokenA, address tokenB, RepayAmounts calldata amt ) external ``` - `tokenA`: Token A for the pair - `tokenB`: Token B for the pair - `amt`: Amounts of tokens to take out, withdraw, repay, and get. #### harvestWMasterChef Harvest Joe reward tokens to in-exec position's owner ```solidity= function harvestWMasterChef() external ``` ### PangolinSpell #### addLiquidityWMiniChef Add liquidity to Pangolin pool, with staking to miniChef ```solidity= function addLiquidityWMiniChef( address tokenA, address tokenB, Amounts calldata amt, uint pid ) external payable ``` - `tokenA`: Token A for the pair - `tokenB`: Token B for the pair - `amt`: Amounts of tokens to supply, borrow, and get. - `pid`: Pool id #### removeLiquidityWMiniChef Remove liquidity from Pangolin pool, from miniChef staking ```solidity= function removeLiquidityWMiniChef( address tokenA, address tokenB, RepayAmounts calldata amt ) external ``` - `tokenA`: Token A for the pair - `tokenB`: Token B for the pair - `amt`: Amounts of tokens to take out, withdraw, repay, and get. #### harvestWMiniChefRewards Harvest staking reward tokens to in-exec position's owner ```solidity= function harvestWMiniChefRewards() external ``` # FAQ