End-to-end tutorial
https://medium.com/opium-network/build-a-call-option-on-opium-432c055fcbfa

Setting up the tutorial environment

Clone repository:
1
git clone [email protected]:RiccardoBiosas/opium-call-option-example.git
2
cd opium-call-option-example
Copied!
Set your INFURA_KEY and MNEMONIC in the .env file:
1
INFURA_API_KEY=''
2
MNEMONIC=''
Copied!
Install the dependencies:
1
yarn install
2
yarn test
Copied!
Main contract:
OptionController.sol
1
pragma solidity 0.5.16;
2
pragma experimental ABIEncoderV2;
3
4
import "openzeppelin-solidity/contracts/math/SafeMath.sol";
5
import "openzeppelin-solidity/contracts/token/ERC20/IERC20.sol";
6
import "openzeppelin-solidity/contracts/token/ERC20/SafeERC20.sol";
7
import "openzeppelin-solidity/contracts/ownership/Ownable.sol";
8
9
import "opium-contracts/contracts/Lib/LibDerivative.sol";
10
import "erc721o/contracts/Libs/LibPosition.sol";
11
12
import "./interfaces/ICore.sol";
13
import "./interfaces/ISyntheticAggregator.sol";
14
import "./interfaces/IRegistry.sol";
15
16
/**
17
@notice Wrapper contract to showcase how to interact with the Opium Protocol's Core contract in order to create and execute derivatives' positions
18
*/
19
20
contract OptionController is LibDerivative, Ownable {
21
using SafeMath for uint256;
22
using SafeERC20 for IERC20;
23
using LibPosition for bytes32;
24
25
address tokenSpender;
26
ICore core;
27
ISyntheticAggregator syntheticAggregator;
28
29
Derivative public derivative;
30
31
/// @notice Initializes Opium contracts
32
/// @dev uses Opium Registry helper functions to get the required Opium contracts
33
/// @param _registry address of Opium Registry contract
34
constructor(address _registry) public {
35
IRegistry registry = IRegistry(_registry);
36
syntheticAggregator = ISyntheticAggregator(registry.getSyntheticAggregator());
37
core = ICore(registry.getCore());
38
tokenSpender = registry.getTokenSpender();
39
}
40
41
/// @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
42
/// @param _derivative Derivative
43
function setDerivative(Derivative memory _derivative) public onlyOwner {
44
derivative = _derivative;
45
}
46
47
/// @notice Wrapper around LibDerivative getDerivativeHash to return hash of the current derivative for off-chain validation purposes
48
/// @return bytes32 of the Derivative derivative hash
49
function getDerivativeHash() external view returns (bytes32) {
50
return getDerivativeHash(derivative);
51
}
52
53
/// @notice Wrapper around Opium core.create to create a derivative
54
/// @dev transfers required margin from msg.sender to tokenSpender
55
/// @param _amount uint256 Amount of derivatives to be created
56
/// @param _addresses address[2] Addresses of buyer(LONG) and seller(SHORT)
57
function create(uint256 _amount, address[2] calldata _addresses) external {
58
(uint256 buyerMargin, uint256 sellerMargin) = syntheticAggregator.getMargin(
59
getDerivativeHash(derivative),
60
derivative
61
);
62
uint256 requiredMargin = _computeMarginRequirement(buyerMargin, sellerMargin, _amount);
63
64
IERC20(derivative.token).safeTransferFrom(msg.sender, address(this), requiredMargin);
65
IERC20(derivative.token).approve(tokenSpender, 0);
66
IERC20(derivative.token).approve(tokenSpender, requiredMargin);
67
core.create(derivative, _amount, _addresses);
68
}
69
70
/// @notice Wrapper around Opium core.execute to execute a derivative SHORT position
71
/// @param _amount uint256 Amount of SHORT positions to be executed
72
function executeShort(uint256 _amount) external {
73
bytes32 derivativeHash = getDerivativeHash(derivative);
74
uint256 shortTokenId = derivativeHash.getShortTokenId();
75
core.execute(msg.sender, shortTokenId, _amount, derivative);
76
}
77
78
/// @notice Wrapper around Opium core.execute to execute a derivative LONG position
79
/// @param _amount uint256 Amount of LONG positions to be executed
80
function executeLong(uint256 _amount) external {
81
bytes32 derivativeHash = getDerivativeHash(derivative);
82
uint256 longTokenId = derivativeHash.getLongTokenId();
83
core.execute(msg.sender, longTokenId, _amount, derivative);
84
}
85
86
/// @notice helper function to calculate the total margin requirement for the creation of a derivative
87
/// @param _buyerMargin uint256 margin of the LONG position
88
/// @param _sellerMargin uint256 margin of the SHORT position
89
/// @param _amount uint256 Amount of derivatives to be created
90
function _computeMarginRequirement(
91
uint256 _buyerMargin,
92
uint256 _sellerMargin,
93
uint256 _amount
94
) private pure returns (uint256) {
95
return _buyerMargin.add(_sellerMargin).mul(_amount);
96
}
97
}
Copied!
Last modified 1mo ago
Copy link