diff --git a/osmosis/handlers.go b/osmosis/handlers.go index bebfce5..ebe875a 100644 --- a/osmosis/handlers.go +++ b/osmosis/handlers.go @@ -15,10 +15,10 @@ var MessageTypeHandler = map[string][]func() txTypes.CosmosMessage{ gamm.MsgSwapExactAmountOut: {func() txTypes.CosmosMessage { return &gamm.WrapperMsgSwapExactAmountOut{} }}, gamm.MsgJoinSwapExternAmountIn: {func() txTypes.CosmosMessage { return &gamm.WrapperMsgJoinSwapExternAmountIn{} }, func() txTypes.CosmosMessage { return &gamm.WrapperMsgJoinSwapExternAmountIn2{} }}, gamm.MsgJoinSwapShareAmountOut: {func() txTypes.CosmosMessage { return &gamm.WrapperMsgJoinSwapShareAmountOut{} }, func() txTypes.CosmosMessage { return &gamm.WrapperMsgJoinSwapShareAmountOut2{} }}, - gamm.MsgJoinPool: {func() txTypes.CosmosMessage { return &gamm.WrapperMsgJoinPool{} }}, + gamm.MsgJoinPool: {func() txTypes.CosmosMessage { return &gamm.WrapperMsgJoinPool{} }, func() txTypes.CosmosMessage { return &gamm.WrapperMsgJoinPool2{} }}, gamm.MsgExitSwapShareAmountIn: {func() txTypes.CosmosMessage { return &gamm.WrapperMsgExitSwapShareAmountIn{} }, func() txTypes.CosmosMessage { return &gamm.WrapperMsgExitSwapShareAmountIn2{} }}, gamm.MsgExitSwapExternAmountOut: {func() txTypes.CosmosMessage { return &gamm.WrapperMsgExitSwapExternAmountOut{} }}, - gamm.MsgExitPool: {func() txTypes.CosmosMessage { return &gamm.WrapperMsgExitPool{} }, func() txTypes.CosmosMessage { return &gamm.WrapperMsgExitPool2{} }}, + gamm.MsgExitPool: {func() txTypes.CosmosMessage { return &gamm.WrapperMsgExitPool{} }, func() txTypes.CosmosMessage { return &gamm.WrapperMsgExitPool2{} }, func() txTypes.CosmosMessage { return &gamm.WrapperMsgExitPool3{} }}, gamm.MsgCreatePool: {func() txTypes.CosmosMessage { return &gamm.WrapperMsgCreatePool{} }, func() txTypes.CosmosMessage { return &gamm.WrapperMsgCreatePool2{} }}, gamm.MsgCreateBalancerPool: {func() txTypes.CosmosMessage { return &gamm.WrapperMsgCreateBalancerPool{} }}, gamm.PoolModelsMsgCreateBalancerPool: {func() txTypes.CosmosMessage { return &gamm.WrapperPoolModelsMsgCreateBalancerPool{} }}, diff --git a/osmosis/modules/gamm/exits.go b/osmosis/modules/gamm/exits.go index 558b37e..d7ee284 100644 --- a/osmosis/modules/gamm/exits.go +++ b/osmosis/modules/gamm/exits.go @@ -1,6 +1,7 @@ package gamm import ( + "errors" "fmt" "strings" @@ -22,6 +23,10 @@ type WrapperMsgExitPool2 struct { WrapperMsgExitPool } +type WrapperMsgExitPool3 struct { + WrapperMsgExitPool +} + type WrapperMsgExitSwapShareAmountIn struct { txModule.Message OsmosisMsgExitSwapShareAmountIn *gammTypes.MsgExitSwapShareAmountIn @@ -128,6 +133,10 @@ func (sf *WrapperMsgExitPool2) String() string { return sf.WrapperMsgExitPool.String() } +func (sf *WrapperMsgExitPool3) String() string { + return sf.WrapperMsgExitPool.String() +} + func (sf *WrapperMsgExitSwapShareAmountIn) HandleMsg(msgType string, msg sdk.Msg, log *txModule.LogMessage) error { sf.Type = msgType sf.OsmosisMsgExitSwapShareAmountIn = msg.(*gammTypes.MsgExitSwapShareAmountIn) @@ -409,6 +418,72 @@ func (sf *WrapperMsgExitPool2) HandleMsg(msgType string, msg sdk.Msg, log *txMod return err } +func (sf *WrapperMsgExitPool3) HandleMsg(msgType string, msg sdk.Msg, log *txModule.LogMessage) error { + sf.Type = msgType + sf.OsmosisMsgExitPool = msg.(*gammTypes.MsgExitPool) + + // Confirm that the action listed in the message log matches the Message type + validLog := txModule.IsMessageActionEquals(sf.GetType(), log) + if !validLog { + return util.ReturnInvalidLog(msgType, log) + } + + // The attribute in the log message that shows you the sent GAMM tokens during the exit + transferEvts := txModule.GetAllEventsWithType(bankTypes.EventTypeTransfer, log) + if len(transferEvts) == 0 { + return errors.New("no transfer events found") + } + + gammTokenOutStr := "" + + for _, evt := range transferEvts { + // This gets the amount of GAMM tokens sent + gammTokenOutStr = txModule.GetLastValueForAttribute(EventAttributeAmount, &evt) + if strings.Contains(gammTokenOutStr, "gamm") { + break + } + + } + + if gammTokenOutStr == "" { + return errors.New("no gamm token out string found") + } + + gammTokenOut, err := sdk.ParseCoinNormalized(gammTokenOutStr) + if err != nil { + return &txModule.MessageLogFormatError{MessageType: msgType, Log: fmt.Sprintf("%+v", log)} + } + sf.TokenIntoPool = gammTokenOut + + if sf.OsmosisMsgExitPool.Sender == "" { + return &txModule.MessageLogFormatError{MessageType: msgType, Log: fmt.Sprintf("%+v", log)} + } + sf.Address = sf.OsmosisMsgExitPool.Sender + + // Address of whoever initiated the exit + poolExitedEvent := txModule.GetEventWithType(gammTypes.TypeEvtPoolExited, log) + if poolExitedEvent == nil { + return &txModule.MessageLogFormatError{MessageType: msgType, Log: fmt.Sprintf("%+v", log)} + } + + // String value for the tokens in, which can be multiple + tokensOutString, err := txModule.GetValueForAttribute(gammTypes.AttributeKeyTokensOut, poolExitedEvent) + if err != nil { + return err + } + + if tokensOutString == "" { + return &txModule.MessageLogFormatError{MessageType: msgType, Log: fmt.Sprintf("%+v", log)} + } + + sf.TokensOutOfPool, err = sdk.ParseCoinsNormalized(tokensOutString) + if err != nil { + return &txModule.MessageLogFormatError{MessageType: msgType, Log: fmt.Sprintf("%+v", log)} + } + + return err +} + func (sf *WrapperMsgExitPool) HandleMsg(msgType string, msg sdk.Msg, log *txModule.LogMessage) error { sf.Type = msgType sf.OsmosisMsgExitPool = msg.(*gammTypes.MsgExitPool) @@ -579,3 +654,7 @@ func (sf *WrapperMsgExitPool) ParseRelevantData() []parsingTypes.MessageRelevant func (sf *WrapperMsgExitPool2) ParseRelevantData() []parsingTypes.MessageRelevantInformation { return sf.WrapperMsgExitPool.ParseRelevantData() } + +func (sf *WrapperMsgExitPool3) ParseRelevantData() []parsingTypes.MessageRelevantInformation { + return sf.WrapperMsgExitPool.ParseRelevantData() +} diff --git a/osmosis/modules/gamm/joins.go b/osmosis/modules/gamm/joins.go index 8cc9f6e..6cfc0ce 100644 --- a/osmosis/modules/gamm/joins.go +++ b/osmosis/modules/gamm/joins.go @@ -1,6 +1,7 @@ package gamm import ( + "errors" "fmt" "strings" @@ -53,6 +54,10 @@ type WrapperMsgJoinPool struct { Claim *sdk.Coin // option claim } +type WrapperMsgJoinPool2 struct { + WrapperMsgJoinPool +} + func (sf *WrapperMsgJoinSwapExternAmountIn) String() string { var tokenSwappedOut string var tokenSwappedIn string @@ -434,6 +439,74 @@ func (sf *WrapperMsgJoinPool) HandleMsg(msgType string, msg sdk.Msg, log *txModu return err } +func (sf *WrapperMsgJoinPool2) HandleMsg(msgType string, msg sdk.Msg, log *txModule.LogMessage) error { + sf.Type = msgType + sf.OsmosisMsgJoinPool = msg.(*gammTypes.MsgJoinPool) + + // Confirm that the action listed in the message log matches the Message type + validLog := txModule.IsMessageActionEquals(sf.GetType(), log) + if !validLog { + return util.ReturnInvalidLog(msgType, log) + } + + // The attribute in the log message that shows you the sent GAMM tokens during the exit + transferEvts := txModule.GetAllEventsWithType(bankTypes.EventTypeTransfer, log) + if len(transferEvts) == 0 { + return errors.New("no transfer events found") + } + + gammTokenOutStr := "" + + for _, evt := range transferEvts { + // This gets the amount of GAMM tokens sent + gammTokenOutStr = txModule.GetLastValueForAttribute(EventAttributeAmount, &evt) + if strings.Contains(gammTokenOutStr, "gamm") { + break + } + + } + + if !strings.Contains(gammTokenOutStr, "gamm") { + return errors.New("gamm token out string must contain gamm") + } + + gammTokenOut, err := sdk.ParseCoinNormalized(gammTokenOutStr) + if err != nil { + return &txModule.MessageLogFormatError{MessageType: msgType, Log: fmt.Sprintf("%+v", log)} + } + sf.TokenOut = gammTokenOut + + // Address of whoever initiated the join + poolJoinedEvent := txModule.GetEventWithType(gammTypes.TypeEvtPoolJoined, log) + + // Address of whoever initiated the join. + senderAddress, err := txModule.GetValueForAttribute("sender", poolJoinedEvent) + if err != nil { + return err + } + + if senderAddress == "" { + return &txModule.MessageLogFormatError{MessageType: msgType, Log: fmt.Sprintf("%+v", log)} + } + sf.Address = senderAddress + + // String value for the tokens in, which can be multiple + tokensInString, err := txModule.GetValueForAttribute(gammTypes.AttributeKeyTokensIn, poolJoinedEvent) + if err != nil { + return err + } + + if tokensInString == "" { + return &txModule.MessageLogFormatError{MessageType: msgType, Log: fmt.Sprintf("%+v", log)} + } + sf.TokensIn, err = sdk.ParseCoinsNormalized(tokensInString) + if err != nil { + return &txModule.MessageLogFormatError{MessageType: msgType, Log: fmt.Sprintf("%+v", log)} + } + + return err +} + func (sf *WrapperMsgJoinSwapExternAmountIn) ParseRelevantData() []parsingTypes.MessageRelevantInformation { relevantData := make([]parsingTypes.MessageRelevantInformation, 1) relevantData[0] = parsingTypes.MessageRelevantInformation{ diff --git a/osmosis/modules/gamm/swaps.go b/osmosis/modules/gamm/swaps.go index 761a840..db44aec 100644 --- a/osmosis/modules/gamm/swaps.go +++ b/osmosis/modules/gamm/swaps.go @@ -362,6 +362,10 @@ func (sf *WrapperMsgSwapExactAmountIn5) HandleMsg(msgType string, msg sdk.Msg, l } } + if len(properTransferEvents) == 0 { + return errors.New("no transfer events with non-empty amounts") + } + firstTransfer := properTransferEvents[0] // Sanity check transfer events diff --git a/osmosis/modules/poolmanager/types.go b/osmosis/modules/poolmanager/types.go index ff2e3f5..7b492ed 100644 --- a/osmosis/modules/poolmanager/types.go +++ b/osmosis/modules/poolmanager/types.go @@ -95,8 +95,14 @@ func (sf *WrapperMsgSwapExactAmountIn) HandleMsg(msgType string, msg sdk.Msg, lo sf.Address = sf.OsmosisMsgSwapExactAmountIn.Sender // The attribute in the log message that shows you the tokens swapped - tokensSwappedEvt := txModule.GetEventWithType("token_swapped", log) - transferEvt := txModule.GetEventWithType("transfer", log) + tokensSwappedEvents := txModule.GetEventsWithType("token_swapped", log) + + var tokensSwappedEvt *txModule.LogMessageEvent + if len(tokensSwappedEvents) == 0 { + tokensSwappedEvt = nil + } else { + tokensSwappedEvt = &tokensSwappedEvents[len(tokensSwappedEvents)-1] + } // We prefer the tokensSwappedEvt if it exists, but it is prone to error // If it does exist, attempt a parse. If parsing fails, try other methods. @@ -104,7 +110,7 @@ func (sf *WrapperMsgSwapExactAmountIn) HandleMsg(msgType string, msg sdk.Msg, lo parsed := false - if tokensSwappedEvt != nil { + if tokensSwappedEvt == 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] @@ -122,6 +128,15 @@ 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 {