Skip to content

Commit

Permalink
slinky's market map generation in genesis
Browse files Browse the repository at this point in the history
  • Loading branch information
pr0n00gler committed Jul 5, 2024
1 parent 2f49cce commit 47f1a65
Show file tree
Hide file tree
Showing 2 changed files with 122 additions and 1 deletion.
24 changes: 23 additions & 1 deletion network/init-neutrond.sh
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,12 @@ CW4_GROUP_CONTRACT=$THIRD_PARTY_CONTRACTS_DIR/cw4_group.wasm

NEUTRON_CHAIN_MANAGER_CONTRACT=$CONTRACTS_BINARIES_DIR/neutron_chain_manager.wasm

# Slinky genesis configs
USE_CORE_MARKETS=true
USE_RAYDIUM_MARKETS=false
USE_UNISWAPV3_BASE_MARKETS=false
USE_COINGECKO_MARKETS=false

echo "Add consumer section..."
$BINARY add-consumer-section --home "$CHAIN_DIR"
### PARAMETERS SECTION
Expand Down Expand Up @@ -719,12 +725,28 @@ function convert_bech32_base64_esc() {
DAO_CONTRACT_ADDRESS_B64=$(convert_bech32_base64_esc "$DAO_CONTRACT_ADDRESS")
echo $DAO_CONTRACT_ADDRESS_B64

echo "Adding marketmap into genesis..."
go run network/slinky_genesis.go --use-core=$USE_CORE_MARKETS --use-raydium=$USE_RAYDIUM_MARKETS --use-uniswapv3-base=$USE_UNISWAPV3_BASE_MARKETS --use-coingecko=$USE_COINGECKO_MARKETS --temp-file=markets.json
MARKETS=$(cat markets.json)

NUM_MARKETS=$(echo "$MARKETS" | jq '.markets | length + 1')

NUM_MARKETS=$NUM_MARKETS; jq --arg num "$NUM_MARKETS" '.app_state["oracle"]["next_id"] = $num' "$GENESIS_PATH" > genesis_tmp.json && mv genesis_tmp.json "$GENESIS_PATH"
MARKETS=$MARKETS; jq --arg markets "$MARKETS" '.app_state["marketmap"]["market_map"] = ($markets | fromjson)' "$GENESIS_PATH" > genesis_tmp.json && mv genesis_tmp.json "$GENESIS_PATH"
jq '.app_state["marketmap"]["last_updated"] = 1' "$GENESIS_PATH" > genesis_tmp.json && mv genesis_tmp.json "$GENESIS_PATH"
MARKETS=$MARKETS; jq --arg markets "$MARKETS" '.app_state["oracle"]["currency_pair_genesis"] += [$markets | fromjson | .markets | values | .[].ticker.currency_pair | {"currency_pair": {"Base": .Base, "Quote": .Quote}, "currency_pair_price": null, "nonce": 0} ]' "$GENESIS_PATH" > genesis_tmp.json && mv genesis_tmp.json "$GENESIS_PATH"
MARKETS=$MARKETS; jq --arg markets "$MARKETS" '.app_state["oracle"]["currency_pair_genesis"] |= (to_entries | map(.value += {id: (.key + 1)} | .value))' "$GENESIS_PATH" > genesis_tmp.json && mv genesis_tmp.json "$GENESIS_PATH"

cat markets.json

rm markets.json

echo "Setting the rest of Neutron genesis params..."
set_genesis_param admins "[\"$NEUTRON_CHAIN_MANAGER_CONTRACT_ADDRESS\"]" # admin module
set_genesis_param treasury_address "\"$DAO_CONTRACT_ADDRESS\"" # feeburner
set_genesis_param fee_collector_address "\"$DAO_CONTRACT_ADDRESS\"," # tokenfactory
set_genesis_param security_address "\"$SECURITY_SUBDAO_CORE_CONTRACT_ADDRESS\"," # cron
set_genesis_param limit 5 # cron
#set_genesis_param allow_messages "[\"*\"]" # interchainaccounts
set_genesis_param signed_blocks_window "\"$SLASHING_SIGNED_BLOCKS_WINDOW\"," # slashing
set_genesis_param min_signed_per_window "\"$SLASHING_MIN_SIGNED\"," # slashing
set_genesis_param slash_fraction_double_sign "\"$SLASHING_FRACTION_DOUBLE_SIGN\"," # slashing
Expand Down
99 changes: 99 additions & 0 deletions network/slinky_genesis.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
// copypasted from: https://github.com/skip-mev/slinky/blob/main/scripts/genesis.go

package main

import (
"flag"
"fmt"

"github.com/skip-mev/slinky/cmd/constants"
mmtypes "github.com/skip-mev/slinky/x/marketmap/types"
)

var (
useCore = flag.Bool("use-core", false, "use core markets")
useRaydium = flag.Bool("use-raydium", false, "use raydium markets")
useUniswapV3Base = flag.Bool("use-uniswapv3-base", false, "use uniswapv3 base markets")
useCoinGecko = flag.Bool("use-coingecko", false, "use coingecko markets")
tempFile = flag.String("temp-file", "markets.json", "temporary file to store the market map")
)

func main() {
// Based on the flags, we determine what market.json to configure. By default, we use Core markets.
// If the user specifies a different market.json, we use that instead.
flag.Parse()

marketMap := mmtypes.MarketMap{
Markets: make(map[string]mmtypes.Market),
}

if *useCore {
fmt.Fprintf(flag.CommandLine.Output(), "Using core markets\n")
marketMap = mergeMarketMaps(marketMap, constants.CoreMarketMap)
}

if *useRaydium {
fmt.Fprintf(flag.CommandLine.Output(), "Using raydium markets\n")
marketMap = mergeMarketMaps(marketMap, constants.RaydiumMarketMap)
}

if *useUniswapV3Base {
fmt.Fprintf(flag.CommandLine.Output(), "Using uniswapv3 base markets\n")
marketMap = mergeMarketMaps(marketMap, constants.UniswapV3BaseMarketMap)
}

if *useCoinGecko {
fmt.Fprintf(flag.CommandLine.Output(), "Using coingecko markets\n")
marketMap = mergeMarketMaps(marketMap, constants.CoinGeckoMarketMap)
}

if err := marketMap.ValidateBasic(); err != nil {
fmt.Fprintf(flag.CommandLine.Output(), "failed to validate market map: %s\n", err)
panic(err)
}

// Write the market map to the temporary file.
if *tempFile == "" {
fmt.Fprintf(flag.CommandLine.Output(), "temp file cannot be empty\n")
panic("temp file cannot be empty")
}

if err := mmtypes.WriteMarketMapToFile(marketMap, *tempFile); err != nil {
fmt.Fprintf(flag.CommandLine.Output(), "failed to write market map to file: %s\n", err)
panic(err)
}
}

// mergeMarketMaps merges the two market maps together. If a market already exists in one of the maps, we
// merge based on the provider set.
func mergeMarketMaps(this, other mmtypes.MarketMap) mmtypes.MarketMap {
for name, otherMarket := range other.Markets {
// If the market does not exist in this map, we add it.
thisMarket, ok := this.Markets[name]
if !ok {
this.Markets[name] = otherMarket
continue
}

seen := make(map[string]struct{})
for _, provider := range thisMarket.ProviderConfigs {
key := providerConfigToKey(provider)
seen[key] = struct{}{}
}

for _, provider := range otherMarket.ProviderConfigs {
key := providerConfigToKey(provider)
if _, ok := seen[key]; !ok {
thisMarket.ProviderConfigs = append(thisMarket.ProviderConfigs, provider)
}
}

this.Markets[name] = thisMarket
}

return this
}

func providerConfigToKey(cfg mmtypes.ProviderConfig) string {
return cfg.Name + cfg.OffChainTicker
}

0 comments on commit 47f1a65

Please sign in to comment.