Opium Network
  • Opium Documentation
  • Introduction to Opium
    • What is Opium
    • FAQs
  • Restrictions
    • Restrictions
  • Security and Audits
    • Disclaimer
    • Audits
    • Bounty program
  • Governance
    • Decentralized setup
    • Governance flow
      • Proposal creating
      • Process of voting – technical description
    • $Opium governance token
  • For users
    • Opium.Finance
    • opium.exchange
  • FOR DEVELOPERS
    • Deployment Addresses
      • Opium Protocol v2
      • Opium Protocol v1
    • High-level overview
    • Opium Protocol V2
      • Core
      • Registry
      • SyntheticAggregator
      • OracleAggregator
      • OpiumProxyFactory
      • OpiumPositionToken
    • Opium Protocol V1
      • Core
      • Registry
      • TokenMinter
      • TokenSpender
      • SyntheticAggregator
      • OracleAggregator
      • Helpers
      • Interfaces
      • Common Errors
        • OracleAggregator Errors
        • Core Errors
      • oID - Oracle recipe
      • sID - Derivative recipe
      • EIP-2547: Composable Multiclass Token
    • Tutorials
      • OracleId examples
      • SyntheticId examples
      • End-to-end tutorial
    • Opium API
      • Subgraph V2
      • Subgraph V1
    • SDK
      • Opium V2 SDK
      • Opium Finance Pools SDK
      • Swap Rate SDK/API
  • Complex description
    • Glossary
    • Opium derivatives
    • Oracle and derivative recipes
    • Oracle and derivative registers
    • Opium margin
    • Opium swaps (TMtm)
    • Opium order books
Powered by GitBook
On this page

Was this helpful?

  1. FOR DEVELOPERS
  2. Tutorials

SyntheticId examples

The financial logic of a product built on top of the Opium Protocol is encoded in a SyntheticId.

A SyntheticId must inherit the IDerivativeLogic interface as the Opium Protocol SyntheticAggregator expects to call some of the functions defined in the IDerivativeLogic contract throughout the lifecycle of the derivative. Specifically, these core functions are:

  • validateInput

  • getMargin

  • getExecutionPayout

  • getAuthorAddress

  • getAuthorCommission

  • thirdPartyExecutionAllowed

  • allowThirdPartyExecution

The core function of a SyntheticId is the getExecutionPayout. It allows a SyntheticId author to describe the payout logic of their financial product. Hence, whether a financial product is a traditional call option or put option, a CDO or some more exotic derivative, that’s the function where the logic needs to be encoded.

The following is an example of a getExecutionPayout implementation for a CALL option:

function getExecutionPayout(Derivative memory _derivative, uint256 _result)
        public
        view
        returns (uint256 buyerPayout, uint256 sellerPayout)
    {
        uint256 ppt;

        uint256 strikePrice = _derivative.params[0];

        if (_derivative.params.length == 2) {
            ppt = _derivative.params[1];
        } else {
            ppt = BASE_PPT;
        }

        if (_result > strikePrice) {
            uint256 profit = _result.sub(strikePrice);
            profit = profit.mul(ppt).div(BASE_PPT);

            if (profit < _derivative.margin) {
                buyerPayout = profit;
                sellerPayout = _derivative.margin.sub(profit);
            } else {
                buyerPayout = _derivative.margin;
                sellerPayout = 0;
            }
        } else {
            buyerPayout = 0;
            sellerPayout = _derivative.margin;
        }
    }

In the above example, in case the option is in the money and its intrinsic value is greater than the allocated margin, then the difference between the underlying's market price and the strike price represents the buyer's profit and the seller's loss. However, if the option is in the money and the profit is greater than the allocated collateral, then the buyer's profit is equal to the entire margin.

Conversely, the following is an example of a PUT option:

function getExecutionPayout(LibDerivative.Derivative memory _derivative, uint256 _result)
        public
        view
        override
        returns (uint256 buyerPayout, uint256 sellerPayout)
    {
        uint256 ppt;

        uint256 strikePrice = _derivative.params[0];

        if (_derivative.params.length == 2) {
            ppt = _derivative.params[1];
        } else {
            ppt = BASE_PPT;
        }

        if (_result < strikePrice) {
            uint256 profit = strikePrice.sub(_result);
            profit = profit.mul(ppt).div(BASE_PPT);

            if (profit < _derivative.margin) {
                buyerPayout = profit;
                sellerPayout = _derivative.margin.sub(profit);
            } else {
                buyerPayout = _derivative.margin;
                sellerPayout = 0;
            }
        } else {
            buyerPayout = 0;
            sellerPayout = _derivative.margin;
        }
    }
PreviousOracleId examplesNextEnd-to-end tutorial

Last updated 3 years ago

Was this helpful?