Premia Finance介紹

Option AMM屆的新秀到底有沒有料?

Anton Cheng
DeFi 燒酒螺
21 min readFeb 26, 2022

--

前言

Premia是去年除了Lyra以外,另一個嘗試Option AMM並且有所突破的團隊。當時剛出來的時候我有去看他們的whitepaper,但看了一分鐘就被嚇跑了,因為很多看起來很可怕的數學。不過現在沈住氣、從文件開始看,發現那些數學其實跟他們的鏈上的機制沒有太大的關係。倒是他們的合約從工程角度有滿多讓我覺得值得參考的地方,就順便分享給大家了。

這篇文章會主要介紹Premia如何進行定價、如何搓合買賣、加上一些我對他們模型的想法。對於選擇權的基礎不太了解或是想要複習一下的,可以快速瀏覽一下我之前寫的選擇權系列簡介:

也推薦複習一下Yuren Ju大大寫的Lyra簡介,因為下面會有一些拿來跟Lyra比較的地方:

Premia機制簡介

很重要的前提是,雖然口口聲聲說是AMM,但其實Premia現在的機制並不像Lyra目標要做完整的AMM: 提供雙向流動性的自動造市商,讓任何使用者可以買跟賣選擇權;相反的,Premia的作法跟Hegic比較類似:所有的LP其實就同時只是選擇權的賣家,大家可以跟這一群賣家買選擇權,並且在任何時候執行,所以可以想像成他們是賣美式選擇權(American option)的撮合器。

另外,每一個存錢進去LP的賣家,其成交的交易其實是分開的:每個買家來對Premia交易時,會按照順序從這群賣家中選出幾個人來當他的「對手」,因此對於「當Premia的LP會不會賺錢」很難一以概之,很大程度上這很靠運氣,你的對手賺錢你就虧錢、他虧錢你就賺錢。不過Premia的token frarming program有特別關照那些存錢進來卻賠錢的賣家,算是很認真的在送錢,不過這邊就不特別討論了。

換句話說,Premia這麼做所也代表他們想解決的核心問題就跟Lyra不同:他們的核心還是偏向於給予買賣雙方一個公平的定價,並且透過一些外加機制來確保池子裡面持續有錢繼續賣。所謂的LP在這裡不需要接受任何方向(買或賣、買權或賣權)的交易,這點就跟我前一篇文章介紹的傳統選擇權造市商的角色有點不同,並不是接受任何方向的交易並試圖賺取Spread;而是可以根據自己的市場預測,選擇要當「哪種選擇權的賣家」,例如只賣ETH call、只賣 BTC put等等,他們官方也把這個當成一個feature在推廣。更多關於這種模型的更多討論,我們留到最後面再說。

Option Pricing

Premia在定價這一塊的處理方法比較特別的有兩塊:(1.) 在最基本的Black Scholes中使用了更完整的vol surface oracle。(2.) 引入了「供需的價格發現機制」:C-Level,可以確保買賣雙方的量大致達成一個平衡,使得資金使用率提高。我們以下分開來介紹:

Implied vol surface

在前面介紹Lyra的文章裡面,有介紹什麼是volatility smile:指的就是在導出Black-Scholes模型之後,大家發現實際上市場上的選擇權定價在strike price不同時,其定價的隱含波動率(implied vol)也不同。這代表我們不能用一個波動率(vol)值給所有的strike price定價。

這也是為什麼Lyra會引用一個skewness,其實就是一個調整參數,在面對不同strike price時,多乘上一個參數,來調整要丟進去Black-Scholes公式的vol值:越向圖的兩邊:這個值應該越高,才符合這個微笑曲線

但是實際上除了執行價跟隱含波動率有關係外,到期時間也是一個重要的要素:如果我們把隱含波動率拿來跟

  1. 執行價與現價關係(moneyness)
  2. 現在到到期日時間(time to expiry)

作圖,就會發現在三維空間這是一個曲面:

因此最好捕捉適用於Black-Scholes公式的vol值的方法,其實是要建立這樣一個曲面的函數,會比使用二維的volatility smile更精準。

講了這麼多,其實就是要說Premia做了一個volatility surface oracle。但這個oracle在實作層沒有什麼特別,因為他是直接利用Chainlink Oracle來進行每兩小時一次的公式係數更新。每當合約需要對新的選擇權定價時,他們就直接讀取幾個係數,然後輸入moneyness以及time to expiry的「多項式」得出一個vol值。GitHub運算在這裡,白話的二項式如下:

