stat

package
v0.8.6 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 2, 2023 License: MIT Imports: 5 Imported by: 1

Documentation

Overview

stat provides support for statistics for various common DeFi primitives on aptos

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type CoinStat

type CoinStat struct {
	// MoveTypeTag is the canonical identifier for the coin.
	MoveTypeTag *aptos.MoveStructTag
	// Decimals of the coin.
	Decimals uint8
	// CoinRegistry is the Hippo Coin Registry
	CoinRegistry *known.HippoCoinRegistryEntry
	// IsStable tells if the coin is stable or not. This is provided by the user.
	IsStable bool
	// Name of the coin. If CoinRegistry is not nil, this is from the registry, otherwise it's from the name on chain with (Not Hippo) appended.
	Name string
	// Symbol of the coin. If CoinRegistry is not nil, this is from the registry, otherwise it's from the symbol on chain with (Not Hippo) appended.
	Symbol string
	// If the information is from hippo or not
	IsHippo bool

	// Price of the coin
	Price float64
	// TotalQuantity is the total quantity of the coin.
	TotalQuantity uint64
	// TotalValue of the coin.
	TotalValue float64
}

CoinStat contains the stat for a coin locked into a protocol.

type ConstantProductPool

type ConstantProductPool struct {
	Coin0        *aptos.MoveStructTag
	Coin0Reserve uint64
	Coin0Value   float64

	Coin1        *aptos.MoveStructTag
	Coin1Reserve uint64
	Coin1Value   float64

	TotalValueLocked float64
}

ConstantProductPool contains stats of the constant product pool.

Example (Aux)

ExampleConstantProductPool shows an example of how to query the constant product pool of a protocol on chain (for aux.exchange)

package main

import (
	"bytes"
	"context"
	"encoding/json"
	"fmt"
	"os"

	"github.com/fardream/go-aptos/aptos"
	"github.com/fardream/go-aptos/aptos/known"
	"github.com/fardream/go-aptos/aptos/stat"
	"github.com/google/go-cmp/cmp"
)

var auxUsdSymbols = []string{
	"USDC",
	"USDCso",
	"USDT",
	"ceUSDC",
	"ceDAI",
	"ceUSDT",
	"zUSDC",
	"zUSDT",
	"BUSD",
	"ceBUSD",
	"zBUSD",
}

// ExampleConstantProductPool shows an example of how to query the constant product pool of a protocol on chain (for aux.exchange)
func main() {
	client, _ := aptos.NewClient(aptos.Mainnet, "")
	auxConfig, _ := aptos.GetAuxClientConfig(aptos.Mainnet)

	resp, err := client.GetAccountResources(context.Background(), &aptos.GetAccountResourcesRequest{
		Address: auxConfig.Address,
	})
	if err != nil {
		panic(err)
	}
	protocol := stat.NewStatForConstantProductPool()

	known.ReloadHippoCoinRegistry(known.HippoCoinRegistryUrl)

	for _, usdSymbol := range auxUsdSymbols {
		stable := known.GetCoinInfoBySymbol(aptos.Mainnet, usdSymbol)
		if stable != nil {
			protocol.AddStableCoins(stable.TokenType.Type)
		}
	}

	for _, resource := range *resp.Parsed {
		resourceType := resource.Type

		if resourceType.Module == "amm" && resourceType.Name == "Pool" && cmp.Equal(auxConfig.Address, resourceType.Address) {
			var amm aptos.AuxAmmPool
			if err := json.Unmarshal(resource.Data, &amm); err != nil {
				fmt.Printf("failed to parse %s due to %v\n", string(resource.Data), err)
				continue
			}
			protocol.AddSinglePool(resourceType.GenericTypeParameters[0].Struct, uint64(amm.XReserve.Value), resourceType.GenericTypeParameters[1].Struct, uint64(amm.YReserve.Value))
		}
	}

	protocol.FillCoinInfo(context.Background(), aptos.Mainnet, client)

	protocol.FillStat()

	var coinBuf bytes.Buffer

	fmt.Fprintln(&coinBuf, "Coin Type, Coin Symbol, Coin Name, Coin Decimal, Total Reserve, Price, Total Value, IsHippo")

	for _, coin := range protocol.Coins {
		isHippo := 0
		if coin.IsHippo {
			isHippo = 1
		}

		fmt.Fprintf(&coinBuf, "%s,%s,%s,%d,%d,%f,%f,%d\n", coin.MoveTypeTag.String(), coin.Symbol, coin.Name, coin.Decimals, coin.TotalQuantity, coin.Price, coin.TotalValue, isHippo)
	}

	fmt.Fprint(os.Stderr, coinBuf.String())

	var poolBuf bytes.Buffer

	fmt.Fprint(&poolBuf, "Coin 0 Type, Coin 0 Symbol, Coin 0 Is Hippo, Coin 0 Decimal, Coin 0 Reserve, Coin 0 Price, Coin 0 Value,")
	fmt.Fprint(&poolBuf, "Coin 1 Type, Coin 1 Symbol, Coin 1 Is Hippo, Coin 1 Decimal, Coin 1 Reserve, Coin 1 Price, Coin 1 Value,")
	fmt.Fprintln(&poolBuf, "Total Value")

	for _, pool := range protocol.Pools {
		coin0Name := pool.Coin0.String()
		coin0Info := protocol.Coins[coin0Name]
		coin0IsHippo := 0
		if coin0Info.IsHippo {
			coin0IsHippo = 1
		}
		fmt.Fprintf(&poolBuf, "%s,%s,%d,%d,%d,%f,%f,", coin0Name, coin0Info.Symbol, coin0IsHippo, coin0Info.Decimals, pool.Coin0Reserve, coin0Info.Price, pool.Coin0Value)

		coin1Name := pool.Coin1.String()
		coin1Info := protocol.Coins[coin1Name]
		coin1IsHippo := 0
		if coin1Info.IsHippo {
			coin1IsHippo = 1
		}
		fmt.Fprintf(&poolBuf, "%s,%s,%d,%d,%d,%f,%f,", coin1Name, coin1Info.Symbol, coin1IsHippo, coin1Info.Decimals, pool.Coin1Reserve, coin1Info.Price, pool.Coin1Value)

		fmt.Fprintf(&poolBuf, "%f\n", pool.TotalValueLocked)
	}

	fmt.Fprint(os.Stderr, poolBuf.String())

}
Output:

