Authors | Jack McPherson <[email protected]> |
Version | 0.1 |
[TODO]
TODO
This document specifies the minimum required interface for the Tracer Pool Swaps protocol. Compliant implementations may implement a superset of the functionality specified in this document, but not a subset.
This document makes uses of the requirements language specified in RFC2119[1]. This document typesets such keywords in both boldface and italics.
Were domain-specific terminology is used, this document defines relevant terms and typesets them in boldface.
Where a function returns multiple types, this indicates that the function returns a tuple of these types. Additionally, where returned values are unnamed, they are free to be either anonymous or named.
Term | Definition |
---|---|
Pair | TODO |
Pool | Smart contract containing two pairs – one long and one short – that tracks changes in the price of an underlying asset. A pool has a fixed leverage. |
Market | Collection of pools, all tracking the same underlying asset, but each having unique leverage. |
Price update | When funds are moved between the two pairs of a pool |
Update interval | Minimum amount of time (in seconds) between price updates |
Frontrunning interval | TODO |
Price execution | See price update |
Shadow pool | Sum of all unexecuted commitments of a given type |
Minting | Act of depositing into a pair |
Burning | Act of withdrawing from a pair |
Commitment | TODO |
Commit | See commitment |
Library? | No |
Interface? | Yes |
Abstract? | No |
Implements | N/A |
None.
None.
Visibility | external |
Restricted? | Yes |
Deploys a new pool with the specified parameters.
Name | Type | Description |
---|---|---|
_owner |
address |
Address of the owner of the deployed pool |
_poolCode |
string |
Ticker for the deployed pool |
_frontRunningInterval |
uint32 |
Front running interval for the deployed pool |
_fee |
bytes16 |
Rebalancing fee for the deployed pool |
_mintBurnFee |
bytes16 |
Total fee charged to minters/burners |
_burnFeePercent |
uint16 |
Percentage mint/burn fee charged to burners |
_leverageAmount |
uint16 |
Leverage for the deployed pool |
_feeAddress |
address |
Address of rebalancing fee recipient for the deployed pool |
_quoteToken |
address |
Address of the ERC20 token that the deployed pool uses as the quote asset |
Name | Type | Description |
---|---|---|
address |
Address of the deployed pool |
Name | Type | Indexed? | Description |
---|---|---|---|
pool |
address |
Yes | Address of the deployed pool |
poolCode |
string |
No | Ticker of the deployed pool |
TODO
Name | Type | Description |
---|---|---|
cumulativePrice |
int256 |
Sum of all sample prices for the current interval |
lastSamplePrice |
int256 |
Most recent sample price for the current interval |
executionPrice |
int256 |
Price for the current execution |
lastExecutionPrice |
int256 |
Most recent price an execution occurred at (i.e., preceding executionPrice above) |
count |
uint32 |
Number of samples for the current interval |
updateInterval |
uint32 |
TODO |
roundStart |
uint40 |
TODO |
None.
Visibility | external |
Restricted? | Yes |
Changes the oracle address of the pool keeper
Name | Type | Description |
---|---|---|
oracle |
address |
Address of the new oracle |
None.
Visibility | external |
Restricted? | No |
Creates a new market. This is where both the market ticker and the price oracle are defined.
Name | Type | Description |
---|---|---|
marketCode |
string |
Ticker for new market |
oracle |
address |
Address of price oracle for new market |
None.
Visibility | external |
Restricted? | No |
Creates a new pool in the market specified by
marketCode
.
Name | Type | Description |
---|---|---|
marketCode |
string |
Ticker of the market the new pool belongs to |
poolCode |
string |
Ticker for the new pool |
updateInterval |
uint32 |
Minimum amount of time between price updates |
frontRunningInterval |
uint32 |
Front running interval for the deployed pool |
fee |
bytes16 |
Rebalancing fee for the deployed pool |
mintBurnFee |
bytes16 |
Total fee charged to minters/burners |
burnFeePercent |
uint16 |
Percentage mint/burn fee charged to burners |
leverageAmount |
uint16 |
Leverage for the deployed pool |
feeAddress |
address |
Address of rebalancing fee recipient for the deployed pool |
quoteToken |
address |
Address of the ERC20 token that the deployed pool uses as the quote asset |
None.
Indicates successful creation of a new pool.
Name | Type | Indexed? | Description |
---|---|---|---|
poolAddress |
address |
Yes | Address of the newly-created pool |
firstPrice |
int256 |
Yes | Price reported by the price oracle upon pool creation |
updateInterval |
uint32 |
Yes | Minimum amount of time between price updates for this pool. See TODO |
market |
string |
No | Ticker of the market to which the newly-created pool belongs |
Indicates successful creation of a new market.
Name | Type | Indexed? | Description |
---|---|---|---|
marketCode |
string |
No | Ticker for this market |
oracle |
address |
No | Address of the price oracle for this market |
Indicates that a new round has occurred.
Name | Type | Indexed? | Description |
---|---|---|---|
oldPrice |
int256 |
Yes | Price before this round |
newPrice |
int256 |
Yes | Price after this round began |
updateInterval |
uint32 |
Yes | Minimum amount of time between price updates. See TODO |
market |
string |
No | Ticker for this market |
Indicates a successful price sample.
Name | Type | Indexed? | Description |
---|---|---|---|
cumulativePrice |
int256 |
Yes | Sum of all price samples for the current round |
count |
int256 |
Yes | Number of price samples for the current round. See TODO |
updateInterval |
uint32 |
Yes | Minimum amount of time between price updates. See TODO |
market |
string |
No | Ticker for this market |
Indicates successful price execution.
Name | Type | Indexed? | Description |
---|---|---|---|
oldPrice |
int256 |
Yes | TODO |
newPrice |
int256 |
Yes | TODO |
updateInterval |
uint32 |
Yes | Minimum amount of time between price updates. See TODO |
market |
string |
No | Ticker for this market |
pool |
string |
No | Ticker for this pool |
Indicates a failed pool update.
Name | Type | Indexed? | Description |
---|---|---|---|
poolCode |
string |
Yes | The ticker of the pool |
reason |
string |
No | The reason the pool failed to update |
Library? | No |
Interface? | Yes |
Abstract? | No |
Implements |
None.
Name | Type | Description |
---|---|---|
marketCode |
string |
Ticker of the market in question |
Name | Type | Description |
---|---|---|
int256 |
Price |
Name | Type | Description |
---|---|---|
marketCode |
string |
Ticker of the market in question |
Name | Type | Description |
---|---|---|
address |
Address of the asset oracle for the specified market |
Visibility | external |
Restricted? | Yes |
Name | Type | Description |
---|---|---|
marketCode |
string |
Ticker of the market |
oracle |
address |
Address of the new price oracle |
None.
None.
Library? | No |
Interface? | Yes |
Abstract? | No |
Implements |
An eumerated type describing the type of a commitment.
-
ShortMint
-
ShortBurn
-
LongMint
-
LongBurn
Describes a commitment.
Name | Type | Description |
---|---|---|
maxImbalance |
bytes16 |
TODO |
amount |
uint112 |
Amount being committed to |
commitType |
CommitType |
Type of this commitment |
created |
uint40 |
TODO |
owner |
address |
Address of the owner of the commitment |
Visibility | external |
Restricted? | No |
Initialises a pool.
Required for EIP1167[TODO] compliance.
Note: this function SHOULD only be able to be called once per pool. This is due to the nature of EIP1167.
Name | Type | Description |
---|---|---|
_updater |
address |
TODO |
_longToken |
address |
Address of the long token for this pool |
_shortToken |
address |
Address of the short token for this pool |
_poolCode |
string |
Ticker for this pool |
_frontRunningInteral |
uint32 |
Minimum amount of time before a commitment can be executed |
_fee |
bytes16 |
Fee for moving funds |
_mintBurnFee |
bytes16 |
Total fee charged to minters/burners |
_burnFeePercent |
uint16 |
Percentage mint/burn fee charged to burners |
_leverageAmount |
uint16 |
How leveraged the pool is |
_feeAddress |
address |
Address of the fee recipient |
_quoteToken |
address |
Address of the quote token for this pool |
None.
Visibility | external |
Restricted? | No |
Submits a commitment.
Name | Type | Description |
---|---|---|
commitType |
CommitType |
Type of commitment being submitted |
maxImbalance |
bytes16 |
TODO |
amount |
uint112 |
Amount to commit to |
None.
Visibility | external |
Restricted? | No |
Cancels an existing commitment, specified by commitID
.
Name | Type | Description |
---|---|---|
commitID |
uint256 |
Unique identifier of the commitment |
None.
Visibility | external |
Restricted? | No |
Executes a set of commitments, specified by
commitIDs
.
Name | Type | Description |
---|---|---|
_commitIDs |
uint128[] |
List of unique identifiers of each commitment to be executed |
None.
Visibility | external |
Restricted? | Yes |
Name | Type | Description |
---|---|---|
oldPrice |
int256 |
Price of the previous price change |
newPrice |
int256 |
New price |
None.
Visibility | external |
Restricted? | Yes |
Modifies the address of the fee receiver, setting it to account
.
Name | Type | Description |
---|---|---|
account |
address |
Address of the new fee recipient |
None.
Name | Type | Indexed? | Description |
---|---|---|---|
longToken |
address |
Yes | Address of this pool’s long position token |
shortToken |
address |
Yes | Address of this pool’s short position token |
quoteToken |
address |
No | Address of this pool’s quote token |
poolCode |
string |
No | Ticker of this pool |
Indicates successful creation of a commitment.
Name | Type | Indexed? | Description |
---|---|---|---|
commitID |
uint128 |
Yes | Unique identifier of the commitment |
amount |
uint128 |
Yes | Amount being committed to |
maxImbalance |
bytes16 |
Yes | TODO |
commitType |
CommitType |
No | Type of this commitment |
Indicates successful cancellation of a commitment.
Name | Type | Indexed? | Description |
---|---|---|---|
commitID |
uint128 |
Yes | Unique identifier of the removed commit |
amount |
uint128 |
Yes | Amount removed from the shadow pool |
commitType |
CommitType |
Yes | Type of the removed commit |
Indicates successful execution of a commitment.
Name | Type | Indexed? | Description |
---|---|---|---|
commitID |
uint128 |
No | Unique identifier of the commit in question |
Indicates successful price change.
Name | Type | Indexed? | Description |
---|---|---|---|
startPrice |
int256 |
Yes | Price of last execution |
endPrice |
int256 |
Yes | Price for this execution |
transferAmount |
uint112 |
Yes | Amount moved between pools |
Library? | No |
Interface? | No |
Abstract? | No |
Implements | IPoolFactory |
Name | Type | Visibility | Immutable? | Description |
---|---|---|---|---|
pairTokenBase |
PoolToken |
public |
No | Base token of this pool |
poolBase |
LeveragedPool |
public |
No | Base pool |
None.
None
TODO
TODO
Visibility? | internal |
Restricted? | No |
Deploys a new ERC20-compliant pair token for a pool.
Name | Type | Description |
---|---|---|
owner |
address |
Address of the owner for the ERC20 pair token |
name |
string |
Name of the ERC20 pair token |
symbol |
string |
Ticker of the ERC20 pair token |
Name | Type | Description |
---|---|---|
address |
Address of the ERC20 pair token |
TODO
Library? | No |
Interface? | No |
Abstract? | No |
Implements | IPoolKeeper |
Name | Type | Visibility | Immutable? | Description |
---|---|---|---|---|
pools |
mapping(string => address) |
public |
No | Maps pool tickers to addresses |
poolMarkets |
mapping(string => mapping(uint32 => string)) |
public |
No | Maps pool tickers to mappings which in turn, map update intervals to market tickers |
upkeep |
mapping(string => mapping(uint32 => Upkeep)) |
public |
No | Maps market tickers to mappings which in turn, map update intervals to Upkeep s |
lastExecutionTime |
mapping(string => uint40) |
public |
No | Maps pool tickers to timestamps |
oracleWrapper |
address |
public |
No | Address of the IOracleWrapper for this contract |
factory |
PoolFactory |
public |
Yes | Instance of PoolFactory for this contract |
Name | Type | Value | Description |
---|---|---|---|
fixedPoint |
bytes16 |
0x403abc16d674ec800000000000000000 |
TODO |
ADMIN |
bytes32 |
TODO | Role definition for OpenZeppelin Contracts' access control implementation |
Determines whether upkeep needs to be performed and produces call data in order to do so.
Name | Type | Description |
---|---|---|
checkData |
bytes |
TODO |
Name | Type | Description |
---|---|---|
upkeepNeeded |
bool |
Flag indicating whether upkeep needs to be performed |
performData |
bytes |
Data suitable for passing to TODO |
TODO
Name | Type | Description |
---|---|---|
TODO
See IPoolKeeper.updateOracleWrapper.
See IPoolKeeper.performUpkeep.
Library? | No |
Interface? | No |
Abstract? | No |
Implements | ILeveragedPool , AccessControl , Initializable |
Name |
Type |
Visibility |
Immutable? |
Description |
---|---|---|---|---|
|
|
|
No |
|
|
|
|
No |
|
|
|
|
No |
|
|
|
|
No |
|
|
|
|
No |
|
|
|
|
No |
|
|
|
|
No |
|
|
|
|
No |
|
|
|
|
No |
|
|
|
|
No |
|
|
|
|
No |
|
|
|
|
No |
|
|
|
|
No |
Name | Type | Value | Description |
---|---|---|---|
UPDATER |
bytes32 |
TODO | Role definition for OpenZepellin Contracts' access control implementation |
ADMIN |
bytes32 |
TODO | Role definition for OpenZepellin Contracts' access control implementation |
FEE_HOLDER |
bytes32 |
TODO | Role definition for OpenZepellin Contracts' access control implementation |
None.
See ILeveragedPool.initialize.
See ILeveragedPool.executeCommitment.
See ILeveragedPool.executePriceChange.
See ILeveragedPool.updateFeeAddress.
None.
Library? | No |
Interface? | No |
Abstract? | No |
Implements | IOracleWrapper , AccessControl |
Name | Type | Visibility | Immutable? | Description |
---|---|---|---|---|
assetOracles |
mapping(string => address) |
public |
No | Maps pool tickers to addresses of price oracles. |
Name | Type | Value | Description |
---|---|---|---|
OPERATOR |
bytes32 |
TODO | Role definition for OpenZeppelin Contracts' access control implementation |
ADMIN |
bytes32 |
TODO | Role definition for OpenZeppelin Contracts' access control implementation |
See TODO
TODO
TODO
None.
- Users can commit to mint short or long.
- If users don't uncommit, this commit is then executed [this is true if a keeper does this - But we might not be getting a keeper to do commits to mint/burn anymore].
- At this time, the configurable mint/burn fee mintBurnFee is applied to the minting. It's multiplied out by the configurable burnFeePercent, such that if the mintBurnFee is 0.05 and the burnFeePercent is 0.4 then 0.05*(1-0.4)=0.03.
- This fee is deducted from the amount of tokens to be minted, so that the user is awarded with 1-0.03=0.97
- The proceeds of the fees are placed in the pool to which the tokens are being minted.
- If using dynamic fees, a snapshot is taken of the value for holding both 1 long and 1 short token from the initialization of the pools. If this value is above 2, then the mintBurnFee is reduced based on a function of total token value - 2. If it's below 2, then it's increased in a like manner.
- Users can commit to burn short or long.
- If users don't uncommit, this commit is then executed [this is true if a keeper does this - But we might not be getting a keeper to do commits to mint/burn anymore].
- At this time, the configurable mint/burn fee mintBurnFee is applied to the burning. It's multiplied out by the configurable burnFeePercent, such that if the mintBurnFee is 0.05 and the burnFeePercent is 0.4 then 0.05*0.4=0.02.
- This fee is added from the amount of tokens to be burned, so that the user is now burning more tokens than they would have been for the value with 1+0.02=1.02
- The proceeds of the fees are placed in the pool to which the tokens are being burned.
- If using dynamic fees, a snapshot is taken of the value for holding both 1 long and 1 short token from the initialization of the pools. If this value is above 2, then the mintBurnFee is reduced based on a function of total token value - 2. If it's below 2, then it's increased in a like manner.
TODO
TODO
In an effort to reduce the storage footprint (and thus gas usage) of the Pool Swaps protocol, integers of widths that are not powers of two are used in several places throughout the system.
While this is not a security hazard a priori, great care should be taken to ensure that operations involving these types are correct – especially arithmetic.
-
TODO
-
TODO