diff --git a/pkg/parser/bebop/parser.go b/pkg/parser/bebop/parser.go index a205223..e3bb29f 100644 --- a/pkg/parser/bebop/parser.go +++ b/pkg/parser/bebop/parser.go @@ -423,12 +423,13 @@ func (p *Parser) parseAggregateSwap(order storage.TradeLog, } quoteTakerAmount := getAggregateOrderInfo(rfqOrder) if filledTakerAmount.Cmp(big.NewInt(0)) > 0 && filledTakerAmount.Cmp(quoteTakerAmount) < 0 { - for i := range rfqOrder.MakerAmounts { + for i := range rfqOrder.MakerAddresses { for j := range rfqOrder.MakerAmounts[i] { tmp := big.NewInt(0).Mul(rfqOrder.MakerAmounts[i][j], filledTakerAmount) rfqOrder.MakerAmounts[i][j] = tmp.Div(tmp, quoteTakerAmount) - - tmp = big.NewInt(0).Mul(rfqOrder.TakerAmounts[i][j], filledTakerAmount) + } + for j := range rfqOrder.TakerAmounts[i] { + tmp := big.NewInt(0).Mul(rfqOrder.TakerAmounts[i][j], filledTakerAmount) rfqOrder.TakerAmounts[i][j] = tmp.Div(tmp, quoteTakerAmount) } } diff --git a/v2/pkg/parser/bebop/bebop_test.go b/v2/pkg/parser/bebop/bebop_test.go index a715bb3..3c04d55 100644 --- a/v2/pkg/parser/bebop/bebop_test.go +++ b/v2/pkg/parser/bebop/bebop_test.go @@ -68,6 +68,33 @@ func TestParseAggregateOrderEvent(t *testing.T) { } } +func TestParseAggregateOrderEvent2(t *testing.T) { + t.Skip("Need to add the rpc url that enables the trace call JSON-RPC") + eventRaw := `{"address":"0xbbbbbbb520d69a9775e85b458c58c648259fad5f","topics":["0xadd7095becdaa725f0f33243630938c861b0bba83dfd217d4055701aa768ec2e","0x0000000000000000000000000000000000000000000000000000000000000000"],"data":"0x","blockNumber":"0x1443cc5","transactionHash":"0xe28041915a516e729bdbf397f79a570d62071216bbda42797062c550be7e71b6","transactionIndex":"0x1","blockHash":"0xa179050f766d694f030e137f924a5d4de2c90bcce223d7a5df52af02b12c6b5e","logIndex":"0x14","removed":false}` + events := types.Log{} + err := json.Unmarshal([]byte(eventRaw), &events) + require.NoError(t, err) + + callFrameRaw := `{ "from": "0xf7dc4ab21a6d8e7a573c13516cf3419b4b8a0002", "gas": "0x3bf47", "gasUsed": "0x1e756", "to": "0xbbbbbbb520d69a9775e85b458c58c648259fad5f", "input": "0xa2f74893000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000004c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006741916c000000000000000000000000f7dc4ab21a6d8e7a573c13516cf3419b4b8a0002000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000001e0000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000380000000000000000000000000f7dc4ab21a6d8e7a573c13516cf3419b4b8a000200000000000000000000000000000000000000000000000000000000000004200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000051c72848c68a965f66fa7a88855f9f7784502a7f0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000004b9ccbb0a44000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000dc25127cc000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000ea0149b816498000000000000000000000000000000000000000000000000000089c7ce1eb5e6f8000000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000416fda3da1cb665ab572b50d5b93c5adc3bbe8a176d23a33d6fca2287d3b6239eb72079e06970a3e5d630379183f41475a5cbe0809f910055e76bad14b47c232eb1b00000000000000000000000000000000000000000000000000000000000000", "calls": [ { "from": "0xbbbbbbb520d69a9775e85b458c58c648259fad5f", "gas": "0x36a15", "gasUsed": "0x2b31", "to": "0x51c72848c68a965f66fa7a88855f9f7784502a7f", "input": "0x1626ba7e56ffa4818cf4a457392fe77d42aa95b26a01f84038c203bcb556902577aba78d000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000416fda3da1cb665ab572b50d5b93c5adc3bbe8a176d23a33d6fca2287d3b6239eb72079e06970a3e5d630379183f41475a5cbe0809f910055e76bad14b47c232eb1b00000000000000000000000000000000000000000000000000000000000000", "output": "0x1626ba7e00000000000000000000000000000000000000000000000000000000", "calls": [ { "from": "0x51c72848c68a965f66fa7a88855f9f7784502a7f", "gas": "0x33ef1", "gasUsed": "0xbb8", "to": "0x0000000000000000000000000000000000000001", "input": "0x56ffa4818cf4a457392fe77d42aa95b26a01f84038c203bcb556902577aba78d000000000000000000000000000000000000000000000000000000000000001b6fda3da1cb665ab572b50d5b93c5adc3bbe8a176d23a33d6fca2287d3b6239eb72079e06970a3e5d630379183f41475a5cbe0809f910055e76bad14b47c232eb", "output": "0x000000000000000000000000a0f1898fb62aee04f9aa1aa5866bc48e6b4cb1d8", "type": "STATICCALL" } ], "type": "STATICCALL" }, { "from": "0xbbbbbbb520d69a9775e85b458c58c648259fad5f", "gas": "0x2bb3d", "gasUsed": "0x75ad", "to": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", "input": "0x23b872dd00000000000000000000000051c72848c68a965f66fa7a88855f9f7784502a7f000000000000000000000000f7dc4ab21a6d8e7a573c13516cf3419b4b8a0002000000000000000000000000000000000000000000000000ea0149b816498000", "output": "0x0000000000000000000000000000000000000000000000000000000000000001", "logs": [ { "address": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", "topics": [ "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", "0x00000000000000000000000051c72848c68a965f66fa7a88855f9f7784502a7f", "0x000000000000000000000000f7dc4ab21a6d8e7a573c13516cf3419b4b8a0002" ], "data": "0x000000000000000000000000000000000000000000000000ea0149b816498000", "position": "0x0" } ], "value": "0x0", "type": "CALL" }, { "from": "0xbbbbbbb520d69a9775e85b458c58c648259fad5f", "gas": "0x240f4", "gasUsed": "0xd61", "to": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", "input": "0x23b872dd00000000000000000000000051c72848c68a965f66fa7a88855f9f7784502a7f000000000000000000000000f7dc4ab21a6d8e7a573c13516cf3419b4b8a0002000000000000000000000000000000000000000000000000089c7ce1eb5e6f80", "output": "0x0000000000000000000000000000000000000000000000000000000000000001", "logs": [ { "address": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", "topics": [ "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", "0x00000000000000000000000051c72848c68a965f66fa7a88855f9f7784502a7f", "0x000000000000000000000000f7dc4ab21a6d8e7a573c13516cf3419b4b8a0002" ], "data": "0x000000000000000000000000000000000000000000000000089c7ce1eb5e6f80", "position": "0x0" } ], "value": "0x0", "type": "CALL" }, { "from": "0xbbbbbbb520d69a9775e85b458c58c648259fad5f", "gas": "0x2234f", "gasUsed": "0x46e5", "to": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", "input": "0x23b872dd000000000000000000000000f7dc4ab21a6d8e7a573c13516cf3419b4b8a000200000000000000000000000051c72848c68a965f66fa7a88855f9f7784502a7f0000000000000000000000000000000000000000000000000000000dc25127cc", "output": "0x0000000000000000000000000000000000000000000000000000000000000001", "calls": [ { "from": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", "gas": "0x217df", "gasUsed": "0x43ca", "to": "0x43506849d7c04f9138d1a2050bbf3a0c054402dd", "input": "0x23b872dd000000000000000000000000f7dc4ab21a6d8e7a573c13516cf3419b4b8a000200000000000000000000000051c72848c68a965f66fa7a88855f9f7784502a7f0000000000000000000000000000000000000000000000000000000dc25127cc", "output": "0x0000000000000000000000000000000000000000000000000000000000000001", "logs": [ { "address": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", "topics": [ "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", "0x000000000000000000000000f7dc4ab21a6d8e7a573c13516cf3419b4b8a0002", "0x00000000000000000000000051c72848c68a965f66fa7a88855f9f7784502a7f" ], "data": "0x0000000000000000000000000000000000000000000000000000000dc25127cc", "position": "0x0" } ], "value": "0x0", "type": "DELEGATECALL" } ], "value": "0x0", "type": "CALL" } ], "logs": [ { "address": "0xbbbbbbb520d69a9775e85b458c58c648259fad5f", "topics": [ "0xadd7095becdaa725f0f33243630938c861b0bba83dfd217d4055701aa768ec2e", "0x0000000000000000000000000000000000000000000000000000000000000000" ], "data": "0x", "position": "0x4" } ], "value": "0x0", "type": "CALL" }` + var callFrame types2.CallFrame + err = json.Unmarshal([]byte(callFrameRaw), &callFrame) + require.NoError(t, err) + + p := MustNewParser() + logs, err := p.ParseWithCallFrame(callFrame, events, uint64(time.Now().Unix())) + require.NoError(t, err) + for _, log := range logs { + require.Equal(t, log.EventHash, p.eventHash) + t.Log(log.Maker) + t.Log(log.MakerToken) + t.Log(log.MakerTokenAmount) + t.Log(log.Taker) + t.Log(log.TakerToken) + t.Log(log.TakerTokenAmount) + t.Log("---------------------") + } +} + func TestParseMultiOrderEvent(t *testing.T) { t.Skip("Need to add the rpc url that enables the trace call JSON-RPC") eventRaw := `{"address":"0xbbbbbbb520d69a9775e85b458c58c648259fad5f","topics":["0xadd7095becdaa725f0f33243630938c861b0bba83dfd217d4055701aa768ec2e","0x0000000000000000000000000000000027611cb25303fa700000000000000001"],"data":"0x","blockNumber":"0x133842c","transactionHash":"0xff46ac555ec7da7aa484864dc0df90217b7f46dfa51627c20ef6e25451c64b15","transactionIndex":"0x10","blockHash":"0xb03cd01d48456c60cdf445e35b0a4d7672b80d801245e516336596f0d5b77951","logIndex":"0x85","removed":false}` diff --git a/v2/pkg/parser/bebop/parser.go b/v2/pkg/parser/bebop/parser.go index c413a52..53ad4f4 100644 --- a/v2/pkg/parser/bebop/parser.go +++ b/v2/pkg/parser/bebop/parser.go @@ -318,17 +318,8 @@ func (p *Parser) parseMultiSwap(order storageTypes.TradeLog, break } - originMakerAmounts := make([]string, len(rfqOrder.MakerAmounts)) - for i, amount := range rfqOrder.MakerAmounts { - originMakerAmounts[i] = amount.String() - } - order.MakerTokenOriginAmount = strings.Join(originMakerAmounts, ",") - - originTakerAmounts := make([]string, len(rfqOrder.TakerAmounts)) - for i, amount := range rfqOrder.TakerAmounts { - originTakerAmounts[i] = amount.String() - } - order.TakerTokenOriginAmount = strings.Join(originTakerAmounts, ",") + order.MakerTokenOriginAmount = joinAmounts(rfqOrder.MakerAmounts) + order.TakerTokenOriginAmount = joinAmounts(rfqOrder.TakerAmounts) if len(rfqOrder.TakerTokens) == 1 { // many to one don't support partial, just handle one - many if fillTakerAmount.Cmp(big.NewInt(0)) > 0 && fillTakerAmount.Cmp(rfqOrder.TakerAmounts[0]) < 0 { @@ -345,17 +336,8 @@ func (p *Parser) parseMultiSwap(order storageTypes.TradeLog, order.Maker = rfqOrder.MakerAddress order.Taker = rfqOrder.TakerAddress - makerAmounts := make([]string, len(rfqOrder.MakerAmounts)) - for i, amount := range rfqOrder.MakerAmounts { - makerAmounts[i] = amount.String() - } - order.MakerTokenAmount = strings.Join(makerAmounts, ",") - - takerAmounts := make([]string, len(rfqOrder.TakerAmounts)) - for i, amount := range rfqOrder.TakerAmounts { - takerAmounts[i] = amount.String() - } - order.TakerTokenAmount = strings.Join(takerAmounts, ",") + order.MakerTokenAmount = joinAmounts(rfqOrder.MakerAmounts) + order.TakerTokenAmount = joinAmounts(rfqOrder.TakerAmounts) if rfqOrder.Expiry != nil { order.Expiry = rfqOrder.Expiry.Uint64() @@ -386,63 +368,65 @@ func (p *Parser) parseAggregateSwap(order storageTypes.TradeLog, } quoteTakerAmount := getAggregateOrderInfo(rfqOrder) - originalMakerAmounts := make([][]string, len(rfqOrder.MakerAmounts)) - originalTakerAmounts := make([][]string, len(rfqOrder.TakerAmounts)) - for i := range rfqOrder.TakerAmounts { - originalMakerAmounts[i] = make([]string, len(rfqOrder.MakerAmounts[i])) - originalTakerAmounts[i] = make([]string, len(rfqOrder.TakerAmounts[i])) - for j := range rfqOrder.TakerAmounts[i] { - originalMakerAmounts[i][j] = rfqOrder.MakerAmounts[i][j].String() - originalTakerAmounts[i][j] = rfqOrder.TakerAmounts[i][j].String() + var orders []storageTypes.TradeLog + + // parse each trade + for i := range rfqOrder.MakerAddresses { + newOrder := storageTypes.TradeLog{ + Exchange: p.Exchange(), + OrderHash: order.OrderHash, + Maker: rfqOrder.MakerAddresses[i], + Taker: rfqOrder.TakerAddress, + MakerToken: strings.Join(rfqOrder.MakerTokens[i], ","), + TakerToken: strings.Join(rfqOrder.TakerTokens[i], ","), + MakerTokenAmount: joinAmounts(rfqOrder.MakerAmounts[i]), + TakerTokenAmount: joinAmounts(rfqOrder.TakerAmounts[i]), + MakerTokenOriginAmount: joinAmounts(rfqOrder.MakerAmounts[i]), + TakerTokenOriginAmount: joinAmounts(rfqOrder.TakerAmounts[i]), + ContractAddress: order.ContractAddress, + BlockNumber: order.BlockNumber, + TxHash: order.TxHash, + LogIndex: order.LogIndex, + TradeIndex: uint64(i), + Timestamp: order.Timestamp, + EventHash: order.EventHash, + Expiry: rfqOrder.Expiry.Uint64(), + } + + if len(rfqOrder.TakerTokens[i]) > 1 { // many-to-one not support partial fill + orders = append(orders, newOrder) + continue } - } - if filledTakerAmount.Cmp(big.NewInt(0)) > 0 && filledTakerAmount.Cmp(quoteTakerAmount) < 0 { - for i := range rfqOrder.MakerAmounts { + // partial fill + if filledTakerAmount.Cmp(big.NewInt(0)) > 0 && filledTakerAmount.Cmp(quoteTakerAmount) < 0 { for j := range rfqOrder.MakerAmounts[i] { tmp := big.NewInt(0).Mul(rfqOrder.MakerAmounts[i][j], filledTakerAmount) rfqOrder.MakerAmounts[i][j] = tmp.Div(tmp, quoteTakerAmount) - - tmp = big.NewInt(0).Mul(rfqOrder.TakerAmounts[i][j], filledTakerAmount) + } + for j := range rfqOrder.TakerAmounts[i] { + tmp := big.NewInt(0).Mul(rfqOrder.TakerAmounts[i][j], filledTakerAmount) rfqOrder.TakerAmounts[i][j] = tmp.Div(tmp, quoteTakerAmount) } } - } - var ( - orders []storageTypes.TradeLog - count int - ) - - for i := range rfqOrder.MakerAmounts { - for j := range rfqOrder.MakerAmounts[i] { - orders = append(orders, storageTypes.TradeLog{ - Exchange: p.Exchange(), - OrderHash: order.OrderHash, - Maker: rfqOrder.MakerAddresses[i], - Taker: rfqOrder.TakerAddress, - MakerToken: rfqOrder.MakerTokens[i][j], - TakerToken: rfqOrder.TakerTokens[i][j], - MakerTokenAmount: rfqOrder.MakerAmounts[i][j].String(), - TakerTokenAmount: rfqOrder.TakerAmounts[i][j].String(), - MakerTokenOriginAmount: originalMakerAmounts[i][j], - TakerTokenOriginAmount: originalTakerAmounts[i][j], - ContractAddress: order.ContractAddress, - BlockNumber: order.BlockNumber, - TxHash: order.TxHash, - LogIndex: order.LogIndex, - TradeIndex: uint64(count), - Timestamp: order.Timestamp, - EventHash: order.EventHash, - Expiry: rfqOrder.Expiry.Uint64(), - }) - count++ - } + newOrder.MakerTokenAmount = joinAmounts(rfqOrder.MakerAmounts[i]) + newOrder.TakerTokenAmount = joinAmounts(rfqOrder.TakerAmounts[i]) + + orders = append(orders, newOrder) } return orders, nil } +func joinAmounts(input []*big.Int) string { + amounts := make([]string, len(input)) + for i, amount := range input { + amounts[i] = amount.String() + } + return strings.Join(amounts, ",") +} + func getAggregateOrderInfo(order AggregateOrder) *big.Int { commandsInd := 0 quoteTakerAmount := big.NewInt(0)