Example (Liquidswap)

ExampleConstantProductPool shows an example of how to query the constant product pool of a protocol on chain (for aux.exchange)

package main

import (
	"bytes"
	"context"
	"encoding/json"
	"fmt"
	"os"

	"github.com/fardream/go-aptos/aptos"
	"github.com/fardream/go-aptos/aptos/known"
	"github.com/fardream/go-aptos/aptos/stat"
)

var liquidSwapUsdSymbols = []string{
	"USDC",
	"USDCso",
	"USDT",
	"ceUSDC",
	"ceDAI",
	"ceUSDT",
	"zUSDC",
	"zUSDT",
	"BUSD",
	"ceBUSD",
	"zBUSD",
}

type LiquidSwapLiquidityPool struct {
	CoinXReserve aptos.Coin `json:"coin_x_reserve"`
	CoinYReserve aptos.Coin `json:"coin_y_reserve"`
}

// ExampleConstantProductPool shows an example of how to query the constant product pool of a protocol on chain (for aux.exchange)
func main() {
	client, _ := aptos.NewClient(aptos.Mainnet, "")

	resp, err := client.GetAccountResources(context.Background(), &aptos.GetAccountResourcesRequest{
		Address: aptos.MustParseAddress("0x05a97986a9d031c4567e15b797be516910cfcb4156312482efc6a19c0a30c948"),
	})
	if err != nil {
		panic(err)
	}
	protocol := stat.NewStatForConstantProductPool()

	known.ReloadHippoCoinRegistry(known.HippoCoinRegistryUrl)

	for _, usdSymbol := range liquidSwapUsdSymbols {
		stable := known.GetCoinInfoBySymbol(aptos.Mainnet, usdSymbol)
		if stable != nil {
			protocol.AddStableCoins(stable.TokenType.Type)
		}
	}

	for _, resource := range *resp.Parsed {
		resourceType := resource.Type

		if resourceType.Module == "liquidity_pool" && resourceType.Name == "LiquidityPool" {
			var amm LiquidSwapLiquidityPool
			if err := json.Unmarshal(resource.Data, &amm); err != nil {
				fmt.Printf("failed to parse %s: %s\n", string(resource.Data), err.Error())
				continue
			}
			protocol.AddSinglePool(resourceType.GenericTypeParameters[0].Struct, uint64(amm.CoinXReserve.Value), resourceType.GenericTypeParameters[1].Struct, uint64(amm.CoinYReserve.Value))
		}
	}

	protocol.FillCoinInfo(context.Background(), aptos.Mainnet, client)

	protocol.FillStat()

	var coinBuf bytes.Buffer

	fmt.Fprintln(&coinBuf, "Coin Type, Coin Symbol, Coin Name, Coin Decimal, Total Reserve, Price, Total Value, IsHippo")

	for _, coin := range protocol.Coins {
		isHippo := 0
		if coin.IsHippo {
			isHippo = 1
		}

		fmt.Fprintf(&coinBuf, "%s,%s,%s,%d,%d,%f,%f,%d\n", coin.MoveTypeTag.String(), coin.Symbol, coin.Name, coin.Decimals, coin.TotalQuantity, coin.Price, coin.TotalValue, isHippo)
	}

	fmt.Fprint(os.Stderr, coinBuf.String())

	var poolBuf bytes.Buffer

	fmt.Fprint(&poolBuf, "Coin 0 Type, Coin 0 Symbol, Coin 0 Is Hippo, Coin 0 Decimal, Coin 0 Reserve, Coin 0 Price, Coin 0 Value,")
	fmt.Fprint(&poolBuf, "Coin 1 Type, Coin 1 Symbol, Coin 1 Is Hippo, Coin 1 Decimal, Coin 1 Reserve, Coin 1 Price, Coin 1 Value,")
	fmt.Fprintln(&poolBuf, "Total Value")

	for _, pool := range protocol.Pools {
		coin0Name := pool.Coin0.String()
		coin0Info := protocol.Coins[coin0Name]
		coin0IsHippo := 0
		if coin0Info.IsHippo {
			coin0IsHippo = 1
		}
		fmt.Fprintf(&poolBuf, "%s,%s,%d,%d,%d,%f,%f,", coin0Name, coin0Info.Symbol, coin0IsHippo, coin0Info.Decimals, pool.Coin0Reserve, coin0Info.Price, pool.Coin0Value)

		coin1Name := pool.Coin1.String()
		coin1Info := protocol.Coins[coin1Name]
		coin1IsHippo := 0
		if coin1Info.IsHippo {
			coin1IsHippo = 1
		}
		fmt.Fprintf(&poolBuf, "%s,%s,%d,%d,%d,%f,%f,", coin1Name, coin1Info.Symbol, coin1IsHippo, coin1Info.Decimals, pool.Coin1Reserve, coin1Info.Price, pool.Coin1Value)

		fmt.Fprintf(&poolBuf, "%f\n", pool.TotalValueLocked)
	}

	fmt.Fprint(os.Stderr, poolBuf.String())

}
Output:

