From 3466a51b4d4d59833deab07ee9ac4ecdb4e8a372 Mon Sep 17 00:00:00 2001 From: Rob Mulholand Date: Fri, 20 Sep 2019 21:37:59 -0500 Subject: [PATCH] Correctly parse uint8 values in contract watcher - calling string(uint8) => insert errors on numeric columns --- .../header/converter/converter.go | 12 ++++++------ .../header/converter/converter_test.go | 17 ++++++++++++++++- .../shared/constants/constants.go | 3 +++ .../shared/helpers/test_helpers/database.go | 18 ++++++++++++++++++ .../helpers/test_helpers/mocks/entities.go | 17 +++++++++++++++++ 5 files changed, 60 insertions(+), 7 deletions(-) diff --git a/pkg/contract_watcher/header/converter/converter.go b/pkg/contract_watcher/header/converter/converter.go index 67a32c25..7815cf48 100644 --- a/pkg/contract_watcher/header/converter/converter.go +++ b/pkg/contract_watcher/header/converter/converter.go @@ -89,9 +89,9 @@ func (c *Converter) Convert(logs []gethTypes.Log, event types.Event, headerID in if len(b) == 32 { seenHashes = append(seenHashes, common.HexToHash(strValues[fieldName])) } - case byte: - b := input.(byte) - strValues[fieldName] = string(b) + case uint8: + u := input.(uint8) + strValues[fieldName] = strconv.Itoa(int(u)) case [32]uint8: raw := input.([32]uint8) converted := convertUintSliceToHash(raw) @@ -173,9 +173,9 @@ func (c *Converter) ConvertBatch(logs []gethTypes.Log, events map[string]types.E if len(b) == 32 { // collect byte arrays of size 32 as hashes seenHashes = append(seenHashes, common.BytesToHash(b)) } - case byte: - b := input.(byte) - strValues[fieldName] = string(b) + case uint8: + u := input.(uint8) + strValues[fieldName] = strconv.Itoa(int(u)) case [32]uint8: raw := input.([32]uint8) converted := convertUintSliceToHash(raw) diff --git a/pkg/contract_watcher/header/converter/converter_test.go b/pkg/contract_watcher/header/converter/converter_test.go index 75e83843..72cfa59a 100644 --- a/pkg/contract_watcher/header/converter/converter_test.go +++ b/pkg/contract_watcher/header/converter/converter_test.go @@ -34,6 +34,7 @@ var _ = Describe("Converter", func() { var tusdWantedEvents = []string{"Transfer", "Mint"} var ensWantedEvents = []string{"NewOwner"} var marketPlaceWantedEvents = []string{"OrderCreated"} + var molochWantedEvents = []string{"SubmitVote"} var err error Describe("Update", func() { @@ -146,7 +147,7 @@ var _ = Describe("Converter", func() { Expect(ok).To(Equal(false)) }) - It("keeps track of hashes derived from bytes32", func() { + It("correctly parses bytes32", func() { con = test_helpers.SetupMarketPlaceContract(marketPlaceWantedEvents, []string{}) event, ok := con.Events["OrderCreated"] Expect(ok).To(BeTrue()) @@ -160,6 +161,20 @@ var _ = Describe("Converter", func() { Expect(result[0].Values["id"]).To(Equal("0x633f94affdcabe07c000231f85c752c97b9cc43966b432ec4d18641e6d178233")) }) + It("correctly parses uint8", func() { + con = test_helpers.SetupMolochContract(molochWantedEvents, []string{}) + event, ok := con.Events["SubmitVote"] + Expect(ok).To(BeTrue()) + + c := converter.Converter{} + c.Update(con) + result, err := c.Convert([]types.Log{mocks.MockSubmitVoteLog}, event, 232) + Expect(err).NotTo(HaveOccurred()) + + Expect(len(result)).To(Equal(1)) + Expect(result[0].Values["uintVote"]).To(Equal("1")) + }) + It("Fails with an empty contract", func() { event := con.Events["Transfer"] c := converter.Converter{} diff --git a/pkg/contract_watcher/shared/constants/constants.go b/pkg/contract_watcher/shared/constants/constants.go index a8d754ac..86c6cd9a 100644 --- a/pkg/contract_watcher/shared/constants/constants.go +++ b/pkg/contract_watcher/shared/constants/constants.go @@ -71,6 +71,7 @@ var DaiContractAddress = "0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359" var TusdContractAddress = "0x8dd5fbCe2F6a956C3022bA3663759011Dd51e73E" var EnsContractAddress = "0x314159265dD8dbb310642f98f50C066173C1259b" var MarketPlaceContractAddress = "0x8e5660b4Ab70168b5a6fEeA0e0315cb49c8Cd539" +var MolochContractAddress = "0x1fd169A4f5c59ACf79d0Fd5d91D1201EF1Bce9f1" var PublicResolverAddress = "0x1da022710dF5002339274AaDEe8D58218e9D6AB5" // Contract Owner @@ -86,6 +87,8 @@ var ENSAbiString = `[{"constant":true,"inputs":[{"name":"node","type":"bytes32"} var MarketPlaceAbiString = `[{"constant":false,"inputs":[{"name":"_ownerCutPerMillion","type":"uint256"}],"name":"setOwnerCutPerMillion","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_legacyNFTAddress","type":"address"}],"name":"setLegacyNFTAddress","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"ERC721_Interface","outputs":[{"name":"","type":"bytes4"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"InterfaceId_ValidateFingerprint","outputs":[{"name":"","type":"bytes4"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"unpause","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"acceptedToken","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"assetId","type":"uint256"}],"name":"cancelOrder","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"paused","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"nftAddress","type":"address"},{"name":"assetId","type":"uint256"}],"name":"cancelOrder","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"nftAddress","type":"address"},{"name":"assetId","type":"uint256"},{"name":"priceInWei","type":"uint256"},{"name":"expiresAt","type":"uint256"}],"name":"createOrder","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"initialize","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"pause","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"nftAddress","type":"address"},{"name":"assetId","type":"uint256"},{"name":"price","type":"uint256"},{"name":"fingerprint","type":"bytes"}],"name":"safeExecuteOrder","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"ownerCutPerMillion","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"assetId","type":"uint256"},{"name":"priceInWei","type":"uint256"},{"name":"expiresAt","type":"uint256"}],"name":"createOrder","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"publicationFeeInWei","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"nftAddress","type":"address"},{"name":"assetId","type":"uint256"},{"name":"price","type":"uint256"}],"name":"executeOrder","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_publicationFee","type":"uint256"}],"name":"setPublicationFee","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"contractName","type":"string"},{"name":"migrationId","type":"string"}],"name":"isMigrated","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_acceptedToken","type":"address"},{"name":"_legacyNFTAddress","type":"address"},{"name":"_owner","type":"address"}],"name":"initialize","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_sender","type":"address"}],"name":"initialize","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"legacyNFTAddress","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"assetId","type":"uint256"}],"name":"auctionByAssetId","outputs":[{"name":"","type":"bytes32"},{"name":"","type":"address"},{"name":"","type":"uint256"},{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"},{"name":"","type":"uint256"}],"name":"orderByAssetId","outputs":[{"name":"id","type":"bytes32"},{"name":"seller","type":"address"},{"name":"nftAddress","type":"address"},{"name":"price","type":"uint256"},{"name":"expiresAt","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"assetId","type":"uint256"},{"name":"price","type":"uint256"}],"name":"executeOrder","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"name":"id","type":"bytes32"},{"indexed":true,"name":"assetId","type":"uint256"},{"indexed":true,"name":"seller","type":"address"},{"indexed":false,"name":"nftAddress","type":"address"},{"indexed":false,"name":"priceInWei","type":"uint256"},{"indexed":false,"name":"expiresAt","type":"uint256"}],"name":"OrderCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"id","type":"bytes32"},{"indexed":true,"name":"assetId","type":"uint256"},{"indexed":true,"name":"seller","type":"address"},{"indexed":false,"name":"nftAddress","type":"address"},{"indexed":false,"name":"totalPrice","type":"uint256"},{"indexed":true,"name":"buyer","type":"address"}],"name":"OrderSuccessful","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"id","type":"bytes32"},{"indexed":true,"name":"assetId","type":"uint256"},{"indexed":true,"name":"seller","type":"address"},{"indexed":false,"name":"nftAddress","type":"address"}],"name":"OrderCancelled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"publicationFee","type":"uint256"}],"name":"ChangedPublicationFee","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"ownerCutPerMillion","type":"uint256"}],"name":"ChangedOwnerCutPerMillion","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"legacyNFTAddress","type":"address"}],"name":"ChangeLegacyNFTAddress","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"id","type":"bytes32"},{"indexed":true,"name":"assetId","type":"uint256"},{"indexed":true,"name":"seller","type":"address"},{"indexed":false,"name":"priceInWei","type":"uint256"},{"indexed":false,"name":"expiresAt","type":"uint256"}],"name":"AuctionCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"id","type":"bytes32"},{"indexed":true,"name":"assetId","type":"uint256"},{"indexed":true,"name":"seller","type":"address"},{"indexed":false,"name":"totalPrice","type":"uint256"},{"indexed":true,"name":"winner","type":"address"}],"name":"AuctionSuccessful","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"id","type":"bytes32"},{"indexed":true,"name":"assetId","type":"uint256"},{"indexed":true,"name":"seller","type":"address"}],"name":"AuctionCancelled","type":"event"},{"anonymous":false,"inputs":[],"name":"Pause","type":"event"},{"anonymous":false,"inputs":[],"name":"Unpause","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"previousOwner","type":"address"},{"indexed":true,"name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"contractName","type":"string"},{"indexed":false,"name":"migrationId","type":"string"}],"name":"Migrated","type":"event"}]` +var MolochAbiString = `[{"constant":true,"inputs":[],"name":"processingReward","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"memberAddress","type":"address"},{"name":"proposalIndex","type":"uint256"}],"name":"getMemberProposalVote","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getCurrentPeriod","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"members","outputs":[{"name":"delegateKey","type":"address"},{"name":"shares","type":"uint256"},{"name":"exists","type":"bool"},{"name":"highestIndexYesVote","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalSharesRequested","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"newDelegateKey","type":"address"}],"name":"updateDelegateKey","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalShares","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"proposalQueue","outputs":[{"name":"proposer","type":"address"},{"name":"applicant","type":"address"},{"name":"sharesRequested","type":"uint256"},{"name":"startingPeriod","type":"uint256"},{"name":"yesVotes","type":"uint256"},{"name":"noVotes","type":"uint256"},{"name":"processed","type":"bool"},{"name":"didPass","type":"bool"},{"name":"aborted","type":"bool"},{"name":"tokenTribute","type":"uint256"},{"name":"details","type":"string"},{"name":"maxTotalSharesAtYesVote","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"memberAddressByDelegateKey","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"gracePeriodLength","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"abortWindow","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getProposalQueueLength","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"summoningTime","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"votingPeriodLength","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"sharesToBurn","type":"uint256"}],"name":"ragequit","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"proposalDeposit","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"startingPeriod","type":"uint256"}],"name":"hasVotingPeriodExpired","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"applicant","type":"address"},{"name":"tokenTribute","type":"uint256"},{"name":"sharesRequested","type":"uint256"},{"name":"details","type":"string"}],"name":"submitProposal","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"proposalIndex","type":"uint256"},{"name":"uintVote","type":"uint8"}],"name":"submitVote","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"highestIndexYesVote","type":"uint256"}],"name":"canRagequit","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"guildBank","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"dilutionBound","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"periodDuration","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"approvedToken","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"proposalIndex","type":"uint256"}],"name":"abort","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"proposalIndex","type":"uint256"}],"name":"processProposal","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"summoner","type":"address"},{"name":"_approvedToken","type":"address"},{"name":"_periodDuration","type":"uint256"},{"name":"_votingPeriodLength","type":"uint256"},{"name":"_gracePeriodLength","type":"uint256"},{"name":"_abortWindow","type":"uint256"},{"name":"_proposalDeposit","type":"uint256"},{"name":"_dilutionBound","type":"uint256"},{"name":"_processingReward","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"name":"proposalIndex","type":"uint256"},{"indexed":true,"name":"delegateKey","type":"address"},{"indexed":true,"name":"memberAddress","type":"address"},{"indexed":true,"name":"applicant","type":"address"},{"indexed":false,"name":"tokenTribute","type":"uint256"},{"indexed":false,"name":"sharesRequested","type":"uint256"}],"name":"SubmitProposal","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"proposalIndex","type":"uint256"},{"indexed":true,"name":"delegateKey","type":"address"},{"indexed":true,"name":"memberAddress","type":"address"},{"indexed":false,"name":"uintVote","type":"uint8"}],"name":"SubmitVote","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"proposalIndex","type":"uint256"},{"indexed":true,"name":"applicant","type":"address"},{"indexed":true,"name":"memberAddress","type":"address"},{"indexed":false,"name":"tokenTribute","type":"uint256"},{"indexed":false,"name":"sharesRequested","type":"uint256"},{"indexed":false,"name":"didPass","type":"bool"}],"name":"ProcessProposal","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"memberAddress","type":"address"},{"indexed":false,"name":"sharesToBurn","type":"uint256"}],"name":"Ragequit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"proposalIndex","type":"uint256"},{"indexed":false,"name":"applicantAddress","type":"address"}],"name":"Abort","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"memberAddress","type":"address"},{"indexed":false,"name":"newDelegateKey","type":"address"}],"name":"UpdateDelegateKey","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"summoner","type":"address"},{"indexed":false,"name":"shares","type":"uint256"}],"name":"SummonComplete","type":"event"}]` + // Look-up table for ABI strings var Abis = map[common.Address]string{ common.HexToAddress("0x314159265dD8dbb310642f98f50C066173C1259b"): ENSAbiString, diff --git a/pkg/contract_watcher/shared/helpers/test_helpers/database.go b/pkg/contract_watcher/shared/helpers/test_helpers/database.go index 9f59bfaa..5a380b24 100644 --- a/pkg/contract_watcher/shared/helpers/test_helpers/database.go +++ b/pkg/contract_watcher/shared/helpers/test_helpers/database.go @@ -239,6 +239,24 @@ func SetupMarketPlaceContract(wantedEvents, wantedMethods []string) *contract.Co }.Init() } +func SetupMolochContract(wantedEvents, wantedMethods []string) *contract.Contract { + p := mocks.NewParser(constants.MolochAbiString) + err := p.Parse() + Expect(err).NotTo(HaveOccurred()) + + return contract.Contract{ + Name: "Moloch", + Address: constants.MolochContractAddress, + StartingBlock: 7218566, + Abi: p.Abi(), + ParsedAbi: p.ParsedAbi(), + Events: p.GetEvents(wantedEvents), + Methods: p.GetSelectMethods(wantedMethods), + FilterArgs: map[string]bool{}, + MethodArgs: map[string]bool{}, + }.Init() +} + // TODO: tear down/setup DB from migrations so this doesn't alter the schema between tests func TearDown(db *postgres.DB) { tx, err := db.Beginx() diff --git a/pkg/contract_watcher/shared/helpers/test_helpers/mocks/entities.go b/pkg/contract_watcher/shared/helpers/test_helpers/mocks/entities.go index dbcd5a5f..b6830710 100644 --- a/pkg/contract_watcher/shared/helpers/test_helpers/mocks/entities.go +++ b/pkg/contract_watcher/shared/helpers/test_helpers/mocks/entities.go @@ -295,6 +295,23 @@ var MockOrderCreatedLog = types.Log{ Removed: false, } +var MockSubmitVoteLog = types.Log{ + Address: common.HexToAddress(constants.MolochContractAddress), + Topics: []common.Hash{ + common.HexToHash("0x29bf0061f2faa9daa482f061b116195432d435536d8af4ae6b3c5dd78223679b"), + common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000061"), + common.HexToHash("0x0000000000000000000000006ddf1b8e6d71b5b33912607098be123ffe62ae53"), + common.HexToHash("0x00000000000000000000000037385081870ef47e055410fefd582e2a95d2960b"), + }, + Data: hexutil.MustDecode("0x0000000000000000000000000000000000000000000000000000000000000001"), + BlockNumber: 8517621, + TxHash: common.HexToHash("0xcc7390a2099812d0dfc9baef201afbc7a44bfae145050c9dc700b77cbd3cd752"), + TxIndex: 103, + BlockHash: common.HexToHash("0x3e82681d8036b1225fcaa8bcd4cdbe757b39f13468286b303cde22146385525e"), + Index: 132, + Removed: false, +} + var ens = strings.ToLower(constants.EnsContractAddress) var tusd = strings.ToLower(constants.TusdContractAddress)