Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

patch/Update pool manager swap amount in parser to take into account cosmwa… #536

Merged
merged 1 commit into from
Mar 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 39 additions & 21 deletions cosmos/modules/tx/logic.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,34 +78,52 @@ func ParseTransferEvent(evt LogMessageEvent) ([]TransferEvent, error) {
return nil, errInvalidTransfer
}

for i := 0; i < len(evt.Attributes); i++ {
attrRecipient := evt.Attributes[i]
if attrRecipient.Key == "recipient" {
attrSenderIdx := i + 1
attrAmountIdx := i + 2
if attrAmountIdx < len(evt.Attributes) {
attrSender := evt.Attributes[attrSenderIdx]
attrAmount := evt.Attributes[attrAmountIdx]
if attrSender.Key == "sender" && attrAmount.Key == EventAttributeAmount {
transfers = append(transfers, TransferEvent{
Recipient: attrRecipient.Value,
Sender: attrSender.Value,
Amount: attrAmount.Value,
})
} else {
return nil, errInvalidTransfer
}
} else {
return nil, errInvalidTransfer
}
} else if i%3 == 0 { // every third attr should be "recipient"
if len(evt.Attributes)%3 != 0 {
return nil, errInvalidTransfer
}

// chunk the attributes into groups of 3
for i := 0; i < len(evt.Attributes); i += 3 {
transferEvent := TransferEvent{}
err := parseTransferAttributeIntoEvent(evt.Attributes[i], &transferEvent)
if err != nil {
return nil, err
}
err = parseTransferAttributeIntoEvent(evt.Attributes[i+1], &transferEvent)
if err != nil {
return nil, err
}
err = parseTransferAttributeIntoEvent(evt.Attributes[i+2], &transferEvent)
if err != nil {
return nil, err
}

// validate the transfer event
if transferEvent.Recipient == "" || transferEvent.Sender == "" || transferEvent.Amount == "" {
return nil, errInvalidTransfer
}

transfers = append(transfers, transferEvent)
}

return transfers, nil
}

func parseTransferAttributeIntoEvent(attr Attribute, evt *TransferEvent) error {
switch attr.Key {
case "recipient":
evt.Recipient = attr.Value
case "sender":
evt.Sender = attr.Value
case "amount":
evt.Amount = attr.Value
default:
return fmt.Errorf("unknown attribute %s", attr.Key)
}

return nil
}

// If order is reversed, the last attribute containing the given key will be returned
// otherwise the first attribute will be returned
func GetValueForAttribute(key string, evt *LogMessageEvent) (string, error) {
Expand Down
74 changes: 44 additions & 30 deletions osmosis/modules/poolmanager/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,42 +152,56 @@ func (sf *WrapperMsgSwapExactAmountIn) HandleMsg(msgType string, msg sdk.Msg, lo

transferEvents := txModule.GetEventsWithType("transfer", log)

var transferEvt *txModule.LogMessageEvent
if len(transferEvents) == 0 {
transferEvt = nil
} else {
transferEvt = &transferEvents[len(transferEvents)-1]
}

if !parsed && transferEvt != nil {
transferEvts, err := txModule.ParseTransferEvent(*transferEvt)
if err != nil {
return err
}
if !parsed && len(transferEvents) > 0 {

var parserError error
var lastParsedIndex int
// We will attempt to get the last transfer event that executed for the sender
// We are scoping it for now so as not to blast all the way to the beginning but to address
// poolmanager CosmWasm pool executions that seem to send some small amount to a different address right at the end
for i := len(transferEvents) - 1; !parsed && len(transferEvents)-2 >= 0 && i >= len(transferEvents)-2; i-- {
lastParsedIndex = i
transferEvt := &transferEvents[i]

transferEvts, err := txModule.ParseTransferEvent(*transferEvt)
if err != nil {
parserError = err
continue
}

// The last transfer event should contain the final transfer to the sender
lastTransferEvt := transferEvts[len(transferEvts)-1]

if lastTransferEvt.Recipient != sf.Address {
parserError = errors.New("transfer event recipient does not match message sender")
continue
}

tokenOut, err := sdk.ParseCoinNormalized(lastTransferEvt.Amount)
if err != nil {
parserError = err
continue
}

// The last route in the hops gives the token out denom and pool ID for the final output
lastRoute := sf.OsmosisMsgSwapExactAmountIn.Routes[len(sf.OsmosisMsgSwapExactAmountIn.Routes)-1]
lastRouteDenom := lastRoute.TokenOutDenom

if tokenOut.Denom != lastRouteDenom {
parserError = errors.New("final transfer denom does not match last route denom")
continue
}

// The last transfer event should contain the final transfer to the sender
lastTransferEvt := transferEvts[len(transferEvts)-1]

if lastTransferEvt.Recipient != sf.Address {
return errors.New("transfer event recipient does not match message sender")
}
sf.TokenOut = tokenOut

tokenOut, err := sdk.ParseCoinNormalized(lastTransferEvt.Amount)
if err != nil {
return err
parsed = true
parserError = nil
}

// The last route in the hops gives the token out denom and pool ID for the final output
lastRoute := sf.OsmosisMsgSwapExactAmountIn.Routes[len(sf.OsmosisMsgSwapExactAmountIn.Routes)-1]
lastRouteDenom := lastRoute.TokenOutDenom

if tokenOut.Denom != lastRouteDenom {
return errors.New("final transfer denom does not match last route denom")
if parserError != nil {
return fmt.Errorf("error parsing transfer event. Last processed index (%d): %s", lastParsedIndex, parserError)
}

sf.TokenOut = tokenOut

parsed = true
}

if !parsed {
Expand Down
Loading