基于Defi的Defi,Alpaca Finance 合约解析

  • Alvan
  • 更新于 2022-06-14 18:29
  • 阅读 1989

Alpaca合约解析与其在DEX中的投资策略

Overview

Alpaca Finance是一个借贷协议,但它和CompoundAave等单纯等待别人从池子里借款从而分红利息的项目不一样,在这里你不仅可以加上杠杆,还可以主动选择一些心仪的流动性挖矿项目并质押进去,吃到多次利润。

Alpaca Leverage Farming 主要有四个组成部分 1.Vault 2.Worker 3.Strategy 4.Fairlaunch(此模块另行介绍)

Architecture

  • 前端(Frontend) - Alpaca 前端接口
  • 清算机器人(Liquidator) - 观察仓位状态,一旦出现资不抵债就进行清算的机器人
  • 复投机器人(Reinvestor) - 自动收获利润又复投的机器人

Vault

顾名思义,这个合约用处是存放借款者的抵押物。作为在此时贡献资金池使用率的回报,借款者还可以向Vault申请资金。一个底层资产对应一个Vault合约。

Worker

worker是一个管理仓位使用方法的合约,使用方法包括但不限于: 1.在一个DEX里开启一个流动性挖矿的仓位 2.平掉这个仓位 3.调节这个仓位 每一个worker都对应特定的一些代币和一个特定的DEX,不同的ERC20代币/DEX会使用不同的worker。

Strategy

strategy合约是具体操作DEX的合约,每次只处理一个特定场景。可以对动态指定的不同的token做出相同逻辑的DEX操作。

FairLaunch

这是Alpaca的激励组件,可以接收ERC20然后给各个token池生成Alpaca代币,每个池子的发放量存在差异

DEX Integration

尽管Alpaca集成了不少不同的DEX,他们之间也在细节上有差别,但是大部分DEX都是基于uniswapV2的机制,在这版文档里我们只讨论与PancakeSwap对接的Worker和Strategy。即以下具体实现:

Worker

PancakeSwap Worker

Strategy

PancakeswapV2RestrictedStrategyAddBaseTokenOnly Strategy PancakeswapV2RestrictedStrategyAddTwoSidesOptimal Strategy PancakeswapV2RestrictedStrategyLiquidate Strategy PancakeswapV2RestrictedStrategyPartialCloseLiquidateStrategy PancakeswapV2RestrictedStrategyPartialCloseMinimizeTrading Strategy PancakeswapV2RestrictedStrategyWithdrawMinimizeTrading Strategy

Vault Contract

Background

Alpaca Finance里最重要的一个操作是通过vaults达成的,注意是vaults而非vault,vault被设计成连接存款者和借款者的中间体,存款者把资产储存进vault,借款者可以借出来一些用于流动性挖矿。 存储token的同时,vault会给用户ibToken,用户可以用这个在Alpaca Finance中进行更多操作,比如获得FairLaunch里的Alpaca激励,获得合作Token激励,以后还有更多。 借出token的同时,用户也可以获得debtToken,这也可以自动获得FairLuanch给的激励。

Abstract

  • Vault会给用户分配ibToken,用来标记用户在此vault里所占的份额(share)。随着时间推移,利息会进入份额,1份份额(share)的实际价值会增加。
  • 当用户开仓时,他们先需要在vault里放质押物。这使得vault的债务价值(debt value)根据借款量增加。
  • 一旦vault收获借款人的利息,vault的债务价值(debt value)会随着利息增加。这意味着随着时间推移,取出资产需要用到的量要比存款时更大。
  • 当用户平仓时,初始抵押品债务会从总债务中去除,流动性挖矿的利息会完整地还给lender。
  • 部分利息会被项目组留下,放在保留金池子里。
  • 由于用户是在不同的时间存款的,我们要用债务份额价值(debt share value)保持记录用户从哪里进入vault。
  • 债务份额(debt share)也被表示成vault铸造的生息token。
  • 债务份额的计算方法:$\frac{DebtValue}{TotalDebtValue} \times ExistingDebtShare$

Structs

struct Position {
   address worker;
   address owner;
   uint256 debtShare;
}
mapping(uint256 => Position) public positions;

Main Function

Vault 主要业务逻辑有: 1.质押token获得ibToken (deposit) 2.赎回token燃烧ibToken (withdraw) 3.执行借贷+DEX流动性挖矿操作,调用worker.work,根据Position里worker的不同具体执行逻辑也不一样 (work) 4.清算,调用worker.liquidate,根据Position里worker的不同具体执行逻辑也不一样 (kill)

Worker Contract

BackGround

borrowers从vault申请款项唯一的办法就是从vault借出钱来做一些操作,特别是加杠杆的流动性挖矿。 每一个worker根据配置比如其连接的DEX和LP token pair 来进行不一样的操作,但是所有的Worker共用一个接口。 然而worker并不一定要做流动性挖矿,也可能就只是做一些简单的操作,比如Syrup Pool。 这部分我们只讲一下所有worker共通的Interface。

Abstract

  • 在整个系统里有多个worker
  • 一个worker可以根据实际情况使用不同的strategy
  • worker会把特定的token对当成整体处理,即使他们在不同的仓里
  • worker和底层资产服务强关联,比如Pancake的BNB-BUSD worker处理不了Wault的BNB-BUSD**
  • Base token是ERC20标准,是worker的主要资产,通常与借款,本金挂钩。
  • Farm token是ERC20标准,与base token结对可以给DEX提供流动性
  • worker把Fram token和Base token成对处理,如果我们需要将现在的farm token作为base token就需要另一个worker,反之亦然。因为在DEX中,Pancake的BNB-BUSD 也与 Pancake的BUSD- BNB不一样。
  • Worker Config作为一个分离出来的合约,存放着worker们的配置信息

