Skip to content

Commit

Permalink
support for large swaps
Browse files Browse the repository at this point in the history
  • Loading branch information
p0mvn committed Jun 7, 2023
1 parent 8f09c79 commit 2dade3e
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 26 deletions.
18 changes: 13 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -450,12 +450,20 @@ localnet-state-export-clean: localnet-clean
localnet-cl-create-positions:
go run tests/cl-go-client/main.go --operation 0

# does 100 swaps in localosmosis at pool id 1
localnet-cl-swap:
go run tests/cl-go-client/main.go --operation 1
# does 100 small randomized swaps in localosmosis at pool id 1
localnet-cl-small-swap:
go run tests/cl-go-client/main.go --operation 1

# does both of localnet-cl-create-positions and localnet-cl-swap
localnet-cl-positions-and-swaps: localnet-cl-create-positions localnet-cl-swap
# does 100 large swaps where the output of the previous swap is swapped back at the
# next swap. localosmosis at pool id 1
localnet-cl-large-swap:
go run tests/cl-go-client/main.go --operation 2

# does both of localnet-cl-create-positions and localnet-cl-small-swap
localnet-cl-positions-small-swaps: localnet-cl-create-positions localnet-cl-small-swap

# does both of localnet-cl-create-positions and localnet-cl-large-swap
localnet-cl-positions-large-swaps: localnet-cl-create-positions localnet-cl-large-swap

# This script retrieves Uniswap v3 Ethereum position data
# from subgraph. It uses WETH / USDC pool. This is helpful
Expand Down
39 changes: 33 additions & 6 deletions tests/cl-go-client/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,24 +63,51 @@ In the current state, it does the following:
- Queries pool with id 1. If does not exist, creates it
- Sets up 100 CL positions (count configured at the top of the file)

### Make Swaps
### Make Small Randomized Swaps

```bash
make localnet-cl-swap
make localnet-cl-small-swap
```

In the current state, it does the following:
- Queries status of the chain to make sure it's running.
- Queries pool with id 1.
- Performs 100 swaps against the pool with id 1.
- Performs 100 randomized swaps against the pool with id 1.

Note that this script does not set up positions, assumming they are
already set up.

### Create Positions and Swap
### Create Positions and Make Small Randomized Swaps

```bash
make localnet-cl-positions-and-swaps
make localnet-cl-positions-small-swaps
```

This script runs "Create Positions" and "Make Swaps" scripts in sequence.
This script runs "Create Positions" and "Make Small Randomized Swaps" scripts in sequence.

### Make Large Invertible Swaps

```bash
make localnet-cl-large-swap
```

In the current state, it does the following:
- Queries status of the chain to make sure it's running.
- Queries pool with id 1.
- Performs 100 large swaps where the output of the previous swap is swapped back at the
next swap.

In other words, it takes one large amount and swaps it into the pool. Then, takes output token
and swaps it back while accounting for the spread factor. This is done to
ensure that we cross ticks while minimizing the chance of running out of funds or liquidity.

Note that this script does not set up positions, assumming they are
already set up.

### Create Positions and Make Large Invertible Swaps

```bash
make localnet-cl-positions-large-swaps
```

This script runs "Create Positions" and "Make Large Invertible Swaps" scripts in sequence.
81 changes: 66 additions & 15 deletions tests/cl-go-client/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,14 @@ const (
// createPositions creates positions in the CL pool with id expectedPoolId.
createPositions operation = iota

// makeManySwaps makes many swaps in the CL pool with id expectedPoolId.
makeManySwaps
// makeManySmallSwaps makes many swaps in the CL pool with id expectedPoolId.
makeManySmallSwaps

// makeManyLargeSwaps makes many large swaps in the CL pool with id expectedPoolId.
// it takes one large amount and swaps it into the pool. Then, takes output token
// and swaps it back while accounting for the spread factor. This is done to
// ensure that we cross ticks while minimizing the chance of running out of funds or liquidity.
makeManyInvertibleLargeSwaps
)

