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

Created 2019-08-17
Status Last Call
Category ERC
Type Standards Track
Authors
  • Runchao Han <runchao.han at monash.edu>

  • Haoyu Lin <chris.haoyul at gmail.com>

Simple Summary

A standard for token contracts providing Atomic Swap-based American Call Option functionalities.

Abstract

This standard provides functionality to make Atomic Swap-based American Call Option payment. The Atomic Swap protocol based on Hashed Time-Locked Contract (HTLC) [^1] has optionality [^2], and such optionality can be utilised to construct American Call Options without trusted third party. This standard defines the common way of implementing this protocol. In particular, this EIP defines technical terms, provides interfaces, and gives reference implementations of this protocol.

Motivation

Atomic Swap allows users to atomically exchange their tokens without trusted third parties while the HTLC is commonly used for the implementation. However, the HTLC-based Atomic Swap has optionality. More specifically, the swap initiator can choose to proceed or abort the swap for several hours, which gives him time for speculating according to the exchange rate. A discussion[^2] shows that the HTLC-based Atomic Swap is equivalent to an American Call Option in finance. On the other hand,thanks to such optionality, the HTLC-based Atomic Swap can be utilised to construct American Call Options without trusted third party. A paper[^3] proposes a secure Atomic-Swap-based American Call Option protocol on smart contracts. This protocol not only eliminates the arbitrage opportunity but also prevents any party from locking the other party's money maliciously. This EIP aims at providing the standard of implementing this protocol in existing token standards.

Specification

The Atomic Swap-based American Call Option smart contract should follow the syntax and semantics of Ethereum smart contracts.

Definitions

Storage Variables

swap

This mapping stores the metadata of the swap contracts, including the parties and tokens involved. Each contract uses different secretHash, and is distinguished by secretHash.

mapping(bytes32 => Swap) public swap;

initiatorAsset

This mapping stores the detail of the asset initiators want to sell, including the amount, the timelock and the state. It is associated with the swap contract with the same secretHash.

mapping(bytes32 => InitiatorAsset) public initiatorAsset;

participantAsset

This mapping stores the details of the asset participants want to sell, including the amount, the timelock and the state. It is associated with the swap contract with the same secretHash.

mapping(bytes32 => ParticipantAsset) public participantAsset;

premiumAsset

This mapping stores the details of the premium initiators attach in the swap contract, including the amount, the timelock and the state. It is associated with the swap contract with the same secretHash.

mapping(bytes32 => Premium) public premium;

Methods

setup

This function sets up the swap contract, including the both parties involved, the tokens to exchanged, and so on.

function setup(bytes32 secretHash, address payable initiator, address tokenA, address tokenB, uint256 initiatorAssetAmount, address payable participant, uint256 participantAssetAmount, uint256 premiumAmount) public payable

initiate

The initiator invokes this function to fill and lock the token she/he wants to sell and join the contract.

function initiate(bytes32 secretHash, uint256 assetRefundTime) public payable

fillPremium

The initiator invokes this function to fill and lock the premium.

function fillPremium(bytes32 secretHash, uint256 premiumRefundTime) public payable

participate

The participant invokes this function to fill and lock the token she/he wants to sell and join the contract.

function participate(bytes32 secretHash, uint256 assetRefundTime) public payable

redeemAsset

One of the parties invokes this function to get the token from the other party, by providing the preimage of the hash lock secret.

function redeemAsset(bytes32 secret, bytes32 secretHash) public

refundAsset

One of the parties invokes this function to get the token back after the timelock expires.

function refundAsset(bytes32 secretHash) public

redeemPremium

The participant invokes this function to get the premium. This can be invoked only if the participant has already invoked participate and the participant's token is redeemed or refunded.

function redeemPremium(bytes32 secretHash) public

refundPremium

The initiator invokes this function to get the premium back after the timelock expires.

function refundPremium(bytes32 secretHash) public

Events

SetUp

This event indicates that one party has set up the contract using the function setup().

event SetUp(bytes32 secretHash, address initiator, address participant, address tokenA, address tokenB, uint256 initiatorAssetAmount, uint256 participantAssetAmount, uint256 premiumAmount);

Initiated

This event indicates that initiator has filled and locked the token to be exchanged using the function initiate().

event Initiated(uint256 initiateTimestamp, bytes32 secretHash, address initiator, address participant, address initiatorAssetToken, uint256 initiatorAssetAmount, uint256 initiatorAssetRefundTimestamp);

Participated

This event indicates that participant has filled and locked the token to be exchanged using the function participate().

event Participated(uint256 participateTimestamp, bytes32 secretHash, address initiator, address participant, address participantAssetToken, uint256 participantAssetAmount, uint256 participantAssetRefundTimestamp);

PremiumFilled

This event indicates that initiator has filled and locked premium using the function fillPremium().

event PremiumFilled(uint256 fillPremiumTimestamp, bytes32 secretHash, address initiator, address participant, address premiumToken, uint256 premiumAmount, uint256 premiumRefundTimestamp);

InitiatorAssetRedeemed/ParticipantAssetRedeemed

These two events indicate that asset has been redeemed by the other party before the timelock by providing secret.

event InitiatorAssetRedeemed(uint256 redeemTimestamp, bytes32 secretHash, bytes32 secret, address redeemer, address assetToken, uint256 amount);
event ParticipantAssetRedeemed(uint256 redeemTimestamp, bytes32 secretHash, bytes32 secret, address redeemer, address assetToken, uint256 amount);

InitiatorAssetRefunded/ParticipantAssetRefunded

These two events indicate that asset has been refunded by the original owner after the timelock expires.

event InitiatorAssetRefunded(uint256 refundTimestamp, bytes32 secretHash, address refunder, address assetToken, uint256 amount);
event ParticipantAssetRefunded(uint256 refundTimestamp, bytes32 secretHash, address refunder, address assetToken, uint256 amount);

PremiumRedeemed

This event indicates that premium has been redeemed by participant. This implies that asset is either redeemed by initiator if it can provide the preimage of secrectHash before asset timelock expires; or refunded by participant if asset timelock expires.

event PremiumRedeemed(uint256 redeemTimestamp,bytes32 secretHash,address redeemer,address token,uint256 amount);

PremiumRefunded

This event indicates that premium has been refunded back to initiator, because of participant doesn't participate at all, by the time of premium timelock expires.

event PremiumRefunded(uint256 refundTimestamp, bytes32 secretHash, address refunder, address token, uint256 amount);

Rationale

Security Considerations

Backwards Compatibility

This proposal is fully backward compatible. Functionalities of existing standards will not be affected by this proposal, as it only provides additional features to them.

Implementation

Please visit here to find our example implementation.

Copyright

Copyright and related rights waived via CC0.

References

[^1]: Hash Time Locked Contracts

[^2]: An Argument For Single-Asset Lightning Network

[^3]: On the optionality and fairness of Atomic Swaps