vol = e[0]+ e[1]* m + e[2]* m² + e[3] t+ e[4]* mt

  • m: adjusted moneyness
  • t: time to expiry
  • e: coefficients

這個公式直接解釋沒什麼意義,其實就是他們找出一個鏈上計算不會太複雜、足夠描述曲面的多項式。每兩小時Oracle就會先在鏈下算出一個曲面,拆解成這五個係數,並用更新一次係數陣列,就相當於為合約提供了新的「波動率曲線」。

C-Level (or C-value)

工程方面比較無聊的oracle說完了,接這著就是Premia主打的功能了:在透過剛剛介紹的oracle讀到「精準的波動率」之後,他們會用black-scholes算出一個選擇權的base price。這個base price是沒有考慮市場供需狀況的,只考慮了波動率。因此接著就透過C-Level的導入,就是為了透過目前到底是「供過於求」還是「供不應求」來進行調整。這就是可以在鏈上自行調整的部分了,因此感覺比較酷一點。我們這裡直接附上公式:

其中 S 代表了流動性,x_t 則代表一個時間點造成的流動性變化率;c 值就是這裡講到的 c-value,他透過 x_t 來進行更新。最後一行只是再寫一次,這個c 值會被用來修正Black-Scholes算出來的結果(我們晚點再介紹最後一項Slippage Coefficient)。

我們可以先觀察這個公式,整個c值最終是被用來當作一個multiplier,所以c值高於1,代表最終價格高於剛剛算的base price,而值越高也代表option越貴,可以想像是「供不應求」的情況;反之若是c值小於1,則是「便宜賣」。所以我們不難猜到,以下這些情況理論上要對c值有這些影響:

  • LP提供流動性:供給變多, c值應該下降
  • LP移除流動性:供給變少, c值應該上升
  • 向LP買選擇權:需求變多, c值應該上升
  • 向LP賣選擇權:需求變少, c值應該下降:但這件事在Premia不會發生,因為這裡只能買不能賣。

回到公式本身,x被定義為交易量的變化率 :在交易量很小的時候會是0,增加流動性時為正、流動性減少實為負。可以看出c值的update是透過前一個c值,然後乘上e^-x ,給大家複習一下這個曲線:

y = e ^ -x

是不是很適合拿來當update的圖啊?在x為正(流動性增加)的時候,這個值小於1,乘上來可以減少c值:x為負(減少流動性)的時候這個值則大於1,可以用來放大c值。

因此每筆交易進行之後,池子都會根據這筆交易對池子的影響,來挑整c值,若是很多人買,c值就會上漲,理論上就會吸引更多賣家把自己的錢存進來等著賣;反之若是賣家太多,c值會下降,讓大家可以用低於base price的價格買到選擇權。Premia也是透過設定一個很高的初始c值,來吸引在協議一上線的時候,會有賣家來提供流動性。

附上官方美美插圖

另一個值得注意的點就是:這個C-Level更新公式有「路徑依賴(path dependent)」的特性,也就是說,透過多筆交易加入流動性、跟只用一筆交易加入流動性,就算總流動性相同,卻會對C-Level造成不同的影響。為此,在實作上Premia使用了一個 “batch deposit” 的機制,就是合約會每隔20個區塊把所有 “deposit” 的流動性一起加總,並只做一次更新。這可以防止有人透過一個區塊內大量小金額存款來的大伏度降低C-Level,然後用便宜的價格買到選擇權,算是一個挺聰明的保護機制。如果合約有在任何地方用到path dependent state update的話,可以參考一下這個做法。

Slippage Coefficient

最後我們再補充一下pricing 的最後一塊,一個叫slippage coefficient的參數。這個參數的意義是考慮池子裡面剩餘的流動性來調整定價,防止任何交易花光池子裡面的流動性。可以想像它的名字來自類似Uniswap有的滑價機制,讓大筆的交易承受一點penalty來保障流動性。

由於Premia AMM只處理買選擇權的狀況,而每次買的時候流動性都是減少的,因此這裡需要的一個函數,能在流動性改變率 (上面的x)= 0~-1 的時候來給予定價penalty。在x = 0時,代表買的數量很小,對流動性幾乎沒有影響,這個multiplier應該是1(代表價格不變);而當x 接近 -1時,代表這個交易將會用掉接近100%的liquidity,這時候就需要例如把價格乘個5倍,來當作penalty。Premia最後給出的公式如下:

