Skip to content

Commit

Permalink
refactor: arb filter for new authz exec swap (#7210)
Browse files Browse the repository at this point in the history
* refactor: arb filter for new authz exec swap

* updates

* updates

* updates
  • Loading branch information
p0mvn authored and czarcas7ic committed Dec 29, 2023
1 parent ebc35fb commit 48a9c68
Show file tree
Hide file tree
Showing 3 changed files with 130 additions and 12 deletions.
4 changes: 2 additions & 2 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -283,12 +283,12 @@
"type": "go",
"request": "launch",
"mode": "test",
"program": "${workspaceFolder}/x/txfees",
"program": "${workspaceFolder}/x/txfees/keeper/txfee_filters",
"args": [
"-test.timeout",
"30m",
"-test.run",
"TestKeeperTestSuite/TestYourName",
"TestTxFeeFilter/TestIsArbTxLooseAuthz_SwapMsg",
"-test.v"
],
},
Expand Down
108 changes: 98 additions & 10 deletions x/txfees/keeper/txfee_filters/arb_tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,42 @@ func (m AffiliateSwapMsg) TokenOutDenom() string {

var _ poolmanagertypes.SwapMsgRoute = AffiliateSwapMsg{}

type InputCoin struct {
Denom string `json:"denom"`
Amount string `json:"amount"`
}

type Slippage struct {
MinOutputAmount string `json:"min_output_amount"`
}

type ContractSwap struct {
InputCoin InputCoin `json:"input_coin"`
OutputDenom string `json:"output_denom"`
Slippage Slippage `json:"slippage"`
}

type ContractSwapMsg struct {
ContractSwap `json:"swap"`
}

// TokenDenomsOnPath implements types.SwapMsgRoute.
func (c ContractSwapMsg) TokenDenomsOnPath() []string {
return []string{c.InputCoin.Denom, c.OutputDenom}
}

// TokenInDenom implements types.SwapMsgRoute.
func (c ContractSwapMsg) TokenInDenom() string {
return c.InputCoin.Denom
}

// TokenOutDenom implements types.SwapMsgRoute.
func (c ContractSwapMsg) TokenOutDenom() string {
return c.OutputDenom
}

var _ poolmanagertypes.SwapMsgRoute = ContractSwapMsg{}

// We check if a tx is an arbitrage for the mempool right now by seeing:
// 1) does start token of a msg = final token of msg (definitionally correct)
// 2) does it have multiple swap messages, with different tx ins. If so, we assume its an arb.
Expand Down Expand Up @@ -107,21 +143,47 @@ func isArbTxLooseAuthz(msg sdk.Msg, swapInDenom string, lpTypesSeen map[gammtype
contractMessage := msgExecuteContract.GetMsg()

// Check that the contract message is an affiliate swap message
if ok := isAffiliateSwapMsg(contractMessage); !ok {
isAffliliateSwap := isAffiliateSwapMsg(contractMessage)
isContractSwap := isContractSwapContractMsg(contractMessage)

if !isAffliliateSwap && !isContractSwap {
return swapInDenom, false
}

var affiliateSwapMsg AffiliateSwapMsg
if err := json.Unmarshal(contractMessage, &affiliateSwapMsg); err != nil {
// If we can't unmarshal it, it's not an affiliate swap message
return swapInDenom, false
if isAffliliateSwap {
var affiliateSwapMsg AffiliateSwapMsg
if err := json.Unmarshal(contractMessage, &affiliateSwapMsg); err != nil {
// If we can't unmarshal it, it's not an affiliate swap message
return swapInDenom, false
}

// Otherwise, we have an affiliate swap message, so we check if it's an arb
affiliateSwapMsg.TokenIn = tokenIn.Denom
swapInDenom, isArb := isArbTxLooseSwapMsg(affiliateSwapMsg, swapInDenom)
if isArb {
return swapInDenom, true
}
}

// Otherwise, we have an affiliate swap message, so we check if it's an arb
affiliateSwapMsg.TokenIn = tokenIn.Denom
swapInDenom, isArb := isArbTxLooseSwapMsg(affiliateSwapMsg, swapInDenom)
if isArb {
return swapInDenom, true
if isContractSwap {
var contractSwapMsg ContractSwapMsg
if err := json.Unmarshal(contractMessage, &contractSwapMsg); err != nil {
// If we can't unmarshal it, it's not a contract swap message
return swapInDenom, false
}

// Otherwise, we have a contract swap message, so we check if it's an arb
swapInDenom, isArb := isArbTxLooseSwapMsg(contractSwapMsg, swapInDenom)
if isArb {
return swapInDenom, true
}

// Also, check sent tokenIn just in case.
contractSwapMsg.InputCoin.Denom = tokenIn.Denom
swapInDenom, isArb = isArbTxLooseSwapMsg(contractSwapMsg, swapInDenom)
if isArb {
return swapInDenom, true
}
}

return swapInDenom, false
Expand Down Expand Up @@ -195,3 +257,29 @@ func isAffiliateSwapMsg(msg []byte) bool {

return true
}

// check if this: https://celatone.osmosis.zone/osmosis-1/txs/8D20755D4E009CB72C763963A76886BCCCC5C2EBFC3F57266332710216A0D10D
func isContractSwapContractMsg(msg []byte) bool {
// Check that the contract message is a valid JSON object
jsonObject := make(map[string]interface{})
err := json.Unmarshal(msg, &jsonObject)
if err != nil {
return false
}

// check the main key is "swap"
swap, ok := jsonObject["swap"].(map[string]interface{})
if !ok {
return false
}

if input_coin, ok := swap["input_coin"].(map[string]interface{}); !ok || len(input_coin) == 0 {
return false
}

if outputDenom, ok := swap["output_denom"].(string); !ok || len(outputDenom) == 0 {
return false
}

return true
}
30 changes: 30 additions & 0 deletions x/txfees/keeper/txfee_filters/arb_tx_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,36 @@ func (suite *KeeperTestSuite) TestIsArbTxLooseAuthz_AffiliateSwapMsg() {
suite.Require().True(isArb)
}

// Tests that the arb filter is enabled on swap msg.
func (suite *KeeperTestSuite) TestIsArbTxLooseAuthz_SwapMsg() {
contractSwapMsg := &txfee_filters.ContractSwapMsg{
ContractSwap: txfee_filters.ContractSwap{
InputCoin: txfee_filters.InputCoin{
Amount: "2775854",
Denom: "ibc/D1542AA8762DB13087D8364F3EA6509FD6F009A34F00426AF9E4F9FA85CBBF1F",
},
OutputDenom: "ibc/D1542AA8762DB13087D8364F3EA6509FD6F009A34F00426AF9E4F9FA85CBBF1F",
Slippage: txfee_filters.Slippage{
MinOutputAmount: "2775854",
},
},
}

msgBz, err := json.Marshal(contractSwapMsg)
suite.Require().NoError(err)

// https://celatone.osmosis.zone/osmosis-1/txs/8D20755D4E009CB72C763963A76886BCCCC5C2EBFC3F57266332710216A0D10D
executeMsg := &wasmtypes.MsgExecuteContract{
Contract: "osmo1etpha3a65tds0hmn3wfjeag6wgxgrkuwg2zh94cf5hapz7mz04dq6c25s5",
Sender: "osmo1dldrxz5p8uezxz3qstpv92de7wgfp7hvr72dcm",
Funds: sdk.NewCoins(sdk.NewCoin("ibc/498A0751C798A0D9A389AA3691123DADA57DAA4FE165D5C75894505B876BA6E4", sdk.NewInt(217084399))),
Msg: msgBz,
}

_, isArb := txfee_filters.IsArbTxLooseAuthz(executeMsg, executeMsg.Funds[0].Denom, map[types.LiquidityChangeType]bool{})
suite.Require().True(isArb)
}

func (suite *KeeperTestSuite) TestIsArbTxLooseAuthz_OtherMsg() {
otherMsg := []byte(`{"update_feed": {}}`)

Expand Down

0 comments on commit 48a9c68

Please sign in to comment.