Giter Club home page Giter Club logo

go-indexed's Introduction

go-indexed

go-indexed is an SDK for interacting Indexed Finance smart contracts using the Golang programming language. It includes a library that leverages the Ethereum RPC client, a CLI for querying the smart contracts from the CLI, and a Discord bot that essentially provides a CLI/Library like usage experience through the Discord platform.

Overview

Discord

A Discord chat bot is included that allows for making read-only calls to Indexed Finance contracts Discord message. It has the current capabilities

  • Return account balance for IndexPools contracts
  • Return account staking balance and stake rewards earned for the staking contracts
  • Return current tokens basketed into an IndexPool
  • Notify about arbitrary conditions:
    • Currently only supports stake earned

CLI

There is a basic CLI that can be used to make simple queries about the smart contracts.

Library

TODO

Installation

$> git clone https://github.com/bonedaddy/go-indexed
$> cd go-indexed
$> go mod download
$> make # builds the CLI and creates an executable in the current directory named gondx

Usage

CLI

At the moment the only CLI command available is gondx pool please see its output for more information.

Discord

First you'll need to create a Discord bot user that will be used, and get an appropriate access token. The following instructions star the Discord bot conencted to infura

$> ./gondx --infura.api_key supersecretinfurakey discord-bot --discord.token "supersecretdiscordtoken"

To view the general help menu send the following message from a channel the bot can read from and send messages to:

!ndx

To view help menu about the notify command:

!ndx notify help

Development

To update the ABIs from the indexed-js submodule: make copy-abi

To update the generated golang code for the ABIs: make gen-bindings

Note: Updating the uniswap bindings is a bit tedious because of the usage of waffle which outputs a combined json file that isnt properly generating the golang bindings so you must manually copy the ABI from the combined json output into its own file

Adding New TVL Tracking

The default behavior for TVL calculation is to derive the price of assets by looking up their ETH uniswap pairs, and converting that to DAI. So for AAVE the USD price determination process is AAVE -> ETH -> DAI

Contract Bindings

bindings/uniswapv2_oracle

These are the contract bindings for the Indexed UniswapV2 Oracle

bindings/uniswapv2

These are contract bindings for uniswapv2 itself

Support

Support development of go-indexed by sending tips to 0x5a361a1dfd52538a158e352d21b5b622360a7c13, all funds received will be re-invested into Indexed Finance via governance token (NDX) purchases, or pool token (defi5, cc10, etc...) purchases.

go-indexed's People

Contributors

bonedaddy avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

go-indexed's Issues

Improve Uniswap Echange Amount Output

The response to this command reads weirdly and should be rewritten.

swapping 0.1 with pair eth-defi5 will yield: 3.1905922930456405

becomes

swapping 0.1ETH will yield 3.1905922930456405 DEFI5

Enable Usage Of Multicall

Lots of information needed by this library requires multiple RPC calls to fetch, which can be extremely expensive. Using multicall would allow us to only make one RPC request.

Enable Backdating Database Price Feed

Using the sync events for each pair contract we should be able to backdate the records in the database to include missing price feeds. This would be useful for recovering from database failures, outages, and for storing previous data when monitoring a new pair.

Enable Circulating Supply Calculation

should be fairly easy to calculate, get total supply and subtract the number of tokens held by the various team contracts (multisig, timelockm, etc...)

Panic During Operation

2021/01/01 11:44:56 bot is now running
panic: runtime error: index out of range [0] with length 0

goroutine 29 [running]:
github.com/bonedaddy/go-indexed/bindings/uniswapv2/pair.(*Uniswapv2pairCaller).GetReserves(0xc0000ae5f0, 0xc000a77cf0, 0x2540be400, 0xecf0a0, 0xc0005cd1a0, 0xc000479b50, 0x0)
	/BUILD/bindings/uniswapv2/pair/v2pair.go:408 +0x1de
github.com/bonedaddy/go-indexed/uniswap.(*Client).GetReserves(0xc0000aec18, 0x8dfe23b239aa2ac0, 0x8d9ea274f5c0e0a, 0x7454176bc26c753c, 0x958ba94dc49490e8, 0xf1d2795c4eaed4e, 0x0, 0x0, 0x0)
	/BUILD/uniswap/client.go:52 +0x176
github.com/bonedaddy/go-indexed/bclient.(*Client).Reserves(0xc0004212d0, 0xd9a0ef, 0x7, 0xc26c753c08d9ea00, 0x0, 0x0)
	/BUILD/bclient/uniswap.go:110 +0x20c
github.com/bonedaddy/go-indexed/bclient.(*Client).EthDaiPrice(0xc0004212d0, 0xc0004810a0, 0x12, 0xc000481700)
	/BUILD/bclient/uniswap.go:87 +0x45
github.com/bonedaddy/go-indexed/bclient.(*Client).NdxDaiPrice(0xc0004212d0, 0x3, 0xc00053e3ca, 0x3)
	/BUILD/bclient/uniswap.go:35 +0xc9