圖大概長這樣,斜度會隨著a (steepness)改變。a 就是他們團隊可控制的參數了。

上述這些東西組合在一起,就是Premia的定價了。挺簡單的吧!

LP 機制

說完定價,再來看看他們怎麼處理內部的Accounting。在合約中,整個Pool合約同時是一個EIP1155的token standard, 就是可以透過 tokenId 在一個合約內部定義多種token,分開紀錄餘額、總供給量等等,因此他們大量的使用不同的“token”來代表不同狀態的資產:總共有free liquidity, reserved liquidity, long token, short token四種。這些待會都會大概介紹一遍。

另一個直得注意的點是,儘管一個資產對(exp: ETH-USDC pair)只會有一個合約,但是關於Put以及Call的所有Accounting都是分開的,也就是說,可以視為兩個池子:一個是提供ETH當流動性並願意Sell Call的池子、一個是提供USDC當流動性並願意Sell Put的池子。這讓LP可以選擇他們想要當哪種種類的賣家,同時能基本確定他們的risk direction(看漲或看跌等等)。

加入流動性 (Deposit)

前面稍微提到過,Premia是透過一個first-in-first-out queue來記錄所有賣家(合約裡被稱為underwriter )。當一個人存錢進來時,就會被加入queue的最後面,並且獲得 free liquidity token。例如今天存入ETH,就會被加到call underwriter 的queue裡,並且獲得 free call liquidity token。

First-In-First-Out Queue

你持有free liquidity token就代表你持有多少「隨時可以移出」的流動性。這些流動性是閒置的,還沒有被拿來真的當作抵押品跟買家對賭。

有人來買的時候

在買家來的時候,就從這個queue裡面選前n個買家,可以湊齊這個數量,然後分別對買賣家更新他們的帳項:

附上一張,從queue中找到足夠流動性的美美插圖
  • 賣家:移除這些賣家的free liquidity token、 mint給他們short token
  • 買家:mint給買家 long token

這裡不難想像:所謂long token跟short token就是成對的:每次會mint 出一定數量的long and short,並讓買家跟賣家分別持有。

持有long token就可以在到期前、現貨價格移動到價內(In the money)時執行,並換取其內在價值;反之身為賣家,任何時候你的對手執行了,你的short token就會變回free liquidity token,繼續提供流動性(這是預設的模式),因此一個LP什麼事都不做的話,他提供的流動性會在上一次賣的選擇權到期會被執行之後,繼續回到Queue當中,成為跟下一個買家對賭的抵押品;不過我們很快會講到gradual withdraw,可能在結算時讓你的short token變成 “reserved liquidity token”,就不會在下一輪繼續被使用了。

移除流動性(Withdraw)

想要移除流動性有幾種方法:最簡單的情況是:如果你的流動性現在是閒置的(free liquidity),只要已經存入超過一天就可以隨時領出來。

不過有很大的機率你在想要退出池子的時候,你的資金是被鎖著的,也就是你現在處於short的狀態。這時候你可以選擇以下兩種方式:

  • Gradual withdraw: 像剛剛有說到的,任何LP都可以在任意時間送一筆交易(setDivestmentTimestamp)表示我想要在某一個時間點之後停止提供流動性:那麼下次結算到你的short倉位時,若是發現時間已經超過你要移除的時間,就會mint給你reserved liquidity token,讓這些流動性不會再被拿去當抵押物,讓你可以隨時移除。
  • Reassign: 你也可以向下一個賣家「買入」你現在正在short的數量,來抵銷現在的倉位。這有點像是把這個position 傳給下一個賣家,但這也代表你要照著現在的市場價格付下一個賣家premium,可能比之前收到的premium更高,一個虧本。而且系統也無法保障剩下的賣家有足夠的流動性接這筆交易。

以上就是基本的週期以及所有你會拿到的token介紹。可以看出其實這整個過程是充滿各種state update,所以一筆交易也不便宜:尤其是如果你運氣不好,或要買的數量大的話,可能要同時找5,6 個LP當作對家,合約就會用一個迴圈更新這五個人的狀態,只能說gas高低很看運氣。為了防止spamming,合約有規定每個LP的最小流動性,以免有人存一大堆1 wei的來讓大家瘋狂迴圈浪費gas。

合約特色: Diamond 💎

在讀他們家的合約的時候,發現他們非常不偷雞的認真實做了完整的「鑽石合約」標準。沒有聽過diamond standard的話十分推薦 Kimi Wu大大的這篇文章:

一言以蔽之,鑽石合約就是透過一個mapping,在一個proxy上面外掛很多實作(implementation)合約:根據用戶所呼叫的function,經過查表,決定要去delegateCall哪一個實作合約。

這樣做最大的好處我覺得有兩個:(1. )可以超過24KB 的合約大小限制:因為邏輯可以被分散在不同的合約裡,非常適合肥大的專案。(2.) storage的管理變得非常的乾淨:因為每個implementation可以分開宣告自己會用到的storage。

不過Premia在他們實作上,其實並沒有很大程度運用第二個性質來管理storage:他們的做法還是一個Proxy共用一個Storage合約。例如主要的Pool合約,就是用一個 PoolStorage.sol 的檔案宣告全部的state variables,並讓所有實作合約共同繼承這個storage contract。這樣最後每個邏輯合約所指向的storage slot在proxy合約上都會是相同的。這樣做一定程度上也比較安全:因為可以保證不會有storage collision。

另一個原因是,他們的合約切割方法並不是依照共同使用的變數 (variable)來切割,所以常常會有多個合約用到同樣的state variable的狀況。他們甚至有一個 PoolView.sol 的合約,基本上就是回傳所有state variable,所以它需要用到所有的storage。

這種把storage獨立成一個合約的寫法,其實已經很大程度提高可讀性了。一定程度來說,這些Storage其實也都還算相關,所以放在一起管理也還算合理。只是我覺得有點可惜沒有真的看到透過Diamond的方式管理storage。

SolidState Library

我也發現他們所有底層的合約(例如EIP1155, ERC20, Ownable…等 )都是從一個他們自己寫的SolidState Library引用進來的,裡面也自己實作了很多Set, List之類的資料結構,讓我覺得滿佩服的,畢竟我都只會call別人的library。這裡提供GitHub給大家,可以按個星星存下來,如果下一個合約想要寫寫看鑽石版本,應該會很實用。

其實他們這裡透過繼承自己寫的Diamond 版 Token contract,理論上也算有用到上面說的鑽石標準storage管理方式。不過不放在同一個專案內,就比較無感了。

模型討論

看完機制介紹以及他們合約的一些特色之後,我也來分享一下我對這個模型的看法:整體上來說,我覺得整體設計是對買家更友善,把更多風險轉嫁到賣家身上。而合約架構這個設計是很有彈性的,下面就列出一些我對這個模型的看法:

簡單容易懂的的參數: C-Level

這是我最喜歡他們設計的一部分,對於任何使用者而言,這個參數可以一目了然讓你知道,現在究竟該不該買,或是存錢進去當賣家。因為這個參數就是一個供需平衡的代表,如果c-level很低,現在東西都便宜賣,很高就代表現在供不應求、現在進來當LP搞不好可以賺一點。

尤其是c-level低的時候,很有可能能在不同選擇權市場找到套利機會,因為買家可以看各個市場有哪些正在被交易的選擇權,很有機會找到現在可以跟Premia 賣家便宜買,在別的地方高價賣的套利機會。

不過這裡延伸分享一個Ping Chen跟我討論到到有趣的點:在Premia這樣的模式下,賣家被要求先存錢,如果最終成交的時候,價格是一個「公平價格」,這樣對賣家是很不公平的。有點像假如今天有個「賣ETH合約」要求你先存入ETH當賣家,然後有人想買的時候依照oracle的定價(現價,也就是公平價格)賣出,那麼賣家跟純粹market sell比起來,徒增了風險跟不確定性,卻沒有一個「獎賞」。用這樣的思路來看,理論上一個理性的市場應該會讓c-level維持在一個高於1的水平,也就是市場會為了補償賣家的風險,平衡在一個稍微overprice的水平。不過這些東西在Premia現在的系統上觀察不會準,因為現在有token farming機制。

更彈性的到期日以及執行價

跟目前市面上其他AMM相比,這樣的模型能給予買家更彈性的報價機制。拿Lyra來比較:Lyra必須透過他們的委員會決定要launch哪些執行價以及到期日,大家能交易的執行價也會因此被限制;但在Premia,基本上對買家而言,只要strike price處於一個正常區間,到期日不要太長,你可以選擇任何你想要的執行價,會給予買家更多彈性。

