Skip to content

Commit

Permalink
bebop get filled taker amount for swap single from contract (#81)
Browse files Browse the repository at this point in the history
  • Loading branch information
linhnt3400 authored Oct 8, 2024
1 parent c8db598 commit d0767c8
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 3 deletions.
23 changes: 23 additions & 0 deletions pkg/parser/bebop/bebop_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,3 +115,26 @@ func TestParseSingleOrderEvent(t *testing.T) {
t.Log(log.TakerToken)
t.Log(log.TakerTokenAmount)
}

func TestParseSwapSingleFromContract(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":"0x13e7401","transactionHash":"0x4b15bfb1024c71eb76a48dbf1d0faea77044433807e2052dbb3a00b3ee054a14","transactionIndex":"0x3f","blockHash":"0x4161ffa4596f3bd812959e7a91038a26d27f57aa51d9ef3ee4cd0772d11c86fe","logIndex":"0x176","removed":false}`
events := types.Log{}
err := json.Unmarshal([]byte(eventRaw), &events)
require.NoError(t, err)
ethClient, err := ethclient.Dial(rpcURL)
if err != nil {
panic(err)
}
traceCalls := tracecall.NewCache(rpcnode.NewClient(zap.S(), ethClient))
p := MustNewParser(traceCalls)
log, err := p.Parse(events, uint64(time.Now().Unix()))
require.NoError(t, err)
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)
}
40 changes: 37 additions & 3 deletions pkg/parser/bebop/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ import (
const (
TradeEvent = "BebopOrder"
OrderParam = "order"

balanceOfMethodID = "0x70a08231"
swapSingleFromContractFunctionName = "swapSingleFromContract"
)

var (
Expand Down Expand Up @@ -206,7 +209,7 @@ func (p *Parser) ParseFromInternalCall(order storage.TradeLog, internalCall type
}
break
}
if filledTakerAmount == nil {
if filledTakerAmount == nil && contractCall.Name != swapSingleFromContractFunctionName {
return order, ErrParamNotFound
}
for _, param := range contractCall.Params {
Expand All @@ -215,7 +218,7 @@ func (p *Parser) ParseFromInternalCall(order storage.TradeLog, internalCall type
}
switch {
case p.singleOrderFunc.Has(contractCall.Name):
return p.parseSingleSwap(order, contractCall, param, filledTakerAmount)
return p.parseSingleSwap(order, contractCall, param, filledTakerAmount, internalCall)
case p.multiOrderFunc.Has(contractCall.Name):
return p.parseMultiSwap(order, contractCall, param, filledTakerAmount)
case p.aggregateOrderFunc.Has(contractCall.Name):
Expand Down Expand Up @@ -281,10 +284,34 @@ func (p *Parser) LogFromExchange(log ethereumTypes.Log) bool {
strings.EqualFold(log.Topics[0].String(), p.eventHash)
}

func (p *Parser) getFilledTakerAmount(order SingleOrder, traceCall types.CallFrame) *big.Int {
for _, call := range traceCall.Calls {
if call.From != strings.ToLower(p.Address()) {
continue
}
if call.To != order.TakerToken {
continue
}
if !strings.HasPrefix(call.Input, balanceOfMethodID) {
continue
}
if len(call.Output) <= 2 {
continue
}
balance, ok := new(big.Int).SetString(call.Output[2:], 16)
if !ok {
continue
}
return balance
}
return nil
}

func (p *Parser) parseSingleSwap(order storage.TradeLog,
contractCall *tradingTypes.ContractCall,
orderParam tradingTypes.ContractCallParam,
fillTakerAmount *big.Int) (storage.TradeLog, error) {
fillTakerAmount *big.Int,
internalCall types.CallFrame) (storage.TradeLog, error) {
var rfqOrder SingleOrder
if err := unpackOrder(orderParam.Value, &rfqOrder); err != nil {
return order, err
Expand All @@ -301,6 +328,13 @@ func (p *Parser) parseSingleSwap(order storage.TradeLog,
break
}

if contractCall.Name == swapSingleFromContractFunctionName {
fillTakerAmount = p.getFilledTakerAmount(rfqOrder, internalCall)
if fillTakerAmount == nil {
return order, ErrParamNotFound
}
}

if fillTakerAmount.Cmp(big.NewInt(0)) > 0 && fillTakerAmount.Cmp(rfqOrder.TakerAmount) < 0 {
tmp := big.NewInt(0).Mul(rfqOrder.MakerAmount, fillTakerAmount)
rfqOrder.MakerAmount = tmp.Div(tmp, rfqOrder.TakerAmount)
Expand Down

0 comments on commit d0767c8

Please sign in to comment.