worker可以被两种角色调用: 1.Operator: 大多数情况是一个Vault合约 2.Reinvestor: 白名单EOA,取出LP收益再复投

Main Function

1.利息复投(_reinvest) 2.调用Strategy的excute方法,并将返回的LP token质押,根据Strategy种类不同具体实现不一样 (work) 3.计算某个position换算成baseToken的价值,用来做清算判断 (health)

Strategy Contract

Background

顾名思义,这类合约只做一件事,那就是制定交易策略,根据DEX,token和需求不同分配不同的Strategy。这一节我们详细介绍策略逻辑和公式。值得注意的是,这个合约是一个耦合度极低的合约,只负责把传给该合约的资产在DEX中操作,再转账,几乎没有存储任何信息,也就是不参与借贷相关的任何逻辑。借贷/还账的逻辑应该在它的上层实现。

Abstract

根据用户的操作,前端会提供一个strategy,比如一个用户想借BUSD在Pancake开一个BUSD- USDT的仓,前端会用PancakeswapV2RestrictedStrategyAddBaseTokenOnly(一种Strategy合约)调用Vault.work,这样Vault将会调用USDT- BUSD PancakeSwap 的worker。worker随后调用PancakeswapV2RestrictedStrategyAddBaseTokenOnly.

Main Function

有六种Strategy都只有一个主要方法,excute:

AddBaseTokenOnly:

提供base token,根据最佳方案兑换farming token,再提供流动性拿LP,推导过程: balance为托管处理的baseToken总量,aIn为swap为farming token的base token,rIn,rOut是池子里的量,有方程组:

$rIn\times rOut = (rIn + aIn)\times(rOut - aOut)$ $\frac{rIn}{rOut} = \frac{balance - aIn}{ aOut }$

得出$aIn^{2} + 2rIn\times aIn - rIn\times balance = 0$,即$aIn=\frac{\sqrt{rIn\times (4balance + 4rIn)}-2rIn}{2}$ 与代码吻合:

uint256 aIn = AlpacaMath.sqrt(rIn.mul(balance.mul(399000000).add(rIn.mul(399000625)))).sub(rIn.mul(19975)) / 19950;

AddTwoSideOptimal

同时提供base token和farming token,合约转换成正好的比例提供流动性,推导过程: bIn,bOut是用户提供的两种token量,aIn是打算换成另一种的多余Token量,aOut是换出的token量,有方程组: $rIn\times rOut = (rIn + aIn)\times(rOut - aOut)$ $\frac{rIn + bIn }{rOut - bOut} = \frac{bIn-aIn}{bOut+aOut}$

得出$aIn^{2} + 2rIn\times aIn + \frac {rIn\times bOut - rOut \times bIn}{rOut+bOut} \times rIn = 0$ 即 $aIn = \frac{\sqrt{4rIn^{2}-4\times (\frac {rIn\times bOut - rOut \times bIn}{rOut+bOut} \times rIn)}-2rIn}{2}$ 与代码吻合:

/// @dev Compute optimal deposit amount helper
 /// @param amtA amount of token A desired to deposit
 /// @param amtB amonut of token B desired to deposit
 /// @param resA amount of token A in reserve
 /// @param resB amount of token B in reserve
 function _optimalDepositA(
   uint256 amtA,
   uint256 amtB,
   uint256 resA,
   uint256 resB
) internal pure returns (uint256) {
   require(amtA.mul(resB) >= amtB.mul(resA), "Reversed");
​
   uint256 a = 9975;
   uint256 b = uint256(19975).mul(resA);
   uint256 _c = (amtA.mul(resB)).sub(amtB.mul(resA));
   uint256 c = _c.mul(10000).div(amtB.add(resB)).mul(resA);
​
   uint256 d = a.mul(c).mul(4);
   uint256 e = AlpacaMath.sqrt(b.mul(b).add(d));
​
   uint256 numerator = e.sub(b);
   uint256 denominator = a.mul(2);
​
   return numerator.div(denominator);
}

Liquidate

提供LPToken,取消所有流动性,之后所有farming token 兑换成base token 返还给用户。

PartialCloseLiquidate

前面和Liquidate一样,也是把一定量的LP取消流动性,再全兑成base token提出来,最后留下一部分baseToken(数目是入参,一般做平账用,由合约传入),剩下的返还给用户。

PartialCloseMinimizeTrading

提供一定量LPToken,取消流动性,返还base token和farming token,如果base token不够lessDebt值(数目是入参,一般做平账用,由合约传入),用farming token兑换至足额,并将base token和剩余的farming token返还。

WithdrawMinimizeTrading

把所有的LPToken取消流动性,返还base token和farming token,如果base token不够lessDebt值(数目是入参,一般做平账用,由合约传入),用farming token兑换至足额,并将base token和剩余的farming token返还。

后记

Alpaca小弟也是最近刚刚接触,看到社区里并没有介绍Alpaca的文章,而这个项目的官方文档也是面向用户多一些,所以我把英文合约文档翻译了一下并把含糊和粗略的地方补全了,斗胆发在社区。如果有前辈研究过这个项目还请指路一下更多的资料,谢谢大家了。

点赞 4
收藏 2
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
Alvan
Alvan
0x8958...672e
区块链开发,喜欢defi,对socialfi很感兴趣,希望能和大家交朋友,个人博客: alvan.coffee 邮箱: 19970216zhang@gmail.com vx: zy122402