# Opium Documentation

### The goal &#x20;

The goal of this documentation is to provide a comprehensive overview of the project for current and future contributors within a formalized path to the full decentralization of the Opium Protocol. As the founding team takes a step back, leaving the government power to the community, it is crucial to have a single point of truth for all stakeholders to refer to. The documentation is published on GitHub and is open for contributions to reflect the growth and development of the project. This current document is the result of work of many contributors, many thanks to all contributors and special thanks for Stani, Kain, Anton, Sergej, Synth and for your contribution, support and endless community calls.

### The scope&#x20;

This Documentation explains:&#x20;

* what the Opium protocol is&#x20;
* how it works with actual examples&#x20;
* how a user without any coding knowledge can interact with it and how a developer can build something on top of the protocol or modify it&#x20;
* what efforts are in place to guarantee the security, including the list of past security audits and the bug bounty program&#x20;
* how to contribute to the development of the Opium protocol with or without tech experience and&#x20;
* how to participate in the grant programs.&#x20;
* A substantial part of the documentation covers the governance processes from discussion of the proposals and voting procedures to the actual execution as well as how $OPIUM tokens can be used and what $OPIUM token holders can vote on.

### **Disclaimer – please read before getting to the next section**

**Opium provides innovative, cutting-edge technology that is yet to be proved by time. As a beta version of a new financial system, the Opium protocol serves primarily the community of experienced DeFi professionals, who are able to evaluate associated risks, including, but not limited to, the technical failure and permanent capital loss.**

**It’s essential to understand that the parallel with traditional financial tools such as derivatives is drawn solely for a simplified explanation of Opium’s possibilities. Despite seeming similarity, DeFi tools are quite different, with their unique costs and benefits, risks and protection mechanisms. The Opium protocol provides software that enables and enforces transactions between two or more parties without a traditional centralized intermediary. Please make sure you fully understand how this software operates, the incentive mechanism that it employs, implications of technical failure and other protocol-specific risks before using any of the Opium products.**


# What is Opium