const (
Expand All @@ -49,20 +55,22 @@ const (
randSeed = 1
maxAmountDeposited = 1_00_000_000
maxAmountSingleSwap = 1_000_000
largeSwapAmount = 90_000_000_000
)

var (
defaultAccountName = fmt.Sprintf("%s%d", accountNamePrefix, 1)
defaultMinAmount = sdk.ZeroInt()
accountMutex sync.Mutex
defaultAccountName = fmt.Sprintf("%s%d", accountNamePrefix, 1)
defaultMinAmount = sdk.ZeroInt()
defaultSpreadFactor = sdk.MustNewDecFromStr("0.001")
accountMutex sync.Mutex
)

func main() {
var (
desiredOperation int
)

flag.IntVar(&desiredOperation, "operation", 0, fmt.Sprintf("operation to run:\ncreate positions: %v, make many swaps: %v", createPositions, makeManySwaps))
flag.IntVar(&desiredOperation, "operation", 0, fmt.Sprintf("operation to run:\ncreate positions: %v, make many swaps: %v", createPositions, makeManySmallSwaps))

flag.Parse()

Expand Down Expand Up @@ -117,9 +125,11 @@ func main() {
case createPositions:
createManyRandomPositions(igniteClient, expectedPoolId, numPositions)
return
case makeManySwaps:
swapSmallAmountsContinuously(igniteClient, expectedPoolId, numSwaps)
case makeManySmallSwaps:
swapRandomSmallAmountsContinuously(igniteClient, expectedPoolId, numSwaps)
return
case makeManyInvertibleLargeSwaps:
swapGivenLargeAmountsBothDirections(igniteClient, expectedPoolId, numSwaps, largeSwapAmount)
default:
log.Fatalf("invalid operation: %d", desiredOperation)
}
Expand Down Expand Up @@ -153,7 +163,7 @@ func createManyRandomPositions(igniteClient cosmosclient.Client, poolId uint64,
}
}

func swapSmallAmountsContinuously(igniteClient cosmosclient.Client, poolId uint64, numSwaps int) {
func swapRandomSmallAmountsContinuously(igniteClient cosmosclient.Client, poolId uint64, numSwaps int) {
for i := 0; i < numSwaps; i++ {
var (
randAccountNum = rand.Intn(8) + 1
Expand All @@ -173,7 +183,48 @@ func swapSmallAmountsContinuously(igniteClient cosmosclient.Client, poolId uint6
tokenInCoin := sdk.NewCoin(tokenInDenom, sdk.NewInt(rand.Int63n(maxAmountSingleSwap)))

runMessageWithRetries(func() error {
return makeSwap(igniteClient, expectedPoolId, accountName, tokenInCoin, tokenOutDenom, tokenOutMinAmount)
_, err := makeSwap(igniteClient, expectedPoolId, accountName, tokenInCoin, tokenOutDenom, tokenOutMinAmount)
return err
})
}

log.Println("finished swapping, num swaps done", numSwaps)
}

func swapGivenLargeAmountsBothDirections(igniteClient cosmosclient.Client, poolId uint64, numSwaps int, largeStartAmount int64) {
var (
randAccountNum = rand.Intn(8) + 1
accountName = fmt.Sprintf("%s%d", accountNamePrefix, randAccountNum)

isToken0In = rand.Intn(2) == 0

tokenOutMinAmount = sdk.OneInt()
)

tokenInDenom := denom0
tokenOutDenom := denom1
if !isToken0In {
tokenInDenom = denom1
tokenOutDenom = denom0
}

tokenInCoin := sdk.NewCoin(tokenInDenom, sdk.NewInt(largeStartAmount))

for i := 0; i < numSwaps; i++ {
runMessageWithRetries(func() error {
tokenOut, err := makeSwap(igniteClient, expectedPoolId, accountName, tokenInCoin, tokenOutDenom, tokenOutMinAmount)

if err == nil {
// Swap the resulting amount out back while accounting for spread factor.
// This is to make sure we can continue swapping back and forth and not run
// out of funds or liquidity.
tempTokenInDenom := tokenInCoin.Denom
// new token in = token out / (1 - spread factor)
tokenInCoin = sdk.NewCoin(tokenOutDenom, tokenOut.ToDec().Quo(sdk.OneDec().Sub(defaultSpreadFactor)).RoundInt())
tokenOutDenom = tempTokenInDenom
}

return err
})
}

Expand All @@ -186,7 +237,7 @@ func createPool(igniteClient cosmosclient.Client, accountName string) uint64 {
Denom1: denom0,
Denom0: denom1,
TickSpacing: 1,
SpreadFactor: sdk.ZeroDec(),
SpreadFactor: defaultSpreadFactor,
}
txResp, err := igniteClient.BroadcastTx(accountName, msg)
if err != nil {
Expand Down Expand Up @@ -227,7 +278,7 @@ func createPosition(client cosmosclient.Client, poolId uint64, senderKeyringAcco
return resp.Amount0, resp.Amount1, resp.LiquidityCreated, nil
}

func makeSwap(client cosmosclient.Client, poolId uint64, senderKeyringAccountName string, tokenInCoin sdk.Coin, tokenOutDenom string, tokenOutMinAmount sdk.Int) error {
func makeSwap(client cosmosclient.Client, poolId uint64, senderKeyringAccountName string, tokenInCoin sdk.Coin, tokenOutDenom string, tokenOutMinAmount sdk.Int) (sdk.Int, error) {
accountMutex.Lock() // Lock access to getAccountAddressFromKeyring
senderAddress := getAccountAddressFromKeyring(client, senderKeyringAccountName)
accountMutex.Unlock() // Unlock access to getAccountAddressFromKeyring
Expand All @@ -247,15 +298,15 @@ func makeSwap(client cosmosclient.Client, poolId uint64, senderKeyringAccountNam
}
txResp, err := client.BroadcastTx(senderKeyringAccountName, msg)
if err != nil {
return err
return sdk.Int{}, err
}
resp := poolmanagertypes.MsgSwapExactAmountInResponse{}
if err := txResp.Decode(&resp); err != nil {
return err
return sdk.Int{}, err
}

log.Println("swap made, token out amount: ", resp.TokenOutAmount)
return nil
return resp.TokenOutAmount, nil
}

func getAccountAddressFromKeyring(igniteClient cosmosclient.Client, accountName string) string {
Expand Down

0 comments on commit 2dade3e

Please sign in to comment.