github.com/diadata-org/diadata@v1.4.593/pkg/dia/service/assetservice/source/camelotv3.go (about) 1 package source 2 3 import ( 4 "strconv" 5 "strings" 6 7 camelotv3 "github.com/diadata-org/diadata/pkg/dia/scraper/exchange-scrapers/camelotv3" 8 uniswapcontract "github.com/diadata-org/diadata/pkg/dia/scraper/exchange-scrapers/uniswap" 9 models "github.com/diadata-org/diadata/pkg/model" 10 11 "github.com/diadata-org/diadata/pkg/utils" 12 13 "github.com/diadata-org/diadata/pkg/dia" 14 "github.com/ethereum/go-ethereum/accounts/abi/bind" 15 "github.com/ethereum/go-ethereum/common" 16 "github.com/ethereum/go-ethereum/ethclient" 17 ) 18 19 type CamelotV3AssetSource struct { 20 RestClient *ethclient.Client 21 WsClient *ethclient.Client 22 relDB *models.RelDB 23 // signaling channels for session initialization and finishing 24 assetChannel chan dia.Asset 25 doneChannel chan bool 26 blockchain string 27 exchange dia.Exchange 28 startBlock uint64 29 factoryContract string 30 waitTime int 31 } 32 33 // NewCamelotV3AssetSource returns a new CamelotV3AssetSource 34 func NewCamelotV3AssetSource(exchange dia.Exchange, relDB *models.RelDB) *CamelotV3AssetSource { 35 log.Info("NewCamelotV3Scraper ", exchange.Name) 36 log.Info("NewCamelotV3Scraper Address ", exchange.Contract) 37 38 var uas *CamelotV3AssetSource 39 40 switch exchange.Name { 41 case dia.CamelotExchangeV3: 42 uas = makeCamelotV3AssetSource(exchange, "", "", relDB, "200", uint64(101163738)) 43 case dia.ThenaV3Exchange: 44 uas = makeCamelotV3AssetSource(exchange, "", "", relDB, "200", uint64(26030310)) 45 } 46 47 go func() { 48 uas.fetchAssets() 49 }() 50 return uas 51 52 } 53 54 // makeCamelotV3AssetSource returns a Camelot asset source. 55 func makeCamelotV3AssetSource(exchange dia.Exchange, restDial string, wsDial string, relDB *models.RelDB, waitMilliseconds string, startBlock uint64) *CamelotV3AssetSource { 56 var ( 57 restClient *ethclient.Client 58 wsClient *ethclient.Client 59 err error 60 uas *CamelotV3AssetSource 61 assetChannel = make(chan dia.Asset) 62 doneChannel = make(chan bool) 63 ) 64 65 log.Infof("Init rest and ws client for %s.", exchange.BlockChain.Name) 66 restClient, err = ethclient.Dial(utils.Getenv(strings.ToUpper(exchange.BlockChain.Name)+"_URI_REST", restDial)) 67 if err != nil { 68 log.Fatal("init rest client: ", err) 69 } 70 wsClient, err = ethclient.Dial(utils.Getenv(strings.ToUpper(exchange.BlockChain.Name)+"_URI_WS", wsDial)) 71 if err != nil { 72 log.Fatal("init rest client: ", err) 73 } 74 75 var waitTime int 76 waitTimeString := utils.Getenv(strings.ToUpper(exchange.BlockChain.Name)+"_WAIT_TIME", waitMilliseconds) 77 waitTime, err = strconv.Atoi(waitTimeString) 78 if err != nil { 79 log.Error("could not parse wait time: ", err) 80 waitTime = 500 81 } 82 83 uas = &CamelotV3AssetSource{ 84 RestClient: restClient, 85 WsClient: wsClient, 86 relDB: relDB, 87 assetChannel: assetChannel, 88 doneChannel: doneChannel, 89 blockchain: exchange.BlockChain.Name, 90 startBlock: startBlock, 91 factoryContract: exchange.Contract, 92 exchange: exchange, 93 waitTime: waitTime, 94 } 95 return uas 96 } 97 98 // getNumPairs returns the number of available pairs on Camelot 99 func (uas *CamelotV3AssetSource) fetchAssets() { 100 101 // filter from contract created https://etherscan.io/tx/0x1e20cd6d47d7021ae7e437792823517eeadd835df09dde17ab45afd7a5df4603 102 var blocknumber int64 103 104 _, startblock, err := uas.relDB.GetScraperIndex(uas.exchange.Name, dia.SCRAPER_TYPE_ASSETCOLLECTOR) 105 if err != nil { 106 log.Error("GetScraperIndex: ", err) 107 } else { 108 uas.startBlock = uint64(startblock) 109 } 110 111 log.Infof("get pool creations from address %s at startblock %v.", uas.factoryContract, uas.startBlock) 112 poolsCount := 0 113 checkMap := make(map[string]struct{}) 114 contract, err := camelotv3.NewCamelotv3Filterer(common.HexToAddress(uas.factoryContract), uas.WsClient) 115 if err != nil { 116 log.Error(err) 117 } 118 119 poolCreated, err := contract.FilterPool( 120 &bind.FilterOpts{Start: uas.startBlock}, 121 []common.Address{}, 122 []common.Address{}, 123 ) 124 if err != nil { 125 log.Error("filter pool created: ", err) 126 } 127 for poolCreated.Next() { 128 poolsCount++ 129 log.Info("pools count: ", poolsCount) 130 blocknumber = int64(poolCreated.Event.Raw.BlockNumber) 131 // Don't repeat sending already sent assets 132 if _, ok := checkMap[poolCreated.Event.Token0.Hex()]; !ok { 133 checkMap[poolCreated.Event.Token0.Hex()] = struct{}{} 134 asset, err := uas.GetAssetFromAddress(poolCreated.Event.Token0) 135 if err != nil { 136 log.Warn("cannot fetch asset from address ", poolCreated.Event.Token0.Hex()) 137 } 138 uas.assetChannel <- asset 139 } 140 if _, ok := checkMap[poolCreated.Event.Token1.Hex()]; !ok { 141 checkMap[poolCreated.Event.Token1.Hex()] = struct{}{} 142 asset, err := uas.GetAssetFromAddress(poolCreated.Event.Token1) 143 if err != nil { 144 log.Warn("cannot fetch asset from address ", poolCreated.Event.Token1.Hex()) 145 } 146 uas.assetChannel <- asset 147 } 148 } 149 err = uas.relDB.SetScraperIndex(uas.exchange.Name, dia.SCRAPER_TYPE_ASSETCOLLECTOR, dia.INDEX_TYPE_BLOCKNUMBER, blocknumber) 150 if err != nil { 151 log.Error("SetScraperIndex: ", err) 152 } 153 uas.doneChannel <- true 154 } 155 156 func (uas *CamelotV3AssetSource) GetAssetFromAddress(address common.Address) (asset dia.Asset, err error) { 157 connection := uas.RestClient 158 159 var tokenContract *uniswapcontract.IERC20Caller 160 161 tokenContract, err = uniswapcontract.NewIERC20Caller(address, connection) 162 if err != nil { 163 log.Error(err) 164 } 165 166 symbol, err := tokenContract.Symbol(&bind.CallOpts{}) 167 if err != nil { 168 log.Error(err) 169 } 170 name, err := tokenContract.Name(&bind.CallOpts{}) 171 if err != nil { 172 log.Error(err) 173 } 174 decimals, err := tokenContract.Decimals(&bind.CallOpts{}) 175 if err != nil { 176 log.Error(err) 177 } 178 179 asset = dia.Asset{ 180 Symbol: symbol, 181 Name: name, 182 Address: address.Hex(), 183 Blockchain: uas.blockchain, 184 Decimals: decimals, 185 } 186 187 return 188 } 189 190 func (uas *CamelotV3AssetSource) Asset() chan dia.Asset { 191 return uas.assetChannel 192 } 193 194 func (uas *CamelotV3AssetSource) Done() chan bool { 195 return uas.doneChannel 196 }