diff --git a/internal/engine/worker/decentralized/contract/rainbow/worker.go b/internal/engine/worker/decentralized/contract/rainbow/worker.go new file mode 100644 index 00000000..e7e170e0 --- /dev/null +++ b/internal/engine/worker/decentralized/contract/rainbow/worker.go @@ -0,0 +1,447 @@ +package rainbow + +import ( + "bytes" + "context" + "fmt" + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/rss3-network/node/config" + "github.com/rss3-network/node/internal/engine" + source "github.com/rss3-network/node/internal/engine/source/ethereum" + "github.com/rss3-network/node/provider/ethereum" + "github.com/rss3-network/node/provider/ethereum/contract" + "github.com/rss3-network/node/provider/ethereum/contract/erc20" + "github.com/rss3-network/node/provider/ethereum/contract/rainbow" + "github.com/rss3-network/node/provider/ethereum/contract/weth" + "github.com/rss3-network/node/provider/ethereum/token" + "github.com/rss3-network/node/schema/worker/decentralized" + "github.com/rss3-network/protocol-go/schema" + activityx "github.com/rss3-network/protocol-go/schema/activity" + "github.com/rss3-network/protocol-go/schema/metadata" + "github.com/rss3-network/protocol-go/schema/network" + "github.com/rss3-network/protocol-go/schema/tag" + "github.com/rss3-network/protocol-go/schema/typex" + "github.com/samber/lo" + "github.com/shopspring/decimal" + "go.uber.org/zap" +) + +var _ engine.Worker = (*worker)(nil) + +type worker struct { + config *config.Module + ethereumClient ethereum.Client + tokenClient token.Client + erc20Filterer *erc20.ERC20Filterer + weth9Filterer *weth.WETH9Filterer +} + +// Name returns the name of the worker. +func (w *worker) Name() string { + return decentralized.Rainbow.String() +} + +// Platform returns the platform of the worker. +func (w *worker) Platform() string { + return decentralized.PlatformRainbow.String() +} + +// Network returns the supported networks of the worker. +func (w *worker) Network() []network.Network { + return []network.Network{ + network.Ethereum, + network.BinanceSmartChain, + network.Base, + network.Polygon, + network.Arbitrum, + network.Avalanche, + network.Optimism, + } +} + +// Tags returns the tags of the worker. +func (w *worker) Tags() []tag.Tag { + return []tag.Tag{ + tag.Exchange, + tag.Transaction, + } +} + +// Types returns the types of the worker. +func (w *worker) Types() []schema.Type { + return []schema.Type{ + typex.ExchangeSwap, + typex.TransactionTransfer, + } +} + +// Filter returns the filter of the worker. +func (w *worker) Filter() engine.DataSourceFilter { + return &source.Filter{} +} + +// Transform transforms the task into an activity. +func (w *worker) Transform(ctx context.Context, task engine.Task) (*activityx.Activity, error) { + ethereumTask, ok := task.(*source.Task) + if !ok { + return nil, fmt.Errorf("invalid task type %T", task) + } + + activity, err := ethereumTask.BuildActivity(activityx.WithActivityPlatform(w.Platform())) + if err != nil { + return nil, fmt.Errorf("build activity: %w", err) + } + + if w.matchSwapTransaction(ethereumTask) { + actions, err := w.transformSwapTransaction(ctx, ethereumTask) + if err != nil { + return nil, fmt.Errorf("handle ethereum swap transaction: %w", err) + } + + activity.Actions = append(activity.Actions, actions...) + } else { + return nil, fmt.Errorf("unknown transaction %s", ethereumTask.ID()) + } + + if len(activity.Actions) == 0 { + return nil, fmt.Errorf("no actions") + } + + zap.L().Info("Processing task", zap.Any("task", ethereumTask)) + zap.L().Info("activity is: ", zap.Any("activity", activity)) + + activity.Type = typex.ExchangeSwap + + return activity, nil +} + +// matchSwapTransaction checks if the transaction matches a swap transaction. +func (w *worker) matchSwapTransaction(task *source.Task) bool { + if task.Transaction == nil || task.Transaction.To == nil { + return false + } + + return *task.Transaction.To == rainbow.AddressRouter && + contract.MatchMethodIDs( + task.Transaction.Input, + rainbow.MethodIDRouterFillQuoteEthToToken, + rainbow.MethodIDRouterFillQuoteTokenToEth, + rainbow.MethodIDRouterFillQuoteTokenToToken, + ) +} + +// transformSwapTransaction transforms a swap transaction into actions. +func (w *worker) transformSwapTransaction(ctx context.Context, task *source.Task) ([]*activityx.Action, error) { + var actions []*activityx.Action + + switch { + case bytes.HasPrefix(task.Transaction.Input, rainbow.MethodIDRouterFillQuoteEthToToken[:4]): + ethToTokenActions, err := w.transformEthToTokenSwap(ctx, task) + if err != nil { + return nil, fmt.Errorf("transform ETH to token swap: %w", err) + } + + actions = append(actions, ethToTokenActions...) + case bytes.HasPrefix(task.Transaction.Input, rainbow.MethodIDRouterFillQuoteTokenToEth[:4]): + tokenToEthActions, err := w.transformTokenToEthSwap(ctx, task) + if err != nil { + return nil, fmt.Errorf("transform token to ETH swap: %w", err) + } + + actions = append(actions, tokenToEthActions...) + case bytes.HasPrefix(task.Transaction.Input, rainbow.MethodIDRouterFillQuoteTokenToToken[:4]): + tokenToTokenActions, err := w.transformTokenToTokenSwap(ctx, task) + if err != nil { + return nil, fmt.Errorf("transform token to token swap: %w", err) + } + + actions = append(actions, tokenToTokenActions...) + default: + return nil, fmt.Errorf("unknown swap type") + } + + return actions, nil +} + +// transformEthToTokenSwap transforms an ETH to token swap transaction. +func (w *worker) transformEthToTokenSwap(ctx context.Context, task *source.Task) ([]*activityx.Action, error) { + var ( + actions []*activityx.Action + valueMap = make(map[*common.Address]*big.Int) + ) + + abi, err := rainbow.RouterMetaData.GetAbi() + if err != nil { + return nil, fmt.Errorf("get abi: %w", err) + } + + method, err := abi.MethodById(rainbow.MethodIDRouterFillQuoteEthToToken[:4]) + if err != nil { + return nil, fmt.Errorf("get method by id: %w", err) + } + + values, err := method.Inputs.UnpackValues(task.Transaction.Input[4:]) + if err != nil { + return nil, fmt.Errorf("unpack values: %w", err) + } + + var input rainbow.RouterFillQuoteEthToTokenInput + if err := method.Inputs.Copy(&input, values); err != nil { + return nil, fmt.Errorf("copy input: %w", err) + } + + w.simulationTransfer(valueMap, true, nil, new(big.Int).Sub(task.Transaction.Value, input.FeeAmount)) + + feeAction, err := w.buildTransactionTransferAction(ctx, task, task.Transaction.From, rainbow.AddressRouter, nil, input.FeeAmount) + if err != nil { + return nil, fmt.Errorf("build transaction transfer action: %w", err) + } + + actions = append(actions, feeAction) + + return w.processSwapLogs(ctx, task, valueMap, actions) +} + +// transformTokenToEthSwap transforms a token to ETH swap transaction. +func (w *worker) transformTokenToEthSwap(ctx context.Context, task *source.Task) ([]*activityx.Action, error) { + var ( + actions []*activityx.Action + valueMap = make(map[*common.Address]*big.Int) + ) + + abi, err := rainbow.RouterMetaData.GetAbi() + if err != nil { + return nil, fmt.Errorf("get abi: %w", err) + } + + method, err := abi.MethodById(rainbow.MethodIDRouterFillQuoteTokenToEth[:4]) + if err != nil { + return nil, fmt.Errorf("get method by id: %w", err) + } + + values, err := method.Inputs.UnpackValues(task.Transaction.Input[4:]) + if err != nil { + return nil, fmt.Errorf("unpack values: %w", err) + } + + var input rainbow.RouterFillQuoteTokenToEthInput + if err := method.Inputs.Copy(&input, values); err != nil { + return nil, fmt.Errorf("copy input: %w", err) + } + + feePercentageBasisPoints := decimal.NewFromBigInt(input.FeePercentageBasisPoints, 0) + + return w.processSwapLogs(ctx, task, valueMap, actions, feePercentageBasisPoints) +} + +// transformTokenToTokenSwap transforms a token to token swap transaction. +func (w *worker) transformTokenToTokenSwap(ctx context.Context, task *source.Task) ([]*activityx.Action, error) { + var ( + actions []*activityx.Action + valueMap = make(map[*common.Address]*big.Int) + ) + + abi, err := rainbow.RouterMetaData.GetAbi() + if err != nil { + return nil, fmt.Errorf("get abi: %w", err) + } + + method, err := abi.MethodById(rainbow.MethodIDRouterFillQuoteTokenToToken[:4]) + if err != nil { + return nil, fmt.Errorf("get method by id: %w", err) + } + + values, err := method.Inputs.UnpackValues(task.Transaction.Input[4:]) + if err != nil { + return nil, fmt.Errorf("unpack values: %w", err) + } + + var input rainbow.RouterFillQuoteTokenToTokenInput + if err := method.Inputs.Copy(&input, values); err != nil { + return nil, fmt.Errorf("copy input: %w", err) + } + + feeAction, err := w.buildTransactionTransferAction(ctx, task, task.Transaction.From, rainbow.AddressRouter, &input.SellTokenAddress, input.FeeAmount) + if err != nil { + return nil, fmt.Errorf("build transaction transfer action: %w", err) + } + + actions = append(actions, feeAction) + + return w.processSwapLogs(ctx, task, valueMap, actions) +} + +// processSwapLogs processes the logs of a swap transaction. +func (w *worker) processSwapLogs(ctx context.Context, task *source.Task, valueMap map[*common.Address]*big.Int, actions []*activityx.Action, feePercentageBasisPoints ...decimal.Decimal) ([]*activityx.Action, error) { + for _, log := range task.Receipt.Logs { + if len(log.Topics) == 0 { + continue + } + + switch log.Topics[0] { + case erc20.EventHashTransfer: + if len(log.Topics) != 3 { + continue + } + + event, err := w.erc20Filterer.ParseTransfer(log.Export()) + if err != nil { + zap.L().Warn("parse event", zap.Error(err)) + continue + } + + if event.From == task.Transaction.From { + w.simulationTransfer(valueMap, true, &event.Raw.Address, event.Value) + } + + if event.To == task.Transaction.From { + w.simulationTransfer(valueMap, false, &event.Raw.Address, event.Value) + } + case weth.EventHashWithdrawal: + event, err := w.weth9Filterer.ParseWithdrawal(log.Export()) + if err != nil { + zap.L().Warn("parse event", zap.Error(err)) + continue + } + + w.simulationTransfer(valueMap, false, nil, event.Wad) + } + } + + tokenIn, tokenOut, err := w.findTokens(valueMap) + if err != nil { + return nil, err + } + + if len(feePercentageBasisPoints) > 0 && !feePercentageBasisPoints[0].IsZero() { + feeAction, err := w.buildFeeAction(ctx, task, tokenOut, valueMap[tokenOut], feePercentageBasisPoints[0]) + if err != nil { + return nil, err + } + + actions = append(actions, feeAction) + } + + swapAction, err := w.buildExchangeSwapAction(ctx, task, task.Transaction.From, task.Transaction.From, tokenIn, tokenOut, valueMap[tokenIn], valueMap[tokenOut]) + if err != nil { + return nil, fmt.Errorf("build exchange swap action: %w", err) + } + + actions = append(actions, swapAction) + + return actions, nil +} + +// findTokens finds the input and output tokens from the value map. +func (w *worker) findTokens(valueMap map[*common.Address]*big.Int) (*common.Address, *common.Address, error) { + tokenIn, exists := lo.FindKeyBy(valueMap, func(_ *common.Address, value *big.Int) bool { + return value.Sign() == -1 + }) + if !exists { + return nil, nil, fmt.Errorf("token in not match") + } + + tokenOut, exists := lo.FindKeyBy(valueMap, func(_ *common.Address, value *big.Int) bool { + return value.Sign() == 1 + }) + if !exists { + return nil, nil, fmt.Errorf("token out not match") + } + + return tokenIn, tokenOut, nil +} + +// buildFeeAction builds a fee action for the swap. +func (w *worker) buildFeeAction(ctx context.Context, task *source.Task, _ *common.Address, amountOut *big.Int, feePercentageBasisPoints decimal.Decimal) (*activityx.Action, error) { + ethDiff := decimal.NewFromBigInt(amountOut, 0) + fees := ethDiff.Mul(feePercentageBasisPoints).DivRound(decimal.NewFromInt(1e18), -1) + + return w.buildTransactionTransferAction(ctx, task, task.Transaction.From, rainbow.AddressRouter, nil, fees.BigInt()) +} + +// simulationTransfer simulates a token transfer in the value map. +func (w *worker) simulationTransfer(valueMap map[*common.Address]*big.Int, transferIn bool, token *common.Address, value *big.Int) { + if valueMap[token] == nil { + valueMap[token] = big.NewInt(0) + } + + if transferIn { + valueMap[token] = new(big.Int).Sub(valueMap[token], value) + } else { + valueMap[token] = new(big.Int).Add(valueMap[token], value) + } +} + +// buildExchangeSwapAction builds an exchange swap action. +func (w *worker) buildExchangeSwapAction(ctx context.Context, task *source.Task, from, to common.Address, tokenIn, tokenOut *common.Address, amountIn, amountOut *big.Int) (*activityx.Action, error) { + tokenInAddress := lo.Ternary(tokenIn != nil && *tokenIn != ethereum.AddressGenesis, tokenIn, nil) + tokenOutAddress := lo.Ternary(tokenOut != nil && *tokenOut != ethereum.AddressGenesis, tokenOut, nil) + + tokenInMetadata, err := w.tokenClient.Lookup(ctx, task.ChainID, tokenInAddress, nil, task.Header.Number) + if err != nil { + return nil, fmt.Errorf("lookup token in metadata: %w", err) + } + + tokenInMetadata.Value = lo.ToPtr(decimal.NewFromBigInt(amountIn, 0).Abs()) + + tokenOutMetadata, err := w.tokenClient.Lookup(ctx, task.ChainID, tokenOutAddress, nil, task.Header.Number) + if err != nil { + return nil, fmt.Errorf("lookup token out metadata: %w", err) + } + + tokenOutMetadata.Value = lo.ToPtr(decimal.NewFromBigInt(amountOut, 0).Abs()) + + return &activityx.Action{ + Type: typex.ExchangeSwap, + Platform: w.Platform(), + From: from.String(), + To: to.String(), + Metadata: metadata.ExchangeSwap{ + From: *tokenInMetadata, + To: *tokenOutMetadata, + }, + }, nil +} + +// buildTransactionTransferAction builds a transaction transfer action. +func (w *worker) buildTransactionTransferAction(ctx context.Context, task *source.Task, from, to common.Address, tokenAddress *common.Address, amount *big.Int) (*activityx.Action, error) { + tokenMetadata, err := w.tokenClient.Lookup(ctx, task.ChainID, tokenAddress, nil, task.Header.Number) + if err != nil { + return nil, fmt.Errorf("lookup token metadata: %w", err) + } + + tokenMetadata.Value = lo.ToPtr(decimal.NewFromBigInt(amount, 0)) + + return &activityx.Action{ + Type: typex.TransactionTransfer, + Platform: w.Platform(), + From: from.String(), + To: to.String(), + Metadata: metadata.TransactionTransfer(*tokenMetadata), + }, nil +} + +func NewWorker(config *config.Module) (engine.Worker, error) { + var err error + + instance := worker{ + config: config, + } + + // Initialize token client. + instance.tokenClient = token.NewClient(instance.ethereumClient) + + // Initialize filterers. + instance.erc20Filterer = lo.Must(erc20.NewERC20Filterer(ethereum.AddressGenesis, nil)) + instance.weth9Filterer = lo.Must(weth.NewWETH9Filterer(ethereum.AddressGenesis, nil)) + + if instance.ethereumClient, err = ethereum.Dial(context.Background(), config.Endpoint.URL, config.Endpoint.BuildEthereumOptions()...); err != nil { + return nil, fmt.Errorf("initialize ethereum client: %w", err) + } + + instance.tokenClient = token.NewClient(instance.ethereumClient) + + return &instance, nil +} diff --git a/internal/engine/worker/decentralized/contract/rainbow/worker_test.go b/internal/engine/worker/decentralized/contract/rainbow/worker_test.go new file mode 100644 index 00000000..34ff25ff --- /dev/null +++ b/internal/engine/worker/decentralized/contract/rainbow/worker_test.go @@ -0,0 +1,687 @@ +package rainbow_test + +import ( + "context" + "math/big" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/rss3-network/node/config" + source "github.com/rss3-network/node/internal/engine/source/ethereum" + worker "github.com/rss3-network/node/internal/engine/worker/decentralized/contract/rainbow" + "github.com/rss3-network/node/provider/ethereum" + "github.com/rss3-network/node/provider/ethereum/contract/rainbow" + "github.com/rss3-network/node/provider/ethereum/endpoint" + workerx "github.com/rss3-network/node/schema/worker/decentralized" + activityx "github.com/rss3-network/protocol-go/schema/activity" + "github.com/rss3-network/protocol-go/schema/metadata" + "github.com/rss3-network/protocol-go/schema/network" + "github.com/rss3-network/protocol-go/schema/typex" + "github.com/samber/lo" + "github.com/shopspring/decimal" + "github.com/stretchr/testify/require" +) + +func TestWorker_Rainbow(t *testing.T) { + t.Parallel() + + type arguments struct { + task *source.Task + config *config.Module + } + + testcases := []struct { + name string + arguments arguments + want *activityx.Activity + wantError require.ErrorAssertionFunc + }{ + { + name: "Swap ETH to GIGA on Ethereum", + arguments: struct { + task *source.Task + config *config.Module + }{ + task: &source.Task{ + Network: network.Ethereum, + ChainID: 1, + Header: ðereum.Header{ + Hash: common.HexToHash("0x49c8f0217c18bb6c1016ab256b214cc0b7cc49188a3d62a1265981598f57547e"), + ParentHash: common.HexToHash("0x2d0397a462ce1b249120c4b03495c83312c0f32be9463715f9f54cb147a5b3e2"), + UncleHash: common.HexToHash("0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347"), + Coinbase: common.HexToAddress("0x95222290DD7278Aa3Ddd389Cc1E1d165CC4BAfe5"), + Number: lo.Must(new(big.Int).SetString("20951604", 0)), + GasLimit: 30000000, + GasUsed: 11763606, + Timestamp: 1728761231, + BaseFee: lo.Must(new(big.Int).SetString("8288888059", 0)), + Transactions: nil, + }, + Transaction: ðereum.Transaction{ + BlockHash: common.HexToHash("0x53ea61bbe1656b89995690376c7c8b525bc046307546814578b7df7ec141557d"), + From: common.HexToAddress("0x9E7E6ee8607628362B25AdF109d5704Db3f4640F"), + Gas: 306544, + GasPrice: lo.Must(new(big.Int).SetString("8848505557", 10)), + Hash: common.HexToHash("0x53ea61bbe1656b89995690376c7c8b525bc046307546814578b7df7ec141557d"), + Input: hexutil.MustDecode("0x3c2b9a7d00000000000000000000000080ed012ef8dcd8e3a347d9034487aebd991bfda5000000000000000000000000111111125421ca6dc452d289314280a0f8842a65000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000013cf57ab448000000000000000000000000000000000000000000000000000000000000000048a76dfc3b000000000000000000000000000000000000000000000000035e0c7d905655d300000000000000003b6d03406c59c360ef92ae28dcda2b60cf0ffc1c08fd3a8fd6f29312000000000000000000000000000000000000000000000000d7e44d53"), + To: lo.ToPtr(common.HexToAddress("0x00000000009726632680FB29d3F7A9734E3010E2")), + Value: lo.Must(new(big.Int).SetString("41000000000000000", 0)), + Type: 2, + ChainID: lo.Must(new(big.Int).SetString("1", 0)), + }, + Receipt: ðereum.Receipt{ + BlockHash: common.HexToHash("0x49c8f0217c18bb6c1016ab256b214cc0b7cc49188a3d62a1265981598f57547e"), + BlockNumber: lo.Must(new(big.Int).SetString("20951604", 0)), + ContractAddress: nil, + CumulativeGasUsed: 8759489, + EffectiveGasPrice: hexutil.MustDecodeBig("0x20f697ad5"), + GasUsed: 229892, + + Logs: []*ethereum.Log{{ + Address: common.HexToAddress("0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"), + Topics: []common.Hash{ + common.HexToHash("0xe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c"), + common.HexToHash("0x000000000000000000000000111111125421ca6dc452d289314280a0f8842a65"), + }, + Data: hexutil.MustDecode("0x00000000000000000000000000000000000000000000000000906c52e9163800"), + BlockNumber: lo.Must(new(big.Int).SetString("20951604", 0)), + TransactionHash: common.HexToHash("0x53ea61bbe1656b89995690376c7c8b525bc046307546814578b7df7ec141557d"), + Index: 199, + Removed: false, + }, { + Address: common.HexToAddress("0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"), + Topics: []common.Hash{ + common.HexToHash("0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"), + common.HexToHash("0x000000000000000000000000111111125421ca6dc452d289314280a0f8842a65"), + common.HexToHash("0x0000000000000000000000006c59c360ef92ae28dcda2b60cf0ffc1c08fd3a8f"), + }, + Data: hexutil.MustDecode("0x00000000000000000000000000000000000000000000000000906c52e9163800"), + BlockNumber: lo.Must(new(big.Int).SetString("20951604", 0)), + TransactionHash: common.HexToHash("0x53ea61bbe1656b89995690376c7c8b525bc046307546814578b7df7ec141557d"), + Index: 200, + Removed: false, + }, { + Address: common.HexToAddress("0x80eD012ef8dcd8e3A347D9034487AeBd991bfDA5"), + Topics: []common.Hash{ + common.HexToHash("0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"), + common.HexToHash("0x0000000000000000000000006c59c360ef92ae28dcda2b60cf0ffc1c08fd3a8f"), + common.HexToHash("0x00000000000000000000000000000000009726632680fb29d3f7a9734e3010e2"), + }, + Data: hexutil.MustDecode("0x000000000000000000000000000000000000000000000000036fa4416eb62355"), + BlockNumber: lo.Must(new(big.Int).SetString("20951604", 0)), + TransactionHash: common.HexToHash("0x53ea61bbe1656b89995690376c7c8b525bc046307546814578b7df7ec141557d"), + Index: 201, + Removed: false, + }, { + Address: common.HexToAddress("0x6c59c360ef92AE28DcdA2B60CF0fFc1C08Fd3a8F"), + Topics: []common.Hash{ + common.HexToHash("0x1c411e9a96e071241c2f21f7726b17ae89e3cab4c78be50e062b03a9fffbbad1"), + }, + Data: hexutil.MustDecode("0x000000000000000000000000000000000000000000000004c3b6b3814f22f3ac000000000000000000000000000000000000000000000000c8388f18004f084d"), + BlockNumber: lo.Must(new(big.Int).SetString("20951604", 0)), + TransactionHash: common.HexToHash("0x53ea61bbe1656b89995690376c7c8b525bc046307546814578b7df7ec141557d"), + Index: 202, + Removed: false, + }, { + Address: common.HexToAddress("0x6c59c360ef92AE28DcdA2B60CF0fFc1C08Fd3a8F"), + Topics: []common.Hash{ + common.HexToHash("0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"), + common.HexToHash("0x000000000000000000000000111111125421ca6dc452d289314280a0f8842a65"), + common.HexToHash("0x00000000000000000000000000000000009726632680fb29d3f7a9734e3010e2"), + }, + Data: hexutil.MustDecode("0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000906c52e9163800000000000000000000000000000000000000000000000000036fa4416eb623550000000000000000000000000000000000000000000000000000000000000000"), + BlockNumber: lo.Must(new(big.Int).SetString("20951604", 0)), + TransactionHash: common.HexToHash("0x53ea61bbe1656b89995690376c7c8b525bc046307546814578b7df7ec141557d"), + Index: 203, + Removed: false, + }, { + Address: common.HexToAddress("0x80eD012ef8dcd8e3A347D9034487AeBd991bfDA5"), + Topics: []common.Hash{ + common.HexToHash("0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"), + common.HexToHash("0x00000000000000000000000000000000009726632680fb29d3f7a9734e3010e2"), + common.HexToHash("0x0000000000000000000000009e7e6ee8607628362b25adf109d5704db3f4640f"), + }, + Data: hexutil.MustDecode("0x000000000000000000000000000000000000000000000000036fa4416eb62355"), + BlockNumber: lo.Must(new(big.Int).SetString("20951604", 0)), + TransactionHash: common.HexToHash("0x53ea61bbe1656b89995690376c7c8b525bc046307546814578b7df7ec141557d"), + Index: 204, + Removed: false, + }}, + Status: 1, + TransactionHash: common.HexToHash("0x53ea61bbe1656b89995690376c7c8b525bc046307546814578b7df7ec141557d"), + TransactionIndex: 110, + }, + }, + config: &config.Module{ + Network: network.Ethereum, + Endpoint: config.Endpoint{ + URL: endpoint.MustGet(network.Ethereum), + }, + }, + }, + want: &activityx.Activity{ + ID: "0x53ea61bbe1656b89995690376c7c8b525bc046307546814578b7df7ec141557d", + Network: network.Ethereum, + Index: 110, + From: "0x9E7E6ee8607628362B25AdF109d5704Db3f4640F", + To: rainbow.AddressRouter.String(), + Type: typex.ExchangeSwap, + Platform: workerx.PlatformRainbow.String(), + Fee: &activityx.Fee{ + Amount: lo.Must(decimal.NewFromString("2034200639509844")), + Decimal: 18, + }, + Calldata: &activityx.Calldata{ + FunctionHash: "0x3c2b9a7d", + }, + Actions: []*activityx.Action{ + { + Type: typex.TransactionTransfer, + Platform: workerx.PlatformRainbow.String(), + From: "0x9E7E6ee8607628362B25AdF109d5704Db3f4640F", + To: rainbow.AddressRouter.String(), + Metadata: metadata.TransactionTransfer{ + Value: lo.ToPtr(lo.Must(decimal.NewFromString("348500000000000"))), + Name: "Ethereum", + Symbol: "ETH", + Decimals: 18, + }, + }, + { + Type: typex.ExchangeSwap, + Platform: workerx.PlatformRainbow.String(), + From: "0x9E7E6ee8607628362B25AdF109d5704Db3f4640F", + To: "0x9E7E6ee8607628362B25AdF109d5704Db3f4640F", + Metadata: metadata.ExchangeSwap{ + From: metadata.Token{ + Value: lo.ToPtr(lo.Must(decimal.NewFromString("40651500000000000"))), + Name: "Ethereum", + Symbol: "ETH", + Decimals: 18, + }, + To: metadata.Token{ + Address: lo.ToPtr("0x80eD012ef8dcd8e3A347D9034487AeBd991bfDA5"), + Value: lo.ToPtr(lo.Must(decimal.NewFromString("247597105465926485"))), + Name: "Gigachad", + Symbol: "GIGA", + Decimals: 9, + Standard: metadata.StandardERC20, + }, + }, + }, + }, + Status: true, + Timestamp: 1728761231, + }, + wantError: require.NoError, + }, + { + name: "Swap TITANX to ETH on Ethereum", + arguments: struct { + task *source.Task + config *config.Module + }{ + task: &source.Task{ + Network: network.Ethereum, + ChainID: 1, + Header: ðereum.Header{ + Hash: common.HexToHash("0xeffb81993ffaa95a6aa1468a5ce98e6d1ca1f05a74ed0b5563b8d599b8ba49d6"), + ParentHash: common.HexToHash("0xccc6959e2240281b8c01ad6ea59cc164c16c2800f36216742656277812baf36c"), + UncleHash: common.HexToHash("0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347"), + Coinbase: common.HexToAddress("0x95222290DD7278Aa3Ddd389Cc1E1d165CC4BAfe5"), + Number: lo.Must(new(big.Int).SetString("20951621", 0)), + GasLimit: 30000000, + GasUsed: 11209801, + Timestamp: 1728761435, + BaseFee: lo.Must(new(big.Int).SetString("8493926498", 0)), + Transactions: nil, + }, + Transaction: ðereum.Transaction{ + BlockHash: common.HexToHash("0xc271bf87f59dd80d59e4c8d90ba5e709304213c71831e1c9f79d9b77ff27fd3a"), + From: common.HexToAddress("0x5b527F39DB322e82D4faB0f6934AF3Ee7007AD1c"), + Gas: 222940, + GasPrice: lo.Must(new(big.Int).SetString("8546056557", 10)), + Hash: common.HexToHash("0xc271bf87f59dd80d59e4c8d90ba5e709304213c71831e1c9f79d9b77ff27fd3a"), + Input: hexutil.MustDecode("0x999b6464000000000000000000000000f19308f923582a6f7c465e5ce7a9dc1bec6665b1000000000000000000000000111111125421ca6dc452d289314280a0f8842a6500000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000003f96ea19b9c9dbb8e000000000000000000000000000000000000000000000000000000001e32b478974000000000000000000000000000000000000000000000000000000000000000008883800a8e000000000000000000000000f19308f923582a6f7c465e5ce7a9dc1bec6665b1000000000000000000000000000000000000000003f96ea19b9c9dbb8e00000000000000000000000000000000000000000000000000000007c77ca5585f16e2380000000000000000000000c45a81bc23a64ea556ab4cdf08a86b61cdceea8bd6f29312000000000000000000000000000000000000000000000000d7e44d53"), + To: lo.ToPtr(common.HexToAddress("0x00000000009726632680FB29d3F7A9734E3010E2")), + Value: lo.Must(new(big.Int).SetString("0", 0)), + Type: 2, + ChainID: lo.Must(new(big.Int).SetString("1", 0)), + }, + Receipt: ðereum.Receipt{ + BlockHash: common.HexToHash("0xeffb81993ffaa95a6aa1468a5ce98e6d1ca1f05a74ed0b5563b8d599b8ba49d6"), + BlockNumber: lo.Must(new(big.Int).SetString("20951621", 0)), + ContractAddress: nil, + CumulativeGasUsed: 9215918, + EffectiveGasPrice: hexutil.MustDecodeBig("0x1fd62796d"), + GasUsed: 160057, + + Logs: []*ethereum.Log{{ + Address: common.HexToAddress("0xF19308F923582A6f7c465e5CE7a9Dc1BEC6665B1"), + Topics: []common.Hash{ + common.HexToHash("0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"), + common.HexToHash("0x0000000000000000000000005b527f39db322e82d4fab0f6934af3ee7007ad1c"), + common.HexToHash("0x00000000000000000000000000000000009726632680fb29d3f7a9734e3010e2"), + }, + Data: hexutil.MustDecode("0x000000000000000000000000000000000000000003f96ea19b9c9dbb8e000000"), + BlockNumber: lo.Must(new(big.Int).SetString("20951621", 0)), + TransactionHash: common.HexToHash("0xc271bf87f59dd80d59e4c8d90ba5e709304213c71831e1c9f79d9b77ff27fd3a"), + Index: 263, + Removed: false, + }, { + Address: common.HexToAddress("0xF19308F923582A6f7c465e5CE7a9Dc1BEC6665B1"), + Topics: []common.Hash{ + common.HexToHash("0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"), + common.HexToHash("0x00000000000000000000000000000000009726632680fb29d3f7a9734e3010e2"), + common.HexToHash("0x000000000000000000000000111111125421ca6dc452d289314280a0f8842a65"), + }, + Data: hexutil.MustDecode("0x000000000000000000000000000000000000000003f96ea19b9c9dbb8e000000"), + BlockNumber: lo.Must(new(big.Int).SetString("20951621", 0)), + TransactionHash: common.HexToHash("0xc271bf87f59dd80d59e4c8d90ba5e709304213c71831e1c9f79d9b77ff27fd3a"), + Index: 264, + Removed: false, + }, { + Address: common.HexToAddress("0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"), + Topics: []common.Hash{ + common.HexToHash("0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"), + common.HexToHash("0x000000000000000000000000c45a81bc23a64ea556ab4cdf08a86b61cdceea8b"), + common.HexToHash("0x000000000000000000000000111111125421ca6dc452d289314280a0f8842a65"), + }, + Data: hexutil.MustDecode("0x00000000000000000000000000000000000000000000000007db9a5970896c73"), + BlockNumber: lo.Must(new(big.Int).SetString("20951621", 0)), + TransactionHash: common.HexToHash("0xc271bf87f59dd80d59e4c8d90ba5e709304213c71831e1c9f79d9b77ff27fd3a"), + Index: 265, + Removed: false, + }, { + Address: common.HexToAddress("0xF19308F923582A6f7c465e5CE7a9Dc1BEC6665B1"), + Topics: []common.Hash{ + common.HexToHash("0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"), + common.HexToHash("0x00000000000000000000000000000000009726632680fb29d3f7a9734e3010e2"), + common.HexToHash("0x000000000000000000000000111111125421ca6dc452d289314280a0f8842a65"), + }, + Data: hexutil.MustDecode("0x0000000000000000000000000000000000000000000000000000000000000000"), + BlockNumber: lo.Must(new(big.Int).SetString("20951621", 0)), + TransactionHash: common.HexToHash("0xc271bf87f59dd80d59e4c8d90ba5e709304213c71831e1c9f79d9b77ff27fd3a"), + Index: 266, + Removed: false, + }, { + Address: common.HexToAddress("0xF19308F923582A6f7c465e5CE7a9Dc1BEC6665B1"), + Topics: []common.Hash{ + common.HexToHash("0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"), + common.HexToHash("0x00000000000000000000000000000000009726632680fb29d3f7a9734e3010e2"), + common.HexToHash("0x000000000000000000000000c45a81bc23a64ea556ab4cdf08a86b61cdceea8b"), + }, + Data: hexutil.MustDecode("0x000000000000000000000000000000000000000003f96ea19b9c9dbb8e000000"), + BlockNumber: lo.Must(new(big.Int).SetString("20951621", 0)), + TransactionHash: common.HexToHash("0xc271bf87f59dd80d59e4c8d90ba5e709304213c71831e1c9f79d9b77ff27fd3a"), + Index: 267, + Removed: false, + }, { + Address: common.HexToAddress("0xc45A81BC23A64eA556ab4CdF08A86B61cdcEEA8b"), + Topics: []common.Hash{ + common.HexToHash("0xc42079f94a6350d7e6235f29174924f928cc2ac818eb64fed8004e115fbcca67"), + common.HexToHash("0x000000000000000000000000111111125421ca6dc452d289314280a0f8842a65"), + common.HexToHash("0x000000000000000000000000111111125421ca6dc452d289314280a0f8842a65"), + }, + Data: hexutil.MustDecode("0xfffffffffffffffffffffffffffffffffffffffffffffffff82465a68f76938d000000000000000000000000000000000000000003f96ea19b9c9dbb8e000000000000000000000000000000000000000000b5305a7ce383ffa91e03f1151092000000000000000000000000000000000000000000330e14b4badb6eecf8c5220000000000000000000000000000000000000000000000000000000000034779"), + BlockNumber: lo.Must(new(big.Int).SetString("20951621", 0)), + TransactionHash: common.HexToHash("0xc271bf87f59dd80d59e4c8d90ba5e709304213c71831e1c9f79d9b77ff27fd3a"), + Index: 268, + Removed: false, + }, { + Address: common.HexToAddress("0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"), + Topics: []common.Hash{ + common.HexToHash("0x7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65"), + common.HexToHash("0x000000000000000000000000111111125421ca6dc452d289314280a0f8842a65"), + }, + Data: hexutil.MustDecode("0x00000000000000000000000000000000000000000000000007db9a5970896c73"), + BlockNumber: lo.Must(new(big.Int).SetString("20951621", 0)), + TransactionHash: common.HexToHash("0xc271bf87f59dd80d59e4c8d90ba5e709304213c71831e1c9f79d9b77ff27fd3a"), + Index: 269, + Removed: false, + }}, + Status: 1, + TransactionHash: common.HexToHash("0xc271bf87f59dd80d59e4c8d90ba5e709304213c71831e1c9f79d9b77ff27fd3a"), + TransactionIndex: 103, + }, + }, + config: &config.Module{ + Network: network.Ethereum, + Endpoint: config.Endpoint{ + URL: endpoint.MustGet(network.Ethereum), + }, + }, + }, + want: &activityx.Activity{ + ID: "0xc271bf87f59dd80d59e4c8d90ba5e709304213c71831e1c9f79d9b77ff27fd3a", + Network: network.Ethereum, + Index: 103, + From: "0x5b527F39DB322e82D4faB0f6934AF3Ee7007AD1c", + To: rainbow.AddressRouter.String(), + Type: typex.ExchangeSwap, + Platform: workerx.PlatformRainbow.String(), + Fee: &activityx.Fee{ + Amount: lo.Must(decimal.NewFromString("1367856174343749")), + Decimal: 18, + }, + Calldata: &activityx.Calldata{ + FunctionHash: "0x999b6464", + }, + Actions: []*activityx.Action{ + { + Type: typex.TransactionTransfer, + Platform: workerx.PlatformRainbow.String(), + From: "0x5b527F39DB322e82D4faB0f6934AF3Ee7007AD1c", + To: rainbow.AddressRouter.String(), + Metadata: metadata.TransactionTransfer{ + Value: lo.ToPtr(lo.Must(decimal.NewFromString("4812835040315580"))), + Name: "Ethereum", + Symbol: "ETH", + Decimals: 18, + }, + }, + { + Type: typex.ExchangeSwap, + Platform: workerx.PlatformRainbow.String(), + From: "0x5b527F39DB322e82D4faB0f6934AF3Ee7007AD1c", + To: "0x5b527F39DB322e82D4faB0f6934AF3Ee7007AD1c", + Metadata: metadata.ExchangeSwap{ + From: metadata.Token{ + Address: lo.ToPtr("0xF19308F923582A6f7c465e5CE7a9Dc1BEC6665B1"), + Value: lo.ToPtr(lo.Must(decimal.NewFromString("1230000000000000000000000000"))), + Name: "TITAN X", + Symbol: "TITANX", + Decimals: 18, + Standard: metadata.StandardERC20, + }, + To: metadata.Token{ + Value: lo.ToPtr(lo.Must(decimal.NewFromString("566215887095950451"))), + Name: "Ethereum", + Symbol: "ETH", + Decimals: 18, + }, + }, + }, + }, + Status: true, + Timestamp: 1728761435, + }, + wantError: require.NoError, + }, + { + name: "Swap PEIPEI to USDC on Ethereum", + arguments: struct { + task *source.Task + config *config.Module + }{ + task: &source.Task{ + Network: network.Ethereum, + ChainID: 1, + Header: ðereum.Header{ + Hash: common.HexToHash("0x1a943b26a8490bca600c79909bf590cf9cb93177ff228ef6b9b3aeeabc180471"), + ParentHash: common.HexToHash("0x2454e595d850603d285aab7403edef2dd35eecd29e412bd87b84faa68b4c2701"), + UncleHash: common.HexToHash("0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347"), + Coinbase: common.HexToAddress("0x95222290DD7278Aa3Ddd389Cc1E1d165CC4BAfe5"), + Number: lo.Must(new(big.Int).SetString("20960347", 0)), + GasLimit: 30000000, + GasUsed: 13080242, + Timestamp: 1728867131, + BaseFee: lo.Must(new(big.Int).SetString("7446526121", 0)), + Transactions: nil, + }, + Transaction: ðereum.Transaction{ + BlockHash: common.HexToHash("0xcd4e9395bb9ee875337c1e126dec94635f234c8107f5378a1f2e6eb5deb90f24"), + From: common.HexToAddress("0xbBb87B2E1aF93c326BA6fA10333c79A02c888ad8"), + Gas: 344747, + GasPrice: lo.Must(new(big.Int).SetString("8453057815", 10)), + Hash: common.HexToHash("0xcd4e9395bb9ee875337c1e126dec94635f234c8107f5378a1f2e6eb5deb90f24"), + Input: hexutil.MustDecode("0x55e4b7be0000000000000000000000003ffeea07a27fab7ad1df5297fa75e77a43cb5790000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000111111125421ca6dc452d289314280a0f8842a6500000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000561ae8868f4c970d16d9ad38000000000000000000000000000000000000000000bb5d5e53e7f26f996904ac00000000000000000000000000000000000000000000000000000000000000a88770ba910000000000000000000000003ffeea07a27fab7ad1df5297fa75e77a43cb57900000000000000000000000000000000000000000555f8b283b64a49d7d70a88c00000000000000000000000000000000000000000000000000000000dc22049e08800000000000003b6d0340bf16540c857b4e32ce6c37d2f7725c8eec869b8b00000000000000003b6d0340b4e16d0168e52d35cacd2c6185b44281ec28c9dcd6f29312000000000000000000000000000000000000000000000000d7e44d53"), + To: lo.ToPtr(common.HexToAddress("0x00000000009726632680FB29d3F7A9734E3010E2")), + Value: lo.Must(new(big.Int).SetString("0", 0)), + Type: 2, + ChainID: lo.Must(new(big.Int).SetString("1", 0)), + }, + Receipt: ðereum.Receipt{ + BlockHash: common.HexToHash("0x1a943b26a8490bca600c79909bf590cf9cb93177ff228ef6b9b3aeeabc180471"), + BlockNumber: lo.Must(new(big.Int).SetString("20960347", 0)), + ContractAddress: nil, + CumulativeGasUsed: 6717867, + EffectiveGasPrice: hexutil.MustDecodeBig("0x1f7d76d17"), + GasUsed: 248433, + + Logs: []*ethereum.Log{{ + Address: common.HexToAddress("0x3fFEea07a27Fab7ad1df5297fa75e77a43CB5790"), + Topics: []common.Hash{ + common.HexToHash("0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"), + common.HexToHash("0x000000000000000000000000bbb87b2e1af93c326ba6fa10333c79a02c888ad8"), + common.HexToHash("0x00000000000000000000000000000000009726632680fb29d3f7a9734e3010e2"), + }, + Data: hexutil.MustDecode("0x0000000000000000000000000000000000000000561ae8868f4c970d16d9ad38"), + BlockNumber: lo.Must(new(big.Int).SetString("20960347", 0)), + TransactionHash: common.HexToHash("0xcd4e9395bb9ee875337c1e126dec94635f234c8107f5378a1f2e6eb5deb90f24"), + Index: 202, + Removed: false, + }, { + Address: common.HexToAddress("0x3fFEea07a27Fab7ad1df5297fa75e77a43CB5790"), + Topics: []common.Hash{ + common.HexToHash("0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"), + common.HexToHash("0x000000000000000000000000bbb87b2e1af93c326ba6fa10333c79a02c888ad8"), + common.HexToHash("0x00000000000000000000000000000000009726632680fb29d3f7a9734e3010e2"), + }, + Data: hexutil.MustDecode("0xfffffffffffffffffffffffffffffffffffffffa6245c58bc3e3d5e07de38a18"), + BlockNumber: lo.Must(new(big.Int).SetString("20960347", 0)), + TransactionHash: common.HexToHash("0xcd4e9395bb9ee875337c1e126dec94635f234c8107f5378a1f2e6eb5deb90f24"), + Index: 203, + Removed: false, + }, { + Address: common.HexToAddress("0x3fFEea07a27Fab7ad1df5297fa75e77a43CB5790"), + Topics: []common.Hash{ + common.HexToHash("0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"), + common.HexToHash("0x00000000000000000000000000000000009726632680fb29d3f7a9734e3010e2"), + common.HexToHash("0x000000000000000000000000111111125421ca6dc452d289314280a0f8842a65"), + }, + Data: hexutil.MustDecode("0x0000000000000000000000000000000000000000555f8b283b64a49d7d70a88c"), + BlockNumber: lo.Must(new(big.Int).SetString("20960347", 0)), + TransactionHash: common.HexToHash("0xcd4e9395bb9ee875337c1e126dec94635f234c8107f5378a1f2e6eb5deb90f24"), + Index: 204, + Removed: false, + }, { + Address: common.HexToAddress("0x3fFEea07a27Fab7ad1df5297fa75e77a43CB5790"), + Topics: []common.Hash{ + common.HexToHash("0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"), + common.HexToHash("0x00000000000000000000000000000000009726632680fb29d3f7a9734e3010e2"), + common.HexToHash("0x000000000000000000000000bf16540c857b4e32ce6c37d2f7725c8eec869b8b"), + }, + Data: hexutil.MustDecode("0x0000000000000000000000000000000000000000555f8b283b64a49d7d70a88c"), + BlockNumber: lo.Must(new(big.Int).SetString("20960347", 0)), + TransactionHash: common.HexToHash("0xcd4e9395bb9ee875337c1e126dec94635f234c8107f5378a1f2e6eb5deb90f24"), + Index: 205, + Removed: false, + }, { + Address: common.HexToAddress("0x3fFEea07a27Fab7ad1df5297fa75e77a43CB5790"), + Topics: []common.Hash{ + common.HexToHash("0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"), + common.HexToHash("0x00000000000000000000000000000000009726632680fb29d3f7a9734e3010e2"), + common.HexToHash("0x000000000000000000000000111111125421ca6dc452d289314280a0f8842a65"), + }, + Data: hexutil.MustDecode("0x0000000000000000000000000000000000000000000000000000000000000000"), + BlockNumber: lo.Must(new(big.Int).SetString("20960347", 0)), + TransactionHash: common.HexToHash("0xcd4e9395bb9ee875337c1e126dec94635f234c8107f5378a1f2e6eb5deb90f24"), + Index: 206, + Removed: false, + }, { + Address: common.HexToAddress("0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"), + Topics: []common.Hash{ + common.HexToHash("0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"), + common.HexToHash("0x000000000000000000000000bf16540c857b4e32ce6c37d2f7725c8eec869b8b"), + common.HexToHash("0x000000000000000000000000b4e16d0168e52d35cacd2c6185b44281ec28c9dc"), + }, + Data: hexutil.MustDecode("0x000000000000000000000000000000000000000000000000155a6c93a446fff9"), + BlockNumber: lo.Must(new(big.Int).SetString("20960347", 0)), + TransactionHash: common.HexToHash("0xcd4e9395bb9ee875337c1e126dec94635f234c8107f5378a1f2e6eb5deb90f24"), + Index: 207, + Removed: false, + }, { + Address: common.HexToAddress("0xbF16540c857B4e32cE6C37d2F7725C8eEC869B8b"), + Topics: []common.Hash{ + common.HexToHash("0x1c411e9a96e071241c2f21f7726b17ae89e3cab4c78be50e062b03a9fffbbad1"), + }, + Data: hexutil.MustDecode("0x0000000000000000000000000000000000000067f12992e52537d238137fb5ae000000000000000000000000000000000000000000000019fdfd59c84dc6e642"), + BlockNumber: lo.Must(new(big.Int).SetString("20960347", 0)), + TransactionHash: common.HexToHash("0xcd4e9395bb9ee875337c1e126dec94635f234c8107f5378a1f2e6eb5deb90f24"), + Index: 208, + Removed: false, + }, { + Address: common.HexToAddress("0xbF16540c857B4e32cE6C37d2F7725C8eEC869B8b"), + Topics: []common.Hash{ + common.HexToHash("0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"), + common.HexToHash("0x000000000000000000000000111111125421ca6dc452d289314280a0f8842a65"), + common.HexToHash("0x000000000000000000000000b4e16d0168e52d35cacd2c6185b44281ec28c9dc"), + }, + Data: hexutil.MustDecode("0x0000000000000000000000000000000000000000555f8b283b64a49d7d70a88c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000155a6c93a446fff9"), + BlockNumber: lo.Must(new(big.Int).SetString("20960347", 0)), + TransactionHash: common.HexToHash("0xcd4e9395bb9ee875337c1e126dec94635f234c8107f5378a1f2e6eb5deb90f24"), + Index: 209, + Removed: false, + }, { + Address: common.HexToAddress("0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"), + Topics: []common.Hash{ + common.HexToHash("0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"), + common.HexToHash("0x000000000000000000000000b4e16d0168e52d35cacd2c6185b44281ec28c9dc"), + common.HexToHash("0x00000000000000000000000000000000009726632680fb29d3f7a9734e3010e2"), + }, + Data: hexutil.MustDecode("0x00000000000000000000000000000000000000000000000000000000e0a0199d"), + BlockNumber: lo.Must(new(big.Int).SetString("20960347", 0)), + TransactionHash: common.HexToHash("0xcd4e9395bb9ee875337c1e126dec94635f234c8107f5378a1f2e6eb5deb90f24"), + Index: 210, + Removed: false, + }, { + Address: common.HexToAddress("0xB4e16d0168e52d35CaCD2c6185b44281Ec28C9Dc"), + Topics: []common.Hash{ + common.HexToHash("0x1c411e9a96e071241c2f21f7726b17ae89e3cab4c78be50e062b03a9fffbbad1"), + }, + Data: hexutil.MustDecode("0x00000000000000000000000000000000000000000000000000002785d6b5cb8c0000000000000000000000000000000000000000000003bf03b9e23d1cc952e9"), + BlockNumber: lo.Must(new(big.Int).SetString("20960347", 0)), + TransactionHash: common.HexToHash("0xcd4e9395bb9ee875337c1e126dec94635f234c8107f5378a1f2e6eb5deb90f24"), + Index: 211, + Removed: false, + }, { + Address: common.HexToAddress("0xB4e16d0168e52d35CaCD2c6185b44281Ec28C9Dc"), + Topics: []common.Hash{ + common.HexToHash("0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"), + common.HexToHash("0x000000000000000000000000111111125421ca6dc452d289314280a0f8842a65"), + common.HexToHash("0x00000000000000000000000000000000009726632680fb29d3f7a9734e3010e2"), + }, + Data: hexutil.MustDecode("0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000155a6c93a446fff900000000000000000000000000000000000000000000000000000000e0a0199d0000000000000000000000000000000000000000000000000000000000000000"), + BlockNumber: lo.Must(new(big.Int).SetString("20960347", 0)), + TransactionHash: common.HexToHash("0xcd4e9395bb9ee875337c1e126dec94635f234c8107f5378a1f2e6eb5deb90f24"), + Index: 212, + Removed: false, + }, { + Address: common.HexToAddress("0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"), + Topics: []common.Hash{ + common.HexToHash("0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"), + common.HexToHash("0x00000000000000000000000000000000009726632680fb29d3f7a9734e3010e2"), + common.HexToHash("0x000000000000000000000000bbb87b2e1af93c326ba6fa10333c79a02c888ad8"), + }, + Data: hexutil.MustDecode("0x00000000000000000000000000000000000000000000000000000000e0a0199d"), + BlockNumber: lo.Must(new(big.Int).SetString("20960347", 0)), + TransactionHash: common.HexToHash("0xcd4e9395bb9ee875337c1e126dec94635f234c8107f5378a1f2e6eb5deb90f24"), + Index: 213, + Removed: false, + }}, + Status: 1, + TransactionHash: common.HexToHash("0xcd4e9395bb9ee875337c1e126dec94635f234c8107f5378a1f2e6eb5deb90f24"), + TransactionIndex: 70, + }, + }, + config: &config.Module{ + Network: network.Ethereum, + Endpoint: config.Endpoint{ + URL: endpoint.MustGet(network.Ethereum), + }, + }, + }, + want: &activityx.Activity{ + ID: "0xcd4e9395bb9ee875337c1e126dec94635f234c8107f5378a1f2e6eb5deb90f24", + Network: network.Ethereum, + Index: 70, + From: "0xbBb87B2E1aF93c326BA6fA10333c79A02c888ad8", + To: rainbow.AddressRouter.String(), + Type: typex.ExchangeSwap, + Platform: workerx.PlatformRainbow.String(), + Fee: &activityx.Fee{ + Amount: lo.Must(decimal.NewFromString("2100018512153895")), + Decimal: 18, + }, + Calldata: &activityx.Calldata{ + FunctionHash: "0x55e4b7be", + }, + Actions: []*activityx.Action{ + { + Type: typex.TransactionTransfer, + Platform: workerx.PlatformRainbow.String(), + From: "0xbBb87B2E1aF93c326BA6fA10333c79A02c888ad8", + To: rainbow.AddressRouter.String(), + Metadata: metadata.TransactionTransfer{ + Address: lo.ToPtr("0x3fFEea07a27Fab7ad1df5297fa75e77a43CB5790"), + Value: lo.ToPtr(lo.Must(decimal.NewFromString("226510048390853047270048940"))), + Name: "PeiPei", + Symbol: "PEIPEI", + Decimals: 18, + Standard: metadata.StandardERC20, + }, + }, + { + Type: typex.ExchangeSwap, + Platform: workerx.PlatformRainbow.String(), + From: "0xbBb87B2E1aF93c326BA6fA10333c79A02c888ad8", + To: "0xbBb87B2E1aF93c326BA6fA10333c79A02c888ad8", + Metadata: metadata.ExchangeSwap{ + From: metadata.Token{ + Address: lo.ToPtr("0x3fFEea07a27Fab7ad1df5297fa75e77a43CB5790"), + Value: lo.ToPtr(lo.Must(decimal.NewFromString("26648240987159182031770463544"))), + Name: "PeiPei", + Symbol: "PEIPEI", + Decimals: 18, + Standard: metadata.StandardERC20, + }, + To: metadata.Token{ + Address: lo.ToPtr("0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"), + Value: lo.ToPtr(lo.Must(decimal.NewFromString("3768588701"))), + Name: "USD Coin", + Symbol: "USDC", + Decimals: 6, + Standard: metadata.StandardERC20, + }, + }, + }, + }, + Status: true, + Timestamp: 1728867131, + }, + wantError: require.NoError, + }, + } + + for _, testcase := range testcases { + testcase := testcase + + t.Run(testcase.name, func(t *testing.T) { + t.Parallel() + + ctx := context.Background() + + instance, err := worker.NewWorker(testcase.arguments.config) + require.NoError(t, err) + + activity, err := instance.Transform(ctx, testcase.arguments.task) + testcase.wantError(t, err) + + // t.Log(string(lo.Must(json.MarshalIndent(activity, "", "\x20\x20")))) + + require.Equal(t, testcase.want, activity) + }) + } +} diff --git a/internal/engine/worker/decentralized/factory.go b/internal/engine/worker/decentralized/factory.go index 5e888361..0957477f 100644 --- a/internal/engine/worker/decentralized/factory.go +++ b/internal/engine/worker/decentralized/factory.go @@ -34,6 +34,7 @@ import ( "github.com/rss3-network/node/internal/engine/worker/decentralized/contract/paragraph" "github.com/rss3-network/node/internal/engine/worker/decentralized/contract/paraswap" "github.com/rss3-network/node/internal/engine/worker/decentralized/contract/polymarket" + "github.com/rss3-network/node/internal/engine/worker/decentralized/contract/rainbow" "github.com/rss3-network/node/internal/engine/worker/decentralized/contract/rss3" "github.com/rss3-network/node/internal/engine/worker/decentralized/contract/savm" "github.com/rss3-network/node/internal/engine/worker/decentralized/contract/stargate" @@ -121,6 +122,8 @@ func newNonCoreWorker(config *config.Module, databaseClient database.Client, red return linear.NewWorker(config) case decentralized.Zerion: return zerion.NewWorker(config) + case decentralized.Rainbow: + return rainbow.NewWorker(config) default: return nil, fmt.Errorf("unsupported worker %s", config.Worker) } diff --git a/internal/node/component/info/network_config.go b/internal/node/component/info/network_config.go index 728f3266..6190044f 100644 --- a/internal/node/component/info/network_config.go +++ b/internal/node/component/info/network_config.go @@ -320,6 +320,7 @@ var NetworkToWorkersMap = map[network.Network][]worker.Worker{ decentralized.Core, decentralized.Curve, decentralized.Highlight, + decentralized.Rainbow, decentralized.Stargate, decentralized.Zerion, }, @@ -332,17 +333,20 @@ var NetworkToWorkersMap = map[network.Network][]worker.Worker{ decentralized.Aave, decentralized.Core, decentralized.Curve, + decentralized.Rainbow, decentralized.Stargate, decentralized.Zerion, }, network.Base: { decentralized.Aave, decentralized.Core, + decentralized.Rainbow, decentralized.Stargate, decentralized.Zerion, }, network.BinanceSmartChain: { decentralized.Core, + decentralized.Rainbow, decentralized.Stargate, decentralized.Zerion, }, @@ -367,6 +371,7 @@ var NetworkToWorkersMap = map[network.Network][]worker.Worker{ decentralized.OpenSea, decentralized.Optimism, decentralized.Paraswap, + decentralized.Rainbow, decentralized.RSS3, decentralized.Stargate, decentralized.Uniswap, @@ -382,6 +387,7 @@ var NetworkToWorkersMap = map[network.Network][]worker.Worker{ }, network.Linea: { decentralized.Core, + decentralized.Rainbow, decentralized.Stargate, decentralized.Uniswap, decentralized.Zerion, @@ -401,6 +407,7 @@ var NetworkToWorkersMap = map[network.Network][]worker.Worker{ decentralized.KiwiStand, decentralized.Matters, decentralized.Optimism, + decentralized.Rainbow, decentralized.Stargate, decentralized.Zerion, }, @@ -413,6 +420,7 @@ var NetworkToWorkersMap = map[network.Network][]worker.Worker{ decentralized.IQWiki, decentralized.Lens, decentralized.Polymarket, + decentralized.Rainbow, decentralized.Stargate, decentralized.Zerion, }, @@ -477,6 +485,7 @@ var WorkerToConfigMap = map[network.Source]map[worker.Worker]workerConfig{ decentralized.Optimism: defaultWorkerConfig(decentralized.Optimism, network.EthereumSource, nil), decentralized.Paraswap: defaultWorkerConfig(decentralized.Paraswap, network.EthereumSource, nil), decentralized.Polymarket: defaultWorkerConfig(decentralized.Polymarket, network.EthereumSource, nil), + decentralized.Rainbow: defaultWorkerConfig(decentralized.Rainbow, network.EthereumSource, nil), decentralized.RSS3: defaultWorkerConfig(decentralized.RSS3, network.EthereumSource, nil), decentralized.SAVM: defaultWorkerConfig(decentralized.SAVM, network.EthereumSource, nil), decentralized.Stargate: defaultWorkerConfig(decentralized.Stargate, network.EthereumSource, nil), diff --git a/provider/ethereum/contract/rainbow/abi/Router.abi b/provider/ethereum/contract/rainbow/abi/Router.abi new file mode 100644 index 00000000..f7bd20d0 --- /dev/null +++ b/provider/ethereum/contract/rainbow/abi/Router.abi @@ -0,0 +1,458 @@ +[ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "EthWithdrawn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "oldOwner", + "type": "address" + } + ], + "name": "OwnerChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "target", + "type": "address" + } + ], + "name": "SwapTargetAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "target", + "type": "address" + } + ], + "name": "SwapTargetRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "TokenWithdrawn", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "buyTokenAddress", + "type": "address" + }, + { + "internalType": "address payable", + "name": "target", + "type": "address" + }, + { + "internalType": "bytes", + "name": "swapCallData", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "feeAmount", + "type": "uint256" + } + ], + "name": "fillQuoteEthToToken", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sellTokenAddress", + "type": "address" + }, + { + "internalType": "address payable", + "name": "target", + "type": "address" + }, + { + "internalType": "bytes", + "name": "swapCallData", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "sellAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feePercentageBasisPoints", + "type": "uint256" + } + ], + "name": "fillQuoteTokenToEth", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sellTokenAddress", + "type": "address" + }, + { + "internalType": "address payable", + "name": "target", + "type": "address" + }, + { + "internalType": "bytes", + "name": "swapCallData", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "sellAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feePercentageBasisPoints", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "isDaiStylePermit", + "type": "bool" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "internalType": "struct PermitHelper.Permit", + "name": "permitData", + "type": "tuple" + } + ], + "name": "fillQuoteTokenToEthWithPermit", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sellTokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "buyTokenAddress", + "type": "address" + }, + { + "internalType": "address payable", + "name": "target", + "type": "address" + }, + { + "internalType": "bytes", + "name": "swapCallData", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "sellAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feeAmount", + "type": "uint256" + } + ], + "name": "fillQuoteTokenToToken", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sellTokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "buyTokenAddress", + "type": "address" + }, + { + "internalType": "address payable", + "name": "target", + "type": "address" + }, + { + "internalType": "bytes", + "name": "swapCallData", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "sellAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feeAmount", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "isDaiStylePermit", + "type": "bool" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "internalType": "struct PermitHelper.Permit", + "name": "permitData", + "type": "tuple" + } + ], + "name": "fillQuoteTokenToTokenWithPermit", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "swapTargets", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "internalType": "bool", + "name": "add", + "type": "bool" + } + ], + "name": "updateSwapTargets", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawEth", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } +] diff --git a/provider/ethereum/contract/rainbow/contract.go b/provider/ethereum/contract/rainbow/contract.go new file mode 100644 index 00000000..a2e14c03 --- /dev/null +++ b/provider/ethereum/contract/rainbow/contract.go @@ -0,0 +1,43 @@ +package rainbow + +import ( + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/rss3-network/node/provider/ethereum/contract" +) + +// Router https://etherscan.io/address/0x00000000009726632680fb29d3f7a9734e3010e2 +//go:generate go run --mod=mod github.com/ethereum/go-ethereum/cmd/abigen --abi ./abi/Router.abi --pkg rainbow --type Router --out contract_router.go + +var ( + AddressRouter = common.HexToAddress("0x00000000009726632680FB29d3F7A9734E3010E2") + + MethodIDRouterFillQuoteEthToToken = contract.MethodID("fillQuoteEthToToken(address,address,bytes,uint256)") + MethodIDRouterFillQuoteTokenToEth = contract.MethodID("fillQuoteTokenToEth(address,address,bytes,uint256,uint256)") + MethodIDRouterFillQuoteTokenToToken = contract.MethodID("fillQuoteTokenToToken(address,address,address,bytes,uint256,uint256)") +) + +type RouterFillQuoteEthToTokenInput struct { + BuyTokenAddress common.Address + Target common.Address + SwapCallData []byte + FeeAmount *big.Int +} + +type RouterFillQuoteTokenToEthInput struct { + SellTokenAddress common.Address + Target common.Address + SwapCallData []byte + SellAmount *big.Int + FeePercentageBasisPoints *big.Int +} + +type RouterFillQuoteTokenToTokenInput struct { + SellTokenAddress common.Address + BuyTokenAddress common.Address + Target common.Address + SwapCallData []byte + SellAmount *big.Int + FeeAmount *big.Int +} diff --git a/provider/ethereum/contract/rainbow/contract_router.go b/provider/ethereum/contract/rainbow/contract_router.go new file mode 100644 index 00000000..6b748f61 --- /dev/null +++ b/provider/ethereum/contract/rainbow/contract_router.go @@ -0,0 +1,1204 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package rainbow + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// PermitHelperPermit is an auto generated low-level Go binding around an user-defined struct. +type PermitHelperPermit struct { + Value *big.Int + Nonce *big.Int + Deadline *big.Int + IsDaiStylePermit bool + V uint8 + R [32]byte + S [32]byte +} + +// RouterMetaData contains all meta data concerning the Router contract. +var RouterMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"EthWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"oldOwner\",\"type\":\"address\"}],\"name\":\"OwnerChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"}],\"name\":\"SwapTargetAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"}],\"name\":\"SwapTargetRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"TokenWithdrawn\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"buyTokenAddress\",\"type\":\"address\"},{\"internalType\":\"addresspayable\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"swapCallData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"feeAmount\",\"type\":\"uint256\"}],\"name\":\"fillQuoteEthToToken\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sellTokenAddress\",\"type\":\"address\"},{\"internalType\":\"addresspayable\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"swapCallData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"sellAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"feePercentageBasisPoints\",\"type\":\"uint256\"}],\"name\":\"fillQuoteTokenToEth\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sellTokenAddress\",\"type\":\"address\"},{\"internalType\":\"addresspayable\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"swapCallData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"sellAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"feePercentageBasisPoints\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"deadline\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"isDaiStylePermit\",\"type\":\"bool\"},{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"internalType\":\"structPermitHelper.Permit\",\"name\":\"permitData\",\"type\":\"tuple\"}],\"name\":\"fillQuoteTokenToEthWithPermit\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sellTokenAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"buyTokenAddress\",\"type\":\"address\"},{\"internalType\":\"addresspayable\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"swapCallData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"sellAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"feeAmount\",\"type\":\"uint256\"}],\"name\":\"fillQuoteTokenToToken\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sellTokenAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"buyTokenAddress\",\"type\":\"address\"},{\"internalType\":\"addresspayable\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"swapCallData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"sellAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"feeAmount\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"deadline\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"isDaiStylePermit\",\"type\":\"bool\"},{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"internalType\":\"structPermitHelper.Permit\",\"name\":\"permitData\",\"type\":\"tuple\"}],\"name\":\"fillQuoteTokenToTokenWithPermit\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"swapTargets\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"add\",\"type\":\"bool\"}],\"name\":\"updateSwapTargets\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawEth\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}]", +} + +// RouterABI is the input ABI used to generate the binding from. +// Deprecated: Use RouterMetaData.ABI instead. +var RouterABI = RouterMetaData.ABI + +// Router is an auto generated Go binding around an Ethereum contract. +type Router struct { + RouterCaller // Read-only binding to the contract + RouterTransactor // Write-only binding to the contract + RouterFilterer // Log filterer for contract events +} + +// RouterCaller is an auto generated read-only Go binding around an Ethereum contract. +type RouterCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// RouterTransactor is an auto generated write-only Go binding around an Ethereum contract. +type RouterTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// RouterFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type RouterFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// RouterSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type RouterSession struct { + Contract *Router // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// RouterCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type RouterCallerSession struct { + Contract *RouterCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// RouterTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type RouterTransactorSession struct { + Contract *RouterTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// RouterRaw is an auto generated low-level Go binding around an Ethereum contract. +type RouterRaw struct { + Contract *Router // Generic contract binding to access the raw methods on +} + +// RouterCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type RouterCallerRaw struct { + Contract *RouterCaller // Generic read-only contract binding to access the raw methods on +} + +// RouterTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type RouterTransactorRaw struct { + Contract *RouterTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewRouter creates a new instance of Router, bound to a specific deployed contract. +func NewRouter(address common.Address, backend bind.ContractBackend) (*Router, error) { + contract, err := bindRouter(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &Router{RouterCaller: RouterCaller{contract: contract}, RouterTransactor: RouterTransactor{contract: contract}, RouterFilterer: RouterFilterer{contract: contract}}, nil +} + +// NewRouterCaller creates a new read-only instance of Router, bound to a specific deployed contract. +func NewRouterCaller(address common.Address, caller bind.ContractCaller) (*RouterCaller, error) { + contract, err := bindRouter(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &RouterCaller{contract: contract}, nil +} + +// NewRouterTransactor creates a new write-only instance of Router, bound to a specific deployed contract. +func NewRouterTransactor(address common.Address, transactor bind.ContractTransactor) (*RouterTransactor, error) { + contract, err := bindRouter(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &RouterTransactor{contract: contract}, nil +} + +// NewRouterFilterer creates a new log filterer instance of Router, bound to a specific deployed contract. +func NewRouterFilterer(address common.Address, filterer bind.ContractFilterer) (*RouterFilterer, error) { + contract, err := bindRouter(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &RouterFilterer{contract: contract}, nil +} + +// bindRouter binds a generic wrapper to an already deployed contract. +func bindRouter(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := RouterMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_Router *RouterRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Router.Contract.RouterCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_Router *RouterRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Router.Contract.RouterTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_Router *RouterRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Router.Contract.RouterTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_Router *RouterCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Router.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_Router *RouterTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Router.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_Router *RouterTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Router.Contract.contract.Transact(opts, method, params...) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_Router *RouterCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _Router.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_Router *RouterSession) Owner() (common.Address, error) { + return _Router.Contract.Owner(&_Router.CallOpts) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_Router *RouterCallerSession) Owner() (common.Address, error) { + return _Router.Contract.Owner(&_Router.CallOpts) +} + +// SwapTargets is a free data retrieval call binding the contract method 0x83c4a19d. +// +// Solidity: function swapTargets(address ) view returns(bool) +func (_Router *RouterCaller) SwapTargets(opts *bind.CallOpts, arg0 common.Address) (bool, error) { + var out []interface{} + err := _Router.contract.Call(opts, &out, "swapTargets", arg0) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// SwapTargets is a free data retrieval call binding the contract method 0x83c4a19d. +// +// Solidity: function swapTargets(address ) view returns(bool) +func (_Router *RouterSession) SwapTargets(arg0 common.Address) (bool, error) { + return _Router.Contract.SwapTargets(&_Router.CallOpts, arg0) +} + +// SwapTargets is a free data retrieval call binding the contract method 0x83c4a19d. +// +// Solidity: function swapTargets(address ) view returns(bool) +func (_Router *RouterCallerSession) SwapTargets(arg0 common.Address) (bool, error) { + return _Router.Contract.SwapTargets(&_Router.CallOpts, arg0) +} + +// FillQuoteEthToToken is a paid mutator transaction binding the contract method 0x3c2b9a7d. +// +// Solidity: function fillQuoteEthToToken(address buyTokenAddress, address target, bytes swapCallData, uint256 feeAmount) payable returns() +func (_Router *RouterTransactor) FillQuoteEthToToken(opts *bind.TransactOpts, buyTokenAddress common.Address, target common.Address, swapCallData []byte, feeAmount *big.Int) (*types.Transaction, error) { + return _Router.contract.Transact(opts, "fillQuoteEthToToken", buyTokenAddress, target, swapCallData, feeAmount) +} + +// FillQuoteEthToToken is a paid mutator transaction binding the contract method 0x3c2b9a7d. +// +// Solidity: function fillQuoteEthToToken(address buyTokenAddress, address target, bytes swapCallData, uint256 feeAmount) payable returns() +func (_Router *RouterSession) FillQuoteEthToToken(buyTokenAddress common.Address, target common.Address, swapCallData []byte, feeAmount *big.Int) (*types.Transaction, error) { + return _Router.Contract.FillQuoteEthToToken(&_Router.TransactOpts, buyTokenAddress, target, swapCallData, feeAmount) +} + +// FillQuoteEthToToken is a paid mutator transaction binding the contract method 0x3c2b9a7d. +// +// Solidity: function fillQuoteEthToToken(address buyTokenAddress, address target, bytes swapCallData, uint256 feeAmount) payable returns() +func (_Router *RouterTransactorSession) FillQuoteEthToToken(buyTokenAddress common.Address, target common.Address, swapCallData []byte, feeAmount *big.Int) (*types.Transaction, error) { + return _Router.Contract.FillQuoteEthToToken(&_Router.TransactOpts, buyTokenAddress, target, swapCallData, feeAmount) +} + +// FillQuoteTokenToEth is a paid mutator transaction binding the contract method 0x999b6464. +// +// Solidity: function fillQuoteTokenToEth(address sellTokenAddress, address target, bytes swapCallData, uint256 sellAmount, uint256 feePercentageBasisPoints) payable returns() +func (_Router *RouterTransactor) FillQuoteTokenToEth(opts *bind.TransactOpts, sellTokenAddress common.Address, target common.Address, swapCallData []byte, sellAmount *big.Int, feePercentageBasisPoints *big.Int) (*types.Transaction, error) { + return _Router.contract.Transact(opts, "fillQuoteTokenToEth", sellTokenAddress, target, swapCallData, sellAmount, feePercentageBasisPoints) +} + +// FillQuoteTokenToEth is a paid mutator transaction binding the contract method 0x999b6464. +// +// Solidity: function fillQuoteTokenToEth(address sellTokenAddress, address target, bytes swapCallData, uint256 sellAmount, uint256 feePercentageBasisPoints) payable returns() +func (_Router *RouterSession) FillQuoteTokenToEth(sellTokenAddress common.Address, target common.Address, swapCallData []byte, sellAmount *big.Int, feePercentageBasisPoints *big.Int) (*types.Transaction, error) { + return _Router.Contract.FillQuoteTokenToEth(&_Router.TransactOpts, sellTokenAddress, target, swapCallData, sellAmount, feePercentageBasisPoints) +} + +// FillQuoteTokenToEth is a paid mutator transaction binding the contract method 0x999b6464. +// +// Solidity: function fillQuoteTokenToEth(address sellTokenAddress, address target, bytes swapCallData, uint256 sellAmount, uint256 feePercentageBasisPoints) payable returns() +func (_Router *RouterTransactorSession) FillQuoteTokenToEth(sellTokenAddress common.Address, target common.Address, swapCallData []byte, sellAmount *big.Int, feePercentageBasisPoints *big.Int) (*types.Transaction, error) { + return _Router.Contract.FillQuoteTokenToEth(&_Router.TransactOpts, sellTokenAddress, target, swapCallData, sellAmount, feePercentageBasisPoints) +} + +// FillQuoteTokenToEthWithPermit is a paid mutator transaction binding the contract method 0xb3093838. +// +// Solidity: function fillQuoteTokenToEthWithPermit(address sellTokenAddress, address target, bytes swapCallData, uint256 sellAmount, uint256 feePercentageBasisPoints, (uint256,uint256,uint256,bool,uint8,bytes32,bytes32) permitData) payable returns() +func (_Router *RouterTransactor) FillQuoteTokenToEthWithPermit(opts *bind.TransactOpts, sellTokenAddress common.Address, target common.Address, swapCallData []byte, sellAmount *big.Int, feePercentageBasisPoints *big.Int, permitData PermitHelperPermit) (*types.Transaction, error) { + return _Router.contract.Transact(opts, "fillQuoteTokenToEthWithPermit", sellTokenAddress, target, swapCallData, sellAmount, feePercentageBasisPoints, permitData) +} + +// FillQuoteTokenToEthWithPermit is a paid mutator transaction binding the contract method 0xb3093838. +// +// Solidity: function fillQuoteTokenToEthWithPermit(address sellTokenAddress, address target, bytes swapCallData, uint256 sellAmount, uint256 feePercentageBasisPoints, (uint256,uint256,uint256,bool,uint8,bytes32,bytes32) permitData) payable returns() +func (_Router *RouterSession) FillQuoteTokenToEthWithPermit(sellTokenAddress common.Address, target common.Address, swapCallData []byte, sellAmount *big.Int, feePercentageBasisPoints *big.Int, permitData PermitHelperPermit) (*types.Transaction, error) { + return _Router.Contract.FillQuoteTokenToEthWithPermit(&_Router.TransactOpts, sellTokenAddress, target, swapCallData, sellAmount, feePercentageBasisPoints, permitData) +} + +// FillQuoteTokenToEthWithPermit is a paid mutator transaction binding the contract method 0xb3093838. +// +// Solidity: function fillQuoteTokenToEthWithPermit(address sellTokenAddress, address target, bytes swapCallData, uint256 sellAmount, uint256 feePercentageBasisPoints, (uint256,uint256,uint256,bool,uint8,bytes32,bytes32) permitData) payable returns() +func (_Router *RouterTransactorSession) FillQuoteTokenToEthWithPermit(sellTokenAddress common.Address, target common.Address, swapCallData []byte, sellAmount *big.Int, feePercentageBasisPoints *big.Int, permitData PermitHelperPermit) (*types.Transaction, error) { + return _Router.Contract.FillQuoteTokenToEthWithPermit(&_Router.TransactOpts, sellTokenAddress, target, swapCallData, sellAmount, feePercentageBasisPoints, permitData) +} + +// FillQuoteTokenToToken is a paid mutator transaction binding the contract method 0x55e4b7be. +// +// Solidity: function fillQuoteTokenToToken(address sellTokenAddress, address buyTokenAddress, address target, bytes swapCallData, uint256 sellAmount, uint256 feeAmount) payable returns() +func (_Router *RouterTransactor) FillQuoteTokenToToken(opts *bind.TransactOpts, sellTokenAddress common.Address, buyTokenAddress common.Address, target common.Address, swapCallData []byte, sellAmount *big.Int, feeAmount *big.Int) (*types.Transaction, error) { + return _Router.contract.Transact(opts, "fillQuoteTokenToToken", sellTokenAddress, buyTokenAddress, target, swapCallData, sellAmount, feeAmount) +} + +// FillQuoteTokenToToken is a paid mutator transaction binding the contract method 0x55e4b7be. +// +// Solidity: function fillQuoteTokenToToken(address sellTokenAddress, address buyTokenAddress, address target, bytes swapCallData, uint256 sellAmount, uint256 feeAmount) payable returns() +func (_Router *RouterSession) FillQuoteTokenToToken(sellTokenAddress common.Address, buyTokenAddress common.Address, target common.Address, swapCallData []byte, sellAmount *big.Int, feeAmount *big.Int) (*types.Transaction, error) { + return _Router.Contract.FillQuoteTokenToToken(&_Router.TransactOpts, sellTokenAddress, buyTokenAddress, target, swapCallData, sellAmount, feeAmount) +} + +// FillQuoteTokenToToken is a paid mutator transaction binding the contract method 0x55e4b7be. +// +// Solidity: function fillQuoteTokenToToken(address sellTokenAddress, address buyTokenAddress, address target, bytes swapCallData, uint256 sellAmount, uint256 feeAmount) payable returns() +func (_Router *RouterTransactorSession) FillQuoteTokenToToken(sellTokenAddress common.Address, buyTokenAddress common.Address, target common.Address, swapCallData []byte, sellAmount *big.Int, feeAmount *big.Int) (*types.Transaction, error) { + return _Router.Contract.FillQuoteTokenToToken(&_Router.TransactOpts, sellTokenAddress, buyTokenAddress, target, swapCallData, sellAmount, feeAmount) +} + +// FillQuoteTokenToTokenWithPermit is a paid mutator transaction binding the contract method 0xb0480bbd. +// +// Solidity: function fillQuoteTokenToTokenWithPermit(address sellTokenAddress, address buyTokenAddress, address target, bytes swapCallData, uint256 sellAmount, uint256 feeAmount, (uint256,uint256,uint256,bool,uint8,bytes32,bytes32) permitData) payable returns() +func (_Router *RouterTransactor) FillQuoteTokenToTokenWithPermit(opts *bind.TransactOpts, sellTokenAddress common.Address, buyTokenAddress common.Address, target common.Address, swapCallData []byte, sellAmount *big.Int, feeAmount *big.Int, permitData PermitHelperPermit) (*types.Transaction, error) { + return _Router.contract.Transact(opts, "fillQuoteTokenToTokenWithPermit", sellTokenAddress, buyTokenAddress, target, swapCallData, sellAmount, feeAmount, permitData) +} + +// FillQuoteTokenToTokenWithPermit is a paid mutator transaction binding the contract method 0xb0480bbd. +// +// Solidity: function fillQuoteTokenToTokenWithPermit(address sellTokenAddress, address buyTokenAddress, address target, bytes swapCallData, uint256 sellAmount, uint256 feeAmount, (uint256,uint256,uint256,bool,uint8,bytes32,bytes32) permitData) payable returns() +func (_Router *RouterSession) FillQuoteTokenToTokenWithPermit(sellTokenAddress common.Address, buyTokenAddress common.Address, target common.Address, swapCallData []byte, sellAmount *big.Int, feeAmount *big.Int, permitData PermitHelperPermit) (*types.Transaction, error) { + return _Router.Contract.FillQuoteTokenToTokenWithPermit(&_Router.TransactOpts, sellTokenAddress, buyTokenAddress, target, swapCallData, sellAmount, feeAmount, permitData) +} + +// FillQuoteTokenToTokenWithPermit is a paid mutator transaction binding the contract method 0xb0480bbd. +// +// Solidity: function fillQuoteTokenToTokenWithPermit(address sellTokenAddress, address buyTokenAddress, address target, bytes swapCallData, uint256 sellAmount, uint256 feeAmount, (uint256,uint256,uint256,bool,uint8,bytes32,bytes32) permitData) payable returns() +func (_Router *RouterTransactorSession) FillQuoteTokenToTokenWithPermit(sellTokenAddress common.Address, buyTokenAddress common.Address, target common.Address, swapCallData []byte, sellAmount *big.Int, feeAmount *big.Int, permitData PermitHelperPermit) (*types.Transaction, error) { + return _Router.Contract.FillQuoteTokenToTokenWithPermit(&_Router.TransactOpts, sellTokenAddress, buyTokenAddress, target, swapCallData, sellAmount, feeAmount, permitData) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_Router *RouterTransactor) TransferOwnership(opts *bind.TransactOpts, newOwner common.Address) (*types.Transaction, error) { + return _Router.contract.Transact(opts, "transferOwnership", newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_Router *RouterSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _Router.Contract.TransferOwnership(&_Router.TransactOpts, newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_Router *RouterTransactorSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _Router.Contract.TransferOwnership(&_Router.TransactOpts, newOwner) +} + +// UpdateSwapTargets is a paid mutator transaction binding the contract method 0x97bbda0e. +// +// Solidity: function updateSwapTargets(address target, bool add) returns() +func (_Router *RouterTransactor) UpdateSwapTargets(opts *bind.TransactOpts, target common.Address, add bool) (*types.Transaction, error) { + return _Router.contract.Transact(opts, "updateSwapTargets", target, add) +} + +// UpdateSwapTargets is a paid mutator transaction binding the contract method 0x97bbda0e. +// +// Solidity: function updateSwapTargets(address target, bool add) returns() +func (_Router *RouterSession) UpdateSwapTargets(target common.Address, add bool) (*types.Transaction, error) { + return _Router.Contract.UpdateSwapTargets(&_Router.TransactOpts, target, add) +} + +// UpdateSwapTargets is a paid mutator transaction binding the contract method 0x97bbda0e. +// +// Solidity: function updateSwapTargets(address target, bool add) returns() +func (_Router *RouterTransactorSession) UpdateSwapTargets(target common.Address, add bool) (*types.Transaction, error) { + return _Router.Contract.UpdateSwapTargets(&_Router.TransactOpts, target, add) +} + +// WithdrawEth is a paid mutator transaction binding the contract method 0x1b9a91a4. +// +// Solidity: function withdrawEth(address to, uint256 amount) returns() +func (_Router *RouterTransactor) WithdrawEth(opts *bind.TransactOpts, to common.Address, amount *big.Int) (*types.Transaction, error) { + return _Router.contract.Transact(opts, "withdrawEth", to, amount) +} + +// WithdrawEth is a paid mutator transaction binding the contract method 0x1b9a91a4. +// +// Solidity: function withdrawEth(address to, uint256 amount) returns() +func (_Router *RouterSession) WithdrawEth(to common.Address, amount *big.Int) (*types.Transaction, error) { + return _Router.Contract.WithdrawEth(&_Router.TransactOpts, to, amount) +} + +// WithdrawEth is a paid mutator transaction binding the contract method 0x1b9a91a4. +// +// Solidity: function withdrawEth(address to, uint256 amount) returns() +func (_Router *RouterTransactorSession) WithdrawEth(to common.Address, amount *big.Int) (*types.Transaction, error) { + return _Router.Contract.WithdrawEth(&_Router.TransactOpts, to, amount) +} + +// WithdrawToken is a paid mutator transaction binding the contract method 0x01e33667. +// +// Solidity: function withdrawToken(address token, address to, uint256 amount) returns() +func (_Router *RouterTransactor) WithdrawToken(opts *bind.TransactOpts, token common.Address, to common.Address, amount *big.Int) (*types.Transaction, error) { + return _Router.contract.Transact(opts, "withdrawToken", token, to, amount) +} + +// WithdrawToken is a paid mutator transaction binding the contract method 0x01e33667. +// +// Solidity: function withdrawToken(address token, address to, uint256 amount) returns() +func (_Router *RouterSession) WithdrawToken(token common.Address, to common.Address, amount *big.Int) (*types.Transaction, error) { + return _Router.Contract.WithdrawToken(&_Router.TransactOpts, token, to, amount) +} + +// WithdrawToken is a paid mutator transaction binding the contract method 0x01e33667. +// +// Solidity: function withdrawToken(address token, address to, uint256 amount) returns() +func (_Router *RouterTransactorSession) WithdrawToken(token common.Address, to common.Address, amount *big.Int) (*types.Transaction, error) { + return _Router.Contract.WithdrawToken(&_Router.TransactOpts, token, to, amount) +} + +// Receive is a paid mutator transaction binding the contract receive function. +// +// Solidity: receive() payable returns() +func (_Router *RouterTransactor) Receive(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Router.contract.RawTransact(opts, nil) // calldata is disallowed for receive function +} + +// Receive is a paid mutator transaction binding the contract receive function. +// +// Solidity: receive() payable returns() +func (_Router *RouterSession) Receive() (*types.Transaction, error) { + return _Router.Contract.Receive(&_Router.TransactOpts) +} + +// Receive is a paid mutator transaction binding the contract receive function. +// +// Solidity: receive() payable returns() +func (_Router *RouterTransactorSession) Receive() (*types.Transaction, error) { + return _Router.Contract.Receive(&_Router.TransactOpts) +} + +// RouterEthWithdrawnIterator is returned from FilterEthWithdrawn and is used to iterate over the raw logs and unpacked data for EthWithdrawn events raised by the Router contract. +type RouterEthWithdrawnIterator struct { + Event *RouterEthWithdrawn // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *RouterEthWithdrawnIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(RouterEthWithdrawn) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(RouterEthWithdrawn) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *RouterEthWithdrawnIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *RouterEthWithdrawnIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// RouterEthWithdrawn represents a EthWithdrawn event raised by the Router contract. +type RouterEthWithdrawn struct { + Target common.Address + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterEthWithdrawn is a free log retrieval operation binding the contract event 0x8455ae6be5d92f1df1c3c1484388e247a36c7e60d72055ae216dbc258f257d4b. +// +// Solidity: event EthWithdrawn(address indexed target, uint256 amount) +func (_Router *RouterFilterer) FilterEthWithdrawn(opts *bind.FilterOpts, target []common.Address) (*RouterEthWithdrawnIterator, error) { + + var targetRule []interface{} + for _, targetItem := range target { + targetRule = append(targetRule, targetItem) + } + + logs, sub, err := _Router.contract.FilterLogs(opts, "EthWithdrawn", targetRule) + if err != nil { + return nil, err + } + return &RouterEthWithdrawnIterator{contract: _Router.contract, event: "EthWithdrawn", logs: logs, sub: sub}, nil +} + +// WatchEthWithdrawn is a free log subscription operation binding the contract event 0x8455ae6be5d92f1df1c3c1484388e247a36c7e60d72055ae216dbc258f257d4b. +// +// Solidity: event EthWithdrawn(address indexed target, uint256 amount) +func (_Router *RouterFilterer) WatchEthWithdrawn(opts *bind.WatchOpts, sink chan<- *RouterEthWithdrawn, target []common.Address) (event.Subscription, error) { + + var targetRule []interface{} + for _, targetItem := range target { + targetRule = append(targetRule, targetItem) + } + + logs, sub, err := _Router.contract.WatchLogs(opts, "EthWithdrawn", targetRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(RouterEthWithdrawn) + if err := _Router.contract.UnpackLog(event, "EthWithdrawn", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseEthWithdrawn is a log parse operation binding the contract event 0x8455ae6be5d92f1df1c3c1484388e247a36c7e60d72055ae216dbc258f257d4b. +// +// Solidity: event EthWithdrawn(address indexed target, uint256 amount) +func (_Router *RouterFilterer) ParseEthWithdrawn(log types.Log) (*RouterEthWithdrawn, error) { + event := new(RouterEthWithdrawn) + if err := _Router.contract.UnpackLog(event, "EthWithdrawn", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// RouterOwnerChangedIterator is returned from FilterOwnerChanged and is used to iterate over the raw logs and unpacked data for OwnerChanged events raised by the Router contract. +type RouterOwnerChangedIterator struct { + Event *RouterOwnerChanged // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *RouterOwnerChangedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(RouterOwnerChanged) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(RouterOwnerChanged) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *RouterOwnerChangedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *RouterOwnerChangedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// RouterOwnerChanged represents a OwnerChanged event raised by the Router contract. +type RouterOwnerChanged struct { + NewOwner common.Address + OldOwner common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterOwnerChanged is a free log retrieval operation binding the contract event 0xb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c. +// +// Solidity: event OwnerChanged(address indexed newOwner, address indexed oldOwner) +func (_Router *RouterFilterer) FilterOwnerChanged(opts *bind.FilterOpts, newOwner []common.Address, oldOwner []common.Address) (*RouterOwnerChangedIterator, error) { + + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + var oldOwnerRule []interface{} + for _, oldOwnerItem := range oldOwner { + oldOwnerRule = append(oldOwnerRule, oldOwnerItem) + } + + logs, sub, err := _Router.contract.FilterLogs(opts, "OwnerChanged", newOwnerRule, oldOwnerRule) + if err != nil { + return nil, err + } + return &RouterOwnerChangedIterator{contract: _Router.contract, event: "OwnerChanged", logs: logs, sub: sub}, nil +} + +// WatchOwnerChanged is a free log subscription operation binding the contract event 0xb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c. +// +// Solidity: event OwnerChanged(address indexed newOwner, address indexed oldOwner) +func (_Router *RouterFilterer) WatchOwnerChanged(opts *bind.WatchOpts, sink chan<- *RouterOwnerChanged, newOwner []common.Address, oldOwner []common.Address) (event.Subscription, error) { + + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + var oldOwnerRule []interface{} + for _, oldOwnerItem := range oldOwner { + oldOwnerRule = append(oldOwnerRule, oldOwnerItem) + } + + logs, sub, err := _Router.contract.WatchLogs(opts, "OwnerChanged", newOwnerRule, oldOwnerRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(RouterOwnerChanged) + if err := _Router.contract.UnpackLog(event, "OwnerChanged", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseOwnerChanged is a log parse operation binding the contract event 0xb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c. +// +// Solidity: event OwnerChanged(address indexed newOwner, address indexed oldOwner) +func (_Router *RouterFilterer) ParseOwnerChanged(log types.Log) (*RouterOwnerChanged, error) { + event := new(RouterOwnerChanged) + if err := _Router.contract.UnpackLog(event, "OwnerChanged", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// RouterSwapTargetAddedIterator is returned from FilterSwapTargetAdded and is used to iterate over the raw logs and unpacked data for SwapTargetAdded events raised by the Router contract. +type RouterSwapTargetAddedIterator struct { + Event *RouterSwapTargetAdded // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *RouterSwapTargetAddedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(RouterSwapTargetAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(RouterSwapTargetAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *RouterSwapTargetAddedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *RouterSwapTargetAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// RouterSwapTargetAdded represents a SwapTargetAdded event raised by the Router contract. +type RouterSwapTargetAdded struct { + Target common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterSwapTargetAdded is a free log retrieval operation binding the contract event 0xb907822409611d127ab6a64611591b98e03a6a85ade4f258bae26b7c1efdfeaf. +// +// Solidity: event SwapTargetAdded(address indexed target) +func (_Router *RouterFilterer) FilterSwapTargetAdded(opts *bind.FilterOpts, target []common.Address) (*RouterSwapTargetAddedIterator, error) { + + var targetRule []interface{} + for _, targetItem := range target { + targetRule = append(targetRule, targetItem) + } + + logs, sub, err := _Router.contract.FilterLogs(opts, "SwapTargetAdded", targetRule) + if err != nil { + return nil, err + } + return &RouterSwapTargetAddedIterator{contract: _Router.contract, event: "SwapTargetAdded", logs: logs, sub: sub}, nil +} + +// WatchSwapTargetAdded is a free log subscription operation binding the contract event 0xb907822409611d127ab6a64611591b98e03a6a85ade4f258bae26b7c1efdfeaf. +// +// Solidity: event SwapTargetAdded(address indexed target) +func (_Router *RouterFilterer) WatchSwapTargetAdded(opts *bind.WatchOpts, sink chan<- *RouterSwapTargetAdded, target []common.Address) (event.Subscription, error) { + + var targetRule []interface{} + for _, targetItem := range target { + targetRule = append(targetRule, targetItem) + } + + logs, sub, err := _Router.contract.WatchLogs(opts, "SwapTargetAdded", targetRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(RouterSwapTargetAdded) + if err := _Router.contract.UnpackLog(event, "SwapTargetAdded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseSwapTargetAdded is a log parse operation binding the contract event 0xb907822409611d127ab6a64611591b98e03a6a85ade4f258bae26b7c1efdfeaf. +// +// Solidity: event SwapTargetAdded(address indexed target) +func (_Router *RouterFilterer) ParseSwapTargetAdded(log types.Log) (*RouterSwapTargetAdded, error) { + event := new(RouterSwapTargetAdded) + if err := _Router.contract.UnpackLog(event, "SwapTargetAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// RouterSwapTargetRemovedIterator is returned from FilterSwapTargetRemoved and is used to iterate over the raw logs and unpacked data for SwapTargetRemoved events raised by the Router contract. +type RouterSwapTargetRemovedIterator struct { + Event *RouterSwapTargetRemoved // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *RouterSwapTargetRemovedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(RouterSwapTargetRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(RouterSwapTargetRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *RouterSwapTargetRemovedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *RouterSwapTargetRemovedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// RouterSwapTargetRemoved represents a SwapTargetRemoved event raised by the Router contract. +type RouterSwapTargetRemoved struct { + Target common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterSwapTargetRemoved is a free log retrieval operation binding the contract event 0x393b8be3e26787f19285ecd039dfd80bc6507828750f4d50367e6efe2524695c. +// +// Solidity: event SwapTargetRemoved(address indexed target) +func (_Router *RouterFilterer) FilterSwapTargetRemoved(opts *bind.FilterOpts, target []common.Address) (*RouterSwapTargetRemovedIterator, error) { + + var targetRule []interface{} + for _, targetItem := range target { + targetRule = append(targetRule, targetItem) + } + + logs, sub, err := _Router.contract.FilterLogs(opts, "SwapTargetRemoved", targetRule) + if err != nil { + return nil, err + } + return &RouterSwapTargetRemovedIterator{contract: _Router.contract, event: "SwapTargetRemoved", logs: logs, sub: sub}, nil +} + +// WatchSwapTargetRemoved is a free log subscription operation binding the contract event 0x393b8be3e26787f19285ecd039dfd80bc6507828750f4d50367e6efe2524695c. +// +// Solidity: event SwapTargetRemoved(address indexed target) +func (_Router *RouterFilterer) WatchSwapTargetRemoved(opts *bind.WatchOpts, sink chan<- *RouterSwapTargetRemoved, target []common.Address) (event.Subscription, error) { + + var targetRule []interface{} + for _, targetItem := range target { + targetRule = append(targetRule, targetItem) + } + + logs, sub, err := _Router.contract.WatchLogs(opts, "SwapTargetRemoved", targetRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(RouterSwapTargetRemoved) + if err := _Router.contract.UnpackLog(event, "SwapTargetRemoved", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseSwapTargetRemoved is a log parse operation binding the contract event 0x393b8be3e26787f19285ecd039dfd80bc6507828750f4d50367e6efe2524695c. +// +// Solidity: event SwapTargetRemoved(address indexed target) +func (_Router *RouterFilterer) ParseSwapTargetRemoved(log types.Log) (*RouterSwapTargetRemoved, error) { + event := new(RouterSwapTargetRemoved) + if err := _Router.contract.UnpackLog(event, "SwapTargetRemoved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// RouterTokenWithdrawnIterator is returned from FilterTokenWithdrawn and is used to iterate over the raw logs and unpacked data for TokenWithdrawn events raised by the Router contract. +type RouterTokenWithdrawnIterator struct { + Event *RouterTokenWithdrawn // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *RouterTokenWithdrawnIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(RouterTokenWithdrawn) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(RouterTokenWithdrawn) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *RouterTokenWithdrawnIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *RouterTokenWithdrawnIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// RouterTokenWithdrawn represents a TokenWithdrawn event raised by the Router contract. +type RouterTokenWithdrawn struct { + Token common.Address + Target common.Address + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTokenWithdrawn is a free log retrieval operation binding the contract event 0x8210728e7c071f615b840ee026032693858fbcd5e5359e67e438c890f59e5620. +// +// Solidity: event TokenWithdrawn(address indexed token, address indexed target, uint256 amount) +func (_Router *RouterFilterer) FilterTokenWithdrawn(opts *bind.FilterOpts, token []common.Address, target []common.Address) (*RouterTokenWithdrawnIterator, error) { + + var tokenRule []interface{} + for _, tokenItem := range token { + tokenRule = append(tokenRule, tokenItem) + } + var targetRule []interface{} + for _, targetItem := range target { + targetRule = append(targetRule, targetItem) + } + + logs, sub, err := _Router.contract.FilterLogs(opts, "TokenWithdrawn", tokenRule, targetRule) + if err != nil { + return nil, err + } + return &RouterTokenWithdrawnIterator{contract: _Router.contract, event: "TokenWithdrawn", logs: logs, sub: sub}, nil +} + +// WatchTokenWithdrawn is a free log subscription operation binding the contract event 0x8210728e7c071f615b840ee026032693858fbcd5e5359e67e438c890f59e5620. +// +// Solidity: event TokenWithdrawn(address indexed token, address indexed target, uint256 amount) +func (_Router *RouterFilterer) WatchTokenWithdrawn(opts *bind.WatchOpts, sink chan<- *RouterTokenWithdrawn, token []common.Address, target []common.Address) (event.Subscription, error) { + + var tokenRule []interface{} + for _, tokenItem := range token { + tokenRule = append(tokenRule, tokenItem) + } + var targetRule []interface{} + for _, targetItem := range target { + targetRule = append(targetRule, targetItem) + } + + logs, sub, err := _Router.contract.WatchLogs(opts, "TokenWithdrawn", tokenRule, targetRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(RouterTokenWithdrawn) + if err := _Router.contract.UnpackLog(event, "TokenWithdrawn", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseTokenWithdrawn is a log parse operation binding the contract event 0x8210728e7c071f615b840ee026032693858fbcd5e5359e67e438c890f59e5620. +// +// Solidity: event TokenWithdrawn(address indexed token, address indexed target, uint256 amount) +func (_Router *RouterFilterer) ParseTokenWithdrawn(log types.Log) (*RouterTokenWithdrawn, error) { + event := new(RouterTokenWithdrawn) + if err := _Router.contract.UnpackLog(event, "TokenWithdrawn", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/schema/worker/decentralized/platform.go b/schema/worker/decentralized/platform.go index d305b17a..8bdc6337 100644 --- a/schema/worker/decentralized/platform.go +++ b/schema/worker/decentralized/platform.go @@ -35,6 +35,7 @@ const ( PlatformParaswap // Paraswap PlatformPolymarket // Polymarket PlatformRSS3 // RSS3 + PlatformRainbow // Rainbow PlatformSAVM // SAVM PlatformStargate // Stargate PlatformUniswap // Uniswap @@ -84,6 +85,7 @@ var ToPlatformMap = map[Worker]Platform{ Paragraph: PlatformParagraph, Paraswap: PlatformParaswap, Polymarket: PlatformPolymarket, + Rainbow: PlatformRainbow, RSS3: PlatformRSS3, SAVM: PlatformSAVM, Stargate: PlatformStargate, diff --git a/schema/worker/decentralized/platform_string.go b/schema/worker/decentralized/platform_string.go index 2a9c61c0..5654b4fc 100644 --- a/schema/worker/decentralized/platform_string.go +++ b/schema/worker/decentralized/platform_string.go @@ -9,11 +9,11 @@ import ( "strings" ) -const _PlatformName = "Unknown1inchAAVEAavegotchiArbitrumBaseBendDAOCowCrossbellCurveENSFarcasterHighlightIQWikiKiwiStandLensLidoLinearLiNEARLooksRareMattersMirrorNounsOpenSeaOptimismParagraphParaswapPolymarketRSS3SAVMStargateUniswapVSLZerion" +const _PlatformName = "Unknown1inchAAVEAavegotchiArbitrumBaseBendDAOCowCrossbellCurveENSFarcasterHighlightIQWikiKiwiStandLensLidoLinearLiNEARLooksRareMattersMirrorNounsOpenSeaOptimismParagraphParaswapPolymarketRSS3RainbowSAVMStargateUniswapVSLZerion" -var _PlatformIndex = [...]uint8{0, 7, 12, 16, 26, 34, 38, 45, 48, 57, 62, 65, 74, 83, 89, 98, 102, 106, 112, 118, 127, 134, 140, 145, 152, 160, 169, 177, 187, 191, 195, 203, 210, 213, 219} +var _PlatformIndex = [...]uint8{0, 7, 12, 16, 26, 34, 38, 45, 48, 57, 62, 65, 74, 83, 89, 98, 102, 106, 112, 118, 127, 134, 140, 145, 152, 160, 169, 177, 187, 191, 198, 202, 210, 217, 220, 226} -const _PlatformLowerName = "unknown1inchaaveaavegotchiarbitrumbasebenddaocowcrossbellcurveensfarcasterhighlightiqwikikiwistandlenslidolinearlinearlooksraremattersmirrornounsopenseaoptimismparagraphparaswappolymarketrss3savmstargateuniswapvslzerion" +const _PlatformLowerName = "unknown1inchaaveaavegotchiarbitrumbasebenddaocowcrossbellcurveensfarcasterhighlightiqwikikiwistandlenslidolinearlinearlooksraremattersmirrornounsopenseaoptimismparagraphparaswappolymarketrss3rainbowsavmstargateuniswapvslzerion" func (i Platform) String() string { if i >= Platform(len(_PlatformIndex)-1) { @@ -59,14 +59,15 @@ func _PlatformNoOp() { _ = x[PlatformParaswap-(26)] _ = x[PlatformPolymarket-(27)] _ = x[PlatformRSS3-(28)] - _ = x[PlatformSAVM-(29)] - _ = x[PlatformStargate-(30)] - _ = x[PlatformUniswap-(31)] - _ = x[PlatformVSL-(32)] - _ = x[PlatformZerion-(33)] + _ = x[PlatformRainbow-(29)] + _ = x[PlatformSAVM-(30)] + _ = x[PlatformStargate-(31)] + _ = x[PlatformUniswap-(32)] + _ = x[PlatformVSL-(33)] + _ = x[PlatformZerion-(34)] } -var _PlatformValues = []Platform{PlatformUnknown, Platform1Inch, PlatformAAVE, PlatformAavegotchi, PlatformArbitrum, PlatformBase, PlatformBendDAO, PlatformCow, PlatformCrossbell, PlatformCurve, PlatformENS, PlatformFarcaster, PlatformHighlight, PlatformIQWiki, PlatformKiwiStand, PlatformLens, PlatformLido, PlatformLinea, PlatformLiNEAR, PlatformLooksRare, PlatformMatters, PlatformMirror, PlatformNouns, PlatformOpenSea, PlatformOptimism, PlatformParagraph, PlatformParaswap, PlatformPolymarket, PlatformRSS3, PlatformSAVM, PlatformStargate, PlatformUniswap, PlatformVSL, PlatformZerion} +var _PlatformValues = []Platform{PlatformUnknown, Platform1Inch, PlatformAAVE, PlatformAavegotchi, PlatformArbitrum, PlatformBase, PlatformBendDAO, PlatformCow, PlatformCrossbell, PlatformCurve, PlatformENS, PlatformFarcaster, PlatformHighlight, PlatformIQWiki, PlatformKiwiStand, PlatformLens, PlatformLido, PlatformLinea, PlatformLiNEAR, PlatformLooksRare, PlatformMatters, PlatformMirror, PlatformNouns, PlatformOpenSea, PlatformOptimism, PlatformParagraph, PlatformParaswap, PlatformPolymarket, PlatformRSS3, PlatformRainbow, PlatformSAVM, PlatformStargate, PlatformUniswap, PlatformVSL, PlatformZerion} var _PlatformNameToValueMap = map[string]Platform{ _PlatformName[0:7]: PlatformUnknown, @@ -127,16 +128,18 @@ var _PlatformNameToValueMap = map[string]Platform{ _PlatformLowerName[177:187]: PlatformPolymarket, _PlatformName[187:191]: PlatformRSS3, _PlatformLowerName[187:191]: PlatformRSS3, - _PlatformName[191:195]: PlatformSAVM, - _PlatformLowerName[191:195]: PlatformSAVM, - _PlatformName[195:203]: PlatformStargate, - _PlatformLowerName[195:203]: PlatformStargate, - _PlatformName[203:210]: PlatformUniswap, - _PlatformLowerName[203:210]: PlatformUniswap, - _PlatformName[210:213]: PlatformVSL, - _PlatformLowerName[210:213]: PlatformVSL, - _PlatformName[213:219]: PlatformZerion, - _PlatformLowerName[213:219]: PlatformZerion, + _PlatformName[191:198]: PlatformRainbow, + _PlatformLowerName[191:198]: PlatformRainbow, + _PlatformName[198:202]: PlatformSAVM, + _PlatformLowerName[198:202]: PlatformSAVM, + _PlatformName[202:210]: PlatformStargate, + _PlatformLowerName[202:210]: PlatformStargate, + _PlatformName[210:217]: PlatformUniswap, + _PlatformLowerName[210:217]: PlatformUniswap, + _PlatformName[217:220]: PlatformVSL, + _PlatformLowerName[217:220]: PlatformVSL, + _PlatformName[220:226]: PlatformZerion, + _PlatformLowerName[220:226]: PlatformZerion, } var _PlatformNames = []string{ @@ -169,11 +172,12 @@ var _PlatformNames = []string{ _PlatformName[169:177], _PlatformName[177:187], _PlatformName[187:191], - _PlatformName[191:195], - _PlatformName[195:203], - _PlatformName[203:210], - _PlatformName[210:213], - _PlatformName[213:219], + _PlatformName[191:198], + _PlatformName[198:202], + _PlatformName[202:210], + _PlatformName[210:217], + _PlatformName[217:220], + _PlatformName[220:226], } // PlatformString retrieves an enum value from the enum constants string name. diff --git a/schema/worker/decentralized/worker.go b/schema/worker/decentralized/worker.go index c3d76478..94970c8f 100644 --- a/schema/worker/decentralized/worker.go +++ b/schema/worker/decentralized/worker.go @@ -37,6 +37,7 @@ const ( Paragraph // paragraph Paraswap // paraswap Polymarket // polymarket + Rainbow // rainbow RSS3 // rss3 SAVM // savm Stargate // stargate @@ -99,6 +100,7 @@ var ToTagsMap = map[Worker][]tag.Tag{ Paragraph: {tag.Social}, Paraswap: {tag.Exchange}, Polymarket: {tag.Exchange}, + Rainbow: {tag.Exchange, tag.Transaction}, RSS3: {tag.Exchange, tag.Collectible}, SAVM: {tag.Transaction}, Stargate: {tag.Transaction}, diff --git a/schema/worker/decentralized/worker_string.go b/schema/worker/decentralized/worker_string.go index e775a499..62b89121 100644 --- a/schema/worker/decentralized/worker_string.go +++ b/schema/worker/decentralized/worker_string.go @@ -9,11 +9,11 @@ import ( "strings" ) -const _WorkerName = "aaveaavegotchiarbitrumbasebenddaocorecowcrossbellcurveenshighlightiqwikikiwistandlenslidolinealinearlooksraremattersmirrormomokanouns1inchopenseaoptimismparagraphparaswappolymarketrss3savmstargateuniswapvslzerion" +const _WorkerName = "aaveaavegotchiarbitrumbasebenddaocorecowcrossbellcurveenshighlightiqwikikiwistandlenslidolinealinearlooksraremattersmirrormomokanouns1inchopenseaoptimismparagraphparaswappolymarketrainbowrss3savmstargateuniswapvslzerion" -var _WorkerIndex = [...]uint8{0, 4, 14, 22, 26, 33, 37, 40, 49, 54, 57, 66, 72, 81, 85, 89, 94, 100, 109, 116, 122, 128, 133, 138, 145, 153, 162, 170, 180, 184, 188, 196, 203, 206, 212} +var _WorkerIndex = [...]uint8{0, 4, 14, 22, 26, 33, 37, 40, 49, 54, 57, 66, 72, 81, 85, 89, 94, 100, 109, 116, 122, 128, 133, 138, 145, 153, 162, 170, 180, 187, 191, 195, 203, 210, 213, 219} -const _WorkerLowerName = "aaveaavegotchiarbitrumbasebenddaocorecowcrossbellcurveenshighlightiqwikikiwistandlenslidolinealinearlooksraremattersmirrormomokanouns1inchopenseaoptimismparagraphparaswappolymarketrss3savmstargateuniswapvslzerion" +const _WorkerLowerName = "aaveaavegotchiarbitrumbasebenddaocorecowcrossbellcurveenshighlightiqwikikiwistandlenslidolinealinearlooksraremattersmirrormomokanouns1inchopenseaoptimismparagraphparaswappolymarketrainbowrss3savmstargateuniswapvslzerion" func (i Worker) String() string { i -= 1 @@ -59,15 +59,16 @@ func _WorkerNoOp() { _ = x[Paragraph-(26)] _ = x[Paraswap-(27)] _ = x[Polymarket-(28)] - _ = x[RSS3-(29)] - _ = x[SAVM-(30)] - _ = x[Stargate-(31)] - _ = x[Uniswap-(32)] - _ = x[VSL-(33)] - _ = x[Zerion-(34)] + _ = x[Rainbow-(29)] + _ = x[RSS3-(30)] + _ = x[SAVM-(31)] + _ = x[Stargate-(32)] + _ = x[Uniswap-(33)] + _ = x[VSL-(34)] + _ = x[Zerion-(35)] } -var _WorkerValues = []Worker{Aave, Aavegotchi, Arbitrum, Base, BendDAO, Core, Cow, Crossbell, Curve, ENS, Highlight, IQWiki, KiwiStand, Lens, Lido, Linea, LiNEAR, Looksrare, Matters, Mirror, Momoka, Nouns, Oneinch, OpenSea, Optimism, Paragraph, Paraswap, Polymarket, RSS3, SAVM, Stargate, Uniswap, VSL, Zerion} +var _WorkerValues = []Worker{Aave, Aavegotchi, Arbitrum, Base, BendDAO, Core, Cow, Crossbell, Curve, ENS, Highlight, IQWiki, KiwiStand, Lens, Lido, Linea, LiNEAR, Looksrare, Matters, Mirror, Momoka, Nouns, Oneinch, OpenSea, Optimism, Paragraph, Paraswap, Polymarket, Rainbow, RSS3, SAVM, Stargate, Uniswap, VSL, Zerion} var _WorkerNameToValueMap = map[string]Worker{ _WorkerName[0:4]: Aave, @@ -126,18 +127,20 @@ var _WorkerNameToValueMap = map[string]Worker{ _WorkerLowerName[162:170]: Paraswap, _WorkerName[170:180]: Polymarket, _WorkerLowerName[170:180]: Polymarket, - _WorkerName[180:184]: RSS3, - _WorkerLowerName[180:184]: RSS3, - _WorkerName[184:188]: SAVM, - _WorkerLowerName[184:188]: SAVM, - _WorkerName[188:196]: Stargate, - _WorkerLowerName[188:196]: Stargate, - _WorkerName[196:203]: Uniswap, - _WorkerLowerName[196:203]: Uniswap, - _WorkerName[203:206]: VSL, - _WorkerLowerName[203:206]: VSL, - _WorkerName[206:212]: Zerion, - _WorkerLowerName[206:212]: Zerion, + _WorkerName[180:187]: Rainbow, + _WorkerLowerName[180:187]: Rainbow, + _WorkerName[187:191]: RSS3, + _WorkerLowerName[187:191]: RSS3, + _WorkerName[191:195]: SAVM, + _WorkerLowerName[191:195]: SAVM, + _WorkerName[195:203]: Stargate, + _WorkerLowerName[195:203]: Stargate, + _WorkerName[203:210]: Uniswap, + _WorkerLowerName[203:210]: Uniswap, + _WorkerName[210:213]: VSL, + _WorkerLowerName[210:213]: VSL, + _WorkerName[213:219]: Zerion, + _WorkerLowerName[213:219]: Zerion, } var _WorkerNames = []string{ @@ -169,12 +172,13 @@ var _WorkerNames = []string{ _WorkerName[153:162], _WorkerName[162:170], _WorkerName[170:180], - _WorkerName[180:184], - _WorkerName[184:188], - _WorkerName[188:196], - _WorkerName[196:203], - _WorkerName[203:206], - _WorkerName[206:212], + _WorkerName[180:187], + _WorkerName[187:191], + _WorkerName[191:195], + _WorkerName[195:203], + _WorkerName[203:210], + _WorkerName[210:213], + _WorkerName[213:219], } // WorkerString retrieves an enum value from the enum constants string name.