From 6353d3371076ee2c3eb421ca209c5d8de509e8d4 Mon Sep 17 00:00:00 2001 From: Mohammed Sohail Date: Thu, 18 Apr 2024 16:03:27 +0800 Subject: [PATCH] feat: add pool, token, common and faucet handlers --- internal/handler/faucet.go | 106 +++++++++++++++++ internal/handler/mint.go | 1 - internal/handler/ownership.go | 87 ++++++++++++++ internal/handler/pool_deposit.go | 97 +++++++++++++++ internal/handler/pool_swap.go | 110 ++++++++++++++++++ internal/handler/seal.go | 87 ++++++++++++++ internal/handler/token_burn.go | 88 ++++++++++++++ internal/handler/token_mint.go | 92 +++++++++++++++ .../{transfer.go => token_transfer.go} | 0 9 files changed, 667 insertions(+), 1 deletion(-) create mode 100644 internal/handler/faucet.go delete mode 100644 internal/handler/mint.go create mode 100644 internal/handler/ownership.go create mode 100644 internal/handler/pool_deposit.go create mode 100644 internal/handler/pool_swap.go create mode 100644 internal/handler/seal.go create mode 100644 internal/handler/token_burn.go create mode 100644 internal/handler/token_mint.go rename internal/handler/{transfer.go => token_transfer.go} (100%) diff --git a/internal/handler/faucet.go b/internal/handler/faucet.go new file mode 100644 index 0000000..c888132 --- /dev/null +++ b/internal/handler/faucet.go @@ -0,0 +1,106 @@ +package handler + +import ( + "context" + "math/big" + + "github.com/celo-org/celo-blockchain/common" + "github.com/grassrootseconomics/celo-tracker/internal/emitter" + "github.com/grassrootseconomics/w3-celo" +) + +type ( + FaucetGiveHandler struct { + topicHash common.Hash + event *w3.Event + } +) + +var ( + faucetGiveTopicHash = w3.H("0x26162814817e23ec5035d6a2edc6c422da2da2119e27cfca6be65cc2dc55ca4c") + faucetGiveEvent = w3.MustNewEvent("Give(address indexed _recipient, address indexed _token, uint256 _amount)") + faucetGiveToSig = w3.MustNewFunc("giveTo(address)", "uint256") + faucetGimmeSig = w3.MustNewFunc("gimme()", "uint256") +) + +func (h *FaucetGiveHandler) HandleLog(ctx context.Context, msg LogMessage, emitter emitter.Emitter) error { + if msg.Log.Topics[0] == faucetGiveTopicHash { + var ( + recipient common.Address + token common.Address + amount big.Int + ) + + if err := faucetGiveEvent.DecodeArgs(msg.Log, &recipient, &token, &amount); err != nil { + return err + } + + faucetGiveEvent := Event{ + Block: msg.Log.BlockNumber, + ContractAddress: msg.Log.Address.Hex(), + Success: true, + Timestamp: msg.BlockTime, + TxHash: msg.Log.TxHash.Hex(), + TxType: "FAUCET_GIVE", + Payload: map[string]any{ + "recipient": recipient.Hex(), + "token": token.Hex(), + "amount": amount.String(), + }, + } + + return emitter.Emit(ctx, faucetGiveEvent) + } + + return nil +} + +func (h *FaucetGiveHandler) HandleRevert(ctx context.Context, msg RevertMessage, emitter emitter.Emitter) error { + if len(msg.InputData) < 8 { + return nil + } + + switch msg.InputData[:8] { + case "63e4bff4": + var ( + to common.Address + ) + + if err := faucetGiveToSig.DecodeArgs(w3.B(msg.InputData), &to); err != nil { + return err + } + + faucetGiveEvent := Event{ + Block: msg.Block, + ContractAddress: msg.ContractAddress, + Success: false, + Timestamp: msg.Timestamp, + TxHash: msg.TxHash, + TxType: "FAUCET_GIVE", + Payload: map[string]any{ + "revertReason": msg.RevertReason, + "from": msg.From, + "to": to.Hex(), + }, + } + + return emitter.Emit(ctx, faucetGiveEvent) + case "de82efb4": + faucetGiveEvent := Event{ + Block: msg.Block, + ContractAddress: msg.ContractAddress, + Success: false, + Timestamp: msg.Timestamp, + TxHash: msg.TxHash, + TxType: "FAUCET_GIVE", + Payload: map[string]any{ + "revertReason": msg.RevertReason, + "from": msg.From, + }, + } + + return emitter.Emit(ctx, faucetGiveEvent) + } + + return nil +} diff --git a/internal/handler/mint.go b/internal/handler/mint.go deleted file mode 100644 index abeebd1..0000000 --- a/internal/handler/mint.go +++ /dev/null @@ -1 +0,0 @@ -package handler diff --git a/internal/handler/ownership.go b/internal/handler/ownership.go new file mode 100644 index 0000000..e0fc77c --- /dev/null +++ b/internal/handler/ownership.go @@ -0,0 +1,87 @@ +package handler + +import ( + "context" + + "github.com/celo-org/celo-blockchain/common" + "github.com/grassrootseconomics/celo-tracker/internal/emitter" + "github.com/grassrootseconomics/w3-celo" +) + +type ( + OwnershipHandler struct { + topicHash common.Hash + event *w3.Event + } +) + +var ( + ownershipTopicHash = w3.H("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") + ownershipEvent = w3.MustNewEvent("OwnershipTransferred(address indexed previousOwner, address indexed newOwner)") + ownershipToSig = w3.MustNewFunc("transferOwnership(address)", "bool") +) + +func (h *OwnershipHandler) HandleLog(ctx context.Context, msg LogMessage, emitter emitter.Emitter) error { + if msg.Log.Topics[0] == ownershipTopicHash { + var ( + previousOwner common.Address + newOwner common.Address + ) + + if err := ownershipEvent.DecodeArgs(msg.Log, &previousOwner, &newOwner); err != nil { + return err + } + + ownershipEvent := Event{ + Block: msg.Log.BlockNumber, + ContractAddress: msg.Log.Address.Hex(), + Success: true, + Timestamp: msg.BlockTime, + TxHash: msg.Log.TxHash.Hex(), + TxType: "OWNERSHIP_TRANSFERRED", + Payload: map[string]any{ + "previousOwner": previousOwner.Hex(), + "newOwner": newOwner.Hex(), + }, + } + + return emitter.Emit(ctx, ownershipEvent) + } + + return nil +} + +func (h *OwnershipHandler) HandleRevert(ctx context.Context, msg RevertMessage, emitter emitter.Emitter) error { + if len(msg.InputData) < 8 { + return nil + } + + switch msg.InputData[:8] { + case "f2fde38b": + var ( + newOwner common.Address + ) + + if err := ownershipToSig.DecodeArgs(w3.B(msg.InputData), &newOwner); err != nil { + return err + } + + ownershipEvent := Event{ + Block: msg.Block, + ContractAddress: msg.ContractAddress, + Success: false, + Timestamp: msg.Timestamp, + TxHash: msg.TxHash, + TxType: "ownership", + Payload: map[string]any{ + "revertReason": msg.RevertReason, + "previousOwner": msg.From, + "newOwner": newOwner.Hex(), + }, + } + + return emitter.Emit(ctx, ownershipEvent) + } + + return nil +} diff --git a/internal/handler/pool_deposit.go b/internal/handler/pool_deposit.go new file mode 100644 index 0000000..6d11d5e --- /dev/null +++ b/internal/handler/pool_deposit.go @@ -0,0 +1,97 @@ +package handler + +import ( + "context" + "math/big" + + "github.com/celo-org/celo-blockchain/common" + "github.com/grassrootseconomics/celo-tracker/internal/emitter" + "github.com/grassrootseconomics/w3-celo" +) + +type ( + PoolDepositHandler struct { + topicHash common.Hash + event *w3.Event + } +) + +var ( + poolDepositTopicHash = w3.H("0x5548c837ab068cf56a2c2479df0882a4922fd203edb7517321831d95078c5f62") + poolDepositEvent = w3.MustNewEvent("Deposit(address indexed initiator, address indexed tokenIn, uint256 amountIn)") + poolDepositSig = w3.MustNewFunc("deposit(address, uint256)", "") +) + +func (h *PoolDepositHandler) HandleLog(ctx context.Context, msg LogMessage, emitter emitter.Emitter) error { + if msg.Log.Topics[0] == poolDepositTopicHash { + var ( + initiator common.Address + tokenIn common.Address + amountIn big.Int + ) + + if err := poolDepositEvent.DecodeArgs( + msg.Log, + &initiator, + &tokenIn, + &amountIn, + ); err != nil { + return err + } + + poolDepositEvent := Event{ + Block: msg.Log.BlockNumber, + ContractAddress: msg.Log.Address.Hex(), + Success: true, + Timestamp: msg.BlockTime, + TxHash: msg.Log.TxHash.Hex(), + TxType: "POOL_DEPOSIT", + Payload: map[string]any{ + "initiator": initiator.Hex(), + "tokenIn": tokenIn.Hex(), + "amountIn": amountIn.String(), + }, + } + + return emitter.Emit(ctx, poolDepositEvent) + } + + return nil +} + +func (h *PoolDepositHandler) HandleRevert(ctx context.Context, msg RevertMessage, emitter emitter.Emitter) error { + if len(msg.InputData) < 8 { + return nil + } + + switch msg.InputData[:8] { + case "47e7ef24": + var ( + tokenIn common.Address + amountIn big.Int + ) + + if err := poolDepositSig.DecodeArgs(w3.B(msg.InputData), &tokenIn, &amountIn); err != nil { + return err + } + + poolDepositEvent := Event{ + Block: msg.Block, + ContractAddress: msg.ContractAddress, + Success: false, + Timestamp: msg.Timestamp, + TxHash: msg.TxHash, + TxType: "POOL_DEPOSIT", + Payload: map[string]any{ + "revertReason": msg.RevertReason, + "initiator": msg.From, + "tokenIn": tokenIn.Hex(), + "amountIn": amountIn.String(), + }, + } + + return emitter.Emit(ctx, poolDepositEvent) + } + + return nil +} diff --git a/internal/handler/pool_swap.go b/internal/handler/pool_swap.go new file mode 100644 index 0000000..f4aaf7c --- /dev/null +++ b/internal/handler/pool_swap.go @@ -0,0 +1,110 @@ +package handler + +import ( + "context" + "math/big" + + "github.com/celo-org/celo-blockchain/common" + "github.com/grassrootseconomics/celo-tracker/internal/emitter" + "github.com/grassrootseconomics/w3-celo" +) + +type ( + PoolSwapHandler struct { + topicHash common.Hash + event *w3.Event + } +) + +var ( + poolSwapTopicHash = w3.H("0xd6d34547c69c5ee3d2667625c188acf1006abb93e0ee7cf03925c67cf7760413") + poolSwapEvent = w3.MustNewEvent("Swap(address indexed initiator, address indexed tokenIn, address tokenOut, uint256 amountIn, uint256 amountOut, uint256 fee)") + poolSwapSig = w3.MustNewFunc("withdraw(address, address, uint256)", "") +) + +func (h *PoolSwapHandler) HandleLog(ctx context.Context, msg LogMessage, emitter emitter.Emitter) error { + if msg.Log.Topics[0] == poolSwapTopicHash { + var ( + initiator common.Address + tokenIn common.Address + tokenOut common.Address + amountIn big.Int + amountOut big.Int + fee big.Int + ) + + if err := poolSwapEvent.DecodeArgs( + msg.Log, + &initiator, + &tokenIn, + &tokenOut, + &amountIn, + &amountOut, + &fee, + ); err != nil { + return err + } + + poolSwapEvent := Event{ + Block: msg.Log.BlockNumber, + ContractAddress: msg.Log.Address.Hex(), + Success: true, + Timestamp: msg.BlockTime, + TxHash: msg.Log.TxHash.Hex(), + TxType: "POOL_SWAP", + Payload: map[string]any{ + "initiator": initiator.Hex(), + "tokenIn": tokenIn.Hex(), + "tokenOut": tokenOut.Hex(), + "amountIn": amountIn.String(), + "amountOut": amountOut.String(), + "fee": fee.String(), + }, + } + + return emitter.Emit(ctx, poolSwapEvent) + } + + return nil +} + +func (h *PoolSwapHandler) HandleRevert(ctx context.Context, msg RevertMessage, emitter emitter.Emitter) error { + if len(msg.InputData) < 8 { + return nil + } + + switch msg.InputData[:8] { + case "d9caed12": + var ( + tokenOut common.Address + tokenIn common.Address + amountIn big.Int + ) + + if err := poolSwapSig.DecodeArgs(w3.B(msg.InputData), &tokenOut, &tokenIn, &amountIn); err != nil { + return err + } + + poolSwapEvent := Event{ + Block: msg.Block, + ContractAddress: msg.ContractAddress, + Success: false, + Timestamp: msg.Timestamp, + TxHash: msg.TxHash, + TxType: "POOL_SWAP", + Payload: map[string]any{ + "revertReason": msg.RevertReason, + "initiator": msg.From, + "tokenIn": tokenIn.Hex(), + "tokenOut": tokenOut.Hex(), + "amountIn": amountIn.String(), + "amountOut": "0", + "fee": "0", + }, + } + + return emitter.Emit(ctx, poolSwapEvent) + } + + return nil +} diff --git a/internal/handler/seal.go b/internal/handler/seal.go new file mode 100644 index 0000000..a76f03e --- /dev/null +++ b/internal/handler/seal.go @@ -0,0 +1,87 @@ +package handler + +import ( + "context" + "math/big" + + "github.com/celo-org/celo-blockchain/common" + "github.com/grassrootseconomics/celo-tracker/internal/emitter" + "github.com/grassrootseconomics/w3-celo" +) + +type ( + SealHandler struct { + topicHash common.Hash + event *w3.Event + } +) + +var ( + sealTopicHash = w3.H("0x6b7e2e653f93b645d4ed7292d6429f96637084363e477c8aaea1a43ed13c284e") + sealEvent = w3.MustNewEvent("SealStateChange(bool indexed _final, uint256 _sealState)") + sealToSig = w3.MustNewFunc("seal(uint256)", "uint256") +) + +func (h *SealHandler) HandleLog(ctx context.Context, msg LogMessage, emitter emitter.Emitter) error { + if msg.Log.Topics[0] == sealTopicHash { + var ( + final bool + sealState big.Int + ) + + if err := sealEvent.DecodeArgs(msg.Log, &final, &sealState); err != nil { + return err + } + + sealEvent := Event{ + Block: msg.Log.BlockNumber, + ContractAddress: msg.Log.Address.Hex(), + Success: true, + Timestamp: msg.BlockTime, + TxHash: msg.Log.TxHash.Hex(), + TxType: "SEAL_STATE_CHANGE", + Payload: map[string]any{ + "final": final, + "sealState": sealState.String(), + }, + } + + return emitter.Emit(ctx, sealEvent) + } + + return nil +} + +func (h *SealHandler) HandleRevert(ctx context.Context, msg RevertMessage, emitter emitter.Emitter) error { + if len(msg.InputData) < 8 { + return nil + } + + switch msg.InputData[:8] { + case "86fe212d": + var ( + sealState big.Int + ) + + if err := sealToSig.DecodeArgs(w3.B(msg.InputData), &sealState); err != nil { + return err + } + + sealEvent := Event{ + Block: msg.Block, + ContractAddress: msg.ContractAddress, + Success: false, + Timestamp: msg.Timestamp, + TxHash: msg.TxHash, + TxType: "SEAL_STATE_CHANGE", + Payload: map[string]any{ + "revertReason": msg.RevertReason, + "sealState": sealState.String(), + }, + } + + return emitter.Emit(ctx, sealEvent) + } + + return nil +} diff --git a/internal/handler/token_burn.go b/internal/handler/token_burn.go new file mode 100644 index 0000000..b33dd1d --- /dev/null +++ b/internal/handler/token_burn.go @@ -0,0 +1,88 @@ +package handler + +import ( + "context" + "math/big" + + "github.com/celo-org/celo-blockchain/common" + "github.com/grassrootseconomics/celo-tracker/internal/emitter" + "github.com/grassrootseconomics/w3-celo" +) + +type ( + BurnHandler struct { + topicHash common.Hash + event *w3.Event + } +) + +var ( + burnTopicHash = w3.H("0xcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca5") + burnEvent = w3.MustNewEvent("Burn(address indexed _burner, uint256 _value)") + burnToSig = w3.MustNewFunc("burn(uint256)", "bool") +) + +func (h *BurnHandler) HandleLog(ctx context.Context, msg LogMessage, emitter emitter.Emitter) error { + if msg.Log.Topics[0] == burnTopicHash { + var ( + burner common.Address + value big.Int + ) + + if err := burnEvent.DecodeArgs(msg.Log, &burner, &value); err != nil { + return err + } + + burnEvent := Event{ + Block: msg.Log.BlockNumber, + ContractAddress: msg.Log.Address.Hex(), + Success: true, + Timestamp: msg.BlockTime, + TxHash: msg.Log.TxHash.Hex(), + TxType: "BURN", + Payload: map[string]any{ + "burner": burner.Hex(), + "value": value.String(), + }, + } + + return emitter.Emit(ctx, burnEvent) + } + + return nil +} + +func (h *BurnHandler) HandleRevert(ctx context.Context, msg RevertMessage, emitter emitter.Emitter) error { + if len(msg.InputData) < 8 { + return nil + } + + switch msg.InputData[:8] { + case "42966c68": + var ( + value big.Int + ) + + if err := burnToSig.DecodeArgs(w3.B(msg.InputData), &value); err != nil { + return err + } + + burnEvent := Event{ + Block: msg.Block, + ContractAddress: msg.ContractAddress, + Success: false, + Timestamp: msg.Timestamp, + TxHash: msg.TxHash, + TxType: "BURN", + Payload: map[string]any{ + "revertReason": msg.RevertReason, + "burner": msg.From, + "value": value.String(), + }, + } + + return emitter.Emit(ctx, burnEvent) + } + + return nil +} diff --git a/internal/handler/token_mint.go b/internal/handler/token_mint.go new file mode 100644 index 0000000..d779665 --- /dev/null +++ b/internal/handler/token_mint.go @@ -0,0 +1,92 @@ +package handler + +import ( + "context" + "math/big" + + "github.com/celo-org/celo-blockchain/common" + "github.com/grassrootseconomics/celo-tracker/internal/emitter" + "github.com/grassrootseconomics/w3-celo" +) + +type ( + MintHandler struct { + topicHash common.Hash + event *w3.Event + } +) + +var ( + mintTopicHash = w3.H("0xab8530f87dc9b59234c4623bf917212bb2536d647574c8e7e5da92c2ede0c9f8") + mintEvent = w3.MustNewEvent("Mint(address indexed _minter, address indexed _beneficiary, uint256 _value)") + mintToSig = w3.MustNewFunc("mintTo(address, uint256)", "bool") +) + +func (h *MintHandler) HandleLog(ctx context.Context, msg LogMessage, emitter emitter.Emitter) error { + if msg.Log.Topics[0] == mintTopicHash { + var ( + minter common.Address + to common.Address + value big.Int + ) + + if err := mintEvent.DecodeArgs(msg.Log, &minter, &to, &value); err != nil { + return err + } + + mintEvent := Event{ + Block: msg.Log.BlockNumber, + ContractAddress: msg.Log.Address.Hex(), + Success: true, + Timestamp: msg.BlockTime, + TxHash: msg.Log.TxHash.Hex(), + TxType: "MINT", + Payload: map[string]any{ + "minter": minter.Hex(), + "to": to.Hex(), + "value": value.String(), + }, + } + + return emitter.Emit(ctx, mintEvent) + } + + return nil +} + +func (h *MintHandler) HandleRevert(ctx context.Context, msg RevertMessage, emitter emitter.Emitter) error { + if len(msg.InputData) < 8 { + return nil + } + + switch msg.InputData[:8] { + case "449a52f8": + var ( + to common.Address + value big.Int + ) + + if err := mintToSig.DecodeArgs(w3.B(msg.InputData), &to, &value); err != nil { + return err + } + + mintEvent := Event{ + Block: msg.Block, + ContractAddress: msg.ContractAddress, + Success: false, + Timestamp: msg.Timestamp, + TxHash: msg.TxHash, + TxType: "MINT", + Payload: map[string]any{ + "revertReason": msg.RevertReason, + "minter": msg.From, + "to": to.Hex(), + "value": value.String(), + }, + } + + return emitter.Emit(ctx, mintEvent) + } + + return nil +} diff --git a/internal/handler/transfer.go b/internal/handler/token_transfer.go similarity index 100% rename from internal/handler/transfer.go rename to internal/handler/token_transfer.go