ERC-2266 Atomic Swap based American Call Option (Atomic Swap-based American Call Option Contract Standard)

Last Call · Vaults & DeFi · created 2019-08-17

A standard that implements, as a smart contract, an American Call Option trade in which a premium is exchanged using an Atomic Swap, where two parties swap tokens without a trusted intermediary.

Why it is needed

An atomic swap using a Hash Time Lock Contract (HTLC) lets two parties swap tokens without an intermediary, but it gives the party who initiates the trade an optionality: they can freely choose whether to go through with the exchange over a period of hours. The initiator can watch exchange rate movements during that window and only complete the trade when it favors them, simply abandoning it otherwise. This is effectively the same as a financial American call option, yet the initiator pays no premium for that option, leaving the counterparty unilaterally disadvantaged. Conversely, properly harnessing this optionality makes it possible to construct a call option product without any trusted third party. This standard defines a common way for protocols to implement this by locking the premium into the contract alongside the swap, removing the arbitrage opportunity and preventing either side from maliciously locking up the other's funds.

What to implement

In depth

Terminology and party definitions

The initiator is the party who posts the swap offer, and the participant is the party who agrees to and joins that offer. asset is the amount of tokens to be exchanged, and premium is the amount of tokens the initiator pays the participant as the price of the option. redeem is the act of claiming the counterparty's token, and refund is the act of reclaiming one's own token after the timelock expires. secret is a random string chosen by the initiator, the preimage of a hash, and secretHash is its hash value used to construct the HTLC. timelock is the deadline before which redeem is possible and after which only refund is possible.

Storage layout: four mappings keyed by secretHash

The contract maintains four mappings keyed by bytes32. swap stores the swap contract's metadata such as the parties and tokens, initiatorAsset stores the amount, timelock, and state of the asset the initiator is selling, participantAsset stores the amount, timelock, and state of the asset the participant is selling, and premium stores the amount, timelock, and state of the premium deposited by the initiator. Each contract uses a distinct secretHash, and the same secretHash links all four mappings into a single contract.

Locking phase: setup, initiate, fillPremium, participate

setup(secretHash, initiator, tokenA, tokenB, initiatorAssetAmount, participant, participantAssetAmount, premiumAmount) creates the contract's skeleton. After that, the initiator locks the asset via initiate(secretHash, assetRefundTime) and the premium via fillPremium(secretHash, premiumRefundTime), and the participant locks their own asset via participate(secretHash, assetRefundTime). Per the Rationale, the participant should decide whether to participate only after the initiator has locked the token and set the timelock, and the initiator should decide whether to proceed with the swap only after the participant has locked theirs.

Settlement phase: redeemAsset and refundAsset

redeemAsset(secret, secretHash) is a function that presents the secret, the preimage of the hashlock, to claim the counterparty's token. When the initiator uses this function to claim the participant's token, the secret is revealed on chain, so the participant can likewise use the same secret to claim the initiator's token. If the timelock expires, either party can use refundAsset(secretHash) to reclaim the token they themselves locked. Redemptions and refunds are recorded respectively via the InitiatorAssetRedeemed, ParticipantAssetRedeemed, InitiatorAssetRefunded, and ParticipantAssetRefunded events.

Premium settlement rules

redeemPremium(secretHash) can only be used by the participant, and only after the participant has already called participate and the participant's token has either been redeemed or refunded. In other words, whether the initiator exercised the option and revealed the secret, or failed to exercise it so the participant was refunded after the timelock expired, a participant who joined receives the premium either way. Conversely, refundPremium(secretHash) is a function that lets the initiator, who completed initiate but whose participant ultimately never joined, reclaim the premium after the premium's timelock expires. This structure guarantees payment for the optionality while preventing malicious locking of funds.

Compatibility and implementation

This proposal maintains full backwards compatibility. Because it only adds functionality without changing the behavior of existing standards, it does not affect existing token standards. The original text also provides an example implementation (Example.sol). The status of this document is Last Call, with a listed deadline of December 31, 2020.

Things to watch out for

Original ERC · ← ERCs