GM Index
Brief explanations of all Index functions
Last updated
Brief explanations of all Index functions
Last updated
The core contract stores the Index's parameters, token data, fee data, and is the router for all deposits and withdrawals. It inherits from Open Zeppelin's ERC-20, Ownable, and Pausable contracts. The protocol and token mechanisms are set according to the following functions:
At contract creation, the constructor sets the contract as an ERC20 token and transfers ownership to the msg.sender
. It also stores the deployer-provided _protocolFeeRecipient
address parameter.
Name | Type | Description |
---|---|---|
Pauses functions with whenNotPaused
modifier in case of emergency or unforeseen events. Must be called by the current owner. The current functions that are pausable are deposit
and withdraw
. This is the standard implementation of the Open Zeppelin Pausable contract.
Resumes operation of paused functions with whenNotPaused
modifier to restore the Index to normal operation. Must be called by the current owner. The current functions that are unpausable are deposit
and withdraw
. This is the standard implementation of the Open Zeppelin Pausable contract.
Sets the nominal base fee for deposits and withdrawals that happen when the particular GM token is at its target Index weighting. Must be called by the current owner. The Fee Base cannot be more than 250 basis points (2.5%). An event with the new fee is emitted.
Sets the base tax for deposits and withdrawals that take the particular GM token away from its target Index weighting. Must be called by the current owner. The Tax Base cannot be more than 250 basis points (2.5%). An event with the new tax is emitted.
Sets the minimum fee for deposits and withdrawals. Must be called by the current owner. The Tax Base cannot be more than 100 basis points (1%). An event with the new fee is emitted.
Updates the address to receive a portion of protocol revenue and emits an event with the new address. Must be called by the current owner.
Sets/updates the ratio of fees to be provided as protocol revenue and emits an event with the new ratio. Must be called by the current owner. The fee ratio must be lower than the FEE_DIVISOR
, immutably set to 100% (10,000) at contract creation.
Parameters:
Adds an individual GMX market token to the Index, so that users are able to deposit/withdraw the token. Tokens can only be added by the current owner. After the addition and ensuing deposits, the Index will begin to incorporate the asset’s value, amount changes, and fees generated from the inflows and outflows.
Each token’s data is stored in the Vault
struct, which is accessed via the vaults
mapping. If a token has an active vault, the token cannot be added again to the Index. This is checked by requiring that the token vault’s active
boolean is not set to true.
The token is also added to the treasuryVaults
bytes32 array, which enables the retrieval by name of each individual token currently in the Index.
The token _weight
function parameter is added to the totalTokenWeights
storage variable.
Lastly, this function stores the token’s already deployed Bank contract (see the Bank Contract section for details) in the token’s Vault
data struct. The Index then approves the bank contract to spend up to the uint256
max allowed value of tokens via the deposit
and withdraw
functions.
Updates the oracle variable for a given token inside its vaults
struct and emits an event with the token name and address of the new oracle. Oracles can only be updated by the current owner. If the token’s vault is not active, the function reverts.
Sets or updates the weight of the given token and emits an event with the new weight. Weights can only be set or updated by the current owner. The function call updates the totalTokenWeights
variable with the new weight. The given token’s vault must be active.
Removes the token's position in the treasuryVaults
bytes32 array, sets the token vault’s active Boolean to false, and emits an event. Vaults can only be removed by the current owner. Being able to delete deprecated tokens is a safety measure if the list ever becomes too large.
This function call will revert if the token’s bank still has funds, if the token still has a non-zero weight in the Index, or if the token cannot be found in the treasuryVaults
array.
It is added in case of airdrops or tokens accidentally sent to the Index. Only the current owner can call this function. The owner inputs the IERC20-wrapped token that has been airdropped or sent into the contract. The function loops through the treasuryVaults
array, and if any position matches the input token, then the function reverts. If the entire array has been searched and no match has been found, the tokens are transferred to the _to
address that was also entered as an argument.
Deposits an amount of eligible GM tokens to the Index, which mints a calculated amount of GMI tokens, subtracts a deposit fee, and sends the rest of the GMI to the depositor. Anyone can call this function. If the amount of deposited tokens is zero or the token is not assigned a weight in the Index, then this function will revert. This function is pausable.
In order to determine the amount of GMI to mint, the following values are calculated/retrieved: totalControlledValue
of the Index, the depositTokenValue
of the user’s deposit, the current totalSupply
of GMI tokens, the deposited token’s present _bankBalance
, and the token’s _targetBalance
.
The very first deposit mints an amount of GMI tokens equal to the deposit’s current value. After the first deposit, the mintAmount
is in proportion to the value of the GM tokens deposited versus the total value of the Index.
The fee percentage is calculated by using the FeeUtils.sol library (see Fees section for further info), which compares the token’s before and after bank balances to the targetBalance
.
The feeAmount
, amountOut
, and protocolFeePayment
are calculated as follows:
If the amountOut
is less than the _minAmountOut
, the function will revert.
The GM asset tokens are now finally deposited into the token bank. The protocolFeePayment
in GMI tokens is minted and sent to the protocolFeeRecipient
, and the amountOut
in GMI tokens is minted and sent to the _recipient
address (generally, this is the caller of the function). An event with the token recipient address, token’s name, and amount is emitted.
Withdraws an amount of GM tokens from the Index by burning GMI tokens of the user. Anyone can call this function. If the amount of deposited tokens is zero or the _recipient
address is the zero address, then this function will revert. As previously mentioned, this function is pausable.
In order to determine the amount of GM tokens that can be withdrawn, the following values are calculated/retrieved: totalControlledValue
of the Index, the current price of the token, the withdrawValue
equivalent to the value of the user’s GMI tokens, the current totalSupply
of GMI tokens, the to-be-withdrawn token’s present _bankBalance
, and the token’s _targetBalance
.
The withdrawal value is calculated by multiplying the amount of GMI tokens to be burned by the total current value of the Index, then dividing by the total GMI supply. From this, the withdrawAmount
of the token can be derived.
The fee percentage is calculated by using the FeeUtils.sol library (see Fees section for further info), which compares the token’s before and after bank balances to the targetBalance
.
The feeAmount
, amountOut
, and protocolFeePayment
are calculated as follows:
If the amountOut
is less than the _minAmountOut
, the function will revert.
The user’s _amount
of GMI tokens are then burned, and the amountOut
of GM tokens are sent to the _recipient
. If feeAmount
is non-zero, then it is transferred to the protocolFeeRecipient
from the GM token’s bank.
Parameters:
Returns:
Calculates the fee basis points or percentage for a hypothetical transaction of a certain amount of a given token. The fee percentage is calculated by using the FeeUtils.sol library (see Fees section for further info), which compares the token’s before and after transaction bank balances to the targetBalance
.
In order to calculate the total feeAmount
, the return value of getFeeBasisPoints
needs to be multipled by a mintAmount
or withdrawAmount
, then divided by the FEE_DIVISOR
.
Gets the current target amount of a given Index token, based on the Index’s current weighting of the token. If the total supply of GMI is zero, this function returns zero.
The weight is retrieved from the token’s vault data struct, multiplied by the total supply of GMI tokens, then divided by the total token weight of the Index.
Loops through the treasuryVaults
bytes32 array and calls the controlledValue
helper function for each token (while passing the rounding Boolean through to the helper function) and adds the returned answer to the totalValue
variable.
Calculates the value of a given Index token by multiplying the current bank Balance by the current price (rounded up, converted to 18 decimals), which is retrieved from the token’s oracle in the getPrice()
helper function (passing the rounding Boolean one final time through to the oracle helper function).
Calls getPrice()
on the token’s stored oracle contract and retrieves the price, which is then rounded up if the roundUp
parameter is true and down if the roundUp
parameter is false.
Returns the amount of tokens deposited in the token’s bank for a given Index asset.
Calculates and returns the ideal balance of the given token by dividing the token’s targetValue
(with token decimals factor) by the current price returned by the token’s oracle. The targetValue
is obtained by multiplying the total Index value (after a potential deposit or withdrawal, rounded in a direction determined upstream if called by deposit()
or withdraw()
) by the ratio of the token’s weight to the totalTokenWeights
of the Index.
Returns true if the asset passed in has a non-zero token weight, which, under normal conditions, means it is a deposit token.
Deposits tokens into their respective token bank contract.
Name | Type | Description |
---|---|---|
Name | Type | Description |
---|---|---|
Name | Type | Description |
---|---|---|
Name | Type | Description |
---|---|---|
Name | Type | Description |
---|---|---|
Name | Type | Description |
---|---|---|
Name | Type | Description |
---|---|---|
Name | Type | Description |
---|---|---|
Name | Type | Description |
---|---|---|
Name | Type | Description |
---|---|---|
Name | Type | Description |
---|---|---|
Name | Type | Description |
---|---|---|
Name | Type | Description |
---|---|---|
Name | Type | Description |
---|---|---|
Name | Type | Description |
---|---|---|
Name | Type | Description |
---|---|---|
Name | Type | Description |
---|---|---|
Name | Type | Description |
---|---|---|
Name | Type | Description |
---|---|---|
Name | Type | Description |
---|---|---|
Name | Type | Description |
---|---|---|
Name | Type | Description |
---|---|---|
Name | Type | Description |
---|---|---|
Name | Type | Description |
---|---|---|
Name | Type | Description |
---|---|---|
Name | Type | Description |
---|---|---|
Name | Type | Description |
---|---|---|
Name | Type | Description |
---|---|---|
Name | Type | Description |
---|---|---|
Name | Type | Description |
---|---|---|
_protocolFeeRecipient
address
The address that receives a portion of protocol revenue
_feeBase
uint256
The base fee applied to each deposit and withdrawal
_taxBase
uint256
The base tax applied depending on if the deposit/withdrawal brings the token bank's amount further away from the targetBalance
than it originally was before the transfer
_minFee
uint256
The minimum fee for deposits and withdrawals
_protocolFeeRecipient
address
The address that receives a portion of protocol revenue
_protocolFeeRatio
uint256
The ratio (percentage) of each fee that goes to the protocolFeeRecipient
as revenue
name
bytes32
Name of the asset to be added
_token
IERC20
The IERC20 interface type of the token
_weight
uint256
The weight that the token will be assigned in relation to the total Index’s token weight
oracle
ITokenOracle
The ITokenOracle interface type of the token’s oracle
bank
IBank
The IBank interface type of the token’s bank
name
bytes32
Identifier of the token
oracle
ITokenOracle
The ITokenOracle interface type of the token’s oracle
name
bytes32
Identifier of the token
_weight
uint256
The weight that the token will be assigned in relation to the total Index’s token weight
name
uint256
The name of the asset to be removed from the treasury’s vaults
_token
IERC20
The IERC20 interface type of the given token
_amount
uint256
The amount of tokens to be removed and sent to _to
_to
address
The address that unsupported tokens will be sent to
name
bytes32
Identifier of the token
_recipient
address
The address to send newly minted GMI tokens to
_amount
uint256
The amount of deposit tokens
_minAmountOut
uint256
The minimum amount of GMI tokens to be received
amountOut
uint256
The amount of GMI tokens sent to _recipient
, usually the caller
name
bytes32
Identifier of the token
_amount
uint256
The amount of deposit tokens
_recipient
address
The address to send newly minted GMI tokens to
_minAmountOut
uint256
The amount of GMI tokens sent to _recipient
, usually the caller
amountOut
uint256
The amount of GM tokens calculated and sent to _recipient
name
bytes32
Identifier of the token
_amount
uint256
The amount of the token to be transferred that the caller wants to calculate the fee for
isWithdraw
Boolean
Set to true if the caller wants to calculate the fee for a withdrawal of the input amount of specific tokens. Set to false for deposits.
name
bytes32
Identifier of the token
unnamed
uint256
The target amount of the Index token
roundUp
Boolean
This argument is passed through to the controlledValue
function
totalValue
uint256
The total value of supported tokens that are in the Index (e.g. the total value deposited across all active token banks)
name
bytes32
Identifier of the token
roundUp
Boolean
This argument is passed through to the getPrice()
function
totalValue
uint256
The total value of the given GM token that are in the Index (e.g. deposited in the token's bank)
name
bytes32
Identifier of the token
roundUp
Boolean
Rounds price
up if true, down if false.
price
uint256
The rounded price from the token’s oracle
name
bytes32
Identifier of the token
balance
uint256
The current token balance of the given token’s bank
name
bytes32
Identifier of the token
withdrawal
Boolean
This argument is normally passed in from the controlledValue()
function and controls whether the tokenValue
will be subtracted from or added to the totalControlledValue
tokenValue
uint256
The value of the token to be deposited or withdrawn
roundUp
Boolean
This argument is passed through to the totalControlledValue
function
balance
uint256
The given token’s target balance that puts it in equilibrium with its set weight in the Index
name
bytes32
Identifier of the token
unnamed
Boolean
Resolves to true if the token has non-zero weight, false otherwise
name
bytes32
Identifier of the token
amount
uint256
The amount of tokens to deposit