Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(vpool): Add governance proposal to edit the swap invariant of one or more vpools #1082

Merged
merged 6 commits into from
Nov 24, 2022

Conversation

Unique-Divine
Copy link
Member

@Unique-Divine Unique-Divine commented Nov 24, 2022

Purpose

Change 1 - EditSwapInvariantsProposal

This PR implements a proposal type that maps one or more trading pairs to corresponding multiplers on the swap invariant. The multiplier then changes the virtual reserves in-place without altering the mark price.

$$ \begin{gather} \text{markPrice} = \frac{y}{x} \\ k := x y \\ \text{newMarkPrice} = \frac{cy}{cx} = \text{markPrice} \\ \text{newK} = (cx)(cy) = c^2xy = c^2 k \end{gather} $$

The "multiplier" is $c^2$. Notice this implies that a multipying both the base and quote reserves by $c$ results in the new value for $k$ without changing price.

This logic is implemented in vpool/keeper/pool_state.go in the EditSwapInvariant function. The function and its governance proposal have related unit tests, types tests, marshalling tests, and a CLI test.

A nice perk of this is we won't need to keep updating the script to get a more accurate mark price.

Change 2 - Lower default reserves in localnet.sh

Case A - Online

If the CoinGecko query works via cURL, localnet.sh will instead grab the ETH and BTC price from this free endpoint and use that to initialize the reserves.

The initial value is chosen from an estimate of how large y should be given some number of traders and size of NUSD the faucet gives.

  local num_users=24000
  local faucet_nusd_amt=100 
  local quote_amt=$(($num_users / 2 * $faucet_nusd_amt * $M)) 

  price_btc=$(cat tmp_vpool_prices.json | jq -r '.bitcoin.usd')
  price_btc=${price_btc%.*}
  base_amt_btc=$(($quote_amt / $price_btc))

The thinking here is to make the pool just big enough that everyone in our Discord (for example) could use the faucet and try to change the reserves of the pool but make it no bigger than that. At least this way, users will be able to see the price change a bit when they open positions.

Case B - Offline

The default reserves are set with y=1e10 (unusd) as the starting point if the script is run offline.

add_genesis_vpools_default() {
  # nibid add-genesis-vpool [pair] [base-asset-reserve] [quote-asset-reserve] [trade-limit-ratio] [fluctuation-limit-ratio] [maxOracle-spread-ratio] [maintenance-margin-ratio] [max-leverage]
  local KILO="000"
  local MEGA="000000"
  local quote_amt=10$KILO$MEGA
  local base_amt_btc=$(($quote_amt / 16500)) # BTC price of $16,500
  local base_amt_eth=$(($quote_amt / 1200)) # ETH price of $1200
  nibid add-genesis-vpool ubtc:unusd $base_amt_btc $quote_amt  0.1 0.1 0.1 0.0625 12
  nibid add-genesis-vpool ueth:unusd $base_amt_eth $quote_amt 0.1 0.1 0.1 0.0625 10
}

@Unique-Divine Unique-Divine linked an issue Nov 24, 2022 that may be closed by this pull request
@Unique-Divine Unique-Divine marked this pull request as ready for review November 24, 2022 18:47
@Unique-Divine Unique-Divine requested a review from a team as a code owner November 24, 2022 18:47
@matthiasmatt
Copy link
Contributor

matthiasmatt commented Nov 24, 2022

As I said to @Unique-Divine, i think making our changes in k public through votation opens a possibility of making money for the traders (at the expense of the protocol):

take for example:

Pool state t0:

  • x = 10k unusd
  • y = 0.625 btc
  • k = 6,250
  • Mark price is 16k

Alice open a long position for ~2k -> mark price to 20k. If i close it now, slippage means i get nothing.

New proposal, Change in k for the pool, new k is 100x bigger:

Pool state t1:

  • x = 1M unusd
  • y = 62,5 btc
  • k = 625,000
  • Mark price is 16k

close a position -> no slippage, i get 2k for free.

If i time this just before the proposal passes, i can actually open long positions for every block before the change with multiple wallets and heavily modify the price between mark and index to collect free money with the slippage

@Unique-Divine
Copy link
Member Author

Unique-Divine commented Nov 24, 2022

This is only for testnet, not live markets.

Since there's no repegging or anything to go with this feature right now, it should just be thought of as a temporary utility function for changing k without resetting the chain.

We may be able to use the keeper function and type later when the dynamic updates have a finished spec.

20*time.Second,
2*time.Second,
"proposal should pass after voting period")
s.PassGovProposal()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❤️

@NibiruHeisenberg NibiruHeisenberg merged commit 4ba2a5c into master Nov 24, 2022
@NibiruHeisenberg NibiruHeisenberg deleted the 1071-featperp-define-good-k-values-for-pools branch November 24, 2022 22:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

feat(perp): define good k values for pools
3 participants