From b6759b95d3f41ac447aa7b8ce4a0dc442693140e Mon Sep 17 00:00:00 2001 From: Nguyen Thuy Linh Date: Fri, 4 Oct 2024 13:26:30 +0700 Subject: [PATCH] pancakeswap exclusive override (#79) --- pkg/parser/pancakeswap/parser.go | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/pkg/parser/pancakeswap/parser.go b/pkg/parser/pancakeswap/parser.go index b5eea82..7ca1cdc 100644 --- a/pkg/parser/pancakeswap/parser.go +++ b/pkg/parser/pancakeswap/parser.go @@ -20,6 +20,8 @@ const ( FilledEvent = "Fill" ) +var BPS = big.NewInt(10000) + type ResolvedOrder struct { Info struct { Reactor common.Address "json:\"reactor\"" @@ -189,7 +191,7 @@ func (p *Parser) recursiveDetectRFQTrades(order storage.TradeLog, call types.Cal if err != nil { continue } - finalOrder, err := p.updateOrder(order, parsedOrder) + finalOrder, err := p.updateOrder(order, parsedOrder, common.HexToAddress(call.From)) if err != nil { continue } @@ -206,7 +208,7 @@ func (p *Parser) recursiveDetectRFQTrades(order storage.TradeLog, call types.Cal return order, fmt.Errorf("%w %s", parser.ErrNotFoundTrade, string(traceData)) } -func (p *Parser) updateOrder(internal storage.TradeLog, parsed []interface{}) (storage.TradeLog, error) { +func (p *Parser) updateOrder(internal storage.TradeLog, parsed []interface{}, sender common.Address) (storage.TradeLog, error) { data, err := json.Marshal(parsed) if err != nil { return storage.TradeLog{}, err @@ -220,18 +222,21 @@ func (p *Parser) updateOrder(internal storage.TradeLog, parsed []interface{}) (s } order := resolvedOrder[0] internal.TakerToken = order.InputToken.String() + blockTime := big.NewInt(int64(internal.Timestamp / 1000)) internal.TakerTokenAmount = decay(order.InputStartAmount, order.InputEndAmount, order.DecayStartTime, order.DecayEndTime, - big.NewInt(int64(internal.Timestamp/1000))).String() + blockTime).String() internal.MakerToken = order.Outputs[0].Token.String() makerAmount := big.NewInt(0) for _, o := range order.Outputs { - makerAmount = makerAmount.Add(makerAmount, decay(o.StartAmount, o.EndAmount, - order.DecayStartTime, order.DecayEndTime, - big.NewInt(int64(internal.Timestamp/1000)))) + output := decay(o.StartAmount, o.EndAmount, order.DecayStartTime, order.DecayEndTime, blockTime) + if !hasFillingRights(order.ExclusiveFiller, sender, order.DecayStartTime, blockTime) { + output = mulDivUp(output, new(big.Int).Add(BPS, order.ExclusivityOverrideBps), BPS) + } + makerAmount = makerAmount.Add(makerAmount, output) } internal.MakerTokenAmount = makerAmount.String() if order.Info.Deadline != nil { @@ -266,6 +271,20 @@ func mulDiv(a, b, c *big.Int) *big.Int { return new(big.Int).Div(new(big.Int).Mul(a, b), c) } +func mulDivUp(x, y, denominator *big.Int) *big.Int { + product := new(big.Int).Mul(x, y) + remainder := new(big.Int).Mod(product, denominator) + result := new(big.Int).Div(product, denominator) + if remainder.Cmp(big.NewInt(0)) > 0 { + result.Add(result, big.NewInt(1)) + } + return result +} + +func hasFillingRights(exclusive, sender common.Address, exclusivityEndTime, blockTime *big.Int) bool { + return exclusive == common.Address{} || blockTime.Cmp(exclusivityEndTime) > 0 || exclusive == sender +} + func (p *Parser) Exchange() string { return parser.ExPancackeSwap }