github.com/bonedaddy/go-indexed/discord.launchWatchers.func1(0xc000430710, 0xc00044e6c0, 0xecf020, 0xc00030b140, 0xc0004212d0, 0xc0004306c0, 0x3)
	/BUILD/discord/discord.go:229 +0x6cf
created by github.com/bonedaddy/go-indexed/discord.launchWatchers
	/BUILD/discord/discord.go:192 +0x1b2

Better Uniswap Querying

Right now uniswap querying is pretty basic, and swap queries dont take in price slippage, etc.. It would be great to have the reply to take in these factors into account.

Cache Command Responses Unlikely To Change

It would be beneficial to cache lookup results that are unlikely to change so as to improve bot performance:

  • Pool Tokens Listing
  • Stake Earned (only poll for fresh results every minute or so)

Add Persistence Layer

Add persistence layer for tracking various update and prices. This would allow us to have processes or goroutines updating a database, and then the discord bot can read from the database.

Blocknative Integration

types:

type AutoGenerated struct {
	ConnectionID string `json:"connectionId"`
	Event        struct {
		Blockchain struct {
			Network string `json:"network"`
			System  string `json:"system"`
		} `json:"blockchain"`
		CategoryCode string `json:"categoryCode"`
		ContractCall struct {
			ContractAddress string `json:"contractAddress"`
			ContractType    string `json:"contractType"`
			MethodName      string `json:"methodName"`
			Params          struct {
				AmountIn     string   `json:"amountIn"`
				AmountOutMin string   `json:"amountOutMin"`
				Deadline     string   `json:"deadline"`
				Path         []string `json:"path"`
				To           string   `json:"to"`
			} `json:"params"`
		} `json:"contractCall"`
		DappID      string    `json:"dappId"`
		EventCode   string    `json:"eventCode"`
		TimeStamp   time.Time `json:"timeStamp"`
		Transaction struct {
			Asset                string    `json:"asset"`
			BlockHash            string    `json:"blockHash"`
			BlockNumber          int       `json:"blockNumber"`
			BlockTimeStamp       time.Time `json:"blockTimeStamp"`
			BlocksPending        int       `json:"blocksPending"`
			Counterparty         string    `json:"counterparty"`
			Direction            string    `json:"direction"`
			From                 string    `json:"from"`
			Gas                  int       `json:"gas"`
			GasPrice             string    `json:"gasPrice"`
			GasUsed              string    `json:"gasUsed"`
			Hash                 string    `json:"hash"`
			Input                string    `json:"input"`
			InternalTransactions []struct {
				ContractCall struct {
					ContractAddress  string `json:"contractAddress"`
					ContractAlias    string `json:"contractAlias"`
					ContractDecimals int    `json:"contractDecimals"`
					ContractName     string `json:"contractName"`
					ContractType     string `json:"contractType"`
					DecimalValue     string `json:"decimalValue"`
					MethodName       string `json:"methodName"`
					Params           struct {
						From  string `json:"_from"`
						To    string `json:"_to"`
						Value string `json:"_value"`
					} `json:"params"`
				} `json:"contractCall,omitempty"`
				From         string `json:"from"`
				Gas          int    `json:"gas"`
				GasUsed      int    `json:"gasUsed"`
				Input        string `json:"input"`
				To           string `json:"to"`
				Type         string `json:"type"`
				Value        string `json:"value"`
				ContractCall struct {
					ContractAddress string `json:"contractAddress"`
					ContractAlias   string `json:"contractAlias"`
					ContractType    string `json:"contractType"`
					MethodName      string `json:"methodName"`
					Params          struct {
						To    string `json:"_to"`
						Value string `json:"_value"`
					} `json:"params"`
				} `json:"contractCall,omitempty"`
				ContractCall struct {
					ContractAddress string `json:"contractAddress"`
					ContractAlias   string `json:"contractAlias"`
					ContractType    string `json:"contractType"`
					MethodName      string `json:"methodName"`
					Params          struct {
						Owner string `json:"_owner"`
					} `json:"params"`
				} `json:"contractCall,omitempty"`
				ContractCall struct {
					ContractAddress string `json:"contractAddress"`
					ContractAlias   string `json:"contractAlias"`
					ContractType    string `json:"contractType"`
					MethodName      string `json:"methodName"`
					Params          struct {
						Owner string `json:"_owner"`
					} `json:"params"`
				} `json:"contractCall,omitempty"`
				ContractCall struct {
					ContractAddress  string `json:"contractAddress"`
					ContractAlias    string `json:"contractAlias"`
					ContractDecimals int    `json:"contractDecimals"`
					ContractType     string `json:"contractType"`
					DecimalValue     string `json:"decimalValue"`
					MethodName       string `json:"methodName"`
					Params           struct {
						To    string `json:"_to"`
						Value string `json:"_value"`
					} `json:"params"`
				} `json:"contractCall,omitempty"`
				ContractCall struct {
					ContractAddress  string `json:"contractAddress"`
					ContractAlias    string `json:"contractAlias"`
					ContractDecimals int    `json:"contractDecimals"`
					ContractType     string `json:"contractType"`
					MethodName       string `json:"methodName"`
					Params           struct {
						Owner string `json:"_owner"`
					} `json:"params"`
				} `json:"contractCall,omitempty"`
			} `json:"internalTransactions"`
			MonitorID         string `json:"monitorId"`
			MonitorVersion    string `json:"monitorVersion"`
			NetBalanceChanges []struct {
				Address        string `json:"address"`
				BalanceChanges []struct {
					Asset struct {
						ContractAddress string `json:"contractAddress"`
						Symbol          string `json:"symbol"`
						Type            string `json:"type"`
					} `json:"asset"`
					Breakdown []struct {
						Amount       string `json:"amount"`
						Counterparty string `json:"counterparty"`
					} `json:"breakdown"`
					Delta string `json:"delta"`
				} `json:"balanceChanges"`
			} `json:"netBalanceChanges"`
			Nonce              int       `json:"nonce"`
			PendingBlockNumber int       `json:"pendingBlockNumber"`
			PendingTimeStamp   time.Time `json:"pendingTimeStamp"`
			Status             string    `json:"status"`
			TimePending        string    `json:"timePending"`
			To                 string    `json:"to"`
			TransactionIndex   int       `json:"transactionIndex"`
			Value              string    `json:"value"`
			WatchedAddress     string    `json:"watchedAddress"`
		} `json:"transaction"`
	} `json:"event"`
	ServerVersion string    `json:"serverVersion"`
	Status        string    `json:"status"`
	TimeStamp     time.Time `json:"timeStamp"`
	UserAgent     string    `json:"userAgent"`
	Version       int       `json:"version"`
}

