Documentation ¶
Overview ¶
stat provides support for statistics for various common DeFi primitives on aptos
Index ¶
- type CoinStat
- type ConstantProductPool
- type ConstantProductPoolProtocol
- func (p *ConstantProductPoolProtocol) AddCoins(coins ...*aptos.MoveStructTag)
- func (p *ConstantProductPoolProtocol) AddPools(pools ...*ConstantProductPool) error
- func (p *ConstantProductPoolProtocol) AddSinglePool(coin0 *aptos.MoveStructTag, reserve0 uint64, coin1 *aptos.MoveStructTag, ...) error
- func (p *ConstantProductPoolProtocol) AddStableCoins(stableCoins ...*aptos.MoveStructTag)
- func (p *ConstantProductPoolProtocol) FillCoinInfo(ctx context.Context, network aptos.Network, aptosClient *aptos.Client) error
- func (p *ConstantProductPoolProtocol) FillStat()
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.
- Set all stable coins' price to 1.
- 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.
- Rewalk the pool until all coin price are filled, or 256 iterations are reached.
- Calculate TVL for pools and totals.