-
Notifications
You must be signed in to change notification settings - Fork 0
Description
Among the current set of parameters are the three parameters: CONTRACT_SIZE, STRIKE_PRICE, and GRANTOR_TOKEN_STRIKE_PRICE. However these three parameters are constrained such that you only need two of these parameters.
I recommend replacing these three parameters with just two parameters:
-
The
CONTRACT_SIZECOLLATERAL_PER_CONTRACT, which is the amount ofCOLLATERAL_ASSETmanipulated per token. This is what is currently calledCONTRACT_SIZE. -
What I would call
SETTLEMENT_ASSET_SIZE, or something similarSETTLEMENT_PER_CONTRACT. This is what you are currently calling theGRANTOR_TOKEN_STRIKE_PRICE, which is not a great name, though I do understand why you choose it. This is the amount ofTARGET_ASSET(which I also suggest renaming toSETTLEMENT_ASSET) manipulated per token.
In particular in the Exercise path code the line
divmod_eq(collateral_amount_to_get, param::ASSET_STRIKE_PRICE, asset_amount_to_pay);
would be replace with the mathematically equivalent line
divmod_eq(asset_amount_to_pay, param::GRANTOR_TOKEN_STRIKE_PRICE, option_amount_to_burn);
or
divmod_eq(asset_amount_to_pay, param::SETTLEMENT_PER_CONTRACT, option_amount_to_burn);
under my proposed name.
Worked Example
Let's do some unit analysis here with a worked example for a call option to purchase (Liquid) Bitcoin (the collatoral asset) using USDT (the settlement asset) at some particular price.
COLLATERAL_PER_CONTRACT would typically be something like 1 000 000 sats / contract (which would be displayed as 0.01 L-BTC / contract) and for call options is typically a round number.
SETTLEMENT_PER_CONTRACT could be something like 115 024 360 000 μ¢ / contract (microcents are units of USDT on liquid, though this would be displayed as $1 150.2436 / contract) and for call options is typically less round than the COLLATERAL_PER_CONTRACT.
The advantage of selecting these two parameters is that these two values are always integers, because the amounts of collatoral asset and settlement asset being manipulated is always an integer multiple of the COLLATERAL_PER_CONTRACT and the SETTLEMENT_PER_CONTRACT.
These two values together imply the strike price, which, for call options, is SETTLEMENT_PER_CONTRACT / COLLATERAL_PER_CONTRACT. In our worked example this is 115 024.36 μ¢ / sats, (which, after changing to more reasonable units would be displayed as $115 024.36 / L-BTC). Notice that this strike price isn't necessarily an integer. Thankfully the options contract can and should be written in a way that avoids directly working with this non-integer value. Instead the strike price would only appear in wallet UX.
A couple of further notes, what your code currently calls the ASSET_STRIKE_PRICE is actually the inverse of the strike price I've defined above; the ASSET_STRIKE_PRICE is constrained to be the CONTRACT_SIZE / GRANTOR_TOKEN_STRIKE_PRICE. The fact that ASSET_STRIKE_PRICE is constrained to be an integer is a big problem for the current implementation which would render the above call option impossible to build on Liquid. Thankfully we can eliminate the use of ASSET_STRIKE_PRICE in the contract without too much difficulty.
Also I'd like to note that what that the options white paper calls "strike price" is actually the SETTLEMENT_PER_CONTRACT and not actually what tradfi people would call the strike price. So definitely be aware of that pitfall when reading that document.
Lastly, I'll note for put options the roles of settlement and collateral are reversed, with USDT held has collateral and LBTC as settlement. So for put options it is the SETTLEMENT_PER_CONTRACT that is usually a round number, and for put options the strike price is now COLLATERAL_PER_CONTRACT / SETTLEMENT_PER_CONTRACT in order to still get units of USDT/LBTC.
(Edited based on the conversation below up to #5 (comment))