Skip to content

Commit

Permalink
use pricing from dex
Browse files Browse the repository at this point in the history
  • Loading branch information
lazynina committed Oct 29, 2024
1 parent 1235c07 commit 1fc58b7
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 47 deletions.
50 changes: 39 additions & 11 deletions routes/base.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,10 +130,12 @@ func (fes *APIServer) GetExchangeRate(ww http.ResponseWriter, rr *http.Request)
}

func (fes *APIServer) GetExchangeDeSoPrice() uint64 {
if fes.UsdCentsPerDeSoExchangeRate > fes.USDCentsToDESOReserveExchangeRate {
return fes.UsdCentsPerDeSoExchangeRate
}
return fes.USDCentsToDESOReserveExchangeRate
// We no longer observe a reserve rate.
return fes.MostRecentDesoDexPriceUSDCents
//if fes.UsdCentsPerDeSoExchangeRate > fes.USDCentsToDESOReserveExchangeRate {
// return fes.UsdCentsPerDeSoExchangeRate
//}
//return fes.USDCentsToDESOReserveExchangeRate
}

type BlockchainDeSoTickerResponse struct {
Expand Down Expand Up @@ -261,14 +263,14 @@ type GateTickerResponse struct {
Low24H string `json:"low_24h"`
}

var currencyPair string
type currencyPair string

const (
GATE_DESO_USDT = "deso_usdt"
GATE_USDT_USD = "usdt_usd"
GateDesoUsdt currencyPair = "deso_usdt"
GateUsdtUsd currencyPair = "usdt_usd"
)

func getTickerResponseFromGate(currencyPair string) (*GateTickerResponse, error) {
func getTickerResponseFromGate(currencyPair currencyPair) (*GateTickerResponse, error) {
httpClient := &http.Client{}
url := fmt.Sprintf("https://api.gateio.ws/api/v4/spot/tickers?currency_pair=%v", currencyPair)
req, err := http.NewRequest("GET", url, nil)
Expand Down Expand Up @@ -302,12 +304,12 @@ func getTickerResponseFromGate(currencyPair string) (*GateTickerResponse, error)
}

func (fes *APIServer) GetGateExchangeRate() (_exchangeRate float64, _err error) {
desoToUSDTTickerResponse, err := getTickerResponseFromGate(GATE_DESO_USDT)
desoToUSDTTickerResponse, err := getTickerResponseFromGate(GateDesoUsdt)
if err != nil {
glog.Errorf("GetGateExchangeRate: Problem fetching exchange rate from gate: %v", err)
return 0, err
}
usdtToUSDTickerResponse, err := getTickerResponseFromGate(GATE_USDT_USD)
usdtToUSDTickerResponse, err := getTickerResponseFromGate(GateUsdtUsd)
if err != nil {
glog.Errorf("GetGateExchangeRate: Problem fetching exchange rate from gate: %v", err)
return 0, err
Expand All @@ -333,6 +335,25 @@ func (fes *APIServer) GetGateExchangeRate() (_exchangeRate float64, _err error)
return usdCentsToDESOExchangePrice, nil
}

func (fes *APIServer) GetExchangeRateFromDeSoDex() (float64, error) {
utxoView, err := fes.backendServer.GetMempool().GetAugmentedUniversalView()
if err != nil {
return 0, err
}
usdcProfileEntry := utxoView.GetProfileEntryForUsername([]byte("dusdc_"))
if usdcProfileEntry == nil {
return 0, fmt.Errorf("GetExchangeRateFromDeSoDex: Could not find profile entry for dusdc_")
}

usdcPKID := utxoView.GetPKIDForPublicKey(usdcProfileEntry.PublicKey)

midPriceDESO, _, _, err := fes.GetHighestBidAndLowestAskPriceFromPKIDs(&lib.ZeroPKID, usdcPKID.PKID, utxoView, 0)
if err != nil {
return 0, err
}
return midPriceDESO, nil
}

// UpdateUSDCentsToDeSoExchangeRate updates app state's USD Cents per DeSo value
func (fes *APIServer) UpdateUSDCentsToDeSoExchangeRate() {
glog.V(2).Info("Refreshing exchange rate...")
Expand All @@ -358,8 +379,14 @@ func (fes *APIServer) UpdateUSDCentsToDeSoExchangeRate() {
glog.Errorf("UpdateUSDCentsToDeSoExchangeRate: Error fetching exchange rate from gate: %v", err)
}

desoDexPrice, err := fes.GetExchangeRateFromDeSoDex()
glog.V(2).Infof("DeSoDex price (USD Cents): %v", desoDexPrice)
if err != nil {
glog.Errorf("UpdateUSDCentsToDeSoExchangeRate: Error fetching exchange rate from DeSoDex: %v", err)
}

// Take the max
lastTradePrice, err := stats.Max([]float64{blockchainDotComPrice, gatePrice})
lastTradePrice, err := stats.Max([]float64{blockchainDotComPrice, gatePrice, desoDexPrice})

// store the most recent exchange prices
// For now, we are using gate.io as the primary exchange
Expand All @@ -368,6 +395,7 @@ func (fes *APIServer) UpdateUSDCentsToDeSoExchangeRate() {
fes.MostRecentCoinbasePriceUSDCents = uint64(gatePrice)
fes.MostRecentBlockchainDotComPriceUSDCents = uint64(blockchainDotComPrice)
fes.MostRecentGatePriceUSDCents = uint64(gatePrice)
fes.MostRecentDesoDexPriceUSDCents = uint64(desoDexPrice)

// Get the current timestamp and append the current last trade price to the LastTradeDeSoPriceHistory slice
timestamp := uint64(time.Now().UnixNano())
Expand Down
94 changes: 58 additions & 36 deletions routes/dao_coin_exchange_with_fees.go
Original file line number Diff line number Diff line change
Expand Up @@ -954,54 +954,24 @@ func (fes *APIServer) GetQuoteCurrencyPriceInUsd(
if desoUsdCents == 0 {
return "", "", "", fmt.Errorf("GetQuoteCurrencyPriceInUsd: Coinbase DESO price is zero")
}

pkid := utxoView.GetPKIDForPublicKey(pkBytes)
if pkid == nil {
return "", "", "", fmt.Errorf("GetQuoteCurrencyPriceInUsd: Error getting pkid for public key %v",
quoteCurrencyPublicKey)
}
ordersBuyingCoin1, err := utxoView.GetAllDAOCoinLimitOrdersForThisDAOCoinPair(
&lib.ZeroPKID, pkid.PKID)
if err != nil {
return "", "", "", fmt.Errorf("GetDAOCoinLimitOrders: Error getting limit orders: %v", err)
}
ordersBuyingCoin2, err := utxoView.GetAllDAOCoinLimitOrdersForThisDAOCoinPair(
pkid.PKID, &lib.ZeroPKID)
if err != nil {
return "", "", "", fmt.Errorf("GetDAOCoinLimitOrders: Error getting limit orders: %v", err)
}
allOrders := append(ordersBuyingCoin1, ordersBuyingCoin2...)
// Find the highest bid price and the lowest ask price
highestBidPrice := float64(0.0)
if lowerUsername == "focus" {
highestBidPrice = float64(FOCUS_FLOOR_PRICE_DESO_NANOS) / float64(lib.NanosPerUnit)
}
lowestAskPrice := math.MaxFloat64
for _, order := range allOrders {
priceStr, err := CalculatePriceStringFromScaledExchangeRate(
lib.PkToString(order.BuyingDAOCoinCreatorPKID[:], fes.Params),
lib.PkToString(order.SellingDAOCoinCreatorPKID[:], fes.Params),
order.ScaledExchangeRateCoinsToSellPerCoinToBuy,
DAOCoinLimitOrderOperationTypeString(order.OperationType.String()))
if err != nil {
return "", "", "", fmt.Errorf("GetQuoteCurrencyPriceInUsd: Error calculating price: %v", err)
}
priceFloat, err := strconv.ParseFloat(priceStr, 64)
if err != nil {
return "", "", "", fmt.Errorf("GetQuoteCurrencyPriceInUsd: Error parsing price: %v", err)
}
if order.OperationType == lib.DAOCoinLimitOrderOperationTypeBID &&
priceFloat > highestBidPrice {

highestBidPrice = priceFloat
}
if order.OperationType == lib.DAOCoinLimitOrderOperationTypeASK &&
priceFloat < lowestAskPrice {

lowestAskPrice = priceFloat
}
var lowestAskPrice, midPriceDeso float64
midPriceDeso, highestBidPrice, lowestAskPrice, err = fes.GetHighestBidAndLowestAskPriceFromPKIDs(
pkid.PKID, &lib.ZeroPKID, utxoView, highestBidPrice)
if err != nil {
return "", "", "", fmt.Errorf("GetQuoteCurrencyPriceInUsd: Error getting price: %v", err)
}
if highestBidPrice != 0.0 && lowestAskPrice != math.MaxFloat64 {
midPriceDeso := (highestBidPrice + lowestAskPrice) / 2.0
midPriceUsd := midPriceDeso * float64(desoUsdCents) / 100

return fmt.Sprintf("%0.9f", midPriceUsd),
Expand All @@ -1018,6 +988,58 @@ func (fes *APIServer) GetQuoteCurrencyPriceInUsd(
quoteCurrencyPublicKey)
}

func (fes *APIServer) GetHighestBidAndLowestAskPriceFromPKIDs(
coin1PKID *lib.PKID,
coin2PKID *lib.PKID,
utxoView *lib.UtxoView,
initialHighestBidPrice float64,
) (float64, float64, float64, error) {
ordersBuyingCoin1, err := utxoView.GetAllDAOCoinLimitOrdersForThisDAOCoinPair(
coin1PKID, coin2PKID)
if err != nil {
return 0, 0, 0, fmt.Errorf("GetDAOCoinLimitOrders: Error getting limit orders: %v", err)
}
ordersBuyingCoin2, err := utxoView.GetAllDAOCoinLimitOrdersForThisDAOCoinPair(
coin2PKID, coin1PKID)
if err != nil {
return 0, 0, 0, fmt.Errorf("GetDAOCoinLimitOrders: Error getting limit orders: %v", err)
}
allOrders := append(ordersBuyingCoin1, ordersBuyingCoin2...)
// Find the highest bid price and the lowest ask price
highestBidPrice := initialHighestBidPrice
lowestAskPrice := math.MaxFloat64
for _, order := range allOrders {
priceStr, err := CalculatePriceStringFromScaledExchangeRate(
lib.PkToString(order.BuyingDAOCoinCreatorPKID[:], fes.Params),
lib.PkToString(order.SellingDAOCoinCreatorPKID[:], fes.Params),
order.ScaledExchangeRateCoinsToSellPerCoinToBuy,
DAOCoinLimitOrderOperationTypeString(order.OperationType.String()))
if err != nil {
return 0, 0, 0, fmt.Errorf("GetQuoteCurrencyPriceInUsd: Error calculating price: %v", err)
}
priceFloat, err := strconv.ParseFloat(priceStr, 64)
if err != nil {
return 0, 0, 0, fmt.Errorf("GetQuoteCurrencyPriceInUsd: Error parsing price: %v", err)
}
if order.OperationType == lib.DAOCoinLimitOrderOperationTypeBID &&
priceFloat > highestBidPrice {

highestBidPrice = priceFloat
}
if order.OperationType == lib.DAOCoinLimitOrderOperationTypeASK &&
priceFloat < lowestAskPrice {

lowestAskPrice = priceFloat
}
}
if highestBidPrice != 0.0 && lowestAskPrice != math.MaxFloat64 {
midPrice := (highestBidPrice + lowestAskPrice) / 2.0

return midPrice, highestBidPrice, lowestAskPrice, nil
}
return 0, 0, 0, fmt.Errorf("GetQuoteCurrencyPriceInUsd: Error calculating price")
}

func (fes *APIServer) CreateMarketOrLimitOrder(
isMarketOrder bool,
request *DAOCoinLimitOrderCreationRequest,
Expand Down
1 change: 1 addition & 0 deletions routes/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,7 @@ type APIServer struct {
MostRecentCoinbasePriceUSDCents uint64
MostRecentBlockchainDotComPriceUSDCents uint64
MostRecentGatePriceUSDCents uint64
MostRecentDesoDexPriceUSDCents uint64

// Base-58 prefix to check for to determine if a string could be a public key.
PublicKeyBase58Prefix string
Expand Down

0 comments on commit 1fc58b7

Please sign in to comment.