Example (Pancakeswap)

ExampleConstantProductPool shows an example of how to query the constant product pool of a protocol on chain (for pancakeswap)

package main

import (
	"bytes"
	"context"
	"encoding/json"
	"fmt"
	"os"

	"github.com/fardream/go-aptos/aptos"
	"github.com/fardream/go-aptos/aptos/known"
	"github.com/fardream/go-aptos/aptos/stat"
)

var pancakeswapUsdSymbols = []string{
	"USDC",
	"USDCso",
	"USDT",
	"ceUSDC",
	"ceDAI",
	"ceUSDT",
	"zUSDC",
	"zUSDT",
	"BUSD",
	"ceBUSD",
	"zBUSD",
}

type TokenPairReserve struct {
	ReserveX aptos.JsonUint64 `json:"reserve_x"`
	ReserveY aptos.JsonUint64 `json:"reserve_y"`
}

// ExampleConstantProductPool shows an example of how to query the constant product pool of a protocol on chain (for pancakeswap)
func main() {
	client, _ := aptos.NewClient(aptos.Mainnet, "")
	resp, err := client.GetAccountResources(context.Background(), &aptos.GetAccountResourcesRequest{
		Address: aptos.MustParseAddress("0xc7efb4076dbe143cbcd98cfaaa929ecfc8f299203dfff63b95ccb6bfe19850fa"),
	})
	if err != nil {
		panic(err)
	}
	protocol := stat.NewStatForConstantProductPool()

	known.ReloadHippoCoinRegistry(known.HippoCoinRegistryUrl)

	for _, usdSymbol := range pancakeswapUsdSymbols {
		stable := known.GetCoinInfoBySymbol(aptos.Mainnet, usdSymbol)
		if stable != nil {
			protocol.AddStableCoins(stable.TokenType.Type)
		}
	}

	for _, v := range *resp.Parsed {
		if v.Type.Name == "TokenPairReserve" {

			var reserve TokenPairReserve

			if err := json.Unmarshal(v.Data, &reserve); err != nil {
				continue
			}

			coin0 := v.Type.GenericTypeParameters[0].Struct
			coin1 := v.Type.GenericTypeParameters[1].Struct

			protocol.AddSinglePool(coin0, uint64(reserve.ReserveX), coin1, uint64(reserve.ReserveY))
		}
	}

	protocol.FillCoinInfo(context.Background(), aptos.Mainnet, client)

	protocol.FillStat()

	var coinBuf bytes.Buffer

	fmt.Fprintln(&coinBuf, "Coin Type, Coin Symbol, Coin Name, Coin Decimal, Total Reserve, Price, Total Value, IsHippo")

	for _, coin := range protocol.Coins {
		isHippo := 0
		if coin.IsHippo {
			isHippo = 1
		}

		fmt.Fprintf(&coinBuf, "%s,%s,%s,%d,%d,%f,%f,%d\n", coin.MoveTypeTag.String(), coin.Symbol, coin.Name, coin.Decimals, coin.TotalQuantity, coin.Price, coin.TotalValue, isHippo)
	}

	fmt.Fprint(os.Stderr, coinBuf.String())

	var poolBuf bytes.Buffer

	fmt.Fprint(&poolBuf, "Coin 0 Type, Coin 0 Symbol, Coin 0 Is Hippo, Coin 0 Decimal, Coin 0 Reserve, Coin 0 Price, Coin 0 Value,")
	fmt.Fprint(&poolBuf, "Coin 1 Type, Coin 1 Symbol, Coin 1 Is Hippo, Coin 1 Decimal, Coin 1 Reserve, Coin 1 Price, Coin 1 Value,")
	fmt.Fprintln(&poolBuf, "Total Value")

	for _, pool := range protocol.Pools {
		coin0Name := pool.Coin0.String()
		coin0Info := protocol.Coins[coin0Name]
		coin0IsHippo := 0
		if coin0Info.IsHippo {
			coin0IsHippo = 1
		}
		fmt.Fprintf(&poolBuf, "%s,%s,%d,%d,%d,%f,%f,", coin0Name, coin0Info.Symbol, coin0IsHippo, coin0Info.Decimals, pool.Coin0Reserve, coin0Info.Price, pool.Coin0Value)

		coin1Name := pool.Coin1.String()
		coin1Info := protocol.Coins[coin1Name]
		coin1IsHippo := 0
		if coin1Info.IsHippo {
			coin1IsHippo = 1
		}
		fmt.Fprintf(&poolBuf, "%s,%s,%d,%d,%d,%f,%f,", coin1Name, coin1Info.Symbol, coin1IsHippo, coin1Info.Decimals, pool.Coin1Reserve, coin1Info.Price, pool.Coin1Value)

		fmt.Fprintf(&poolBuf, "%f\n", pool.TotalValueLocked)
	}

	fmt.Fprint(os.Stderr, poolBuf.String())

}
Output:

type ConstantProductPoolProtocol

type ConstantProductPoolProtocol struct {
	Coins       map[string]*CoinStat
	StableCoins []*aptos.MoveStructTag
	Pools       map[string]*ConstantProductPool

	TotalValueLocked float64
}

ConstantProductPoolProtocol contains stat for all pools on a protocol

func NewStatForConstantProductPool

func NewStatForConstantProductPool() *ConstantProductPoolProtocol

NewStatForConstantProductPool creates a new struct to hold the stat.

func (*ConstantProductPoolProtocol) AddCoins

func (p *ConstantProductPoolProtocol) AddCoins(coins ...*aptos.MoveStructTag)

AddCoins add coins to the pool.

func (*ConstantProductPoolProtocol) AddPools

func (p *ConstantProductPoolProtocol) AddPools(pools ...*ConstantProductPool) error

AddPools add pools to the stat

func (*ConstantProductPoolProtocol) AddSinglePool

func (p *ConstantProductPoolProtocol) AddSinglePool(coin0 *aptos.MoveStructTag, reserve0 uint64, coin1 *aptos.MoveStructTag, reserve1 uint64) error

AddSinglePool add a single pool to the stat of the pool

func (*ConstantProductPoolProtocol) AddStableCoins

func (p *ConstantProductPoolProtocol) AddStableCoins(stableCoins ...*aptos.MoveStructTag)

AddStableCoins add stable coins to the protocol stat

func (*ConstantProductPoolProtocol) FillCoinInfo

func (p *ConstantProductPoolProtocol) FillCoinInfo(ctx context.Context, network aptos.Network, aptosClient *aptos.Client) error

FillCoinInfo fills the missing coins. Consider calling known.ReloadHippoCoinRegistry before hand. If all coin infos are available from Hippo Registry, no query will be made to the aptos network.

func (*ConstantProductPoolProtocol) FillStat

func (p *ConstantProductPoolProtocol) FillStat()

FillStat fills the stat. It assumes the stat of the coins have already been filled.

  1. Set all stable coins' price to 1.
  2. Walk through the pool list. If one of the coin price is known, the unknown coin price will be known_price * known_coin_quantity / unknown_coin_quantity.
  3. Rewalk the pool until all coin price are filled, or 256 iterations are reached.
  4. Calculate TVL for pools and totals.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL