Issuance

Pool Factory Smart Contract Address

All actions other than minting and redeeming of derivatives are carried out by calling the Vault Factory Proxy contract.

$VAULT_FACTORY_PROXY=/set address by the network/

Set-up

This guide will use seth - a tool built by Dapphub to interact directly with smart contracts. To install, run the below command. Note: the Dapp Tools suite installs Nix OS

curl https://dapp.tools/install | sh

Follow the remaining steps at: https://github.com/dapphub/dapptools/tree/master/src/seth#example-sethrc-file in order to select the SETH_CHAIN and address/key.

Vault Factory

Get all registries:

seth call $VAULT_FACTORY_PROXY "derivativeSpecificationRegistry()"
seth call $VAULT_FACTORY_PROXY "oracleRegistry()"
seth call $VAULT_FACTORY_PROXY "oracleIteratorRegistry()"
seth call $VAULT_FACTORY_PROXY "collateralTokenRegistry()"
seth call $VAULT_FACTORY_PROXY "collateralSplitRegistry()"

Get fee-dependent variables:

seth call $VAULT_FACTORY_PROXY "protocolFee()"
seth call $VAULT_FACTORY_PROXY "feeWallet()"
seth call $VAULT_FACTORY_PROXY "authorFeeLimit()"
seth call $VAULT_FACTORY_PROXY "settlementDelay()"

Vault Enumeration

Get all vaults addresses:

seth call $VAULT_FACTORY_PROXY "getAllVaults()"

Check the current state of the vault, where status 0 is created, 1 is minting, 2 is live, 3 is settled

seth call $VAULT "state()"

Get time-dependent variables of the vault:

seth call $VAULT "initializationTime()"
seth call $VAULT "liveTime()"
seth call $VAULT "settleTime()"

Get all linked addresses:

seth call $VAULT "derivativeSpecification()"
seth call $VAULT "collateralToken()"
seth call $VAULT "oracles()"
seth call $VAULT "oracleIterators()"
seth call $VAULT "collateralSplit()"
seth call $VAULT "primaryToken()"
seth call $VAULT "complementToken()"

Get all fee-dependent vault's params:

seth call $VAULT "feeWallet()"
seth call $VAULT "protocolFee()"
seth call $VAULT "authorFeeLimit()"

Get settlement params:

seth call $VAULT "underlyingStart()"
seth call $VAULT "underlyingEnd()"
eth call $VAULT "primaryConversion()"
eth call $VAULT "complementConversion()"

Minting and Redeeming

mint method is used to mint derivatives, where the collateral amount parameter is expressed in minimal units.

seth send $VAULT "mint(uint256)" $COLLATERAL_AMOUNT

redeem and refund methods are used to exchange derivatives back for collateral, where primary and complement token amounts are expressed in minimal units. refund allows users to exchange equal quantities of primary and complement tokens for collateral in any vault state. redeem can be used to exchange any amounts of either primary or complement tokens for collateral, but only once the vault has settled. Params underlyingStartRoundHints and underlyingEndRoundHints in redem are used to reduce the number of iterations needed to find the required oracle values during the settlment process.

seth send $VAULT "refund(uint256)" $TOKEN_AMOUNT
seth send $VAULT "redeem(uint256, uint256, uint[] memory, uint[] memory)" $PRIMARY_TOKEN_AMOUNT $COMPLEMENT_TOKEN_AMOUNT $UNDERLYING_START_ROUND_HINTS $UNDERLYING_END_ROUND_HINTS

Creating a New Vault

Creating a vault based on a chosen specification requires a user to go through the following steps:

1) Create Vault

When creating the vault, user specifies initializationTime , which serves as the starting point of the vault's lifecycle and allows the creator to make sure that the derivative goes live and settles at any desired point in time, i.e. enables to keep a precise issuance schedule.

seth send $VAULT_FACTORY_PROXY "createVault(string, uint)" \
$SPECIFICATION_SYMBOL $INITIALIZATION_TIME

2) Get Vault Address

vault_index = $(seth call $VAULT_FACTORY_PROXY "getLastVaultIndex()")
vault = $(seth call $VAULT_FACTORY_PROXY "getVault(uint)" $vault_index)

3) Initialize Vault

After the vault has been created, the user calls the initialize function, which creates the derivative tokens and changes the vault's state to Minting - derivative issuance can now begin.

