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: slinky's market map generation in genesis #614

Merged
merged 4 commits into from
Jul 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 20 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=${USE_CORE_MARKETS:-true}
USE_RAYDIUM_MARKETS=${USE_RAYDIUM_MARKETS:-false}
USE_UNISWAPV3_BASE_MARKETS=${USE_UNISWAPV3_BASE_MARKETS:-false}
USE_COINGECKO_MARKETS=${USE_COINGECKO_MARKETS:-false}

echo "Add consumer section..."
$BINARY add-consumer-section --home "$CHAIN_DIR"
### PARAMETERS SECTION
Expand Down Expand Up @@ -719,12 +725,25 @@ 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"
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"

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
}
Loading