相反的,賣家要承受的風險跟收益就非常的多樣化了:儘管可以指定方向 (賣買權or賣賣權),但你的倉位還是可以千變萬化,以賣買權(Call)為例,如果今天買家要買一個執行價超高的買權,你的倉位就是風險低,利潤也低;如果買家要買執行價很低的買權,則突然變成高風險高報酬。所以我個人覺得對賣家而言,能決定方向這件事情不足以彌補最終倉位的不可決定性。

更不可控的鎖倉機制

第二個讓我覺得不敢當賣家的原因則是不可控的到期日:現在合約中對於到期日的限制是1~90天,也就是說全憑運氣,你可能最長一次資產就被鎖住90天。重點是這90天換來的搞不好是一個很低的premium。

我們可以回頭看看Lyra目前的做法:他們透過不同Round,強迫所有用戶不可以對AMM交易超過這個Round結束時間到期日的選擇權,因此LP每次只要確保:我願意提供流動性到這個round結束,就可以在確定的時間收回流動性。這就讓LP比較能夠控制,再怎麼賠,至少兩週後可以拿回我的錢。

Lyra這樣做的缺點也很明顯:不能夠支援到期日較長的交易。因為在Lyra中,所有LP都是平等的買家和賣家,大家收益也都相等,總不能強迫大家全部都一個週期鎖住90天吧。就算真的這樣,快到週期結尾的時候,一般用戶一樣沒剩多少到期日的選擇。

我覺得Premia的作法其實可以有更多彈性,但是工程上也會複雜不少:若是已經把所有賣家分開處理,理論上可以透過一些更複雜的記帳方式,確保每個賣家可以對自己想賣的選擇權有更多控制權:例如可能有些人就是願意讓流動性被鎖住比較久,有些人就不願意賣太接近現價的選擇權。

不是真☆AMM,但優化版可以做結構性產品

上面有稍微提過,在Premia中,其實LP就是賣家,而不是真正意義上支援買賣雙向的「造市商」。所以像Lyra特別介紹的各種Hedge手法在Premia完全沒有被提及。他們的說法是:你要知道自己的directional preference才會來當LP,我們也就不用幫你做什麼delta hedge了。(Delta Hedge的目的就是無論市場怎麼移動都賺錢)。這麼說確實是很合理,理論上你真的很想hedge的話,你也可以寫一個合約當成Premia的賣家,然後隨著賣出的選擇權不同,自動hedge自己的倉位。

值得一提的是,如果大家還記得Ribbon這類的Option Vault商品的話,會發現如果Premia可以做到讓賣家有更多控制權的優化,其實這個架構是很適合被套用到結構商品或是自動化策略:由於選池子的過程中就已經選了你的profolio preference,例如我選擇提供ETH當作流動性來賣covered call,就其實是看漲,也很像Ribbon的call selling vault了。不同的點是,Ribbon的「策略」在於可以自動化選擇好的執行價來賣的,Premia以目前的架構就做不到這點,因為要賣什麼是由買家想買什麼決定。如果Premia可以做到讓賣家定義更精準的策略,那理論上Premia可以滿足更多樣化的買家需求,理論上定價也會比較公平,相較於Ribbon要在一次拍賣中盡量賣完,Premia的「自動販售」功能會讓賣家有較穩定的收益。

結語

雖然我好像不小心一直攻擊Premia不是真的AMM,但這只是因為我本來抱著看到「自動造市商」的期望來看Premia,最後發現跟我想像不一樣所以有點小失望。但這不代表它不配稱為AMM,畢竟DeFi Option老祖宗Hegic兩年前就開始叫自己Option AMM了,只能說這個題目很大,大家可以目標嘗試解決的同的問題。

我認為Premia的設計其實是滿有趣的,從模型上,這個用queue的設計我覺得也是乍看很不可行,但是其實提供了很多彈性,也直接擺明了避開了很多其他AMM設計會遇到的問題(例如怎麼算LP token的價值、怎麼確保LP不能透過存錢或提領時間差多賺或少賠…等等)。而實作上,看到他們寫的SolidState Library 只能說看到這誠意都跪了,非常期待這個願意從頭刻套件的工程團隊能夠繼續用強大的技術教育我。

最後,特別感謝Ping Chen 以及 Anderson Chen 幫忙審稿 😍,也附上我用英文寫的一篇關於他們合約的「學習筆記」,應該跟這篇中文版有不少重複的觀點,但是有多著重在合約的一些實作細節上,也懇請大家支持了 🥳

寫完文章又可以出去玩啦!

--

--