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.