The protocol is based on the [Opium Whitepaper](https://github.com/OpiumProtocol/opium-contracts/blob/master/docs/opium_whitepaper.pdf) and runs on the blockchain; it is decentralized. The protocol codebase is [open-source](https://github.com/OpiumProtocol/) and maintained by the community.&#x20;

Opium was developed by a founding team and contributiors with expertise in technology, trading and finance. After the successful launch of the protocol, the team stepped back from governance. Currently, the protocol is governed by $OPIUM token holders and supported by members of the community, ecosystem partners and a decentralized team of contributors.

### A brief description of Opium

The Opium protocol is a smart escrow that enables two parties to make a trustless contract and holds an asset on their behalf until contract terms are fully or partially fulfilled. It is used when two parties are in the process of completing a transaction, and there is uncertainty over whether one party will be able to fulfill their obligations or when the transaction depends on an outcome of a future event. A safe accepts an asset according to a rule and releases it in some time according to another rule that depends on an oracle. Oracle communicates to the escrow whether the desired event occurred or not or provides some numerical data and thus triggers the execution of the transaction.&#x20;

A very simple example of how an escrow works would be hiring a freelancer to perform some tasks. Parties agree on parameters, such as scope, deadline and remuneration, and create a safe. A hiring party deposits money. After the deadline, an oracle reports how much work is done. Depending on how much work is completed, the safe will give the freelancer either a percentage or the full sum.

One doesn’t need any technical knowledge to create an escrow or safe; once created, a safe will work endlessly as programmed. Anyone interested in entering a contract with the same parameters can use the existing escrow. The contracts are always made between two people, and there is no risk to affect the agreements of other users.

![](/files/qcnmWvmZU9Uz7SSCAd73)

### Use cases

1. For example, two people wager on the outcome of the Italian soccer championship serie A. They create a unique escrow and deposit the same amount of money in a safe, let’s say 600 euro. The safe closes for a week. After a week, it checks who won the final and transfers 1,200 euros to a person who has correctly guessed the winner.&#x20;
2. A financial derivative escrow operates in a similar way. One or both parties lock collateral and enter into a financial contract at some price, analogous to futures or options. Let’s assume one participant made a deposit of 3,000 dollars on assumption that the oil price will be above 100$, another paid him a premium. In a week, depending on where the oil price stands, participants receive money in the agreed proportion, plus the first participant gets the remaining of their deposit. It is a decentralized and trustless analogue of a traditional option contract.


# FAQs

#### What is the Opium Protocol?

Opium is a protocol on Ethereum that facilitates trustless contracts between parties through smart escrow. With the help of Opium, users can schedule transactions, make wagers, create different primitives similar to the ones existing on traditional markets and more. Because of its simplicity and composability protocol can be applied to solve a wide range of problems: from peer-to-peer bets up to financial derivatives.

#### Why does Opium matter?

Smart escrow can solve many problems of the financial world. It enables creating any complex financial contracts similar to CeFi derivatives, risk tranching, using different collaterals. All operations are fast and easy to execute at a fraction of previously associated costs, don’t require a centralized intermediary and can be set with great flexibility, which makes it possible for anyone to create new, previously unfeasible markets.

#### What makes Opium different?

Thanks to the simplicity of its logic, the Opium protocol is highly flexible and versatile. It may support (thanks to optimistic oracles and term structure) any underlying — there are Opium-powered projects that use olive oil and fine art as the underlying — and any type of decentralized financial instruments for hedging or speculation. One doesn’t need any technical knowledge to create a smart escrow, the Opium Protocol enables users to make various products and recipes just by adding and removing parameters. Moreover, its simplicity helps Opium be composable with other DeFi protocols.&#x20;

Opium can be seen as a proxy for real-world problems, as traditional derivatives are somewhat hard to understand and use, while high fees and long transaction times make the creation of financial markets for some collateral unfeasible. It is essential to understand that even if creating a decentralized derivative contract or a new market is easy from the technical point of view, it requires knowledge of financial tools and an understanding of DeFi. Opium is a solution for DeFi experts and professional developers, please make sure you understand how it works and never transact with assets you can’t afford to lose.

#### What does it do?

The Opium protocol is a smart escrow that enables two parties to make a trustless contract and holds an asset on their behalf until contract terms are fully or partially fulfilled.

To enter into a contract, two parties create a safe by setting the desired parameters in a standardized escrow. A safe accepts an asset according to a rule, locks it for the specified period of time and after this period is over releases it according to another rule that depends on an oracle. Oracle communicates to the escrow whether the desired event occurred or not and thus triggers the execution of the transaction.

A very simple example of how an escrow works would be hiring a freelancer to perform some task. Parties agree on parameters, such as scope, deadline and remuneration, and create a safe. A hiring party deposits money. After the deadline, an oracle checks how much work is done. Depending on how much work is completed, the safe will give the freelancer either a percentage or the full sum.

#### Is the protocol fully developed?

The first version of the protocol is live on Ethereum mainnet and was audited by two companies, SmartDec and MixBytes. Despite all major components being operable, the protocol as a whole is under active development and testing by the community. Thanks to community members’s contribution, Opium constantly improves and adjusts to the new standards. The code is open-source; anyone can contribute to the development of the Opium Protocol on GitHub.

#### How safe is it to use?

It is important to understand that all blockchain-based protocols and technology itself are new and there is no guarantee of its safety. Most of the protocols and applications are run by people with a deep knowledge of the technology and willingness to “test in prod” their ideas and potentially be exposed to the greater risk.

#### Who is behind it?

Opium was developed by a founding team and contributiors with expertise in technology, trading and finance. After the successful launch of the protocol, the team stepped back from governance. Currently, the protocol is governed by $OPIUM token holders and supported by members of the community, ecosystem partners and a decentralized team of contributors.

#### What is liquidity mining? Can anyone participate?

Liquidity mining or yield farming is a process of providing liquidity via cryptocurrencies or tokens to DeFi protocols. In contrast with technical mining, liquidity mining on AMM doesn’t automatically imply a reward. Adding liquidity to a pool may seem an easy job, however, it requires deep knowledge and understanding of different risks associated with it like impermanent loss, risk of liquidity providers and others. So it is sophisticated users with knowledge in the field who maintain the ecosystem. They compete with each other and receive tokens for their expert contribution. Disclaimer: please be sure you understand how LM works, do expect possible losses and never supply funds that you are not ready to lose. Remember that LM is not for regular users and you will compete with professional parties (like with technical mining of Bitcoin, Ethereum...)

#### What can I do with protocol?

As a user/contributor, you can participate in the projects built on top of the protocol, buying some products or adding liquidity to a pool. Please note that some projects are subject to restricted access. As a developer, you can build your own projects on top of the protocol; for example, one team created a market for decentralized analogues of futures contracts on Olive oil. Alternatively, you may find a vulnerability and participate in the Opium bug bounty program. As a specialist in some field, you can contribute to project development. For example, this documentation is open-source, so if you see a way to improve it, you can make a submission. As a financial engineer, you can build a bot to arbitrage between products and protocols.

Please refer to the Interact with Opium section for more details.

#### Are there any restrictions and why?

The protocol itself runs on blockchain, thus it is decentralized and owned by the community, which means it is impossible to stop it or restrict its usage in any jurisdiction.

However, the projects built on top of the protocol can have their own terms of service including but not limited to restrictions based on geographical location or jurisdiction, expertise level of users and the amount of risk involved in the product. To learn more about project-specific restrictions, refer to the websites of a corresponding project.

#### What else do I need to know before doing anything with Opium?

Read the disclaimer, do your own research, understand the risks associated with the technology you are about to use and form your own opinion about it. Check the local regulations to make sure you can use the platform.


# Restrictions

1. The Opium protocol, its products and websites are for sophisticated users only. It should be clear that despite the underlying technology of the Opium protocol being simple to use, the creation of financial contracts requires knowledge and experience. Thus, Opium is not meant to be broadly adopted by end-users; it serves primarily the community of developers and DeFi professionals, who are able to evaluate associated risks, including, but not limited to, the technical failure and permanent capital loss.&#x20;
2. To be compliant with the local regulations, the Opium protocol and Opium products can’t be accessed by citizens and residents of the USA, Japan and some other jurisdictions. Although it is impossible to prevent users from the above-mentioned territories from accessing blockchain and development modules, the website and other parts of the Opium ecosystem are blocked for certain geographies. Please note that by trying to access Opium via VPN or lying about your citizenship you are breaking the law. It’s essential to understand that the parallel with traditional financial tools such as derivatives is drawn solely for a simplified explanation of Opium’s possibilities. Despite seeming similarity, DeFi tools are quite different, with their unique costs and benefits, risks and protection mechanisms. For example “call option” on a decentralized protocol may describe a financial primitive that behaves like a “call option spread” most of the time, but has some crucial differences in terms of counterparty risk (managed by blockchain), settlement asset, technological risks and underlying asset.&#x20;
3. The Opium protocol provides software that enables and enforces transactions between two or more parties without a traditional centralized intermediary but via a smart contract. If the software fails to execute an operation due to malfunction, exploit or underperformance, parties may lose their funds without the ability to bring the case to the court of law for arbitration. A smart contract isn’t a person, neither it is controlled by any person or persons and thus it cannot be forced in court or otherwise to pause, reverse or change a transaction. There is no legal enforcement associated with the contract. Please make sure you fully understand how this software operates, the incentive mechanism that it employs, implications of technical failure and other protocol-specific risks before using any of the Opium products.&#x20;
4. When in doubt, please refer to the Terms and Conditions that can be found at The Opium Finance website and other parts of the Opium ecosystem. To learn more about the software, please review the technical documentation and code.&#x20;
5. Never transact with funds you can’t afford to lose.


# Disclaimer

The Opium protocol is a smart escrow or a set of smart contracts available on demand as software to facilitate trustless contracts. It doesn't offer a service or advice of any kind, neither can it be considered a finished product. Despite all major components being operable, the protocol as a whole is under active development and testing by the community. It is within the scope of the bug bounty program; the code is open-source and available on GitHub; contributions are accepted as a part of governance mining.&#x20;

There are several inherent risks associated with the protocol, the most typical being:&#x20;

* Delays in or complete failure of transactions being confirmed&#x20;
* Faults, defects, hacks, exploits, errors, or unforeseen circumstances occurring in respect of the platform or the technologies that the platform depends on&#x20;
* Loss of private keys&#x20;
* Attacks on the platform or the technologies that the platform depends on including for example distributed denial of service, Sybil attacks, phishing, social engineering, hacking, smurfing, malware, double spending, majority-mining, consensus-based or other mining attacks, misinformation campaigns, forks, and spoofing.&#x20;

The first version of the protocol is live on Ethereum mainnet and was audited by two companies, SmartDec and MixBytes. The audit does not give any warranties on the security of the code, utility of the code, sustainability of the business model, regulatory regime for the business model, or any other statement about fitness of the contracts to purpose, or their bug free status. The audit findings are for discussion and educational purposes only. You should always conduct your own research and risk analysis.


# Audits

## **Disclaimer**&#x20;

**The audit does not give any warranties on the security of the code, utility of the code, sustainability of the business model, regulatory regime for the business model, or any other statement about fitness of the contracts to purpose, or their bug free status. The audit documentations are for discussion purposes only. You should always conduct your own research and risk analysis.**&#x20;

## **Audits**

### **Audit of Opium Protocol V2 done by Pessimistic**

[Read the full report here](https://github.com/OpiumProtocol/opium-protocol-v2/blob/main/audits/Opium%20v2%20Security%20Analysis%20by%20Pessimistic.pdf)

### **Audit of Opium Protocol V2 done by Igor Gulamov**

[Read the full report here](https://github.com/OpiumProtocol/opium-protocol-v2/blob/main/audits/Opium%20protocol%20audit.pdf)

### **Audit of Opium Protocol V1 done by SmartDec**

“The contracts were completely manually analyzed, their logic was checked and compared with the one described in the documentation. Besides, the results of the automated analysis were manually verified. The audit showed no critical issues.” - SmartDec.&#x20;

[Read the full report here](https://github.com/OpiumProtocol/opium-contracts/blob/master/docs/audit/OpiumSmartDecSmartContractAudit.pdf)&#x20;

### **Audit of Opium Protocol V1 done by MixBytes**

Conclusion: “Smart contracts have been audited and several suspicious places have been spotted. During the audit 1 critical issue was found, one issue was marked as major because it could lead to some undesired behavior, also several warnings and comments were found and discussed with the client. After working on the reported findings all of them were resolved or acknowledged (if the problem was not critical). So, the contracts are assumed as secure to use according to our security criteria.” - MixBytes&#x20;

[Read the full report here](https://github.com/OpiumProtocol/opium-contracts/blob/master/docs/audit/OpiumNetworkProtocolAuditMixBytes.pdf)

### **Audit of staking smart contracts of Opium Network done by Pessimistic**&#x20;

“In this report, we considered the security of staking smart contracts of Opium Network project. We performed our audit according to the procedure described below. The code is of high quality. The initial audit showed only a few issues of low severity. They do not endanger project security in any way.

After the audit, the code base was updated to the latest version. In this version, the developers added the documentation, also code quality issues were fixed.” - Pessimistic

[Read the full report here](https://static.opium.finance/docs/audits/OpiumStakingAuditPessimistic.pdf)

### **Audit of staking smart contracts of Opium Network done by MixBytes**

“The audited scope includes a staking mechanism based on Opium protocol. Staking contract allows users to organize and participate in pools of some specific positions on Opium core protocol. The project includes two main modules: a staking module that implements general staking functionality and a position tokenization module that wraps Opium positions into ERC-20 token.” - MixBytes

[Read the full report here](https://static.opium.finance/docs/audits/OpiumStakingAuditMixBytes.pdf)


# Bounty program

The Opium bug bounty program supports a community-led effort to improve the on-chain security of the OPIUM Protocol. Contributors who make valuable security discoveries – such as detecting a previously unknown smart contract bug – will be rewarded a bounty according to the rules outlined below.

### Rules&#x20;

The rules are adopted from the Ethereum Foundation’s bug bounty program rules and applicable for the Opium Protocol bug bounty program:&#x20;

* Issues that have already been submitted by another user or are already known to the Opium team are not eligible for bounty rewards
* Public disclosure of a vulnerability makes the reported bug ineligible for a bounty&#x20;
* The Opium core development team, core units, contributors, and all other people paid by Opium Ecosystem, directly or indirectly (including the external auditors), are not eligible for rewards&#x20;
* Submissions should be within the Bounty scope, outlined below.

### Scope&#x20;

Attack vectors that affect the off-chain components of an architecture are outside of the scope of the bounty programme but their submission is still welcome. Examples of such threats are:&#x20;

* Vulnerabilities in the supported third-party wallets&#x20;
* XSS attacks&#x20;
* DDoS

Furthermore, smart contract bugs that do not lead to a loss of funds might be classified as not bearing any threats and thus not be eligible for the bounty.

The scope of the present bounty is focused solely on smart contracts developed by the Opium core contributors for the Opium Protocol. The list of codebases eligible for the bounty program includes but is not limited to:&#x20;

<https://github.com/OpiumProtocol/opium-protocol-v2>

[https://github.com/OpiumProtocol/opium-contracts ](<https://github.com/OpiumProtocol/opium-contracts >)

<https://github.com/OpiumProtocol/erc721o>

If a vulnerability satisfies the previously highlighted criteria but is not included in the list of repositories above, its eligibility will be at the discretion of the OPIUM DAO.

### Compensation&#x20;

* High threat - up to 100,000 DAI&#x20;
* Medium threat - up to 20,000 DAI&#x20;
* Low threat - up to 2,000 DAI

The reward will be delivered only after ascertaining the severity of the reported issue and the successful implementation of a patch to the reported exploit.

### **Submission process**

Send your bug findings to the [Discord](https://discord.com/invite/9cYkPEm) or contact core contributors in [Telegram](https://t.me/opium_network)&#x20;

The vulnerability must not be disclosed publicly or to any other person, entity or email address before Opium Team has been notified, has fixed the issue, and has granted permission for public disclosure. In addition, disclosure must be made within 24 hours following discovery of the vulnerability.

A detailed report of a vulnerability increases the likelihood of a reward and may increase the reward amount. Please provide as much information about the vulnerability as possible, including:

* The conditions on which reproducing the bug is contingent
* The steps needed to reproduce the bug or, preferably, a proof of concept
* The potential implications of the vulnerability being abused

Anyone who reports a unique, previously-unreported vulnerability that results in a change to the code or a configuration change and who keeps such vulnerability confidential until it has been resolved by our engineers will be recognized publicly for their contribution if they choose so.


# Decentralized setup

The goal of the Opium team is to achieve full decentralization through the appropriate ecosystem. The framework was designed which combines financial incentives with decentralized governance mechanisms to achieve transparency, security and sustainability of protocol’s growth and development over time.

The Opium protocol is collectively governed by Opium token holders, who have the power to propose actions, vote on them and allocate funds to support selected initiatives. If the Opium Protocol codebase upgrade leads to the creation of additional parameters, they will also be controlled by the Opium DAO.

Governance setup of the Opium Protocol consists of:&#x20;

* Gnosis Safe (acts like a DAO) Snapshot (enables off-chain voting)&#x20;
* SafeSnap (a part that implements the code)&#x20;
* Supplemented with last resort Aragon DAO as a part of the on-chain voting


# Governance flow

A typical proposal lifecycle from inception to execution looks as follows:

* **Discussion:** a participant comes up with a proposal, discusses it with other Opium community members, collects feedback, analyzes all pros and cons
* **Compromise:** the discussion is finalized when a compromise is reached
* **Voting:** the same or other participant makes a proposal on a signalling vote to decide if the proposal will be implemented or not. Community members have at least 48 hours to vote  on the proposal
* **Execution:** If the proposal passes, blockchain executes the proposal automatically. Otherwise, or invalid transaction appears

![](/files/Jtap7ItfggP5AdP1wj6j)


# Proposal creating

### Discussion

First, create a discussion on the [Opium Governance Forum](https://forum.opium.network/) in one of the following sections:

* Governance
* Learn about&#x20;
* Opium Build on Opium&#x20;
* Bounties and contests&#x20;
* Other&#x20;

Try to stay objective and list all pros and cons of your proposal, so every community member can make up their mind about the initiative. However, you can explain and advocate for  your point of view freely in the comments.&#x20;

The author of the discussion is responsible for the flow of the discussion: keep it up-to-date, so every person new to  the discussion won’t need to scroll through all the comments and can easily see the updates in the main post.

The discussion is finalized when a compromise is reached.&#x20;

### Making the proposal

Making the proposal is the final step before actual voting. The proposal with the clear points that can be voted on with a simple Yes (Agree) or No (Disagree). If the proposal implies some actions add a batch of transactions while creating a voting proposal.

### Voting

The voting period must be set to at least 48 hours, so community members will have the opportunity  to evaluate the initiative make up their minds and vote on it. However, for urgent matters this requirement can be dropped.

[Read more about the voting principles](https://cloudflare-ipfs.com/ipfs/QmXRK6Egnnd2dMGZV3WCL1H7z3YVJjGgt8pQBmdeurzt38)

Opium  token holders receive voting power proportionally to the number of their governance tokens on balance.&#x20;

[All the votings happen here](https://signal.opium.network/#/)

### **Execution**

After the off-chain voting is over, the result is sent to Reality.eth to record on-chain whether it passed or failed. If a proposal passes, the initiative is auto-executed, if it fails, blockchain marks it as an invalid transaction. For a visual representation of the process see the picture below.

If you suspect a malicious action, freeze a proposal and send it for arbitration. Opium Aragon DAO is set as an arbitrator, which allows $OPIUM token holders to decide the outcomes of the proposals using on-chain voting in case of disputes or attacks.


# Process of voting – technical description

![](/files/UAeIKl1nGOrHauHRBO8n)

As the voting on the proposals is happening off-chain, and to be able to verify the results on-chain, an oracle is needed. Reality.eth, an optimistic Layer 2 solution for voting, plays this role. The system verifies whether off-chain proposals and votes were made according to the DAO requirements by the Proof-of-Stake mechanism.

### Reality.eth

The proposal is sent to Reality.eth for 24 hours\* (\*the time frame can be changed by governance) for the bond staking. Bond is the minimum amount of ETH to be staked in Reality.eth to successfully validate the off-chain proposal and proceed with its on-chain execution.

For example, a person staked 0.2 ETH and confirmed that the proposal “passed”, then another  person staked 0.4 ETH and confirmed that the proposal “failed” and so on until the person who staked the biggest amount “wins'.' The last and their answer is sent as a try outcome.&#x20;

![](/files/ThJBN1nmHHZERdWkzhbF)

If there are suspicions of  foul play, anyone can stop the bond staking and ask the Arbitrator –(Opium Aragon DAO ) to have an on-chain voting about the proposal validation.

### Gnosis Safe

If the proposal passes the outcome is sent to the DAO Module of Gnosis Safe to execute the transactions outlined within the proposal. If the proposal fails, it is marked as an invalid transaction.

There is a standard additional security measure called Arbitrator, which allows anyone to put potentially malicious proposals on hold and to pass the right to provide the final decision to a particular 3rd party in case of disputes between stakers.

### Arbitrator

If there is a suspicious attempt  to overrule the actual results or send an invalid transaction and execute the malicious action. Opium Aragon DAO acts as Arbitrator and initiates an on-chain voting for Opium holders to decide whether the outcomes of the proposal are valid or not.&#x20;

![](/files/1T2WeC2HlmOatRvzUW99)

### Guardians

There is an additional feature called Guardians that can be added if the community votes in favor of it.&#x20;

It is a “switch to on-chain voting” for every proposal that is being brought from optimistic on-chain layer to implementation. It can perform just one action, to request arbitration (freeze proposals) without the need to pay any arbitration fees. The Guardians are assignable by the owner of the Arbitration contract (Opium Aragon DAO). The rationale of Guardian is to allow a trusted entity (multisig of appointed guardians) to quickly react to the malicious or spam proposals without the need to waste money on arbitration fees. Since the Guardian’s actions are restricted and the Guardian could be easily changed by the Opium Aragon DAO, it does not introduce any single point of failure and serves solely for DAO security purposes.


# $Opium governance token

**$OPIUM tokens are neither financial instruments nor securities. They merely serve as a tool that will help community to build the foundation for a derivatives trading ecosystem which will be permissionless and decentralized. The information in this update is for information purposes only (and does not constitute financial or other advice or an inducement to purchase or sell any service or security (however defined under applicable law).**

### Overview

The Opium token or $Opium is an ERC20 virtual asset that plays a key role in protocol’s autonomy and decentralisation. The token holders can propose, delegate and vote on project-related initiatives and thus collectively govern the protocol.

As in other DeFi projects, placing tokens into the hands of users incentivizes the community to keep the protocol up to date and constantly improve it.

$Opium g\ives rights to:&#x20;

* Change DAO parameters within its permissions&#x20;
* Execute actions on its behalf&#x20;
* Allocate the Active Users Fund (ex. for Liquidity Mining Programs, Bounty Programs and other)&#x20;
* Make changes to the Opium Protocol codebase.&#x20;

Contributors can stake their tokens into different subunits of the DAO to represent a specific role/function in the community or take specific risk. There are few different options at the moment with different risk/return/duties profile, please make sure your skills are in a good fit and feel free to propose new staking modules with new duties towards protocol maintenance and development.

Currently, users of the Opium protocol can receive $Opium tokens through liquidity and governance mining.

### Mining

Mining is a process of rewarding a user with governance power, governance tokens or tokens of another type, in exchange for their contribution to a protocol.

First of its kind, technical mining started with Bitcoin: miners confirmed transactions by solving cryptographic equations and automatically gained remuneration in the first cryptocurrency. Other cryptocurrencies and blockchains, including Ethereum, rely on the same Proof-of-Work process, and so do DeFi protocols that operate on Ethereum.

However, as any financial system, centralized or not, the new protocols needed liquidity to operate and that’s how liquidity mining came into being. Liquidity mining or yield farming is a process of providing liquidity via cryptocurrencies or tokens to DeFi protocols. In contrast with technical mining, liquidity mining on AMM doesn’t automatically imply reward as it comes with some risks.

Typically, liquidity providers add a specific ratio of assets into a liquidity pool to offset a potential risk. If the adverse event takes place, part of the staked assets will be used to cover losses and thus liquidity providers will partially lose their funds. As the market for virtual assets is extremely volatile, there is a possibility of impermanent loss—the situation when keeping virtual assets in the wallet would be more profitable for the owner. In other words, liquidity mining is not a fast and easy way to earn tokens, it requires financial acumen and deep knowledge of the DeFi ecosystem.

As liquidity mining has been criticized for favouring passive participation over active contribution, governance mining emerged as a solution. Governance mining rewards community members for skilled contributions through a number of mechanisms. In this scenario, contributors can provide not only their computing power or liquify, but solve any problem in line with their skills, from finding the right candidate to launching a marketing campaign, and be rewarded for their efforts. The reward will depend on the scope, frequency and outcome of the contribution.

### Initial distribution&#x20;

![](/files/zf8PI2J4nwuuoJ3KCJhs)

The minted supply of $OPIUM is 100,000,000. The initial distribution of this supply is projected as follows:

**60%: Active users**&#x20;

This fund is used to allocate governance to active users of the protocol for the benefit of the Opium ecosystem, as described in the previous chapter. The definition of active users will be decided regularly by governance. More tokens can be allocated for specific actions such as providing liquidity on a specified instrument or term, building actively-used instruments, or other essential activities. The tokens in this fund will be unlocked gradually and distributed retroactively to active community members, based on the specified criteria of active usage.

**16%: Early backers and advisors**&#x20;

This fund will be used to compensate early backers and advisors for their contribution to the success of Opium thus far. The tokens are going to be vested continuously for the next two years.

**14%: Opium Founding Team**&#x20;

This fund will be used to cover the expenses of the founding team behind the Opium Protocol, and to support key hires and the future growth of the team. A part of these tokens will be granted to past, current and future contributors of the Opium Team and will be vested continuously for the next four years. Opium Team is a fast-growing distributed community of builders consisting of developers, mathematicians, traders, and consultants who strive to further grow and develop the Opium Ecosystem.

**10%: Governance Reserve Fund**&#x20;

This fund will be used for external initiatives and partnerships which will help the Opium ecosystem to further grow and flourish. $OPIUM token holders have full control over the usage of this fund through governance proposals and voting.


# Opium.Finance

Opium.finance is a decentralized finance platform where people create markets.Be your own banker and hedge fund manager with a wide range of сutting-edge financial tools

![](/files/-MfXE4PpkmDHMg_JRtps)

![](/files/-MfXE7SPOgAwJIdXmnjX)

**Visit** [**opium.finance**](https://opium.finance) **to find out more about the available products.**&#x20;

*Opium.Finance is not available in the United States or other prohibited jurisdictions.*


# opium.exchange

a non-custodial platform for decentralized derivatives

![opium.exchange](/files/-M655skGy3UKfF1wRM0C)

* Opium Exchange is a non-custodial platform for decentralized derivatives
* Trade, hedge, or invest without intermediaries
* Audited by SmartDec
* High-speed orders on meta-transactions are combined with on-chain settlement
* Marginal trades: from regular margin to turbo trades

You can check it out on [**opium.exchange**](https://opium.exchange)&#x20;

*Opium.Exchange is not available in the United States or other prohibited jurisdictions.*


# Deployment Addresses

Ecosystem Gnosis Safe (DAO)

<table><thead><tr><th width="211">Chain</th><th>Address</th></tr></thead><tbody><tr><td>Ethereum</td><td><a href="https://etherscan.io/address/0xDbC2F7f3bCcccf54F1bdA43C57E8aB526e379DF1">0xDbC2F7f3bCcccf54F1bdA43C57E8aB526e379DF1</a></td></tr><tr><td>Arbitrum</td><td><a href="https://arbiscan.io/address/0xc9162e9e8A6C47E7346a3fe6Dda9fab54Dfbe49B">0xc9162e9e8A6C47E7346a3fe6Dda9fab54Dfbe49B</a></td></tr><tr><td>Polygon</td><td><a href="https://polygonscan.com/address/0x964C04B87D14dF4aa74169874C4B15A87EED360d">0x964C04B87D14dF4aa74169874C4B15A87EED360d</a></td></tr></tbody></table>

Select the version of the protocol

{% content-ref url="/pages/At46puxE9OyPMpjvtpdF" %}
[Opium Protocol v2](/for-developers/deployment-addresses/opium-protocol-v2)
{% endcontent-ref %}

{% content-ref url="/pages/Kxcf76RHMpHKdoChI5Mk" %}
[Opium Protocol v1](/for-developers/deployment-addresses/opium-protocol-v1)
{% endcontent-ref %}


# Opium Protocol v2

The latest versions of Opium Protocol v2 are deployed at the addresses listed below. Each chain has different deployment addresses.

## Mainnet

### Ethereum

| Contract            | Proxy                                                                                                                 | Implementation                                                                                                        |
| ------------------- | --------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- |
| Registry            | [0xbd0e3097F47cEcA12407bAc42cDD574cf3072F23](https://etherscan.io/address/0xbd0e3097F47cEcA12407bAc42cDD574cf3072F23) | [0x85d9c3784B277Bc10e1504Aa8f647132ba17A674](https://etherscan.io/address/0x85d9c3784B277Bc10e1504Aa8f647132ba17A674) |
| Core                | [0x33afAaA35df82D56833B7EEacb2b65Eb805AC774](https://etherscan.io/address/0x33afAaA35df82D56833B7EEacb2b65Eb805AC774) | [0xE6AFB8b01CAF0214706116c7Dc3B978E6eb8ce7e](https://etherscan.io/address/0xE6AFB8b01CAF0214706116c7Dc3B978E6eb8ce7e) |
| TokenSpender        | [0x2f79B00B04907C038f006f3d318380ECDFe81050](https://etherscan.io/address/0x2f79B00B04907C038f006f3d318380ECDFe81050) | [0x33A18faF0E7f6c7ed971BF5eC289d516C370e76D](https://etherscan.io/address/0x33A18faF0E7f6c7ed971BF5eC289d516C370e76D) |
| OpiumProxyFactory   | [0x6E797659154AD0D6f199feaFA2E2086Ce0239Fbf](https://etherscan.io/address/0x6E797659154AD0D6f199feaFA2E2086Ce0239Fbf) | [0x61EFdF8c52b49A347E69dEe7A62e0921A3545cF7](https://etherscan.io/address/0x61EFdF8c52b49A347E69dEe7A62e0921A3545cF7) |
| OpiumPositionToken  | -                                                                                                                     | [0xfad909b14e52b42d3b4214b6e12b0bc582b3cfcb](https://etherscan.io/address/0xfad909b14e52b42d3b4214b6e12b0bc582b3cfcb) |
| OracleAggregator    | [0xC135bE47acCEf605E72C5017e450aE0207C97Afb](https://etherscan.io/address/0xC135bE47acCEf605E72C5017e450aE0207C97Afb) | [0xAF5F031b8D5F12AD80d5E5f13C99249d82AfFfe2](https://etherscan.io/address/0xAF5F031b8D5F12AD80d5E5f13C99249d82AfFfe2) |
| SyntheticAggregator | [0x06eb4bCc14b8C1664a2d4e2CdE8fA2F992332fCd](https://etherscan.io/address/0x06eb4bCc14b8C1664a2d4e2CdE8fA2F992332fCd) | [0x2f92AE7f568c1Fe3379eE47Daa7819E1362bf25d](https://etherscan.io/address/0x2f92AE7f568c1Fe3379eE47Daa7819E1362bf25d) |
| ProxyAdmin          | -                                                                                                                     | [0x17b6ffe276e8a4a299a5a87a656afc5b8fa3ee4a](https://etherscan.io/address/0x17b6ffe276e8a4a299a5a87a656afc5b8fa3ee4a) |

Helpers

| Contract             | Address                                                                                                               |
| -------------------- | --------------------------------------------------------------------------------------------------------------------- |
| BalanceHelper        | [0x8338448b3E4D4e9a34382747f4Ed66D9bFB345e3](https://etherscan.io/address/0x8338448b3E4D4e9a34382747f4Ed66D9bFB345e3) |
| PayoutHelper         | [0xc0c6cb9e715a805da7d7bab58e655fe79b535600](https://etherscan.io/address/0xc0c6cb9e715a805da7d7bab58e655fe79b535600) |
| OnChainPositionsLens | [0xfa01Fd6118445F811753D96178F2ef8AE77caa53](https://etherscan.io/address/0xfa01Fd6118445F811753D96178F2ef8AE77caa53) |

### Arbitrum One

| Contract            | Proxy                                                                                                                | Implementation                                                                                                       |
| ------------------- | -------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- |
| Registry            | [0x17b6ffe276e8A4a299a5a87a656aFc5b8FA3ee4a](https://arbiscan.io/address/0x17b6ffe276e8A4a299a5a87a656aFc5b8FA3ee4a) | [0x845a7872d1cDe2B3285dE9f66B1D2EC70307cC6b](https://arbiscan.io/address/0x845a7872d1cDe2B3285dE9f66B1D2EC70307cC6b) |
| Core                | [0x1497A23a2abC0DAFFb8e333183cfC181b24bB570](https://arbiscan.io/address/0x1497A23a2abC0DAFFb8e333183cfC181b24bB570) | [0x5854694204828385ED3d5B9d0FF912794D78cdaE](https://arbiscan.io/address/0x5854694204828385ED3d5B9d0FF912794D78cdaE) |
| TokenSpender        | [0x0A9A6CD7485Dd77c6cec28FB1bd64D5969B79132](https://arbiscan.io/address/0x0A9A6CD7485Dd77c6cec28FB1bd64D5969B79132) | [0x7C78bfaDb7F0EA6E84CC5196B6fAC48fb1cFA34E](https://arbiscan.io/address/0x7C78bfaDb7F0EA6E84CC5196B6fAC48fb1cFA34E) |
| OpiumProxyFactory   | [0x328bC74ccA6578349B262D21563d5581DAA43a16](https://arbiscan.io/address/0x328bC74ccA6578349B262D21563d5581DAA43a16) | [0x5a608F8dfD67504Eb1F07D0b32ACD8753160fCA3](https://arbiscan.io/address/0x5a608F8dfD67504Eb1F07D0b32ACD8753160fCA3) |
| OpiumPositionToken  | -                                                                                                                    | [0x6384f8070fda183e2b8ce0d521c0a9e7606e30ea](https://arbiscan.io/address/0x6384f8070fda183e2b8ce0d521c0a9e7606e30ea) |
| OracleAggregator    | [0x85d9c3784B277Bc10e1504Aa8f647132ba17A674](https://arbiscan.io/address/0x85d9c3784B277Bc10e1504Aa8f647132ba17A674) | [0xC3e733eaCCD9c3bc54450aCe8074F589760Ae079](https://arbiscan.io/address/0xC3e733eaCCD9c3bc54450aCe8074F589760Ae079) |
| SyntheticAggregator | [0xE6AFB8b01CAF0214706116c7Dc3B978E6eb8ce7e](https://arbiscan.io/address/0xE6AFB8b01CAF0214706116c7Dc3B978E6eb8ce7e) | [0xbd0e3097F47cEcA12407bAc42cDD574cf3072F23](https://arbiscan.io/address/0xbd0e3097F47cEcA12407bAc42cDD574cf3072F23) |
| ProxyAdmin          | -                                                                                                                    | [0x2ba5fee02489c4c7d550b82044742084a652f01a](https://arbiscan.io/address/0x2ba5fee02489c4c7d550b82044742084a652f01a) |

Helpers

| Contract             | Address                                                                                                              |
| -------------------- | -------------------------------------------------------------------------------------------------------------------- |
| BalanceHelper        | [0x2f92AE7f568c1Fe3379eE47Daa7819E1362bf25d](https://arbiscan.io/address/0x2f92AE7f568c1Fe3379eE47Daa7819E1362bf25d) |
| PayoutHelper         | [0x06eb4bCc14b8C1664a2d4e2CdE8fA2F992332fCd](https://arbiscan.io/address/0x06eb4bCc14b8C1664a2d4e2CdE8fA2F992332fCd) |
| OnChainPositionsLens | [0xfa01Fd6118445F811753D96178F2ef8AE77caa53](https://arbiscan.io/address/0xfa01Fd6118445F811753D96178F2ef8AE77caa53) |

## Testnet

### Arbitrum (testnet)

| Contract            | Proxy                                                                                                                        | Implementation                                                                                                               |
| ------------------- | ---------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| Registry            | [0x9285CAA6F92D9Ba197966E854174e9B27B2061e5](https://testnet.arbiscan.io/address/0x9285CAA6F92D9Ba197966E854174e9B27B2061e5) | [0x48ccef1ecc69e0b5e5fd3340c15f9a2e18563022](https://testnet.arbiscan.io/address/0x48ccef1ecc69e0b5e5fd3340c15f9a2e18563022) |
| Core                | [0x416d29de99e346c59100680a14d44De08891dE30](https://testnet.arbiscan.io/address/0x416d29de99e346c59100680a14d44De08891dE30) | [0x384a5683155f035200cb16fbed0aedb2a6ffaf37](https://testnet.arbiscan.io/address/0x384a5683155f035200cb16fbed0aedb2a6ffaf37) |
| TokenSpender        | [0xdFDe0C087DF52627673043a86E657B927ee10c4b](https://testnet.arbiscan.io/address/0xdFDe0C087DF52627673043a86E657B927ee10c4b) | [0xaC7C9f40F404Df8f5c0436087b7E9e7b0735f90b](https://testnet.arbiscan.io/address/0xaC7C9f40F404Df8f5c0436087b7E9e7b0735f90b) |
| OpiumProxyFactory   | [0x3ea7753bE2d0ab682cd0f0B8803f3331BC5230fc](https://testnet.arbiscan.io/address/0x3ea7753bE2d0ab682cd0f0B8803f3331BC5230fc) | [0x5C97c97ea1015E4f2aE4274c022A06957Eddbb46](https://testnet.arbiscan.io/address/0x5C97c97ea1015E4f2aE4274c022A06957Eddbb46) |
| OpiumPositionToken  | -                                                                                                                            | [0x7b006dfca781aee11b4a4e9f42c3239ecd4dcf39](https://testnet.arbiscan.io/address/0x7b006dfca781aee11b4a4e9f42c3239ecd4dcf39) |
| OracleAggregator    | [0xd030051cd8Cc0760fb0Fa857bbFDb8f9C3dAcaDE](https://testnet.arbiscan.io/address/0xd030051cd8Cc0760fb0Fa857bbFDb8f9C3dAcaDE) | [0x5f1670bdbafcbea39579083dfd56984bb4a34d25](https://testnet.arbiscan.io/address/0x5f1670bdbafcbea39579083dfd56984bb4a34d25) |
| SyntheticAggregator | [0x3c1150e52d028DCD67a0bA986D332D54A8baC29A](https://testnet.arbiscan.io/address/0x3c1150e52d028DCD67a0bA986D332D54A8baC29A) | [0x01A44DbFE8a2b9568BEA0C0Db938E0dF93682910](https://testnet.arbiscan.io/address/0x01A44DbFE8a2b9568BEA0C0Db938E0dF93682910) |
| ProxyAdmin          | -                                                                                                                            | [0xFcEAF12d8A38E1135124E4251A462bA92F22b172](https://testnet.arbiscan.io/address/0xFcEAF12d8A38E1135124E4251A462bA92F22b172) |

Helpers

| Contract             | Address                                                                                                                      |
| -------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| BalanceHelper        | [0x60682B5B1C0AA76c0104AE77CCBFfbE95cE9Bc8a](https://testnet.arbiscan.io/address/0x60682B5B1C0AA76c0104AE77CCBFfbE95cE9Bc8a) |
| PayoutHelper         | [0x42A02e1CC96974834Bd1eB2C02D34f68853Bb305](https://testnet.arbiscan.io/address/0x42A02e1CC96974834Bd1eB2C02D34f68853Bb305) |
| OnChainPositionsLens | [0x4b214B8AaFBdeB170b550Bb2dfed41AadD9aCf74](https://testnet.arbiscan.io/address/0x4b214B8AaFBdeB170b550Bb2dfed41AadD9aCf74) |

### **Polygon (Mumbai)**

| Contract            | Proxy                                                                                                                           | Implementation                                                                                                                  |
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
| Registry            | [0x9285CAA6F92D9Ba197966E854174e9B27B2061e5](https://mumbai.polygonscan.com/address/0x9285CAA6F92D9Ba197966E854174e9B27B2061e5) | [0x7C40069bdC198925007786414343681bceCFd91D](https://mumbai.polygonscan.com/address/0x7C40069bdC198925007786414343681bceCFd91D) |
| Core                | [0x416d29de99e346c59100680a14d44De08891dE30](https://mumbai.polygonscan.com/address/0x416d29de99e346c59100680a14d44De08891dE30) | [0x8d4129b538EEdaD7169ff53dd710E152eab9eB4B](https://mumbai.polygonscan.com/address/0x8d4129b538EEdaD7169ff53dd710E152eab9eB4B) |
| TokenSpender        | [0xdFDe0C087DF52627673043a86E657B927ee10c4b](https://mumbai.polygonscan.com/address/0xdFDe0C087DF52627673043a86E657B927ee10c4b) | [0xa370CF1BB01e368FFdDB81A6511E6Ef072131A77](https://mumbai.polygonscan.com/address/0xa370CF1BB01e368FFdDB81A6511E6Ef072131A77) |
| OpiumProxyFactory   | [0x3ea7753bE2d0ab682cd0f0B8803f3331BC5230fc](https://mumbai.polygonscan.com/address/0x3ea7753bE2d0ab682cd0f0B8803f3331BC5230fc) | [0x30654f4145A67345CF1B701eac259aA7a2e06FE7](https://mumbai.polygonscan.com/address/0x30654f4145A67345CF1B701eac259aA7a2e06FE7) |
| OpiumPositionToken  | -                                                                                                                               | [0x7b006dfca781aee11b4a4e9f42c3239ecd4dcf39](https://mumbai.polygonscan.com/address/0x7b006dfca781aee11b4a4e9f42c3239ecd4dcf39) |
| OracleAggregator    | [0xd030051cd8Cc0760fb0Fa857bbFDb8f9C3dAcaDE](https://mumbai.polygonscan.com/address/0xd030051cd8Cc0760fb0Fa857bbFDb8f9C3dAcaDE) | [0x5F1670bdbAfcbEA39579083Dfd56984bb4A34d25](https://mumbai.polygonscan.com/address/0x5F1670bdbAfcbEA39579083Dfd56984bb4A34d25) |
| SyntheticAggregator | [0x3c1150e52d028DCD67a0bA986D332D54A8baC29A](https://mumbai.polygonscan.com/address/0x3c1150e52d028DCD67a0bA986D332D54A8baC29A) | [0xF69821f7364FFc154E4a5003794EE2D9F40FD8Cc](https://mumbai.polygonscan.com/address/0xF69821f7364FFc154E4a5003794EE2D9F40FD8Cc) |
| ProxyAdmin          | -                                                                                                                               | [0xFcEAF12d8A38E1135124E4251A462bA92F22b172](https://mumbai.polygonscan.com/address/0xFcEAF12d8A38E1135124E4251A462bA92F22b172) |

**Helpers**

| Contract             | Address                                                                                                                         |
| -------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
| BalanceHelper        | [0xBd7C4B9aB1AC188E11CA046a996e378ecBB2a031](https://mumbai.polygonscan.com/address/0xBd7C4B9aB1AC188E11CA046a996e378ecBB2a031) |
| PayoutHelper         | [0x0D4168f4e87C391D2A92264841106140bc12FE02](https://mumbai.polygonscan.com/address/0x0D4168f4e87C391D2A92264841106140bc12FE02) |
| OnChainPositionsLens | [0x1e700c04c9F7c9d6c92F0B1a50dAf103b09E5821](https://mumbai.polygonscan.com/address/0x1e700c04c9F7c9d6c92F0B1a50dAf103b09E5821) |


# Opium Protocol v1

The latest versions of Opium Protocol v1 are deployed at the addresses listed below. Each chain has different deployment addresses.

## Mainnet

### Ethereum

| Contract            | Address                                                                                                               |
| ------------------- | --------------------------------------------------------------------------------------------------------------------- |
| LibPosition         | [0x56c54b408c44B12f6c9219C9c73Fcda4E783FC20](https://etherscan.io/address/0x56c54b408c44B12f6c9219C9c73Fcda4E783FC20) |
| Registry            | [0x7f5f4087006ba4f4985b32f9d1079ee2f8594af8](https://etherscan.io/address/0x7f5f4087006ba4f4985b32f9d1079ee2f8594af8) |
| Core                | [0xd60F0A53c7e97f78fe4AC9013F5749920C601494](https://etherscan.io/address/0xd60F0A53c7e97f78fe4AC9013F5749920C601494) |
| SwaprateMatch       | [0x09a439c50465e447cb1a662da536f23a7e39374e](https://etherscan.io/address/0x09a439c50465e447cb1a662da536f23a7e39374e) |
| TokenSpender        | [0x8bd75f96EfA089aEcf6Ac4CD0B671e2428f4B2af](https://etherscan.io/address/0x8bd75f96EfA089aEcf6Ac4CD0B671e2428f4B2af) |
| TokenMinter         | [0x35Aab5c69cEA76E643Fd3287aC9523bD670445b2](https://etherscan.io/address/0x35Aab5c69cEA76E643Fd3287aC9523bD670445b2) |
| OracleAggregator    | [0xB69890912E40A7849fCA058bb118Cfe7d70932c4](https://etherscan.io/address/0xB69890912E40A7849fCA058bb118Cfe7d70932c4) |
| SyntheticAggregator | [0x3a943C50Bcde3E357916ce6E109626213Fd36105](https://etherscan.io/address/0x3a943C50Bcde3E357916ce6E109626213Fd36105) |

### Polygon

| Contract            | Address                                                                                                                                  |
| ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| LibPosition         | [0xd85De2Eb815eF57c84531Bc2397407B18E62C9d7](https://explorer-mainnet.maticvigil.com/address/0xd85De2Eb815eF57c84531Bc2397407B18E62C9d7) |
| Registry            | [0x1213b2951B48a39981801e059223827ce4182354](https://explorer-mainnet.maticvigil.com/address/0x1213b2951B48a39981801e059223827ce4182354) |
| Core                | [0xB3F6281655276150E97e5029B607a6D4d2E21972](https://explorer-mainnet.maticvigil.com/address/0xB3F6281655276150E97e5029B607a6D4d2E21972) |
| TokenSpender        | [0xC7b068B897507312c2DACEd5E537eB658c49608D](https://explorer-mainnet.maticvigil.com/address/0xC7b068B897507312c2DACEd5E537eB658c49608D) |
| TokenMinter         | [0x880e37B98f7c058b3563970F256614FF4a580637](https://explorer-mainnet.maticvigil.com/address/0x880e37B98f7c058b3563970F256614FF4a580637) |
| OracleAggregator    | [0x56c54b408c44B12f6c9219C9c73Fcda4E783FC20](https://explorer-mainnet.maticvigil.com/address/0x56c54b408c44B12f6c9219C9c73Fcda4E783FC20) |
| SyntheticAggregator | [0xC955F3c0d5a87710996D13B1f9AA3A77552D7a7E](https://explorer-mainnet.maticvigil.com/address/0xC955F3c0d5a87710996D13B1f9AA3A77552D7a7E) |

### Binance Smart Chain

| Contract            | Address                                                                                                              |
| ------------------- | -------------------------------------------------------------------------------------------------------------------- |
| LibPosition         | [0x780F4b0E786bD703F21E4D22F48Ced4A877845De](https://bscscan.com/address/0x780F4b0E786bD703F21E4D22F48Ced4A877845De) |
| Registry            | [0x2e9AC4D0882165dCE317F23925060Ca3551782a9](https://bscscan.com/address/0x2e9AC4D0882165dCE317F23925060Ca3551782a9) |
| Core                | [0xC1e31C2db9f238809FE58089a7Fa7cE5aA7E52c6](https://bscscan.com/address/0xC1e31C2db9f238809FE58089a7Fa7cE5aA7E52c6) |
| TokenSpender        | [0xAb87BcB35bd0871f8278786AD75b06990d6373B3](https://bscscan.com/address/0xAb87BcB35bd0871f8278786AD75b06990d6373B3) |
| TokenMinter         | [0x90716893C1012166F2F182b61f69f0391673dD88](https://bscscan.com/address/0x90716893C1012166F2F182b61f69f0391673dD88) |
| OracleAggregator    | [0xC7b068B897507312c2DACEd5E537eB658c49608D](https://bscscan.com/address/0xC7b068B897507312c2DACEd5E537eB658c49608D) |
| SyntheticAggregator | [0x50680ea9B104ab8c70Ae80c46F4715a7531b3765](https://bscscan.com/address/0x50680ea9B104ab8c70Ae80c46F4715a7531b3765) |

## Testnet

### Ethereum (Rinkeby)

<table><thead><tr><th width="253">Contract</th><th>Address</th></tr></thead><tbody><tr><td>LibPosition</td><td><a href="https://rinkeby.etherscan.io/address/0xecfb28f107de2bFB325E339293dE3A01C1CfFA74">0xecfb28f107de2bFB325E339293dE3A01C1CfFA74</a></td></tr><tr><td>Registry</td><td><a href="https://rinkeby.etherscan.io/address/0xE665EA43121674964bcd330F65D512e718b7A50b">0xE665EA43121674964bcd330F65D512e718b7A50b</a></td></tr><tr><td>Core</td><td><a href="https://rinkeby.etherscan.io/address/0xE995d8E9E0a01c938e6ae5B05720Af245953dC57">0xE995d8E9E0a01c938e6ae5B05720Af245953dC57</a></td></tr><tr><td>Match</td><td><a href="https://rinkeby.etherscan.io/address/0x00bC68b57dbEdcffe3007890f581f1BE0a2CddaE">0x00bC68b57dbEdcffe3007890f581f1BE0a2CddaE</a></td></tr><tr><td>SwaprateMatch</td><td><a href="https://rinkeby.etherscan.io/address/0xC80B660E445d764B7741b59A33818d6526A830B2">0xC80B660E445d764B7741b59A33818d6526A830B2</a></td></tr><tr><td>TokenSpender</td><td><a href="https://rinkeby.etherscan.io/address/0xE39b9D5dC766102181D4C5Cd7df1691565B52032">0xE39b9D5dC766102181D4C5Cd7df1691565B52032</a></td></tr><tr><td>TokenMinter</td><td><a href="https://rinkeby.etherscan.io/address/0xDEe1031c5D64788976E78d78c63C2fd6b411c4ee">0xDEe1031c5D64788976E78d78c63C2fd6b411c4ee</a></td></tr><tr><td>OracleAggregator</td><td><a href="https://rinkeby.etherscan.io/address/0xe1Fd20231512611a5025Dec275464208070B985f">0xe1Fd20231512611a5025Dec275464208070B985f</a></td></tr><tr><td>SyntheticAggregator</td><td><a href="https://rinkeby.etherscan.io/address/0x8Fb660ab5542D752047312443742f209C88E2170">0x8Fb660ab5542D752047312443742f209C88E2170</a></td></tr></tbody></table>

### Polygon (Mumbai)

| Contract            | Address                                                                                                                                 |
| ------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| LibPosition         | [0x0cE1f283ca59C4F7fE7581DDb94e08eBff17869E](https://explorer-mumbai.maticvigil.com/address/0x0cE1f283ca59C4F7fE7581DDb94e08eBff17869E) |
| Registry            | [0xF228cA0a9c1A62C3b69454C6dB35d77f359D7ee1](https://explorer-mumbai.maticvigil.com/address/0xF228cA0a9c1A62C3b69454C6dB35d77f359D7ee1) |
| Core                | [0x2c8c1bf1d072dfec1cBd39512aA02DF2F0943221](https://explorer-mumbai.maticvigil.com/address/0x2c8c1bf1d072dfec1cBd39512aA02DF2F0943221) |
| Match               | [0x17f47E461DFdC7c6ee320044B730588407d841f3](https://explorer-mumbai.maticvigil.com/address/0x17f47E461DFdC7c6ee320044B730588407d841f3) |
| SwaprateMatch       | [0xdEa52ff7B21adc17FdbA46B6052aF9B1c0399565](https://explorer-mumbai.maticvigil.com/address/0xdEa52ff7B21adc17FdbA46B6052aF9B1c0399565) |
| TokenSpender        | [0x3F1fF59Ba18C8b540Be9d5Affe63a536e08dF36A](https://explorer-mumbai.maticvigil.com/address/0x3F1fF59Ba18C8b540Be9d5Affe63a536e08dF36A) |
| TokenMinter         | [0x6137B159970e8c9C26f12235Fb6609CfBC6EE357](https://explorer-mumbai.maticvigil.com/address/0x6137B159970e8c9C26f12235Fb6609CfBC6EE357) |
| OracleAggregator    | [0xa46e8eD10B0CD1FD75DC23210a5e351A1C9dE9dd](https://explorer-mumbai.maticvigil.com/address/0xa46e8eD10B0CD1FD75DC23210a5e351A1C9dE9dd) |
| SyntheticAggregator | [0x411b868dF2Ca9C6dc889d48019B08779747a7b8f](https://explorer-mumbai.maticvigil.com/address/0x411b868dF2Ca9C6dc889d48019B08779747a7b8f) |

### Binance Smart Chain (Testnet)

| Contract            | Address                                                                                                                      |
| ------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| LibPosition         | [0x9857f4030a76c0e2F08811DdA016eF157b0A738E](https://testnet.bscscan.com/address/0x9857f4030a76c0e2F08811DdA016eF157b0A738E) |
| Registry            | [0xc19397ccCB7EDdFb83533cfdE6d21EfC2EB860ef](https://testnet.bscscan.com/address/0xc19397ccCB7EDdFb83533cfdE6d21EfC2EB860ef) |
| Core                | [0x05D3b4cb841F1A05736010aa1fd59389bC88770B](https://testnet.bscscan.com/address/0x05D3b4cb841F1A05736010aa1fd59389bC88770B) |
| Match               | [0x12d0E89911130698150C5c13F964AAc468a2B076](https://testnet.bscscan.com/address/0x12d0E89911130698150C5c13F964AAc468a2B076) |
| SwaprateMatch       | [0x2B289C6271d259515fA9cca8978ca4BAb4ff1e7F](https://testnet.bscscan.com/address/0x2B289C6271d259515fA9cca8978ca4BAb4ff1e7F) |
| TokenSpender        | [0xF343EE410b7a313511845e964a9f6E4adBDF0398](https://testnet.bscscan.com/address/0xF343EE410b7a313511845e964a9f6E4adBDF0398) |
| TokenMinter         | [0xF228cA0a9c1A62C3b69454C6dB35d77f359D7ee1](https://testnet.bscscan.com/address/0xF228cA0a9c1A62C3b69454C6dB35d77f359D7ee1) |
| OracleAggregator    | [0x2c8c1bf1d072dfec1cBd39512aA02DF2F0943221](https://testnet.bscscan.com/address/0x2c8c1bf1d072dfec1cBd39512aA02DF2F0943221) |
| SyntheticAggregator | [0x17f47E461DFdC7c6ee320044B730588407d841f3](https://testnet.bscscan.com/address/0x17f47E461DFdC7c6ee320044B730588407d841f3) |


# High-level overview

The Opium Protocol is an oracle-agnostic smart escrow that allows to build and trade fully customizable financial products in a trustless fashion.

The two building blocks of the Opium Protocol are derivative recipes and oracle recipes. A derivative recipe encodes the financial specifications that describe a product whereas an oracle recipe specifies what data source should be used to settle a product upon its expiry.

![](https://lh5.googleusercontent.com/xnPdBzlfeBb_fEbGLPQCEnzvwUb7VpHgWOv9RiMh_12UOBiArmYkXa9Jik2fuCPHW-9gwA0_DMx91AahOyP_YPTFp8eCJA-ct5altEKpO5TzkJfU3T-dBOu9U_8I8SYBJQj6zVpI=s0)

### Development life cycle  of a derivative:

From a developer perspective, the main steps to develop a financial product on top of the Opium Protocol can be broken down into a few simple steps:

1\) Creation of an oracle

2\) Creation of a derivative recipe

3\) Provision of the oracle data upon the derivative’s maturity in order to perform its settlement

4\) Execution<br>

Let’s go through them step by step.<br>

Each financial instrument built on top of the Opium Protocol needs to be associated with an oracle whose responsibility is to provide the necessary data for its settlement. An oracle can be either an on-chain or an off-chain data source.&#x20;

From the Opium Protocol’s perspective, what matters is that the OracleAggregator - the data layer of the protocol- receives a derivative recipe’s required data within a specific time frame after its maturity. As such, off-chain data sources, although not in line with the spirit of decentralization, can be used if a derivative author wishes to do so, further decreasing the development burden placed required to craft financial instruments on Opium. <br>

Moving on to the second step, once a ‘source of truth’ for a financial instrument has been established, it is immediately possible to create a derivative recipe - hence mint LONG/SHORT positions for it. Derivative recipes can be created both by contracts or off-chain with the usage of a client library (web3.js, ethers.js, web3.py etc.) or SDK. All that is required is to understand the schema of a derivative in the Opium Protocol.

The core structure of a derivative product built on Opium needs to implement the following schema:

* **`uint256 margin`**

The reference collateral requirement of the given derivative product

* **`uint256 endTime`**

The expiry date of the given derivative product -  namely the date after which the parties involved in the product life-cycle will be allowed to call its execution and settlement

* **`uint256[] params`**

An array of arbitrary parameters, the first of which is the strike price of the derivative product

* **`address oracleId`**

The address of the account - either EOA (externally owned account) or contract account- that will be responsible to provide the data necessary for the settlement of the derivative

* **`address token`**

The ERC20 token to be used as a margin for the product.

* **`address syntheticId`**

The address of the derivative recipe.

The specifications encoded in a derivative structure are then packed and hashed to generate a footprint of a financial product which can be used within the Opium Protocol for the creation and execution of new positions.<br>

Once a derivative has been created, a derivative author must ensure that the selected oracle will provide the Opium Protocol with the required data within a specific time window (currently two weeks) after its maturity. Failing to do so will invalidate the derivative and will result in all the allocated capital being returned to the respective owners.<br>

Finally, if the third step has been performed successfully, the derivative’s positions can be executed. A position can be executed either by its owner or by a third-party if the respective position’s owner has enabled such a feature. A position owner can be either an EOA - externally owned account- or a contract account.<br>

And that’s it!

As you can see, since it’s possible to rely on ready-to-use third-party oracles and a derivative can be executed by its respective owners - hence, it doesn’t require a derivative’s author to take care of its programmatic execution-, the only step that is actually fundamental is to have a proper understanding of the financial instruments’ data schema adopted by the Opium Protocol - as described in the second step.

As a result, the creation of financial instruments on Opium is, by design, accessible to developers and non-developers, alike - but, at the same time, it allows for a high degree of customization for more development-intensive use-cases.<br>


# Opium Protocol V2

## Introduction

Opium v2 is a permissionless smart financial escrow protocol that allows its users to create fully customizable financial products. Its primary use-case is the management of derivatives, which are represented as a pair of LONG and SHORT ERC20 Opium position tokens. As a financial engineer, you can easily create a derivative contract with Opium v2 and be rewarded a portion of the reserves accrued by the protocol for each successful settlement of your own financial products. As a seller and buyer, you can partake in (for example) PUT or CALL options on an underlying by holding a specific Opium position token, you can exchange them on an AMM, exercise them at expiry or redeem them for initial margin if you hold an equal amount of LONG and SHORT positions. The focus of the design is to be as lean as possible as to enable the greatest flexibility and interoperability with other financial primitives.

## **Changelog from Opium Protocol v1**

1. Completely removed `pooled derivative` logic
2. Changed `ERC721o` to `ERC20`: `LONG` and `SHORT` position tokens and removed `TokenMinter` contract
3. Removed all Matching contracts, as ERC20 positions are compatible with protocols like `1inch Limit Order Protocol` and `0x`
4. Changed Solidity version to latest with best practices refactoring
5. Changed `create` to support `amounts` instead of `quantities` (fractional derivatives)
6. Separated `create` process into `create` and `mint` to reduce gas costs
7. Changed `execute` to support `amounts` instead of `quantities` (fractional derivatives)
8. Added `redeem` derivatives function to burn `LONG` + `SHORT` in return of `initial margin`
9. Added upgradability
10. Added emergency mechanisms
11. Added governance and roles
12. Performed additional refactoring and optimizations

## Core protocol modules

![](/files/4WT0ZCzlMJRycajTw4cD)

{% content-ref url="/pages/MLr1bCerX6Y8y2UcdSvo" %}
[Core](/for-developers/opium-protocol-v2/core)
{% endcontent-ref %}

{% content-ref url="/pages/IpjiveAy24bS3VwyrwB0" %}
[Registry](/for-developers/opium-protocol-v2/registry)
{% endcontent-ref %}

{% content-ref url="/pages/PJSRaIE937NYTWVgn8mf" %}
[SyntheticAggregator](/for-developers/opium-protocol-v2/syntheticaggregator)
{% endcontent-ref %}

{% content-ref url="/pages/8ai3bmOgBrwwtQ7hRqUC" %}
[OracleAggregator](/for-developers/opium-protocol-v2/oracleaggregator)
{% endcontent-ref %}

{% content-ref url="/pages/IVHOSkQ3HwtuZsC5srYL" %}
[OpiumProxyFactory](/for-developers/opium-protocol-v2/opiumproxyfactory)
{% endcontent-ref %}

{% content-ref url="/pages/yOdnAjuVz0hLk2PyEWcX" %}
[OpiumPositionToken](/for-developers/opium-protocol-v2/opiumpositiontoken)
{% endcontent-ref %}

## **Derivative author fees and protocol reserves**

### **Execution**

Derivatives authors can set a fee (limited) on the profit that trades make from execution. Part of this fee goes to protocol execution reserves and the rest goes to the derivative author.

Example:

| Name                                       | Value     |
| ------------------------------------------ | --------- |
| *\[input] Execution profit*                | *100 ETH* |
| *\[input] Derivative author fee*           | *5%*      |
| *\[input] Protocol execution reserve part* | *10%*     |
| \[output] Total reserve                    | 5 ETH     |
| \[output] Protocol execution reserve       | 0.5 ETH   |
| \[output] Derivative author reserve        | 4.5 ETH   |

### Redemption

| Name                                         | Value      |
| -------------------------------------------- | ---------- |
| *\[input] Initial margin*                    | *1000 ETH* |
| *\[input] Derivative author redemption part* | *0.1%*     |
| *\[input] Protocol redemption preserve part* | *10%*      |
| \[output] Total reserve                      | 1 ETH      |
| \[output] Protocol redemption reserve        | 0.1 ETH    |
| \[output] Derivative author reserve          | 0.9 ETH    |

## Security measures

### Derivative data cache

Since all syntheticId’s (derivative logic contracts) are third party contracts that are being consumed by the protocol, protocol MUST consider them as potentially malicious and act accordingly. This is why all data consumption calls (except derivative parameters validation) are only made once and are stored in cache thereafter.

### P2P Vaults

As an additional security measure there was introduced a so-called “P2P Vault”, which’s only purpose is a bookkeeping of cash flows for each particular derivative (ticker). It’s being increased on every incoming cash flow and deceased on every outcoming cash flow. It’s decreasing by greater value that it counts at the moment will result in transaction’s reverting.

This bookkeeping helps to prevent any potentially (not yet known) malicious derivatives from stealing funds withheld for other derivatives settlement.

## ACL

### Upgradability

All the core contracts of the Opium Protocol are upgradeable. The upgradeability is ensured by the openzeppelin’s “@openzeppelin/contracts-upgradeable” library which uses the unstructured storage proxies pattern and it is assumed that it safely protects from storage clashes between the proxy contract and the implementation contract. However, in order to avoid storage layout collisions between different implementation contract versions we have added a fixed length uint256 array (with 50 as length everywhere except for the OpiumPositionToken) which is assumed that will allow up to 50 storage slots (or 30 storage slots for the OpiumPositionToken) to add new variable/modify the contract without shifting down the storage layout and cause clashes.

### Roles

| Category  | ID | Role                                                  | Description                                                                                                                                                                                                                                                                     |
| --------- | -- | ----------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Setup     | 0  | DEFAULT\_ADMIN                                        | Special role set by default by the OpenZeppelin AccessControl library. It has the highest privilege level and can manage all the other roles (assign a role, revoke a role)                                                                                                     |
| Setup     | 1  | PROTOCOL\_ADDRESSES\_SETTER\_ROLE                     | Role responsible for updating the Opium Protocol core contracts' addresses                                                                                                                                                                                                      |
| Setup     | 5  | NO\_DATA\_CANCELLATION\_PERIOD\_SETTER\_ROLE          | Role responsible for updating the RegistryEntities.ProtocolParametersArgs.noDataCancellationPeriod                                                                                                                                                                              |
| Setup     | 7  | WHITELISTER\_ROLE                                     | Role responsible for managing (adding and removing accounts) the whitelist                                                                                                                                                                                                      |
| Setup     | 10 | REGISTRY\_MANAGER\_ROLE                               | Role responsible for updating the Registry address itself stored in the Opium Protocol core contracts that consume the Registry                                                                                                                                                 |
| Setup     | 18 | CORE\_CONFIGURATION\_UPDATER\_ROLE                    | Role responsible for updating (applying) new core configuration if it was changed in the registry                                                                                                                                                                               |
| Reserve   | 2  | EXECUTION\_RESERVE\_CLAIMER\_ADDRESS\_SETTER\_ROLE    | Role responsible for updating the reserve recipient's address of the profitable execution of derivatives positions                                                                                                                                                              |
| Reserve   | 3  | REDEMPTION\_RESERVE\_CLAIMER\_ADDRESS\_SETTER\_ROLE   | Role responsible for updating the reserve recipient's address of the redemption of market neutral positions                                                                                                                                                                     |
| Reserve   | 4  | EXECUTION\_RESERVE\_PART\_SETTER\_ROLE                | Role responsible for updating the fixed part (percentage) of the derivative author fees that goes to the protocol execution reserve                                                                                                                                             |
| Reserve   | 8  | DERIVATIVE\_AUTHOR\_EXECUTION\_FEE\_CAP\_SETTER\_ROLE | Role responsible for updating the maximum fee that a derivative author can set as a commission originated from the profitable execution of derivatives positions                                                                                                                |
| Reserve   | 9  | REDEMPTION\_RESERVE\_PART\_SETTER\_ROLE               | Role responsible for updating the fixed part (percentage) of the initial margin that will be deducted to the reserves during redemption of market neutral positions. Also sets fixed part (percentage) of this redemption reserves that goes to the protocol redemption reserve |
| Emergency | 6  | GUARDIAN\_ROLE                                        | Role responsible for globally pausing the protocol                                                                                                                                                                                                                              |
| Emergency | 11 | PARTIAL\_CREATE\_PAUSE\_ROLE                          | Role responsible for pausing Core.create                                                                                                                                                                                                                                        |
| Emergency | 12 | PARTIAL\_MINT\_PAUSE\_ROLE                            | Role responsible for pausing Core.mint                                                                                                                                                                                                                                          |
| Emergency | 13 | PARTIAL\_REDEEM\_PAUSE\_ROLE                          | Role responsible for pausing Core.redeem                                                                                                                                                                                                                                        |
| Emergency | 14 | PARTIAL\_EXECUTE\_PAUSE\_ROLE                         | Role responsible for pausing Core.execute                                                                                                                                                                                                                                       |
| Emergency | 15 | PARTIAL\_CANCEL\_PAUSE\_ROLE                          | Role responsible for pausing Core.cancel                                                                                                                                                                                                                                        |
| Emergency | 16 | PARTIAL\_CLAIM\_RESERVE\_PAUSE\_ROLE                  | Role responsible for pausing Core.claimReserve                                                                                                                                                                                                                                  |
| Emergency | 17 | PROTOCOL\_UNPAUSER\_ROLE                              | Role responsible for globally unpausing the protocol                                                                                                                                                                                                                            |


# Core

### Domain logic

It is the main user-facing entry-point to the Opium Protocol. It acts as the sole controller of all the financial and business logic operations of the protocol. It also acts as an escrow for the funds allocated for all the financial products built on top of Opium.

The user-facing business logic operations include:

* Creation of a new derivative
* Minting of new positions of an existing derivative
* Execution of a derivative position
* Redemption of market-neutral positions
* Cancellation of a derivative position (if execution is not possible)
* Claim reserves (for derivative authors)

### Actors

Users and contracts are expected to interact with the Core contract. Within the Opium Protocol, the Core contract is also the only contract that interacts with all the other core contracts.

### Data / control flow

It is expected to receive data and stateful actions from anyone - users and contracts. Within the Opium protocol, it also both pulls data from specific data sources (Registry, SyntheticAggregator, OracleAggregator, OpiumPositionToken) and pushes/performs stateful actions on other contracts (OpiumProxyFactory).

### Restrictions

The main restriction that relies on a third-party is the "pausability" of its user-facing functions: the Core contract operations can be restricted partially or completely by the governance if they activate one of the emergency mechanism options provided by the Registry contract. The other restrictions are related to the business requirements that Core needs to satisfy: as a user-facing contract performing financial operations in a permissionless environment, all the external functions perform checks to ensure the compliance of the user-provided data with its own logic and data models. Some of these checks include ensuring that a derivative cannot be exercised before expiry (time-based validation), preventing a third-party from manipulating the data of a derivative contract after its creation (caching validation) and ensuring that only the authorized actors can withdraw and/or exercise their rightful assets (access-control validation).


# Registry

### Domain logic

It is a parameter and address discovery module with its own granular access-control logic and setters that allow the authorized actors to change critical protocol-wide parameters.

### Actors

The rationale of the access-control logic is to have a role per each setter and an admin role to be delegated to a DAO (not part of the core protocol itself).

### Data / control flow

It is the ‘source of truth’ of the protocol as all other protocol’s contracts are in a pull-based consumer relation with it - with the partial exception of the module RegistryManager which provides to the core contracts a function to allow an authorized party whose role is managed in the current Registry to point to a new Registry

### Restrictions

The main business logic restrictions are the restrictions set by its own access-control logic: with the exception of the admin, no role should be authorized to call more than a single. See “ACL” section in the documentation.


# SyntheticAggregator

### Domain logic

It allows users and consumer contracts to query information about a specific derivative. It is not, however, just a data provider but it also performs one stateful security-critical operation: the caching of a non-cached derivative. This is fundamental as it prevents malicious actors from manipulating the internal data model of a derivative during its own financial lifecycle.

### Actors

Both users and third-party contracts are expected to interact with the SyntheticAggregator as consumers. The only Opium Protocol’s contract that directly consumes the SyntheticAggregator data is the Core contract.

The SyntheticAggregator is itself a consumer of a SyntheticId, a derivative contract compliant with the IDerivative interface.

### Data / control flow

The SyntheticAggregator is expected to be a direct consumer of only SyntheticId contracts. All the other relations with other contracts expect the SyntheticAggregator to be the data provider from which a consumer contract pulls the data related to a SyntheticId.

### Restrictions

The most critical restriction is that the SyntheticAggregator should cache the SyntheticId data only once during a derivative’s lifecycle to avoid malicious manipulations.

It is also expected to only retrieve information from contracts that comply with the IDerivative interface specification.


# OracleAggregator

### Domain logic

It is the data layer of the Opium Protocol. Its main responsibility is to store the required data to perform the settlement of a given derivative after its maturity. It does not, however, perform any business logic validation in itself as it is designed to be as flexible and lean as possible.

### Actors

Both users and third-party contracts are expected to interact with the OracleAggregator as consumers both to pull and push data. Within the Opium Protocol contract that directly consumes the OracleAggregator data is the Core contract as it is the contract responsible to perform financial operations.

### Data / control flow

It is only a recipient of data provided by other accounts. All the contracts that require data from the Oracle Aggregator need to pull it using the OracleAggregator.getData which is assumed to be the only entry-point. The only contract that pulls data from the OracleAggregator within the Opium protocol is the Core contract.

### Restrictions

The only restriction that is enforced on the OracleAggregator level is to not allow the same data to be pushed more than once on the same ‘data entry’, whereby a data entry is defined by `[address][timestamp]`. As such, it is the responsibility of a consumer contract to perform any kind of business logic validation - such as, in the case of Core, fetching the data provided by the correct OracleId and not fetching any data provided before the maturity of a derivative.


# OpiumProxyFactory

### Domain logic

It is the only entry point to perform stateful operations on derivative positions - as derivative positions are represented as erc20 tokens, these operations include minting and burning and the deployment itself of a new erc20 contracts.

### Actors

All the stateful logic of the OpiumProxyFactory is expected to involve only Core - as the controller of the OpiumProxyFactory - and the Opium position tokens - as an entity which is manipulated by the OpiumProxyFactory.

### Data / control flow

The stateful operations are expected to have a one way data and control flow whereby the Core contract calls the OpiumProxyFactory with the financial parameters of a derivative and subsequently the OpiumProxyFactory ‘translates’ the financial parameters into an erc20 api compatible language - i.e: the creation of a new derivative with LONG and SHORT positions is translated into the deployment of two erc20 contracts with an equivalent supply each.

### Restrictions

All the stateful functions should only be accessible to the Core contract


# OpiumPositionToken

### Domain logic

It is an erc20-permit contract representing either a LONG or SHORT position associated with a given derivative. It serves the purpose of bookkeeping for a position type of a derivative as much as that of a tokenized asset that can be composed with other financial primitives.

### Actors

Users and contracts are expected to be the holders of Opium position tokens. The OpiumPositionToken contract itself also interacts with other contracts within the Opium Protocol such as Core and, especially, the OpiumProxyFactory.

### Data / control flow

The stateful operations are expected to have a one way data and control flow where the OpiumPositionToken contract is always the receiver and it is controlled by the OpiumProxyFactory. The OpiumPositionToken can interact with other contracts if, for instance, the recipient of a “mint” operation triggered by the OpiumProxyFactory is itself a contract.

### Restrictions

The accessibility of stateful functions of the OpiumPositionToken is restricted to the OpiumProxyFactory.


# Opium Protocol V1

{% content-ref url="/pages/-MlOhWzrDKZpYjt2lEeC" %}
[Core](/for-developers/protocol/core)
{% endcontent-ref %}

{% content-ref url="/pages/-MlR6s4TexEat8P9UsTN" %}
[Registry](/for-developers/protocol/registry)
{% endcontent-ref %}

{% content-ref url="/pages/-MlQyMwkbwoRPsc5a9gO" %}
[TokenMinter](/for-developers/protocol/tokenminter)
{% endcontent-ref %}

{% content-ref url="/pages/-MlOrDKAtiOn9DFmC1Kl" %}
[TokenSpender](/for-developers/protocol/token-spender)
{% endcontent-ref %}

{% content-ref url="/pages/-MlOrlPQpc1L-\_zd5dJS" %}
[SyntheticAggregator](/for-developers/protocol/syntheticaggregator)
{% endcontent-ref %}

{% content-ref url="/pages/-MlOrVt38QJ6bhSQJ7Nn" %}
[OracleAggregator](/for-developers/protocol/oracle-aggregator)
{% endcontent-ref %}

{% content-ref url="/pages/-MlR7ktCpV0MxHPWqOJN" %}
[Helpers](/for-developers/protocol/helpers)
{% endcontent-ref %}

{% content-ref url="/pages/-MlOsftRtq1cd0wbtsHL" %}
[Interfaces](/for-developers/protocol/interfaces)
{% endcontent-ref %}

{% content-ref url="/pages/-MlOsQdlFfkEToNly\_gG" %}
[Common Errors](/for-developers/protocol/common-errors)
{% endcontent-ref %}

{% content-ref url="/pages/-LapHYXt-teYWsXrcpKr" %}
[oID - Oracle recipe](/for-developers/protocol/oracle-recipe)
{% endcontent-ref %}

{% content-ref url="/pages/-LapH1\_7AH6gWTji5Z-e" %}
[sID - Derivative recipe](/for-developers/protocol/derivative-recipe)
{% endcontent-ref %}

{% content-ref url="/pages/-M7mPym4fr11X7lVWxLh" %}
[EIP-2547: Composable Multiclass Token](/for-developers/protocol/eip-2547-composable-multiclass-token)
{% endcontent-ref %}


# Core

It is the main contract of the Opium Protocol. It exposes most of the user-facing functions that a user or a contract need to use in order to interact with the Opium Protocol, such as the creation of new financial products or their executions. &#x20;

The Core contract is responsible for processing the data encoded in a derivative recipe and for fetching the data from a specified oracle recipe for the purpose of calculating payouts, validating a financial product’s specs.

### Contract functions description

**`create(Derivative memory _derivative, uint256 _quantity, address[2] memory _addresses) public`**

If the derivative recipe is valid and the `msg.sender` calling core.create is providing a collateral allowance that matches the margin requirements specified in the derivative recipe, it transfers the collateral from the user via the `TokenSpender` contract and subsequently it mints a **LONG** and a **SHORT** `ERC721O` tokens for the given derivative recipe via the `TokenMinter` and transfers them respectively to the specified buyer and seller. As an argument it accepts `LibDerivative.derivative,` `uint256` quantity as the number of positions that the `TokenMinter` shall mint and a tuple of addresses - respectively the buyer and the seller- that shall be the recipients of the minted positions.

**`execute(uint256 _tokenId, uint256 _quantity, Derivative memory _derivative)`**

`msg.sender` executes a single derivative position type with a specified quantity. The position type being executed is represented by its unique `ERC721O` `tokenId`. Internally the function performs the required validation - such as checking whether the derivative associated to the `tokenId` is expired, the `OracleAggregator` has already provided the necessary data to settle the derivative and `msg.sender` is allowed to execute the given position. If all the validations are passed successfully, then it checks whether the provided `tokenId` belongs to a **LONG** or **SHORT** position and then proceeds to computing the payout logic according to the specifications encoded in the derivative recipe - specifically the `getExecutionPayout` specified in `IDerivativeLogic`- and the outcome cached in the OracleAggregator from the given derivative’s oracle recipe. After calculating the buyer’s and seller’s payouts, it finally forwards the payout to the winning party and,  if specified, it calculates the commission of the derivative’s author. As an argument it accepts the `uint256` `_tokenId` unique `tokenId` of the position to be executed, `uint256` \_quantity the number of positions to be executed, and `LibDerivative.Derivative` the derivative recipe associated with the given `tokenId`.

**`execute(uint256[] _tokenId, uint256[] _quantity, Derivative[] memory _derivative)`**

`msg.sender` executes a batch of derivatives’ positions with a specified quantity. The high-level logic introduced for `execute(uint256 _tokenId, uint256 _quantity, Derivative memory _derivative)` is applied to each provided position by looping through their array.&#x20;

**`execute(address _tokenOwner, uint256 _tokenId, uint256 _quantity, Derivative memory _derivative)`**

`msg.sender` executes a single derivative’s position type on behalf of `_tokenOwner`. An additional check is required in cases where a third-party requests the execution of a derivative’s position type owned by another account. Internally it checks whether the derivative recipe contract implementing the `IDerivativeLogic` interface allows the execution from third-parties by calling the `IDerivativeLogic` function `thirdPartyExecutionAllowed`, which returns a boolean. If true, the remaining high-level logic is identical to `execute(uint256 _tokenId, uint256 _quantity, Derivative memory _derivative)`

**`execute(address _tokenOwner, uint256[] memory  _tokenId, uint256[] memory _quantity, Derivative[] memory _derivative)`**

`msg.sender` executes a batch of derivatives’ positions on behalf of `_tokenOwner`. The logic being performed on each position is identical to `execute(address _tokenOwner, uint256 _tokenId, uint256 _quantity, Derivative memory _derivative)`but applied on each element of the supplied arrays.

**`cancel(uint256 _tokenId, uint256 _quantity, Derivative memory _derivative)`**

It allows the cancellation of the execution of a derivative if no data was provided to perform its settlement after 2 weeks from its maturity. If the execution is canceled, then all the allocated margins are returned to the respective position's owners. More importantly, once a position is canceled, it won’t be possible to execute it even if the oracle data will finally arrive at a later time.

**`cancel(uint256[] memory _tokenId, uint256[] memory _quantity, Derivative[] memory _derivative)`**

It allows the cancellation of a batch of derivatives if no data was provided to perform their settlement after 2 weeks for each of their maturity. The logic is identical to `cancel(uint256 _tokenId, uint256 _quantity, Derivative memory _derivative)` but it is applied to each of the derivatives’ positions array in a loop.

**`withdrawFee(address _tokenAddress) public`**

Allows the author of a derivative to withdraw the fees that were specified in the related derivative recipe as a commission for the author of said financial product. As an address it accepts the ERC20 address of the token with which the derivative author will be compensated - generally it is the ERC20 token used as a margin for the derivative itself.


# Registry

Registry keeps track of the contracts currently being used in the Opium protocol.&#x20;

All its user-facing functions are read-only and can be used to fetch the addresses of the contracts currently in use in the Opium Protocol rather than hardcoding them.

### Contract functions description

**`changeOpiumAddress() external view returns (address)`**

It allows to change the address of the recipient of the settlement fees within the Opium Protocol. It can only be called by the current account being the recipient of the settlement fees.

**`getMinter() external view returns (address)`**

It returns the current `TokenMinter` address

**`getTokenSpender() external view returns (address)`**

It returns the current `TokenSpender` address

**`getOpiumAddress() external view returns (address)`**

It returns the account that is currently set to receive settlement fees in the Opium Protocol.

**`getCore() external view returns (address)`**

It returns the current `Core` address

**`getOracleAggregator() external view returns (address)`**

It returns the current `OracleAggregator` address

**`getSyntheticAggregator() external view returns (address)`**

It returns the current `SyntheticAggregator` address


# TokenMinter

Its main responsibility is to perform actions on tokens representing the **LONG** and **SHORT** positions of a financial product.&#x20;

As the Opium Protocol makes use of its own token standard `ERC721O`, the `TokenMinter` exposes a set of functions to work with it.&#x20;

Its main consumer in the Opium Protocol is the Core contract, which makes use of the `TokenMinter` to mint **LONG**/**SHORT** positions upon the creation of a new financial product and burn them after the successful execution of the said financial product.&#x20;

### Contract functions description

**`mint(address _buyer, address _seller, bytes32 _derivativeHash, uint256 _quantity) external`**

Wrapper around `ERC7210BackwardCompatible` `_mint`. It mints **LONG** and **SHORT** `ERC721O` tokens according to the specified quantity respectively to the buyer and the seller. The `tokenId` of the **LONG** and **SHORT** position token is computed based on the provided `_derivativeHash`. The access to the function is restricted by the `onlyCore` modifier which grants its usage only to the `Core` contract.&#x20;

**`mint(address _buyer, bytes32 _derivativeHash, uint256 _quantity)`**

only for pooled

**`burn(address _tokenOwner, uint256 _tokenId, uint256 _quantity) external`**

Wrapper around ERC7210BackwardCompatible `_burn`. It burns a specified `tokenId` position on behalf of a `_tokenOwner`. The access to the function is restricted by the `onlyCore` modifier which grants its usage only to the `Core` contract.&#x20;

**`name() external view returns(string memory)`**

It returns a common name for all the position tokens.

**`symbol() external external view returns(string memory)`**

It returns a common symbol for all the position tokens.

**`isApprovedOrOwner(address _spender, address _owner, uint256 _tokenId) public view returns(bool)`**

**`isOpiumSpender(address _spender) public view returns(bool)`**


# TokenSpender

It is the ‘asset manager’ of the Opium Protocol. Its core responsibility is to manage the transfer of ERC20 and `ERC721O` tokens.&#x20;

Its only consumer contract in the Opium Protocol is the Core contract, which makes use of the `TokenSpender` for actions such as receiving the required margin (collateral) from a user upon a financial product’s creation and transferring the said margin upon a financial product’s execution according to the payout and the outcome fetched at expiry from the `OracleAggregator`.

### Contract functions description

**`claimTokens(IERC20 token, address from, address to, uint256 amount) external onlyWhitelisted`**

As an argument it takes an ERC20 address, the address of the sender from, the address of the recipient to and the `uint256 amount` to be managed. Its main responsibility is to transfer the money from the sender to the recipient with the specified quantity. The function’s usage is restricted by the modifier `onlyWhitelisted`, which allows only a set of whitelisted contracts to call a function to which it is applied. The whitelist of the allowed contracts is managed by the Opium Protocol’s governance contracts.

**`claimPositions(IERC721O token, address from, address to, uint256 tokenId, uint256 amount) onlyWhitelisted`**

As an argument it takes an `ERC721O` address, the address of the sender from, the address of the recipient to and the uint256 amount to be managed. Its main responsibility is to transfer the money from the sender to the recipient with the specified quantity. The function’s usage is restricted by the modifier `onlyWhitelisted`, which allows only a set of whitelisted contracts to call a function to which it is applied. The whitelist of the allowed contracts is managed by the Opium Protocol’s governance contracts.


# SyntheticAggregator

It allows users and consumer contracts to query information about a given derivative recipe and, internally, it is provided with some stateful logic to initialize a new financial product’s sensitive data.

### Contract functions description

**`getAuthorCommission(bytes32 _derivativeHash, Derivative memory _derivative) public returns(uint256 commission)`**

It returns the uint256 amount of fees in basis point 10000 that the derivative recipe’s author will receive for creating the given derivative recipe. Internally, the function performs stateful logic via the \_initDerivative function to check if a derivative’s data has already been initialized and, if not, it initializes it.

**`getAuthorAddress(bytes32 _derivativeHash, Derivative memory _derivative) public returns(address authorAddress)`**

It returns the address of the recipient of derivative recipe author’s fees. Internally, the function performs stateful logic via the \_initDerivative function to check if a derivative’s data has already been initialized and, if not, it initializes it.

**`getMargin(bytes32 _derivativeHash, Derivative memory _derivative) public returns(uint256 buyerMargin, uint256 sellerMargin)`**

It returns the margin of the LONG (buyer) and SHORT(seller) positions of a derivative recipe. As the margins are fully customizable, it checks the collateral requirements specified in the related derivative recipe by calling the \`getMargin\` function specified in the IDerivativeLogic interface. Internally, the function performs stateful logic to check if a derivative’s data has already been initialized and, if not, it initializes it.

**`isPool(bytes32 _derivativeHash, Derivative memory _derivative) public returns(bool result)`**


# OracleAggregator

It is the data layer of the Opium Protocol.

&#x20;The OracleAggregator is the contract responsible for providing the necessary data to settle a financial product in the Opium Protocol.&#x20;

It does not implement any specific oracle logic as it is designed to be more oracle-agnostic. This grants developers the freedom to choose the data source of their application - be it any oracle of their choosing or an off-chain API.

### Contract functions description

**`__callback(uint256 timestamp, uint256 data) public`**

The main OracleAggregator function that users and consumer contracts will use the most. It receives and caches the data from msg.sender based on the oracleId address and the provided timestamp - be it an oracle or an off-chain data source- so that it can be provided to the Core contract for the settlement of its related financial product. It takes as an argument the address of the oracle recipe’s oracleId and the uint256 timestamp

**`getData(address oracleId, uint256 timestamp) public view returns(uint256 dataResult)`**

If present, it returns the cached data associated with a given oracleId and timestamp. t takes as an argument the address of the oracle recipe’s oracleId and the uint256 timestamp

**`hasData(address oracleId, uint256 timestamp) public view returns(bool result)`**

It checks whether the OracleAggregator has already been provided with data for a given address oracleId and uint256 timestamp key pair

**`calculateFetchPrice(address oracleId) public returns(uint256 fetchPrice)`**

deprecated

**`registerQuery(address oracleId, uint256 timestamp)`**

deprecated

**`fetchData(address oracleId, uint256 timestamp) public`**

deprecated

**`recursivelyFetchData(address oracleId, uint256 timestamp, uint256 period, uint256 times) public`**

deprecated


# Helpers

### **BalanceHelper**

It provides a utility function to batch requests to check the balances and allowances of a user for a given list of ERC20 tokens.

#### Contract functions description

**`balancesOf`**

### **PayoutHelper**

It provides a utility function to query the execution payout of a given derivative recipe with different results.

#### Contract functions description

**`getExecutionPayouts`**

### **HasCommission**

It provides a set of functions that can be implemented by a derivative recipe contract in order to query and set the data related to the commission that the derivative recipe’s author should receive.

#### Contract functions description

**`getAuthorAddress() public view returns(address)`**

&#x20;It returns the address of the derivative author - which is set when the `HasCommission` contract is deployed as its `msg.sender`

**`getAuthorCommission() public view returns(uin256)`**

It returns the commission received by the derivative author when the derivative is executed. The commission is set as a constant at 0.25% of the payout’s profit.

### **ExecutableByThirdParty**

It provides a set of functions that can be implemented by a derivative recipe contract in order to allow a third-party to request its execution after maturity and to query whether the third party execution has already been allowed.

#### Contract functions description

**`thirdpartyExecutionAllowed`**

It checks whether any third-party is allowed to execute a synthetic's position on behalf of `msg.sender.`

**`allowThirdpartyExecution`**

It allows msg.sender to enable any third-party to perform the execution of their positions on their behalf.


# Interfaces

### **IDerivativeLogic**

Derivative recipes implementing the IDerivativeLogic interface can make use of the HasCommission and ExecutableByThirdParty helper contracts. The HasCommission contract exposes the view functions to query information about the derivative’s author and sets the commission for the creation of the derivative at 0.25% of the profit. The ExecutableByThirdParty implements the set of functions necessary to allow third-party execution and query whether it has already been granted.<br>

**`validateInput(Derivative memory _derivative) public view returns(bool);`**

It should allow to implement custom validation requirements for a derivative recipe

**`getMargin(Derivative memory _derivative) public view returns(uint256 buyerMargin, uint256 sellerMargin)`**

**`getExecutionPayout(Derivative memory _derivative, uint256 _result) public view returns(uint256 buyerPayout, uint256 sellerPayout)`**

The heart of customization of a derivative recipe. It is the function called by the Core contract to retrieve the payouts of a buyer and a seller. Any kind of payout logic - from traditional call/put options to more exotic products- should be implemented here.

**`getAuthorAddress() public view returns(address authorAddress);`**

It should return the derivative author’s address

**`getAuthorCommission() public view returns(uint256 commission);`**

It should return the derivative author’s commission

**`allowThirdPartyExecution(bool _allow) public`**

It should implement the logic to enable third party execution of the derivative’s positions

**`thirdPartyExecutionAllowed(address _derivativeOwner) public view returns(bool)`**

It should allow to retrieve whether third-party positions’ execution has been enabled for a given `_derivativeOwner` address

**`isPool() public view returns(bool)`**

deprecated<br>

### **IOracleId**

**`fetchData(address oracleId, uint256 timestamp) public`**

**`recursivelyFetchData(address oracleId, uint256 timestamp, uint256 period, uint256 times) public`**

**`calculateFetchPrice(address oracleId) public returns(uint256 fetchPrice)`**


# Common Errors

In this section you will find an explanation of the exceptions used by the Opium Protocol to ensure the consistency of its internal data models and business logic.

While developing a financial product on top of the Opium Protocol, it is possible to encounter one of the exceptions described in this section in case the code does not comply with the Opium Protocol's internal specifications.&#x20;

As not all exceptions are quite self-explanatory, the intent of the present documentation is to provide a more helpful descriptions of the errors that a developer might encounter.

{% content-ref url="/pages/-MlR-uAScJ1ZZdppmebZ" %}
[OracleAggregator Errors](/for-developers/protocol/common-errors/oracleaggregator)
{% endcontent-ref %}

{% content-ref url="/pages/-MlQzfkNSBupE\_n-Q2Ak" %}
[Core Errors](/for-developers/protocol/common-errors/core)
{% endcontent-ref %}


# OracleAggregator Errors

**`ERROR_ORACLE_AGGREGATOR_DATA_DOESNT_EXIST`**

The exception is triggered when the OracleAggregator `getData` function is called and the requested data for a given oracleId and timestamp has not yet been cached.

**`ERROR_ORACLE_AGGREGATOR_DATA_ALREADY_EXIST`**

The exception is triggered when an OracleId tries to push data twice with the same timestamp to the OracleAggregator - which would result in overriding the previously cached result.

**`ERROR_ORACLE_AGGREGATOR_NOT_ENOUGH_ETHER`**

deprecated

**`ERROR_ORACLE_AGGREGATOR_QUERY_WAS_ALREADY_MADE`**

deprecated


# Core Errors

**`ERROR_CORE_TICKER_WAS_CANCELLED`**

The error is triggered when an account tries to either create or execute a previously canceled derivative.

**`ERROR_CORE_SYNTHETIC_VALIDATION_ERROR`**

The error is triggered at the moment of a derivative’s positions creation if the provided LibDerivative.Derivative schema includes invalid parameters

**`ERROR_CORE_NOT_ENOUGH_TOKEN_ALLOWANCE`**

The error is triggered when an account tries to create a derivative’s positions without providing an amount of margin that matches the amount of collateral specified in the derivative recipe.

**`ERROR_CORE_TOKEN_IDS_AND_QUANTITIES_LENGTH_DOES_NOT_MATCH`**

The error is triggered when an account tries to either execute or cancel an array of positions represented by their tokenIds but provides a mismatching array of quantities - as every element in the array of quantities is the amount of positions that the account wishes to execute or cancel

**`ERROR_CORE_TOKEN_IDS_AND_DERIVATIVES_LENGTH_DOES_NOT_MATCH`**

The error is triggered when an account tries to either execute or cancel an array of positions represented by their tokenIds but provides a mismatching array of derivatives - as every element in the array of tokenIds is associated to a derivative in the array of derivatives

**`ERROR_CORE_EXECUTION_BEFORE_MATURITY_NOT_ALLOWED`**

The error is triggered when an account tries to execute a derivative before its maturity as specified in the endTime field of the derivative structure

**`ERROR_CORE_SYNTHETIC_EXECUTION_WAS_NOT_ALLOWED`**

The error is triggered when an account tries to execute a derivative that does not enable third-party execution without being its creator&#x20;

**`ERROR_CORE_CANCELLATION_IS_NOT_ALLOWED`**

The error is triggered when an account tries to cancel a derivative sooner than two weeks since its maturity in case no data was provided to the OracleAggregator

**`ERROR_CORE_UNKNOWN_POSITION_TYPE`**

The error is triggered in case the provided tokenId is not recognized by the Opium protocol<br>


# oID - Oracle recipe

```
pragma solidity 0.5.16;

/// @title Opium.Interface.IOracleId contract is an interface that every oracleId should implement
interface IOracleId {
    /// @notice Requests data from `oracleId` one time
    /// @param timestamp uint256 Timestamp at which data are needed
    function fetchData(uint256 timestamp) external payable;

    /// @notice Requests data from `oracleId` multiple times
    /// @param timestamp uint256 Timestamp at which data are needed for the first time
    /// @param period uint256 Period in seconds between multiple timestamps
    /// @param times uint256 How many timestamps are requested
    function recursivelyFetchData(uint256 timestamp, uint256 period, uint256 times) external payable;

    /// @notice Requests and returns price in ETH for one request. This function could be called as `view` function. Oraclize API for price calculations restricts making this function as view.
    /// @return fetchPrice uint256 Price of one data request in ETH
    function calculateFetchPrice() external returns (uint256 fetchPrice);

    // Event with oracleId metadata JSON string (for DIB.ONE derivative explorer)
    event MetadataSet(string metadata);
}

```


# sID - Derivative recipe

```
pragma solidity 0.5.16;
pragma experimental ABIEncoderV2;

/// @title Opium.Lib.LibDerivative contract should be inherited by contracts that use Derivative structure and calculate derivativeHash
contract LibDerivative {
    // Opium derivative structure (ticker) definition
    struct Derivative {
        // Margin parameter for syntheticId
        uint256 margin;
        // Maturity of derivative
        uint256 endTime;
        // Additional parameters for syntheticId
        uint256[] params;
        // oracleId of derivative
        address oracleId;
        // Margin token address of derivative
        address token;
        // syntheticId of derivative
        address syntheticId;
    }

    /// @notice Calculates hash of provided Derivative
    /// @param _derivative Derivative Instance of derivative to hash
    /// @return derivativeHash bytes32 Derivative hash
    function getDerivativeHash(Derivative memory _derivative) public pure returns (bytes32 derivativeHash) {
        derivativeHash = keccak256(abi.encodePacked(
            _derivative.margin,
            _derivative.endTime,
            _derivative.params,
            _derivative.oracleId,
            _derivative.token,
            _derivative.syntheticId
        ));
    }
}

```

```
pragma solidity 0.5.16;
pragma experimental ABIEncoderV2;

import "../Lib/LibDerivative.sol";

/// @title Opium.Interface.IDerivativeLogic contract is an interface that every syntheticId should implement
contract IDerivativeLogic is LibDerivative {
    /// @notice Validates ticker
    /// @param _derivative Derivative Instance of derivative to validate
    /// @return Returns boolean whether ticker is valid
    function validateInput(Derivative memory _derivative) public view returns (bool);

    /// @notice Calculates margin required for derivative creation
    /// @param _derivative Derivative Instance of derivative
    /// @return buyerMargin uint256 Margin needed from buyer (LONG position)
    /// @return sellerMargin uint256 Margin needed from seller (SHORT position)
    function getMargin(Derivative memory _derivative) public view returns (uint256 buyerMargin, uint256 sellerMargin);

    /// @notice Calculates payout for derivative execution
    /// @param _derivative Derivative Instance of derivative
    /// @param _result uint256 Data retrieved from oracleId on the maturity
    /// @return buyerPayout uint256 Payout in ratio for buyer (LONG position holder)
    /// @return sellerPayout uint256 Payout in ratio for seller (SHORT position holder)
    function getExecutionPayout(Derivative memory _derivative, uint256 _result)	public view returns (uint256 buyerPayout, uint256 sellerPayout);

    /// @notice Returns syntheticId author address for Opium commissions
    /// @return authorAddress address The address of syntheticId address
    function getAuthorAddress() public view returns (address authorAddress);

    /// @notice Returns syntheticId author commission in base of COMMISSION_BASE
    /// @return commission uint256 Author commission
    function getAuthorCommission() public view returns (uint256 commission);

    /// @notice Returns whether thirdparty could execute on derivative's owner's behalf
    /// @param _derivativeOwner address Derivative owner address
    /// @return Returns boolean whether _derivativeOwner allowed third party execution
    function thirdpartyExecutionAllowed(address _derivativeOwner) public view returns (bool);

    /// @notice Returns whether syntheticId implements pool logic
    /// @return Returns whether syntheticId implements pool logic
    function isPool() public view returns (bool);

    /// @notice Sets whether thirds parties are allowed or not to execute derivative's on msg.sender's behalf
    /// @param _allow bool Flag for execution allowance
    function allowThirdpartyExecution(bool _allow) public;

    // Event with syntheticId metadata JSON string (for DIB.ONE derivative explorer)
    event MetadataSet(string metadata);
}

```


# EIP-2547: Composable Multiclass Token

#### Opium.Team has decided to create Ethereum Improvement Proposal for Opium token standard to receive an official name. Opium token standard is also known as ERC-721o.

If you can give us some feedback and review, we will be really grateful!&#x20;

The proposal you can find here <https://github.com/ethereum/EIPs/pull/2547>

#### [Read more about Opium token standard](https://docs.opium.network/introduction-to-opium/opium-token-standard-erc-721o)


# Tutorials

In the present chapter you'll find technical tutorials and code snippets that showcase how to develop on top of the Opium Protocol - from developing single central components such as SyntheticIds and OracleIds to more end-to-end tutorial that will guide the reader throughout the entire development of a financial product's life-cycle.


# OracleId examples

As the Opium Protocol OracleAggregator is designed to be data source agnostic, it is up to the developer to implement what kind of on-chain or off-chain mechanism is the most suitable to their application.

As it was explained in the previous chapter, in the Opium protocol a financial instrument is defined by two separate entities:

* Derivative recipe
* Oracle recipe

For the purpose of sharing a common vocabulary, we refer to the contract entity implementing the oracle recipe as OracleId.&#x20;

In fact, the OracleAggregator itself uses the same terminology. In the OracleAggregator we have a nested mapping that maps the address of an OracleId to a mapping that maps the timestamp when the OracleId provided data to the OracleAggregator to the numerical value provided.

The OracleId’s value is therefore cached and made available to the Opium Protocol Core contract for the execution of the related derivative’s positions (see below):(.

```
mapping(address => mapping(uint256 => uint256)) private dataCache;
```

A possible pattern for the development of OracleIds is to split their logic in an OracleId and an OracleSubId. This allows to reason more clearly on the oracle logic and enforce a better separation of concerns and [single responsibility principle](< https://en.wikipedia.org/wiki/Single-responsibility_principle>).

The OracleId is responsible for pushing data into the OracleAggregator contract by calling the OracleAggregator callback function and the OracleSubId is responsible for implementing the oracle-specific logic. The OracleSubId logic can be implemented using Chainlink, UMA etc..

As the most popular oracle solution in the Ethereum space thus far is Chainlink, in the following example we showcase how to implement the OracleId/OracleSubId pattern:

```
interface IChainlinkOracle {
    function getLatestPrice() external returns(int);
}

contract OracleIdar is IOracleId, Ownable {
    IOracleAggregator oracleAggregator;
    uint256 public result;

    constructor(address _registry) public {
        IRegistry registry = IRegistry(_registry);
        oracleAggregator = IOracleAggregator(registry.getOracleAggregator());
    }
    /// @notice Wrapper around Opium oracleAggregator.__callback to push the data related to the underlying's market price
    /// @param _oracleSubId address of the oracleSubId - the data source whose result is being pushed into the OracleAggregator
    /// @param _timestamp uint256 unix timestamp of when the data is being pushed
    function __callback(address _oracleSubId, uint256 _timestamp) external onlyOwner {
        require(
            !oracleAggregator.hasData(address(this), _timestamp) && _timestamp < now,
            "Only when no data and after timestamp allowed"
        );
        uint256 data = uint256(IChainlinkOracle(_oracleSubId).getLatestPrice());
        result = data;

        oracleAggregator.__callback(_timestamp, result);
    }

    function fetchData(uint256 timestamp) external payable {}

    function recursivelyFetchData(
        uint256 timestamp,
        uint256 period,
        uint256 times
    ) external payable {}

    function calculateFetchPrice() external returns (uint256 fetchPrice) {}
}
```

In the above code snippet, the contract implements the OracleId interface. In the OracleId \_\_callback function, the contract fetches the required data from the OracleSubId and provides it to the OracleAggregator.

The OracleSubId is a basic implementation of a Chainlink pricefeed:

```
contract OracleSubId {
    AggregatorV3Interface internal priceFeed;

    /**
        AAVE/ETH price feed (8 decimals)
     */
    constructor() public {
        priceFeed = AggregatorV3Interface(0x6Df09E975c830ECae5bd4eD9d90f3A95a4f88012);
    }

    function getLatestPrice() public view returns(int) {
        (
            uint80 roundId,
            int price,
            uint startedAt,
            uint timeStamp,
            uint80 answeredInRound
        ) = priceFeed.latestRoundData();
        return price;
    }

}
```


# 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<br>

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;
        }
    }
```


# End-to-end tutorial

https\://medium.com/opium-network/build-a-call-option-on-opium-432c055fcbfa

## Setting up the tutorial environment

Clone repository:

```
git clone git@github.com:RiccardoBiosas/opium-call-option-example.git
cd opium-call-option-example
```

Set your INFURA\_KEY and MNEMONIC in the .env file:

```
INFURA_API_KEY=''
MNEMONIC=''
```

Install the dependencies:

```
yarn install
yarn test
```

Main contract:

{% code title="OptionController.sol" %}

```bash
pragma solidity 0.5.16;
pragma experimental ABIEncoderV2;

import "openzeppelin-solidity/contracts/math/SafeMath.sol";
import "openzeppelin-solidity/contracts/token/ERC20/IERC20.sol";
import "openzeppelin-solidity/contracts/token/ERC20/SafeERC20.sol";
import "openzeppelin-solidity/contracts/ownership/Ownable.sol";

import "opium-contracts/contracts/Lib/LibDerivative.sol";
import "erc721o/contracts/Libs/LibPosition.sol";

import "./interfaces/ICore.sol";
import "./interfaces/ISyntheticAggregator.sol";
import "./interfaces/IRegistry.sol";

/**
    @notice Wrapper contract to showcase how to interact with the Opium Protocol's Core contract in order to create and execute derivatives' positions
 */

contract OptionController is LibDerivative, Ownable {
    using SafeMath for uint256;
    using SafeERC20 for IERC20;
    using LibPosition for bytes32;

    address tokenSpender;
    ICore core;
    ISyntheticAggregator syntheticAggregator;

    Derivative public derivative;

    /// @notice Initializes Opium contracts
    /// @dev uses Opium Registry helper functions to get the required Opium contracts
    /// @param _registry address of Opium Registry contract
    constructor(address _registry) public {
        IRegistry registry = IRegistry(_registry);
        syntheticAggregator = ISyntheticAggregator(registry.getSyntheticAggregator());
        core = ICore(registry.getCore());
        tokenSpender = registry.getTokenSpender();
    }

    /// @notice Sets derivative template as a state variable which will be used as a template to create SHORT/LONG positions and execute them in the `create`, `executeShort`, `executeLong` functions
    /// @param _derivative Derivative
    function setDerivative(Derivative memory _derivative) public onlyOwner {
        derivative = _derivative;
    }

    /// @notice Wrapper around LibDerivative getDerivativeHash to return hash of the current derivative for off-chain validation purposes
    /// @return bytes32 of the Derivative derivative hash
    function getDerivativeHash() external view returns (bytes32) {
        return getDerivativeHash(derivative);
    }

    /// @notice Wrapper around Opium core.create to create a derivative
    /// @dev transfers required margin from msg.sender to tokenSpender
    /// @param _amount uint256 Amount of derivatives to be created
    /// @param _addresses address[2] Addresses of buyer(LONG) and seller(SHORT)
    function create(uint256 _amount, address[2] calldata _addresses) external {
        (uint256 buyerMargin, uint256 sellerMargin) = syntheticAggregator.getMargin(
            getDerivativeHash(derivative),
            derivative
        );
        uint256 requiredMargin = _computeMarginRequirement(buyerMargin, sellerMargin, _amount);

        IERC20(derivative.token).safeTransferFrom(msg.sender, address(this), requiredMargin);
        IERC20(derivative.token).approve(tokenSpender, 0);
        IERC20(derivative.token).approve(tokenSpender, requiredMargin);
        core.create(derivative, _amount, _addresses);
    }

    /// @notice Wrapper around Opium core.execute to execute a derivative SHORT position
    /// @param _amount uint256 Amount of SHORT positions to be executed
    function executeShort(uint256 _amount) external {
        bytes32 derivativeHash = getDerivativeHash(derivative);
        uint256 shortTokenId = derivativeHash.getShortTokenId();
        core.execute(msg.sender, shortTokenId, _amount, derivative);
    }

    /// @notice Wrapper around Opium core.execute to execute a derivative LONG position
    /// @param _amount uint256 Amount of LONG positions to be executed
    function executeLong(uint256 _amount) external {
        bytes32 derivativeHash = getDerivativeHash(derivative);
        uint256 longTokenId = derivativeHash.getLongTokenId();
        core.execute(msg.sender, longTokenId, _amount, derivative);
    }

    /// @notice helper function to calculate the total margin requirement for the creation of a derivative
    /// @param _buyerMargin uint256 margin of the LONG position
    /// @param _sellerMargin uint256 margin of the SHORT position
    /// @param _amount uint256 Amount of derivatives to be created
    function _computeMarginRequirement(
        uint256 _buyerMargin,
        uint256 _sellerMargin,
        uint256 _amount
    ) private pure returns (uint256) {
        return _buyerMargin.add(_sellerMargin).mul(_amount);
    }
}
```

{% endcode %}


# Opium API

{% content-ref url="/pages/W1QTCD6RL8dJNhwJeeq9" %}
[Subgraph V2](/for-developers/opium-api/subgraph-v2)
{% endcontent-ref %}

{% content-ref url="/pages/-M7mNoAIyApxNStcMF9h" %}
[Subgraph V1](/for-developers/opium-api/opium-protocol-on-the-graph)
{% endcontent-ref %}


# Subgraph V2

GraphQL subgraph with realtime data for [**Opium Protocol**](https://opium.network/) **V2** to make systems that use the protocol more robust and reliable. Also, it helps developers to easily understand Opium Protocol and integrate it into their projects.

Source code: <https://github.com/OpiumProtocol/opium-v2-subgraph>

| Network            | URL                                                                                    |
| ------------------ | -------------------------------------------------------------------------------------- |
| Arbitrum One       | <https://thegraph.com/hosted-service/subgraph/opiumprotocol/opium-v2-arbitrum-one>     |
| Arbitrum (testnet) | <https://thegraph.com/hosted-service/subgraph/opiumprotocol/opium-v2-arbitrum-rinkeby> |


# Subgraph V1

GraphQL subgraph with realtime data for [**Opium Protocol**](https://opium.network/) **V1** to make systems that use the protocol more robust and reliable. Also, it helps developers to easily understand Opium Protocol and integrate it into their projects.

The Graph team pinned this subgraph to the main page of the explorer.

Source code: <https://github.com/OpiumProtocol/opium-contracts/tree/master/thegraph>

| Network                    | URL                                                                                |
| -------------------------- | ---------------------------------------------------------------------------------- |
| Ethereum Mainnet           | <https://thegraph.com/explorer/subgraph/opiumprotocol/opium-network>               |
| Ethereum (Rinkeby Testnet) | <https://thegraph.com/hosted-service/subgraph/opiumprotocol/opium-network-rinkeby> |


# SDK

Software Development Kit

Protocol

{% content-ref url="/pages/3lQvR1lA4CMBod6CI104" %}
[Opium V2 SDK](/for-developers/opium-sdk/opium-v2-sdk)
{% endcontent-ref %}

Projects built on Opium Protocol

{% content-ref url="/pages/ctVWFprEG80qFLXAlum6" %}
[Opium Finance Pools SDK](/for-developers/opium-sdk/opium-finance-pools-sdk)
{% endcontent-ref %}

{% content-ref url="/pages/-M7mNHPre4o-QP9ZhL3X" %}
[Swap Rate SDK/API](/for-developers/opium-sdk/swap-rate-sdk-api)
{% endcontent-ref %}


# Opium V2 SDK

The Opium V2 SDK is the entry-point to all the core functionality of the Opium Protocol.

The SDK is divided in 4 main services:

* Core protocol contract wrappers
* Subgraph service
* Simulator service
* DerivativeLensFactory

Read more: <https://github.com/OpiumProtocol/opium-v2-sdk>


# Opium Finance Pools SDK

The Opium Finance Pools SDK is the entry-point to all the core functionality of the Opium Finance pools.

Read more: <https://github.com/OpiumProtocol/ofi-pools-sdk>


# Swap Rate SDK/API

### Swap Rate SDK and API now available <a href="#id-811c" id="id-811c"></a>

Smooth implementation of market-making, trading, and hedging strategies with automated bots. Also, everyone can now integrate interest rate swaps into existing projects.

**Our release includes**

* [HTTP API](https://opiumprotocol.github.io/swaprate-api/) for products, orders, authentication and system configuration
* [Socket.io API](https://opiumprotocol.github.io/swaprate-api/socket.html) for receiving immediate updates on curves (charts), swaps, positions on supported protocols and orders
* [JavaScript (TypeScript) SDK](https://opiumprotocol.github.io/swaprate-js/) implementing

Read more in our article: [***Swap Rate SDK/API are available now***](https://medium.com/opium-network/swap-rate-sdk-api-are-available-now-c4e3169b733)


# Glossary

**Margin token:** any ERC-20 token that is specified in the contract and used for collateral and payout of the position.&#x20;

**Opium position token:** after the creation of a contract, tokens that are minted by the Opium minter represent a short or long position that consists of information of a derivative and oracle recipe and a prepaid margin. Opium derivative tokens can easily be composed into portfolios and traded in any ecosystem that supports the ERC-721 token standard.\
\
**Opium portfolio token:** multiple Opium derivative tokens can be composed into an Opium portfolio token and traded as one. Portfolios can be recomposed by taking out or adding Opium derivative tokens from the portfolio. At any time, portfolios can also be decomposed, turning the whole portfolio back into Opium derivative tokens.

**Opium derivative:** a financial agreement where parties downpay specified margins that will be redistributed after maturity according to the specified oracle and derivative logic. Every derivative also differs according to parameters, such as maturity and required margin.&#x20;

**Derivative recipe:** a derivative recipe is a set of logic that defines how certain margin input is recalculated into a payout at the end of a contract. The derivative recipe needs data input to come to an exact numbe&#x72;**.** This data is fed by the oracle recipe. As derivative recipes are Turing complete, almost any financial product can be created.

**Derivative register:** the derivative register keeps track of all the underlying margins behind each ticker and oracle ID to make sure that there is always enough margin in the system, even if a third party derivative recipe is corrupted.

**Oracle recipe:** An oracle recipe describes how data will be fetched from an off-chain or on-chain source, which data exactly will be fetched, and how this data will be processed. As oracle recipes are Turing complete, it allows for very specific data input. Besides price data, it also supports event and status data.&#x20;

**Oracle register:** the Oracle Register stores all the data, supplied by oracle recipes, that was ever requested by the system. In this way, data only has to be transferred once to the blockchain and all other contracts using the same data can use this without paying fees for transferring the data.

**Opium swaps (TMtm):** in order, a user signs how much of what he wants to receive, and how much of what he is willing to give in return. This can comprise very complex swaps built up from multiple components such as assets, tokens, and derivatives and gives a professional trading experience.

**Opium relayer:** an Opium relayer matches users' orders and broadcasts them to the blockchain. He is incentivized by a relay fee and possible arbitrage opportunities that he can find between different markets and platforms.

**Opium affiliate:** an affiliate looks for the best prices in the market and redirects users' orders to the relayer that offers the best price. An affiliate does not broadcast orders to the blockchain himself. For his services, an affiliate will most likely demand an affiliate fee. \
\
**Opium minter:** after the creation of a contract, the Opium minter mints long and short derivative tokens to the respective owners of the positions. The Opium minter is also responsible for composing and recomposing portfolio tokens and burning position tokens after a contract has matured and paid out.

**Ticker:** a ticker is made up of the derivative and oracle recipes and the parameters (such as maturity, margin and strike price) that make up the agreement.

**TokenID:** besides the information that a ticker shows, a tokenID also specifies if someone owns the long or short token of an agreement.&#x20;


# Opium derivatives

Opium derivatives are a special animal that can handle the logic of most financial deals between traders.&#x20;

What is **common** between all financial derivatives?&#x20;

1. They all are agreements between future buyer(s) and seller(s) also known as *counterparties.*
2. All derivatives have an underlying product and price source (important for blockchain)
3. Every derivative specifies the maturity date, margin requirements and other specifics such as strike price, leverage or pay-out clauses.

What are the **differences** among derivatives?

1. Mechanism of P\&L among counterparties.&#x20;
2. Other technical details such as settlement-price calculation, way of delivery after execution and law and regulation.

The motivation to built Opium was to create an innovative protocol that can handle various derivatives in the same way and provide settlement and trading based on blockchain guaranteeing trustless and virtually free of charge administration.&#x20;

Opium defines derivatives as follows:

![Opium derivatives](/files/-LzCo17qawjM16wJU93F)

{% hint style="info" %}
***Opium derivative:*** Two counterparties enter into a deal and deposit margins m1 and m2. The derivative is created and the counterparties' Long or Short position is ''stored'' in an Opium derivative token. After the maturity of the contract, the total margin M=m1+m2 is redistributed according to the derivative recipe formul&#x61;***,*** based on the price that is fed by the oracle recipe at maturity. The first party receives x% of the total margin and the second party receives (1-x%) of the total margin deposit M correspondingly.
{% endhint %}

By changing the derivative logic component and using it in combination with an oracle logic component, we virtually can create any financial instrument on any asset.&#x20;

Think about derivatives on cryptocurrencies, hash-rates of a blockchain and just simply stocks, bonds, swaps, and commodities. All is possible with the right derivative and oracle recipe. When markets are established, users can build their own products on products (options on futures for example), but also insurance products to cover tail risks of other products and ensure tranches of a certain index of products.


# Oracle and derivative recipes

Oracle and derivative recipes are special contracts in which anyone can describe the logic of a derivative or oracle. This logic is stored in the recipe, and the Opium core has access to it when it wants to run the logic when needed, for example at the execution of positions. The Opium core checks the formulas in derivative or oracle recipes and uses the result for getting the price from the real world and redistribution of the margin.\
\
Derivative recipes can be constructed for any derivative as the high-level logic is the same: payouts of margin inputs are calculated in some way (derivative recipe) according to certain price or event data (oracle recipe). Derivatives in the Opium Network can be cash-settled or physically delivered (in case of cryptocurrency or tokenized asset). Derivative recipes describe how margin inputs are paid out at execution, and oracle recipes describe the way of data fetching, which exact data is fetched and how this data is processed.

![Oracle and derivatives recipes](/files/-LzCoN7uom08y2p9Exk2)

As an example, a contract can be based on the US Dollar price of Ethereum that uses an oracle recipe that simply fetches the data from Binance by using Oraclize and directly feeds it to the contract.

![Example of a simple oracle recipe](/files/-Lz6k3HuKyDDDoxQO_VO)

A more complex variant can be where the price is fetched from Binance, Kraken and the KyberNetwork, where the price from Binance and Kraken is fetched through ChainLink and the price from KyberNetwork with a read function on the Ethereum network. After fetching the 3 prices, an average is calculated and fed into the registry contract to calculate the payout.&#x20;

![A more complex oracle recipe](/files/-Lz6kK25uVOwz-LJkqqI)

Many variants to feed data can be thought of and the Opium Network does not limit anyone to use a specific solution for their contracts:

* Oraclize
* ChainLink
* Tellor
* Running an auction
* Voting
* Manually
* Others...

The beautiful thing about Opium recipes is that they are Turing complete, and thus can comprise any logic. For example, if a data source does not respond, certain dispute resolutions as a second data source or voting can be implemented.&#x20;

\ <br>


# Oracle and derivative registers

Oracle and derivative recipes should be registered at either their respective Oracle or Derivative register to connect to the Opium Network. Registers store data about the qualities of a recipe and secure the Opium Network against hacks. Once data is supplied to the register, it cannot be changed.

The derivative register stores how much margin was placed at the creation of a contract. The Opium core uses this data to determine payouts when one of the counterparties uses the withdrawal function. Counterparties can never receive more from the contract than initially was put up as collateral. This means that even if a third party derivative recipe is corrupted, it will never be able to steal money from the system. In this way, it is guaranteed that there is always enough margin in the system for all the outstanding positions in the Opium Network.\
\
The oracle register stores all the data, supplied by oracle recipes, that was ever requested by the system. In this way, data only has to be transferred once to the blockchain and all other contracts using the same data can use this without paying fees for transferring the data to the blockchain.\
\
This means that if after maturity one contract is executed, all the other contracts with the same specifics are technically also matured. Users just have to withdraw their part of the margin by using the withdrawal function. If after 2 weeks contracts have not been executed, because the oracle recipe was unable to deliver data, both parties can withdraw their initially placed margin from the derivative register. \
\
The oracle register also stores which publicKey queried the data, and before fetching checks if there was enough Ether supplied to finish the fetching function.

![Registers store data and secure the system against hacks.](/files/-Lyjj5AXT65OQLz4AKMm)


# Opium margin

To create a derivative contract, participants need to provide collateral (margin) that will be used to pay the counterparty if a position is liable. Within this margin, the position payout is guaranteed for the counterparty. In general, the maximum amount of profit to be earned is known for both counterparties. Depending on how derivative recipes are structured, insurance products can be connected to guarantee payouts above the placed margins by counterparties.

{% hint style="info" %}
In the Opium protocol we define margin as any ERC-20 token.&#x20;
{% endhint %}

Users can choose their desired token as a margin and create the corresponding contract. Specifications of the derivative contract include the type and amount of margin token, so participants can assess the risks connected to this contract and know what is the maximum delivery of which amount of tokens. As an example, USDT and DAI are both stable coins pegged to the US Dollar but carry inherently different risks. The Opium Protocol is unbiased towards the usage of margin tokens. Users can choose themselves which tokens they use as collateral.

![Any ERC-20 token can be used as collateral](/files/-LynyN_cMV2ymyOsjiV2)

<br>

&#x20; &#x20;


# Opium swaps (TMtm)

In financial markets, traders often combine orders to take or reduce exposure in multiple positions at the same time. This was our motivation for designing the TMtm mechanism. It enables a variety of operations such as buying, selling, swapping and creating spreads in simple, but also complex ways.

The swap function executes TMtm-swaps:

{% hint style="info" %}
***TMtm swap:*** user requests to provide {T amount of Opium Tokens + M amount of ERC-20 margin} in exchange for {T amount of Opium Tokens + M amount of ERC-20 margin}
{% endhint %}

With this standard protocol request, it is possible to sell, buy and exchange tokens or spreads. For example:&#x20;

> {4xFuture, 0, 0, 6xUSDT} is a sell order of 4 Futures for 6 USDT Tokens.
>
> {0, 5xDAI, 10xOptions, 0} is a buy order of 10 Options for 5 DAI  Tokens.
>
> {4xFuture, 6xUSDT, 10xOptions, 0} is a combined sell order for \[10 Options - 4 Futures] spread with a price to pay of 6 USDT coins.
>
> {4xFutureA, 0, 8xFutureB, 0} is a buy order of 8 FutureB with paying of 4 FutureA
>
> {1xPortfolio, 0, 0, 1200xDAI} is a sell order of user Portfolio for 1200 DAI coins

Orders are signed by the user and allow the Opium Network to withdraw funds needed to execute the order. &#x20;


# Opium order books

The Opium Network transfers the clearing, settlement and trading functions from centralized agents to the blockchain, with support of relayers. Core and sensitive functions are stored on-chain and all computational intense processes are run on the overlay of relayers but verified on-chain. Relayers are motivated by commission fees and can also carry out arbitrage functions between different orders, markets, and ecosystems.

The Opium Protocol is unbiased towards how matched orders are broadcasted to the blockchain and how order books are presented to users. What matters for the protocol is that TMtm interfaces are used and orders are matched correctly.&#x20;

Orders can be broadcasted to the blockchain by anyone. Though, relayers might require the user to state ‘senderAddress’ - the only Ethereum address that is allowed to broadcast the orders to the blockchain. This prevents frontrunning and order collision and enhances the trading experience.

Relayers can set up order books that are quoted in any base margin currency and are free to benefit from arbitrage opportunities by matching orders in different order books, making a free profit whilst providing liquidity to the system. TMtm order models can be used for simple trades, but also allow users to set up complex orders.