seth send $vault "initialize()"

Adding a New Derivative Specification

To create a new derivative specification, follow these steps:

1) Add Oracles

The protocol potentially supports specifications that make use of multiple oracles simultaneously, but this capability is still under development and has not been fully tested.

To check whether an oracle is already included in the registry, use the get function on the Keccak-256 hash of the address for the oracle in question.

If the oracle used by your derivative is already in the oracleRegistry, you can proceed to the next step. If not, you can add them using the setOracle method in the Vault Factory.

seth send $VAULT_FACTORY_PROXY "setOracle(bytes32, address)"

2) Add oracle iterator

If the oracle iterator used by your derivative is already in the oracleIteratorRegistry, you can proceed to the next step. If not, you can add them using the setOracleIterator method in the Vault Factory.

seth send $VAULT_FACTORY_PROXY "setOracleIterator(bytes32, address)"

3) Add Collateral Token

To check whether an oracle is already included in the registry, use the get function on the Keccak-256 hash of the address for the collateral token in question.

If the collateral used by your derivative is already in the collateraTokenRegistry, please proceed to the next step. If not, you can add any ERC20 token to the registry using the setCollateralToken method in the Vault Factory.

seth send $VAULT_FACTORY_PROXY "setCollateralToken(bytes32, address)"

4) Add Collateral Split

You could use one of the existing collateral split functions, or add a new one. To do that, implement the ICollateralSplit interface and deploy the collateral split contract. Once you have deployed the contract, it can be added to collateralSplitRegistry using the setCollateralSplit method in Vault Factory.

seth send $VAULT_FACTORY_PROXY "setCollateralSplit(bytes32, address)"

5) Add Derivative Specification

DerivativeSpecification contract should be used for deployments of new specifications. All params should be set in the specification constructor.

Once you have deployed your derivative specification contract, it can be added to derivativeSpecificationRegistry using the setDerivativeSpecification method in the Vault Factory.

Please note that a new derivative specification must have a previously unused symbol. Also, it must not be identical to an existing specification in all but the symbol.

seth send $VAULT_FACTORY_PROXY "setDerivativeSpecification(bytes32, address)"

Reading Data With View Contract

/// @title Reading key data from specified Vault
contract VaultView {
/// @notice Contains key information about a Vault
struct Vault {
address self;
uint256 liveTime;
uint256 settleTime;
int256 underlyingStart;
int256 underlyingEnd;
uint256 primaryConversion;
uint256 complementConversion;
uint256 protocolFee;
uint256 authorFeeLimit;
uint256 state;
address oracle;
uint oracleDecimals;
address oracleIterator;
address collateralSplit;
bool isPaused;
}
/// @notice Contains key information about a derivative token
struct Token {
address self;
string name;
string symbol;
uint8 decimals;
uint userBalance;
}
/// @notice Contains key information from Derivative Specification
struct DerivativeSpecification {
address self;
string name;
string symbol;
uint denomination;
uint authorFee;
uint primaryNominalValue;
uint complementNominalValue;
bytes32[] oracleSymbols;
}
/// @notice Getting information about a Vault, its derivative tokens and specification
/// @param _vault vault address
/// @return vaultData vault-specific information
/// @return derivativeSpecificationData vault's derivative specification
/// @return collateralData vault's collateral token metadata
/// @return lockedCollateralAmount vault's total locked collateral amount
/// @return primaryData vault's primary token metadata
/// @return complementData vault's complement token metadata
function getVaultInfo(address _vault)
external view
returns (
Vault memory vaultData,
DerivativeSpecification memory derivativeSpecificationData,
Token memory collateralData,
uint lockedCollateralAmount,
Token memory primaryData,
Token memory complementData
)
{...}
/// @notice Getting vault derivative token balances
/// @param _owner address for which balances are being extracted
/// @param _vaults list of all vaults
/// @return primaries primary token balances
/// @return complements complement token balances
function getVaultTokenBalancesByOwner(
address _owner,
address[] calldata _vaults
)
external
view
returns (uint256[] memory primaries, uint256[] memory complements)
{...}
/// @notice Getting any ERC20 token balances
/// @param _owner address for which balances are being extracted
/// @param _tokens list of all tokens
/// @return balances token balances
function getERC20BalancesByOwner(address _owner, address[] calldata _tokens)
external
view
returns (uint256[] memory balances)
{...}
}