Update Price Change Information

Price change should show "increased" or "decreased" instead of "changed".

yeah - if you wanted to be fancy with your text you could quasiquote the figure and replace "changed" with 'increased' or 'decreased'

Create command that returns relevant indexed-finance contracts

It would be great if we had a bot command that lists indexed-finance contracts. Often users in discord as for a specific token contract/address and sometimes it's a bit of a pain to find it.

Example usage:

<User> !ndx contract NDX
<NDXBot> The contract for the NDX token is: 0x86772b1409b61c639eaac9ba0acfbb6e238e5f83

<User> !ndx contract DEFI5
<NDXBot> The contract for the DEFI5 token is: 0xfa6de2697d59e88ed7fc4dfe5a33dac43565ea41

<User> !ndx contract UNIV2:CC10-ETH
<NDXBot> The contract for the UNIV2:CC10-ETH LP token is: 0x2701ea55b8b4f0fe46c15a0f560e9cf0c430f833

Add Governance Database Watcher

  • Every 10 minutes check to see the current proposal count, if greater than our last store the missing information in the database.
  • Every 60 minutes check to see if existing non-executed proposals have been cancelled or executed

Example table


// Proposal is a given governance proposal submission
type Proposal struct {
	gorm.Model
	ID           int64
	Proposer     string
	Eta          int64
	StartBlock   int64
	FortVotes    int64
	AgainstVotes int64
	Canceled     bool
	Executed     bool
}

Align Text Output

Non-embedded messages sent by the bot are currently not aligned, and look somewhat ugly.

Enable Pool Addres Calculation

// encodeState encodes the state as with abi.encode() in the smart contracts.
func computePoolAddress(a, b []byte) ([]byte, error) {
    args := abi.Arguments{
        {Type: abiUint256},
        {Type: abiUint256},
    }
    enc, err := args.Pack(
        a,
        b,
    )
    // now you have abi.encode(a,b)
    h := crypto.Keccak256(enc)
    // now you have keccak(abi.encode(a,b))
    // return the last 20 bytes
    return h[12:]
}

Cleanup Codebase

Right now theres a lot of duplicated code primarily for the price tracking bot logic, as well as database update routines. This makes it cumbersome to update and add new indices.

Add TVL To Bot Information

Individual index price bots should display the TVL for the corresponding pool in their name, while the ndxbot shoudl show both tvls.

For example:

DEFI5: $55.90 | 6M TVL
CC10: $49.40 | 6M TVL
NDXBot: $8.20 | 15M TVL

Dashboard Functionality

Enable exporting metrics to prometheus and grafana for dashboard functionality

a dashboard showing how much TVL both indexes have, how many fees the swaps have generated, # of addresses who hold DeFI5 and CC10, volume, how much is minted etc. would be awesome!

TODO

  • enable storing tvl information in db
  • record token total supply in db
  • record fees generated in db
  • record total token holder information in db

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.