如何从零设计一个 DEX
作者:Joseph Xu
编排:黑羽小斗
文章:Buidler DAO
封面:Photo by Salvatore Andrea Santacroce on Unsplash
注:文章仅代表个人观点,不构成任何投资意见
作者说
过去的一两年中,那些被市场验证为有效的 AMM 模型算法已经很少再进行更新迭代了。AMM 的核心问题也渐渐从设计一套高效合理的算法,回归到金融市场的本质——流动性。如今的 NFT 这一类型的资产标的同样也面临一样的流动性匮乏等问题的考验。而 NFT 市场中却一直没有有效的 DEX 能够真正从流动性汇聚的角度解决交易撮合和价格发现等问题。今天我们的主题就从 AMM DEX 出发,向大家分享我们在设计 Midaswap Protocol 这个 NFT 流动性协议过程中,是如何从现有的 AMM 方案当中寻找灵感和启发,又是如何在这些既有的方案中改进和创新以解决 NFT 市场中独有的痛点和需求。
—— Joseph
文章整理自 Midaswap 工程师 Joseph 在经济模型小组的内部分享。
如对经济模型研究感兴趣,欢迎扫码添加 BuidlerDAO 小助手入群,请备注经济模型。同时也欢迎项目方和我们一起探讨经济模型。
全文 7680 字,预计阅读时间 24 分钟
文章速览
01/ 如何从零设计一个 DEX
02/ NFT AMM 的困难三角
03/ NFT AMM 市场已有的方案
04/ Bonding Curves
05/ 从已有 DEX 中借鉴的灵感
06/ Midaswap AMM 的设计思路
自 Q3 以来,NFT 市场经历了剧烈的波动,蓝筹 NFT 纷纷跳水。忽略项目方、发行方各种操作的影响,流动性依然是 NFT 市场里最重要的问题。就目前来说,仅在 EVM 链上,我们可以把 NFT 大致定性成 ETH 的一个衍生品。
此外,无论是否参与过 NFT 的交易,大家应该都已经关注到了 blur.io 的迅速成功。在流动性解决方案上,Blur 似乎已经交出了一份来自中心化交易所/聚合器的高分答卷。它现在几乎已经占据了这个市场里面最大的买单流动性的份额,而且作为一个后起之秀,尤其是在 Opensea 已经在头把交椅上这么多年的情况下,它还能如此迅速地崛起。其实我们可以说 Blur 已经将中心化的流动性方案做得很好。但是中心化无论是对于我们 dApp 的开发者来说,还是对于各个公链上的生态来说,我们一直都认为中心化可能只是这个交易市场里面的一部分,我们希望寻求的是我们怎么能在链上搭建属于我们的 NFT 交易所,或者说 NFT DEX。所以我们今天希望能够在接下来的探讨当中讨论以下的一些问题:
- 构建一个去中心化的 NFT 交易所应该采用什么样的流动性方案?
- 在思考和设计去中心化的 NFT AMM 时,现有 DEX 的 AMM 方案都有什么可以借鉴的地方?
- ERC721 和 ERC20 作为完全不同的资产标的在其 AMM 模型设计上又会有哪些不同?
我们今天便带着这些问题,和大家一起探讨学习,同时也试图向大家分享我们的产品 Midaswap 在模型设计上经历过 的思路历程。
如何从零设计一个 DEX
先从一个比较抽象的问题开始,就是当我们去设计一个 DEX 时,我们需要经历哪些思想上的斗争,或者我们需要做出哪些选择?
首先估计大家都知道,选择一个 AMM 曲线,可能是所有的 AMM 设计者在一开始就需要确立的方向。诚然 x+y=k 或者 x·y=k,亦或是 Balancer 那种更魔改型的多币池的那种恒定函数,其实它们都可以叫做 CFMM,恒定函数做式商。这里的 x 和 y,包括 balancer 公式里的 b 等等,它们其实代表的都是所对应的这个市场,或者这个流动性池里面所涉及到的资产余额,或者说供应量。他们依据供应量之间的比例关系或者各种各样的创造出来的数量关系,重新在这个市场里撮合定价。所以,我们考虑选择一个什么样的曲线,往往和这个流动性协议它认为自己所能吸引的目标性的资产标的是有关的。稳定币的交易,比如 Curve V2,它会选择一个混合式的恒定函数做事商,在平衡点附近,它的模型更接近恒定和的曲线,而在平衡点较远的地方,它更像是 Uniswap v3 恒定积的方法。所以说其实并没有一个完美的 AMM 曲线,更多的是怎么样寻找到一个适合你自己这个市场的一个 AMM 曲线。
然后其实大家就会面临第二个问题,就是我们希望流动性是怎么排布的。当然这涉及到两个方面的问题,一个是流动性是需要在全区间内排布,还是在一个固定价格区间内排布,或者说是在 LP 提供的一个价格范围内排布。这一点上其实就是 Uni V2 和 Uni V3 之间的差异。Uni V2 其实设计了一个十分简洁的模型,它将两种代币全区间排布,严格地遵守了 xy=k 这样的一个 AMM 曲线。但是 Uni V2 也带来了另一个问题,就是在曲线两端时资本利用效率大为降低。Uni V3 在这方面做了革新,他们为 LP 提供了新的功能,LP 可以在他希望的区间提供流动性,也就是 Uni V3 定义的 range order 功能。它的 AMM 曲线其实就不是一个简单的 xy=k ,它是无数个 xy=k 的叠加的结果。选择了这个流动性区间的排布其实背后还有另外一个问题,就是你希望你的流动性是水平地摆置,还是纵向地摆置?可能现在没有一个较为直观的方法给大家解释这两个之间的差别,我们后续会进一步做阐释。
第三个也是最重要的一个问题,就是你是怎么激励你的 LP 的?LP 其实是 DEX 或者游戏里最重要的参与角色。没有 LP 就没有流动性深度,也就没有良好的交易体验。所以所有的 DEX 其实都会面临这样的一个问题,就是怎么吸引到 LP?当然我们知道所有的 DEX 都会用交易手续费收益来吸引自己的 LP。有一些新兴的流动性协议会为 LP 创造更多组合性上的收益,比如流动性质押或者流动性代币的一些组合性的玩法,类似 Paraspace 就使得 Uniswap 的 LP 们能通过借贷实现更多杠杆上的组合性玩法。其实这些方面都是为了增加流动性池对 LP 的吸引力。如我们刚刚所说,LP 是这个流动性协议这个游戏能够玩得转的最重要的因素。我们如果没有一个良好的机制去吸引 LP,那其实这个飞轮是无法正向运转的。
然后我们就来到第四个问题,就是你应该如何向你的交易者们收费?这一点上其实现有的 DEX 们还是挺一致的,就是怎么向交易者收费几乎都是由创建流动性池的人决定一个费率,像 Uniswap,Joe 它可能有多级费率。我们这里可以提一嘴的是在 Joe V2 当中,它的费率是一个动态手续费。我们也看到 Uni V4 做出了这方面的跟进,它通过 hook 的形式引进了动态手续费。动态手续费率代表着更先进的一种产品设计,因为动态手续费率不光可以形成一个负反馈系统来平衡市场,在某种程度上还可以对冲 LP 的无偿损失。在这里我们不会过多涉及到这部分的内容,但是这一环肯定也是作为一个 AMM 的设计者来说必须要考虑到的。
然后就是选择 LP 的凭证。这一点上有很多流派。Uni V2 选择了 ERC20, Uni V3 选择了 ERC721,Joe V2 选择了 ERC1155。其实 LP Token 是由前面四个选择共同决定的。流动性的分布方式和在流动性协议中进行量化流动性的方式最终会决定 LP Token 的形式。以 Uni V2 和 Uni V3 的之间的差异为例,Uni V2 是在全区间分布流动性,所以在每一个价格节点上,只要两个 LP 提供流动性资产的占总资产的比例是一样的,那我们就认为这两部分流动性是等价的,所以 Uniswap v2 同一流动性池内的 LP Token 都是同质化的。因为每一个价格点上,我们都会公平地认为他们为市场提供了资本贡献。而 Uni V3 因为引入了 range order(限价流动性),所以流动性本身的有效性就有了新的定义。并不是所有的流动性在任何时候都会参与市场交易,只有在价格区间扫过范围内的流动性才真正为这个市场提供资本贡献。所以它需要将每个 LP 的仓位进行非同质化封装,为它们包裹上一层 ERC721 的 Token ,这可能是目前看来相对来说比较好的方案。当然我们不知道 Uni V4 接下来会怎么样,但是我认为在 Uni V4 的流动性方案并没有和 Uni V3 产生巨大差异的情况下, E2C721 可能仍然是它 LP Token 的最好选择。
经历了上面这 5 个重要环节的抉择和挣扎,我们已经确立了一个 AMM 协议大致的方向。所以刚刚这个过程其实也是帮助大家有这样一个头脑风暴的过程。如果这 5 个环节都没有问题的时候,我们才真正进入了 AMM 模型设计的大门,我们开始能够去讨论一些更细节的问题。
NFT AMM 的困难三角
刚刚的话题都在讨论 ERC20 AMM DEX 的设计,包括 Uni, Curve, Balancer 等现在市面上主流的 AMM DEX。我们今天的主题则是 NFT AMM。NFT AMM 的币对一侧是 ERC721 的 NFT,另一侧是 ERC20 或者 ETH 这样的同质化代币。当这两种资产标的放在一个 AMM 流动性池当中时,我们会遇到一些十分原生的矛盾。
首先最重要的是在传统 NFT 的交易市场当中,它们依赖的是一种 bid ask 的交易模式,更像是一种订单簿市场。订单簿市场在某一侧流动性缺乏的情况下,流动速率是十分差的。所以 NFT 市场缺乏很好的做市工具和充足的买方流动性。一直以来,大家都诟病 NFT 的内生价值是缺乏的,且它的买方流动性无论在任何一条公链上都是极度匮乏的状态,所以换手率的严重不足就导致了流动性注定是枯竭的。所以我们在想,如果将 NFT AMM 直接引入到现有的 AMM DEX 市场当中,在不经过任何改动的情况下,它很有可能会面临 ETH 侧或者 ERC20 侧流动性严重不足的问题。这是大家在一开始就需要面临的一个问题。
然后第二个重要的问题,也是很现实的问题,就是 NFT 是整颗进行交易的。因为 NFT 本身它非同质化的特性,在不加以任何其他附加设计的情况下,没有一个 NFT 的 Holder 愿意出售 10% 的 NFT 给另外一个人。这从资产本身的特性来说也是不成立的。这其实引入了一个问题:我们原本的 AMM DEX 在代币的精度范围内是无限可细分的。如果说一些主流的 ERC20 是 18 位精度的话,那它在 18 位精度以内都是可以细分的,也就是说价格曲线可以无限趋近于一个连续的曲线。而 NFT 是一个断点状的流动性,这往往就意味着它有很大的流动性缺口。我们要靠一条什么样的曲线将点和点之间连接起来,这也是一个很重要的问题。
同时从另外一个角度讲,因为 Token ID 本身是整数个交易的,NFT 的交易门槛一直以来是相对过高的。散户在购买 ETH 时,如果他的 USDT 不够购买一个以太坊,他可以选择只购买价值 100USDT 的以太坊。但是当一个 NFT 价值 1ETH 时,用户不可能花 100USDT 去购买一个百分之多少比例的 NFT。之前市场当中已经有流动性协议提出为 NFT 引入碎片化设计。碎片化当然是一个很简单直接的方案,但是碎片化方案又引入了困难三角的第三个问题:碎片化的 NFT 还具有 NFT 本身的交易属性吗?
任何一个 NFT 集合发行出来时,它会根据 Metadata 中的属性来决定某一个 NFT ID 或者某一组 NFT ID 的稀有度。不同的稀有度往往就决定了这些 NFT Holder 对于自己 NFT 价格的期望是不同的。而碎片化意味着所有投入到这个碎片化流动性池当中的 NFT 都是被一视同仁的,因为我们没有办法在一个已经碎片化的流动性池当中再去分辨某部分碎片是来自于某一个高稀有度的 NFT。
这其实就是我们所说的 NFT 去中心化协议所必须面临的三个核心的痛点。如果在这三个问题当中没有一个取舍的话,可能 NFT AMM 设计会遇到很大的困难。
NFT AMM 市场已有的方案
我们再来看下现有的 NFT AMM 市场上有哪些已经比较成熟的解决方案。比如 NFTX 是将 NFT 无差别地碎片化成 ERC20,再通过 Sushi Swap 的池子构建成交易对。它简单粗暴地绕过了 Token Decimal Conflict 这个问题,但是它也忽略了交易者和 Holder 对于 NFT 稀缺性的差异化判断和价格期望。稀缺性高的 NFT 无法在这种 AMM 模型下得到好的价值发现。
另外一个项目 Sudoswap 是原生 NFT 资产第一个类似于 AMM 的 DEX。为什么这里说类似于 AMM,因为它和大家通常理解的 AMM 的角色设定是有一些差异的。我们简单介绍一下 Sudoswap 这个项目,它将每一个流动性提供者变成交易者的对手方。流动性提供者按照他所设定的 bonding Curve 设计自己的流动性提供方案。每一个流动性提供者就拥有一个流动性池,并确定这个池子是双向池还是单向池。双向池意味着你既可以买入也可以卖出 NFT,流动性是双边的。双边意味着你可以接收两边的资产互换。它也可以提供单边池,比如说你只提供 ETH,类似你这个 LP 挂了一个 NFT 的买单,交易者可以将 NFT 卖入这个纯 ETH 的池子当中。反过来也成立,你可以提供纯 NFT 的流动性池,那它更像是挂了一个 NFT 的卖单。
所以这个过程当中 LP 的角色是被淡化的,LP 更像是交易者的另外一种形式,只不过从某种程度上可以享受一些更定制化的交易功能。但是这会带来两个问题,第一个问题就是如果一个 LP 拥有一个流动性池,这就意味着每一个流动性池之间的流动性是无法聚合的。我们刚刚提到 NFT 市场最重要的问题是买方的流动性是缺乏的。在这样的一个大前提下,如果还将所有流动性割裂到单个 LP 的流动池子当中,这其实在某种程度上依然是将流动性孤岛化。流动性无法聚合在某种程度上违背了 AMM 本身的初衷: AMM 希望在一个市场内聚合流动性以提供更好的流动深度,然后撮合出一个真正符合这个市场现在情绪的价格。这一点上它其实是没有办法达到的,每一个流动型池彼此之间互相割裂,而且不互相影响。另外一个角度,在单一流动性池当中,NFT 的稀缺性是默认相同的。也就是说一个 LP 在他自己的流性流动性池当中提供 3 个 NFT,这 2 个 NFT 他是不会为他们一一定价的。如果一个 LP 手上有三个不同稀有度的 NFT 并有不同的期望,他可能需要创建三个流动性池才能满足这样的需求。
所以说在这两个项目其实是 NFT AMM 市场当中已经比较成熟的两个项目。这两项目都解决了我们刚刚说的三个问题中的一部分问题,但是自身可能存在一些 Trade Off,一部分问题被他们选择性地忽视或者妥协了。那么我们在思考的就是有没有一个 NFT 模型能够将这些问题做一个很好的解决,或者说我们能不能通过一套 NFT 模型将这三个问题解决到大家能够接受的一个程度内。
Bonding Curves
我们会接下来给大家详细解释一下 Bonding Curve,作为后面我们聊详细的解决方案的一个铺垫。Bonding Curve 本质上是一系列用来实现价格发现的数学函数。它其实就是将资产的供应量映射到资产价格当中。从上述两个 curve 图中明显能看出,左边是一个线性的 Bonding Curve,右边是一个指数函数的 Bonding Curve。图中,绿色的点代表 ERC20 在仓位当中的位置,而 ERC721 用红色的点来表示。以左边这个图为例,如果在这样的一个流动性池当中,它的流动性是怎么分布的呢?在价格最低的地方,即它所设定的价格的起点以及接下来的第二个点放置的是 FT 的流动性,也就是 ERC20 的流动性。而在上面的三个点放置的是 ERC721 的流动性。当这个流动性池当中被交易者买走一个 NFT 的时候,中间的这一颗红色的点就会被置换成绿色。也就是说这个市场当中每买走一个 NFT,这个价格就会线性地增长一个恒定的值。而每卖出一个 NFT,这个池子当中所提供的 inDEX price 就会下降一个恒定的值。同理在指数函数当中是一样的,它只不过将这个公差变成了一个公比。
Sudoswap 值得肯定的是它开创性地将 Bonding Curve 引入到 NFT 的交易当中,这确实为流动性提供者们提供了很好的做市的自由度。但是就像刚刚提到的,在它的设计里,LP 之间的流动性池是割裂的,所以说它的 Bonding Curve 在某种程度上丧失了对市场全貌的一个描述能力。我们没有办法从某一个流动性池当中真正地看到这个市场交易到什么程度。它在市场中交易的 inDEX Price 也不能够反映整个 NFT Collection 市场的特性,陷入一种 “管中窥豹” 的窘境。
从已有 DEX 中借鉴的灵感
综合以上痛点以及现有的成熟产品的设计,我们就在思考什么样的 NFT AMM 能够解决上述这些问题。首先我们还是会回到一些市场上主流的 ERC20 DEX 当中,去寻找一些能给我们启发或者灵感的元素。
首先我们认真地研究了 Uniswap V3, Uniswap V3 给我们提供了一个很好的 Inspiration,首先 LP 们可以在限价范围内提供流动性,这一点类似刚刚提到的 Sudoswap 当中 LP 限定好自己流动性的 bonding Curve,然后在这个范围内提供流动性。那么我们其实就会有一个想法,LP 是否可以按照某种 bonding Curve 自由地在我们的一个流动性池当中提供自己的流动性。在这样的基础上,我们可能需要对它辅助一个 Non Fungible LP Token,也就是一个 ERC721 的 LP 凭证,这样才能确定好 LP 的每一个仓位,其实彼此之间是非同质化的。
然后我们又去深入地调研了 Joe V2 的协议设计,它在 Uni V3 的基础上进行了一些升级。首先 LP 的这个 Curve(曲线) 它是能够自定义的,它可以选择 LP 流动性的稀疏程度,选择流动性是否全局地铺在自己这个 Range Order 的价格区间上,它可以选择点状的流动性提供,同时它还利用 Liquidity Book 的设计,将链上交易在微观的维度上可以实现类似于 Order Book 的交易模式。这是一种更为新式的流动性分布的方案。
从这两个 ERC20 DEX 当中我们获得的最重要的灵感是图上提到的这四点。如果说 ERC20 DEX 给我们设计 NFT AMM 提供了哪些重要启发的话,最重要的还是我们不应该忽略 NFT 本身 Token ID 之间的差异,我们应该允许 LP 对于自己的流动性有差异性的期望。同时我们不应该将 LP 的流动性分割到它的每一个私有的流动性池当中,我们应该聚合它们买端的流动性。只有聚合的流动性才能为交易者提供更好的交易体验,更低的滑点以及提供更加及时的交易体验。在流动性缺乏和无法聚合的情况下,交易者想要卖出一个 NFT 时的体验是很差的。
Midaswap AMM 的设计思路
讲到这里,我们就可以重新去讨论应该怎么去设计我们自己的 NFT AMM。在这之前我们可以先讨论一个和这个话题稍微有一点远的问题,如果大家也看过 Uniswap V3 相关的资料,大家都知道 Uniswap V3 有一套自己衡量价格的标识,它把这个系统叫做 Tick。Tick 其实是一个 1.0001 的指数函数,Tick 每增长一,它就会在对应的价格上面乘 1.0001,也就是说 Tick 和价格彼此之间是一一映射的。为什么会这样设计?其实所有的 DEX 都会有一套自己的价格标尺,这个价格标尺是为了从几乎无限的价格中取出对于我们 AMM 最有效的一个价格尺度。在这些价格尺度中间的流动性其实是被忽略的,我们只将我们的流动性提供在这些我们设定好的 Tick 当中。
与之对应的另外一个比较主流的设计是 Liquidity Bin。Bin 顾名思义是像箱子一样的东西,我们可以将每一个价格标尺上面的流动性看作每一个 LP 为这一个价格堆叠流动性深度的箱子的高度。打个最简单的比方,我作为一个 LP 在 ETH 等于 1000USDC 这个位置提供了 USDC 的流动性,我提供了 1000,那我就会将 1000 这个价格的 Bin 上的流动性深度往上堆叠 1000 的高度。第二个人过来提供 2000,他就会将这个流动性深度提高到 3000 的高度。
为什么要在这里讲这一点?其实 Tick 相对来说是更符合 Uni V3 流动性的激励方案。而 Bin 我们认为它作为一个竖直方向堆叠的流动性方案,更适合离散的 NFT 流动性。我们可以把一个 NFT 流动性理解成一个小箱子,我们就可以堆叠在 Bin 的价格上。每有一个 NFT 的 Holder 或者一个 LP 过来为这个价格提供一个 NFT 流动性,我们就将它理解成在这个价格上,它会往上落一个箱子。
为什么我们说只是简单地学习某个 ERC20 DEX 没有办法能够同时解决上面的三个问题呢?首先不同的 NFT Token ID 之间存在着稀有度的差异,这部分产生价值期望的差异对于 NFT 这种资产标的是原生性的。而这一点上其实和我们大多数 ERC20 的 DEX 是有很大的差别的。因为 ERC20 DEX 中的流动性池在一个固定的时刻内是不可能有两个交易者在以不同的价格进行成交的。所以说如果我们希望构建一个复合的 NFT 市场,那我们就需要既学习中心化交易所订单薄的撮合模式,还需要学习在 DEX 的 AMM 模型中流动性聚合的方法。
那我们就有了这样一个设计:重新将中心化 NFT 市场中特有的 Best Offer 和 Floor Price 这两个概念引入进来。首先 Best Offer 是指在当前市场内最高的 NFT 报价,也就是买方对于这个 Collection 的 NFT 最高的理想价格,而 Floor Price 是当前这个市场内 NFT 卖单的最低报价。有了这两个价格之后,就形成了流动性市场的一个分水岭:
- 在 Floor Price 以上,我们可以利用 Bonding Curve 这种流动性提供方案为 NFT 交易者提供类似于 Order Book 的交易体验。举个例子,当某一个 LP 选择在 3 个以太坊到 5 个以太坊的区间里提供 NFT 的流动性,那这些 NFT 就会遵循他自己设计的 Bonding Curve 散落在 3 个到 5 个以太坊的价格点上。交易者在任意时刻进场交易的时候,他都可以选择自己心仪的 NFT 进行交易。那这个 NFT 在某种程度上其实就已经被 LP 限定住了一个价格。每进行一次交易,它可以在这个 LP 的这个 Bonding Curve 当中有一次价格的增长。
- 而 AMM 模型被应用在 Best Offer 及 Best Offer 价格以下。这里提供 FT 流动性的 LP 更像是在 Blur 市场当中提供买单流动性,可以被认为是同质化的。他们在自己希望提供流动性的价格区间内去安置自己的 FT 流动性,在同一个价格点下它们的流动性被认为是等价且聚合的。将这部分流动性聚合后,无论从市场的资本利用效率还是交易效率来讲,都大大提高了用户在卖出一个 NFT 时的交易体验。
这样一个 NFT 市场的设计,可以在某种程度上对于之前我们提到的三个痛点进行中和。我们选取了一个较为 Balance 的点,在不忽略 NFT Token ID 的情况下,还能为大家提供较好的流动性深度和较为低的 NFT 交易滑点。我认为在不忽略 NFT 原生交易需求角度来说,这可能是目前我们能想到的最好的方案。同时要提到另外一点,就是 Best Offer 和 Floor Price 作为 NFT 市场当中重要的两个价格指标,我们这样的一个交易市场其实是可以提供一个链上的 Oracle,或者说我们可以为某一个 NFT 交易市场提供一个很好的价格发现功能,而不是依赖于某一个外置的这个 NFT 市场去辅助 NFT 的定价。此外,一个纯链上的 NFT 交易市场为 DeFi 当中的可组合性也提供了很多的可能性。比如说我们的 LP Token 可以继续去做 Lending 杠杆的叠加,我们的这个 Oracle 也可以辅助一些链上预言机的报价。这些点都是我们为什么迫切地需要一个高效的能够解决交易者和 LP 需求的 NFT AMM 的原因。