diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 0364254b3a4..930306eac32 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -11,17 +11,7 @@ Closes: #XXX > Add a description of the overall background and high level changes that this PR introduces -*(E.g.: This pull request improves documation of area A by adding ....* - - -## Brief Changelog - -*(for example:)* - - - *The metadata is stored in the blob store on job creation time as a persistent artifact* - - *Deployments RPC transmits only the blob storage reference* - - *Daemons retrieve the RPC data from the blob cache* - +*(E.g.: This pull request improves documentation of area A by adding ....* ## Testing and Verifying @@ -45,6 +35,11 @@ This change added tests and can be verified as follows: ## Documentation and Release Note - - Does this pull request introduce a new feature or user-facing behavior changes? (yes / no) - - Is a relevant changelog entry added to the `Unreleased` section in `CHANGELOG.md`? (yes / no) - - How is the feature or change documented? (not applicable / specification (`x//spec/`) / [Osmosis docs repo](https://github.com/osmosis-labs/docs) / not documented) \ No newline at end of file + - [ ] Does this pull request introduce a new feature or user-facing behavior changes? + - [ ] Changelog entry added to `Unreleased` section of `CHANGELOG.md`? + +Where is the change documented? + - [ ] Specification (`x/{module}/README.md`) + - [ ] Osmosis documentation site + - [ ] Code comments? + - [ ] N/A \ No newline at end of file diff --git a/.github/workflows/changelog-entry-reminder.yml b/.github/workflows/changelog-entry-reminder.yml index 5e86eb18e8a..cbbf0f5d15f 100644 --- a/.github/workflows/changelog-entry-reminder.yml +++ b/.github/workflows/changelog-entry-reminder.yml @@ -14,7 +14,7 @@ jobs: uses: Zomzog/changelog-checker@v1.3.0 with: fileName: CHANGELOG.md - noChangelogLabel: no-changelog + noChangelogLabel: A:no-changelog checkNotification: Simple env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/check-broken-links.yml b/.github/workflows/check-broken-links.yml index c98b30929e0..ecb5f74e790 100644 --- a/.github/workflows/check-broken-links.yml +++ b/.github/workflows/check-broken-links.yml @@ -13,7 +13,7 @@ jobs: - name: Link Checker id: lychee - uses: lycheeverse/lychee-action@v1.6.1 + uses: lycheeverse/lychee-action@v1.8.0 with: args: --exclude-loopback --verbose --no-progress './**/*.md' './**/*.html' env: diff --git a/.github/workflows/import_paths.yml b/.github/workflows/import_paths.yml index 209bfef3b21..a0420000018 100644 --- a/.github/workflows/import_paths.yml +++ b/.github/workflows/import_paths.yml @@ -41,7 +41,7 @@ jobs: run: go version - name: Get data from build cache - uses: actions/cache@v2 + uses: actions/cache@v3 with: # In order: # * Module download cache diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 4eaf9be6c73..0d82d05b3b5 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -26,7 +26,7 @@ jobs: .github/** Makefile - name: Get data from build cache - uses: actions/cache@v2 + uses: actions/cache@v3 with: # In order: # * Module download cache diff --git a/.github/workflows/required_labels.yml b/.github/workflows/required_labels.yml index a0abea269e9..a5aacac0c42 100644 --- a/.github/workflows/required_labels.yml +++ b/.github/workflows/required_labels.yml @@ -9,7 +9,7 @@ jobs: state_compatability_labels: runs-on: ubuntu-latest steps: - - uses: mheap/github-action-required-labels@v2 + - uses: mheap/github-action-required-labels@v4 env: GITHUB_TOKEN: ${{ secrets.ADD_TO_PROJECT_PAT }} with: #Require one of the following labels diff --git a/.vscode/launch.json b/.vscode/launch.json index 8987b5680c0..66fabebba47 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -25,6 +25,258 @@ "OSMOSIS_E2E_DEBUG_LOG": "false", }, "preLaunchTask": "e2e-setup" - } + }, + { + "name": "x/concentrated-liquidity", + "type": "go", + "request": "launch", + "mode": "test", + "program": "${workspaceFolder}/x/concentrated-liquidity", + "args": [ + "-test.timeout", + "30m", + "-test.run", + "TestKeeperTestSuite/TestYourName", + "-test.v" + ], + }, + { + "name": "x/cosmwasmpool", + "type": "go", + "request": "launch", + "mode": "test", + "program": "${workspaceFolder}/x/cosmwasmpool", + "args": [ + "-test.timeout", + "30m", + "-test.run", + "TestKeeperTestSuite/TestYourName", + "-test.v" + ], + }, + { + "name": "x/downtime-detector", + "type": "go", + "request": "launch", + "mode": "test", + "program": "${workspaceFolder}/x/downtime-detector", + "args": [ + "-test.timeout", + "30m", + "-test.run", + "TestKeeperTestSuite/TestYourName", + "-test.v" + ], + }, + { + "name": "x/epochs", + "type": "go", + "request": "launch", + "mode": "test", + "program": "${workspaceFolder}/x/epochs", + "args": [ + "-test.timeout", + "30m", + "-test.run", + "TestKeeperTestSuite/TestYourName", + "-test.v" + ], + }, + { + "name": "x/gamm", + "type": "go", + "request": "launch", + "mode": "test", + "program": "${workspaceFolder}/x/gamm", + "args": [ + "-test.timeout", + "30m", + "-test.run", + "TestKeeperTestSuite/TestYourName", + "-test.v" + ], + }, + { + "name": "x/ibc-hooks", + "type": "go", + "request": "launch", + "mode": "test", + "program": "${workspaceFolder}/x/ibc-hooks", + "args": [ + "-test.timeout", + "30m", + "-test.run", + "TestKeeperTestSuite/TestYourName", + "-test.v" + ], + }, + { + "name": "x/ibc-rate-limit", + "type": "go", + "request": "launch", + "mode": "test", + "program": "${workspaceFolder}/x/ibc-rate-limit", + "args": [ + "-test.timeout", + "30m", + "-test.run", + "TestKeeperTestSuite/TestYourName", + "-test.v" + ], + }, + { + "name": "x/incentives", + "type": "go", + "request": "launch", + "mode": "test", + "program": "${workspaceFolder}/x/incentives", + "args": [ + "-test.timeout", + "30m", + "-test.run", + "TestKeeperTestSuite/TestYourName", + "-test.v" + ], + }, + { + "name": "x/lockup", + "type": "go", + "request": "launch", + "mode": "test", + "program": "${workspaceFolder}/x/lockup", + "args": [ + "-test.timeout", + "30m", + "-test.run", + "TestKeeperTestSuite/TestYourName", + "-test.v" + ], + }, + { + "name": "x/mint", + "type": "go", + "request": "launch", + "mode": "test", + "program": "${workspaceFolder}/x/mint", + "args": [ + "-test.timeout", + "30m", + "-test.run", + "TestKeeperTestSuite/TestYourName", + "-test.v" + ], + }, + { + "name": "x/pool-incentives", + "type": "go", + "request": "launch", + "mode": "test", + "program": "${workspaceFolder}/x/pool-incentives", + "args": [ + "-test.timeout", + "30m", + "-test.run", + "TestKeeperTestSuite/TestYourName", + "-test.v" + ], + }, + { + "name": "x/poolmanager", + "type": "go", + "request": "launch", + "mode": "test", + "program": "${workspaceFolder}/x/poolmanager", + "args": [ + "-test.timeout", + "30m", + "-test.run", + "TestKeeperTestSuite/TestYourName", + "-test.v" + ], + }, + { + "name": "x/protorev", + "type": "go", + "request": "launch", + "mode": "test", + "program": "${workspaceFolder}/x/protorev", + "args": [ + "-test.timeout", + "30m", + "-test.run", + "TestKeeperTestSuite/TestYourName", + "-test.v" + ], + }, + { + "name": "x/superfluid", + "type": "go", + "request": "launch", + "mode": "test", + "program": "${workspaceFolder}/x/superfluid", + "args": [ + "-test.timeout", + "30m", + "-test.run", + "TestKeeperTestSuite/TestYourName", + "-test.v" + ], + }, + { + "name": "x/tokenfactory", + "type": "go", + "request": "launch", + "mode": "test", + "program": "${workspaceFolder}/x/tokenfactory", + "args": [ + "-test.timeout", + "30m", + "-test.run", + "TestKeeperTestSuite/TestYourName", + "-test.v" + ], + }, + { + "name": "x/twap", + "type": "go", + "request": "launch", + "mode": "test", + "program": "${workspaceFolder}/x/twap", + "args": [ + "-test.timeout", + "30m", + "-test.run", + "TestKeeperTestSuite/TestYourName", + "-test.v" + ], + }, + { + "name": "x/txfees", + "type": "go", + "request": "launch", + "mode": "test", + "program": "${workspaceFolder}/x/txfees", + "args": [ + "-test.timeout", + "30m", + "-test.run", + "TestKeeperTestSuite/TestYourName", + "-test.v" + ], + }, + { + "name": "x/valset-pref", + "type": "go", + "request": "launch", + "mode": "test", + "program": "${workspaceFolder}/x/valset-pref", + "args": [ + "-test.timeout", + "30m", + "-test.run", + "TestKeeperTestSuite/TestYourName", + "-test.v" + ], + }, ] } \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index 2c0a4eb2d63..07146910074 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,6 +1,9 @@ { "tabnine.experimentalAutoImports": true, "go.lintTool": "golangci-lint", + "go.lintFlags": [ + "--fast" + ], "go.formatTool": "goimports", "go.useLanguageServer": true, "[go.mod]": { @@ -24,4 +27,4 @@ "editor.defaultFormatter": "xaver.clang-format" }, "clang-format.style": "{BasedOnStyle: Google, IndentWidth: 2, ColumnLimit: 120, AlignConsecutiveAssignments: true, AlignConsecutiveDeclarations: true, SpacesInSquareBrackets: true}" -} +} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json index ab56522001c..2bae461cc39 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -7,6 +7,16 @@ "label": "e2e-setup", "type": "shell", "command": "make e2e-setup" + }, + { + "label": "test-unit", + "type": "shell", + "command": "make test-unit", + "problemMatcher": [], + "group": { + "kind": "test", + "isDefault": true + } } ] } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 14d2c0377d7..7e605d96a7e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -46,6 +46,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * [#4659](https://github.com/osmosis-labs/osmosis/pull/4659) implement AllPools query in x/poolmanager. * [#4783](https://github.com/osmosis-labs/osmosis/pull/4783) Update wasmd to 0.31.0 + * [#4629](https://github.com/osmosis-labs/osmosis/pull/4629) add amino proto annotations * [#4830](https://github.com/osmosis-labs/osmosis/pull/4830) Add gas cost when we AddToGaugeRewards, linearly increase with coins to add * [#4886](https://github.com/osmosis-labs/osmosis/pull/4886) Implement MsgSplitRouteSwapExactAmountIn and MsgSplitRouteSwapExactAmountOut that supports route splitting. * [#5000](https://github.com/osmosis-labs/osmosis/pull/5000) osmomath.Power panics for base < 1 to temporarily restrict broken logic for such base. @@ -66,6 +67,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * [#4974](https://github.com/osmosis-labs/osmosis/pull/4974) Add lock id to `MsgSuperfluidUndelegateAndUnbondLockResponse` * [#2741](https://github.com/osmosis-labs/osmosis/pull/2741) Prevent updating the twap record if `ctx.BlockTime <= record.Time` or `ctx.BlockHeight <= record.Height`. Exception, can update the record created when creating the pool in the same block. * [#5129](https://github.com/osmosis-labs/osmosis/pull/5129) Relax twap record validation in init genesis to allow one of the spot prices to be non-zero when twap error is observed. + * [#5165](https://github.com/osmosis-labs/osmosis/pull/5165) Improve error message when fully exiting from a pool. + * [#5187](https://github.com/osmosis-labs/osmosis/pull/5187) Expand `IncentivizedPools` query to include internally incentivized CL pools. + * [#5239](https://github.com/osmosis-labs/osmosis/pull/5239) Implement `GetTotalPoolShares` public keeper function for GAMM. ### API breaks @@ -76,6 +80,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * [#4868](https://github.com/osmosis-labs/osmosis/pull/4868) Remove wasmEnabledProposals []wasm.ProposalType from NewOsmosisApp * [#4983](https://github.com/osmosis-labs/osmosis/pull/4983) Consume a gas when creating a new token using tokenfactory as a spam deterrence mechanism. * [#4951](https://github.com/osmosis-labs/osmosis/pull/4951) Implement pool liquidity query in pool manager, deprecate the one in gamm +* [#5138](https://github.com/osmosis-labs/osmosis/pull/5138) Rename swap fee to spread factor. Broke PoolI interface. Did not break CLI, message, pool models, queries or events. ## v15.1.0 @@ -207,7 +212,7 @@ This release includes stableswap, and expands the IBC safety & composability fun * Gamm: * Introduction of the stableswap pool type - * Multi-hop swapfee reduction + * Multi-hop spread factor reduction * Filtered queries to help front-ends * Adding a spot price v2 query * spotprice v1beta1 had baseassetdenom and quoteassetdenom backwards. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 97fa3fac6b4..5f6d3bee6e1 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -105,7 +105,7 @@ On the function you want to generate a unit test for, right click the function n This type of test is mainly for functions that would be triggered by incoming messages (we interact directly with the message server since all other metadata is stripped from a message by the time it hits the msg_server): ```go -func(suite *KeeperTestSuite) TestCreateDenom() { +func(s *KeeperTestSuite) TestCreateDenom() { testCases := map[string] struct { subdenom string expectError bool @@ -157,7 +157,7 @@ This type of test is mainly for functions that would be triggered by other modul // TestMintExportGenesis tests that genesis is exported correctly. // It first initializes genesis to the expected value. Then, attempts // to export it. Lastly, compares exported to the expected. -func(suite *KeeperTestSuite) TestMintExportGenesis() { +func(s *KeeperTestSuite) TestMintExportGenesis() { testCases := map[string] struct { expectedGenesis *types.GenesisState } { diff --git a/Makefile b/Makefile index efc9b0de000..d03ac729d8d 100644 --- a/Makefile +++ b/Makefile @@ -83,6 +83,19 @@ ifeq (,$(findstring nostrip,$(OSMOSIS_BUILD_OPTIONS))) BUILD_FLAGS += -trimpath endif +# Note that this skips certain tests that are not supported on WSL +# This is a workaround to enable quickly running full unit test suite locally +# on WSL without failures. The failures are stemming from trying to upload +# wasm code. An OS permissioning issue. +is_wsl := $(shell uname -a | grep -i Microsoft) +ifeq ($(is_wsl),) + # Not in WSL + SKIP_WASM_WSL_TESTS := "false" +else + # In WSL + SKIP_WASM_WSL_TESTS := "true" +endif + ############################################################################### ### Build ### ############################################################################### @@ -252,7 +265,7 @@ test: test-unit test-build test-all: test-race test-cover test-unit: - @VERSION=$(VERSION) go test -mod=readonly -tags='ledger test_ledger_mock norace' $(PACKAGES_UNIT) + @VERSION=$(VERSION) SKIP_WASM_WSL_TESTS=$(SKIP_WASM_WSL_TESTS) go test -mod=readonly -tags='ledger test_ledger_mock norace' $(PACKAGES_UNIT) test-race: @VERSION=$(VERSION) go test -mod=readonly -race -tags='ledger test_ledger_mock' $(PACKAGES_UNIT) @@ -462,8 +475,9 @@ cl-create-bigbang-config: ### Go Mock ### ############################################################################### -go-mock-update-pool-module: +go-mock-update: mockgen -source=x/poolmanager/types/routes.go -destination=tests/mocks/pool_module.go -package=mocks + mockgen -source=x/poolmanager/types/pool.go -destination=tests/mocks/pool.go -package=mocks .PHONY: all build-linux install format lint \ go-mod-cache draw-deps clean build build-contract-tests-hooks \ diff --git a/README.md b/README.md index e988e1e7173..3d7e8d39dea 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ swap-type use cases. Bonding curves, while have found its primary use case in decentralized exchange mechanisms, its potential use case can be further extended through the customizability that Osmosis offers. Through the customizability offered by Osmosis such as custom-curve AMMs, -dynamic adjustments of swap fees, multi-token liquidity pools--the AMM +dynamic adjustments of spread factors, multi-token liquidity pools--the AMM can offer decentralized formation of token fundraisers, interchain staking, options market, and more for the Cosmos ecosystem. diff --git a/app/apptesting/concentrated_liquidity.go b/app/apptesting/concentrated_liquidity.go index 41502974c9a..4055d0b0575 100644 --- a/app/apptesting/concentrated_liquidity.go +++ b/app/apptesting/concentrated_liquidity.go @@ -21,7 +21,7 @@ var ( ) // PrepareConcentratedPool sets up an eth usdc concentrated liquidity pool with pool ID 1, tick spacing of 100, -// no liquidity and zero swap fee. +// no liquidity and zero spread factor. func (s *KeeperTestHelper) PrepareConcentratedPool() types.ConcentratedPoolExtension { return s.PrepareCustomConcentratedPool(s.TestAccs[0], ETH, USDC, DefaultTickSpacing, sdk.ZeroDec()) } @@ -41,6 +41,31 @@ func (s *KeeperTestHelper) PrepareConcentratedPoolWithCoinsAndFullRangePosition( return clPool } +// createConcentratedPoolsFromCoinsWithSpreadFactor creates CL pools from given sets of coins and respective swap fees. +// Where element 1 of the input corresponds to the first pool created, element 2 to the second pool created etc. +func (s *KeeperTestHelper) CreateConcentratedPoolsAndFullRangePositionWithSpreadFactor(poolDenoms [][]string, spreadFactor []sdk.Dec) { + for i, curPoolDenoms := range poolDenoms { + s.Require().Equal(2, len(curPoolDenoms)) + var curSpreadFactor sdk.Dec + if len(spreadFactor) > i { + curSpreadFactor = spreadFactor[i] + } else { + curSpreadFactor = sdk.ZeroDec() + } + + clPool := s.PrepareCustomConcentratedPool(s.TestAccs[0], curPoolDenoms[0], curPoolDenoms[1], DefaultTickSpacing, curSpreadFactor) + fundCoins := sdk.NewCoins(sdk.NewCoin(curPoolDenoms[0], DefaultCoinAmount), sdk.NewCoin(curPoolDenoms[1], DefaultCoinAmount)) + s.FundAcc(s.TestAccs[0], fundCoins) + s.CreateFullRangePosition(clPool, fundCoins) + } +} + +// createConcentratedPoolsFromCoins creates CL pools from given sets of coins (with zero swap fees). +// Where element 1 of the input corresponds to the first pool created, element 2 to the second pool created etc. +func (s *KeeperTestHelper) CreateConcentratedPoolsAndFullRangePosition(poolDenoms [][]string) { + s.CreateConcentratedPoolsAndFullRangePositionWithSpreadFactor(poolDenoms, []sdk.Dec{sdk.ZeroDec()}) +} + // PrepareConcentratedPoolWithCoinsAndLockedFullRangePosition sets up a concentrated liquidity pool with custom denoms. // It also creates a full range position and locks it for 14 days. func (s *KeeperTestHelper) PrepareConcentratedPoolWithCoinsAndLockedFullRangePosition(denom1, denom2 string) (types.ConcentratedPoolExtension, uint64, uint64) { @@ -49,18 +74,18 @@ func (s *KeeperTestHelper) PrepareConcentratedPoolWithCoinsAndLockedFullRangePos s.FundAcc(s.TestAccs[0], fundCoins) positionId, _, _, _, _, concentratedLockId, err := s.App.ConcentratedLiquidityKeeper.CreateFullRangePositionLocked(s.Ctx, clPool.GetId(), s.TestAccs[0], fundCoins, time.Hour*24*14) s.Require().NoError(err) - clPool, err = s.App.ConcentratedLiquidityKeeper.GetPoolFromPoolIdAndConvertToConcentrated(s.Ctx, clPool.GetId()) + clPool, err = s.App.ConcentratedLiquidityKeeper.GetConcentratedPoolById(s.Ctx, clPool.GetId()) s.Require().NoError(err) return clPool, concentratedLockId, positionId } // PrepareCustomConcentratedPool sets up a concentrated liquidity pool with the custom parameters. -func (s *KeeperTestHelper) PrepareCustomConcentratedPool(owner sdk.AccAddress, denom0, denom1 string, tickSpacing uint64, swapFee sdk.Dec) types.ConcentratedPoolExtension { +func (s *KeeperTestHelper) PrepareCustomConcentratedPool(owner sdk.AccAddress, denom0, denom1 string, tickSpacing uint64, spreadFactor sdk.Dec) types.ConcentratedPoolExtension { // Mint some assets to the account. s.FundAcc(s.TestAccs[0], DefaultAcctFunds) // Create a concentrated pool via the poolmanager - poolID, err := s.App.PoolManagerKeeper.CreatePool(s.Ctx, clmodel.NewMsgCreateConcentratedPool(owner, denom0, denom1, tickSpacing, swapFee)) + poolID, err := s.App.PoolManagerKeeper.CreatePool(s.Ctx, clmodel.NewMsgCreateConcentratedPool(owner, denom0, denom1, tickSpacing, spreadFactor)) s.Require().NoError(err) // Retrieve the poolInterface via the poolID diff --git a/app/apptesting/gamm.go b/app/apptesting/gamm.go index d9f0fbb3947..7f209c43df6 100644 --- a/app/apptesting/gamm.go +++ b/app/apptesting/gamm.go @@ -218,8 +218,8 @@ func (s *KeeperTestHelper) ModifySpotPrice(poolID uint64, targetSpotPrice sdk.De s.Require().NoError(err) } else { swapOut := sdk.NewCoins(sdk.NewCoin(quoteDenom, sdk.NewInt(amountTrade.RoundInt64()).Abs())) - swapFee := pool.GetSwapFee(s.Ctx) - tokenIn, err := pool.CalcInAmtGivenOut(s.Ctx, swapOut, baseDenom, swapFee) + spreadFactor := pool.GetSpreadFactor(s.Ctx) + tokenIn, err := pool.CalcInAmtGivenOut(s.Ctx, swapOut, baseDenom, spreadFactor) s.Require().NoError(err) s.FundAcc(s.TestAccs[0], sdk.NewCoins(tokenIn)) msg := gammtypes.MsgSwapExactAmountOut{ diff --git a/app/apptesting/test_suite.go b/app/apptesting/test_suite.go index e84228585db..12e971a4452 100644 --- a/app/apptesting/test_suite.go +++ b/app/apptesting/test_suite.go @@ -3,6 +3,7 @@ package apptesting import ( "encoding/json" "fmt" + "os" "testing" "time" @@ -388,6 +389,23 @@ func (s *KeeperTestHelper) StateNotAltered() { s.Require().Equal(oldState, newState) } +func (s *KeeperTestHelper) SkipIfWSL() { + SkipIfWSL(s.T()) +} + +// SkipIfWSL skips tests if running on WSL +// This is a workaround to enable quickly running full unit test suite locally +// on WSL without failures. The failures are stemming from trying to upload +// wasm code. An OS permissioning issue. +func SkipIfWSL(t *testing.T) { + t.Helper() + skip := os.Getenv("SKIP_WASM_WSL_TESTS") + fmt.Println("SKIP_WASM_WSL_TESTS", skip) + if skip == "true" { + t.Skip("Skipping Wasm tests") + } +} + // CreateRandomAccounts is a function return a list of randomly generated AccAddresses func CreateRandomAccounts(numAccts int) []sdk.AccAddress { testAddrs := make([]sdk.AccAddress, numAccts) diff --git a/app/upgrades/v13/upgrade_test.go b/app/upgrades/v13/upgrade_test.go index 96c49800f25..77aeb9f02e5 100644 --- a/app/upgrades/v13/upgrade_test.go +++ b/app/upgrades/v13/upgrade_test.go @@ -46,6 +46,7 @@ func dummyUpgrade(suite *UpgradeTestSuite) { } func (suite *UpgradeTestSuite) TestUpgrade() { + suite.SkipIfWSL() testCases := []struct { name string pre_upgrade func() diff --git a/app/upgrades/v15/upgrade_test.go b/app/upgrades/v15/upgrade_test.go index 00ac4265ecc..57b785761a4 100644 --- a/app/upgrades/v15/upgrade_test.go +++ b/app/upgrades/v15/upgrade_test.go @@ -37,6 +37,7 @@ var DefaultAcctFunds sdk.Coins = sdk.NewCoins( func (suite *UpgradeTestSuite) SetupTest() { suite.Setup() + suite.SkipIfWSL() } func TestUpgradeTestSuite(t *testing.T) { @@ -56,7 +57,7 @@ func (suite *UpgradeTestSuite) TestMigrateNextPoolIdAndCreatePool() { gammKeeper := suite.App.GAMMKeeper poolmanagerKeeper := suite.App.PoolManagerKeeper - nextPoolId := gammKeeper.GetNextPoolId(ctx) + nextPoolId := gammKeeper.GetNextPoolId(ctx) //nolint:staticcheck // we're using the deprecated version for testing. suite.Require().Equal(expectedNextPoolId, nextPoolId) // system under test. @@ -97,13 +98,13 @@ func (suite *UpgradeTestSuite) TestMigrateBalancerToStablePools() { suite.FundAcc(testAccount, DefaultAcctFunds) // Create the balancer pool - swapFee := sdk.MustNewDecFromStr("0.003") + spreadFactor := sdk.MustNewDecFromStr("0.003") exitFee := sdk.ZeroDec() poolID, err := suite.App.PoolManagerKeeper.CreatePool( suite.Ctx, balancer.NewMsgCreateBalancerPool(suite.TestAccs[0], balancer.PoolParams{ - SwapFee: swapFee, + SwapFee: spreadFactor, ExitFee: exitFee, }, []balancer.PoolAsset{ diff --git a/app/upgrades/v15/upgrades.go b/app/upgrades/v15/upgrades.go index e5a0f82d04c..3c4e5944314 100644 --- a/app/upgrades/v15/upgrades.go +++ b/app/upgrades/v15/upgrades.go @@ -102,7 +102,7 @@ func migrateBalancerPoolToSolidlyStable(ctx sdk.Context, gammKeeper *gammkeeper. // initialize the stableswap pool stableswapPool, err := stableswap.NewStableswapPool( poolId, - stableswap.PoolParams{SwapFee: balancerPool.GetSwapFee(ctx), ExitFee: balancerPool.GetExitFee(ctx)}, + stableswap.PoolParams{SwapFee: balancerPool.GetSpreadFactor(ctx), ExitFee: balancerPool.GetExitFee(ctx)}, balancerPoolLiquidity, []uint64{1, 1}, "osmo1k8c2m5cn322akk5wy8lpt87dd2f4yh9afcd7af", // Stride Foundation 2/3 multisig diff --git a/app/upgrades/v16/concentrated_pool.go b/app/upgrades/v16/concentrated_pool.go index a9516e2472f..0017255973c 100644 --- a/app/upgrades/v16/concentrated_pool.go +++ b/app/upgrades/v16/concentrated_pool.go @@ -46,10 +46,10 @@ func createConcentratedPoolFromCFMM(ctx sdk.Context, cfmmPoolIdToLinkWith uint64 return nil, NoDesiredDenomInPoolError{desiredDenom0} } - // Swap fee is 0.2%, which is an authorized swap fee. - swapFee := cfmmPool.GetSwapFee(ctx) + // Swap fee is 0.2%, which is an authorized spread factor. + spreadFactor := cfmmPool.GetSpreadFactor(ctx) - createPoolMsg := clmodel.NewMsgCreateConcentratedPool(poolCreatorAddress, desiredDenom0, denom1, TickSpacing, swapFee) + createPoolMsg := clmodel.NewMsgCreateConcentratedPool(poolCreatorAddress, desiredDenom0, denom1, TickSpacing, spreadFactor) concentratedPool, err := poolmanagerKeeper.CreateConcentratedPoolAsPoolManager(ctx, createPoolMsg) if err != nil { return nil, err @@ -64,20 +64,20 @@ func createConcentratedPoolFromCFMM(ctx sdk.Context, cfmmPoolIdToLinkWith uint64 // Returns error if fails to create concentrated liquidity pool from CFMM pool. // Returns error if fails to get gauges for CFMM pool. // Returns error if fails to get gauge for the concentrated liquidity pool. -func createCanonicalConcentratedLiquidityPoolAndMigrationLink(ctx sdk.Context, cfmmPoolId uint64, desiredDenom0 string, keepers *keepers.AppKeepers) error { +func createCanonicalConcentratedLiquidityPoolAndMigrationLink(ctx sdk.Context, cfmmPoolId uint64, desiredDenom0 string, keepers *keepers.AppKeepers) (poolmanagertypes.PoolI, error) { concentratedPool, err := createConcentratedPoolFromCFMM(ctx, cfmmPoolId, desiredDenom0, *keepers.AccountKeeper, *keepers.GAMMKeeper, *keepers.PoolManagerKeeper) if err != nil { - return err + return nil, err } // Get CFMM gauges cfmmGauges, err := keepers.PoolIncentivesKeeper.GetGaugesForCFMMPool(ctx, cfmmPoolId) if err != nil { - return err + return nil, err } if len(cfmmGauges) == 0 { - return ErrNoGaugeToRedirect + return nil, ErrNoGaugeToRedirect } // Get longest gauge duration from balancer. @@ -94,7 +94,7 @@ func createCanonicalConcentratedLiquidityPoolAndMigrationLink(ctx sdk.Context, c // Get concentrated gauge correspondng to the distribution epoch duration. concentratedGaugeId, err := keepers.PoolIncentivesKeeper.GetPoolGaugeId(ctx, concentratedPool.GetId(), distributionEpochDuration) if err != nil { - return err + return nil, err } // Iterate through all the distr records, and redirect the old balancer gauge to the new concentrated gauge. @@ -118,5 +118,5 @@ func createCanonicalConcentratedLiquidityPoolAndMigrationLink(ctx sdk.Context, c }, }) - return nil + return concentratedPool, nil } diff --git a/app/upgrades/v16/concentrated_pool_test.go b/app/upgrades/v16/concentrated_pool_test.go index 719d8f1d45d..74b8667648f 100644 --- a/app/upgrades/v16/concentrated_pool_test.go +++ b/app/upgrades/v16/concentrated_pool_test.go @@ -22,11 +22,12 @@ const ( ) var ( - defaultAmount = sdk.NewInt(100) - desiredDenom0 = v16.DesiredDenom0 - desiredDenom0Coin = sdk.NewCoin(desiredDenom0, defaultAmount) - daiCoin = sdk.NewCoin(v16.DAIIBCDenom, defaultAmount) - usdcCoin = sdk.NewCoin(v16.USDCIBCDenom, defaultAmount) + defaultDaiAmount = sdk.NewInt(7300000000) + defaultDenom0mount = sdk.NewInt(10000000000) + desiredDenom0 = v16.DesiredDenom0 + desiredDenom0Coin = sdk.NewCoin(desiredDenom0, defaultDenom0mount) + daiCoin = sdk.NewCoin(v16.DAIIBCDenom, defaultDaiAmount) + usdcCoin = sdk.NewCoin(v16.USDCIBCDenom, defaultDaiAmount) ) func (suite *ConcentratedUpgradeTestSuite) SetupTest() { @@ -90,8 +91,8 @@ func (suite *ConcentratedUpgradeTestSuite) TestCreateConcentratedPoolFromCFMM() suite.Require().NoError(err) suite.Require().Equal(clPoolReturned, clPoolInState) - // Validate CL and balancer pools have the same swap fee. - suite.Require().Equal(balancerPool.GetSwapFee(suite.Ctx), clPoolReturned.GetSwapFee(suite.Ctx)) + // Validate CL and balancer pools have the same spread factor. + suite.Require().Equal(balancerPool.GetSpreadFactor(suite.Ctx), clPoolReturned.GetSpreadFactor(suite.Ctx)) // Validate that CL and balancer pools have the same denoms balancerDenoms, err := suite.App.PoolManagerKeeper.RouteGetPoolDenoms(suite.Ctx, balancerPool.GetId()) @@ -108,7 +109,7 @@ func (suite *ConcentratedUpgradeTestSuite) TestCreateConcentratedPoolFromCFMM() } } -func (suite *ConcentratedUpgradeTestSuite) TestCreateCanonicalConcentratedLiuqidityPoolAndMigrationLink() { +func (suite *ConcentratedUpgradeTestSuite) TestCreateCanonicalConcentratedLiquidityPoolAndMigrationLink() { suite.Setup() lockableDurations := suite.App.PoolIncentivesKeeper.GetLockableDurations(suite.Ctx) @@ -200,7 +201,7 @@ func (suite *ConcentratedUpgradeTestSuite) TestCreateCanonicalConcentratedLiuqid } suite.App.PoolIncentivesKeeper.SetDistrInfo(suite.Ctx, originalDistrInfo) - err = v16.CreateCanonicalConcentratedLiuqidityPoolAndMigrationLink(suite.Ctx, tc.cfmmPoolIdToLinkWith, tc.desiredDenom0, &suite.App.AppKeepers) + clPool, err := v16.CreateCanonicalConcentratedLiquidityPoolAndMigrationLink(suite.Ctx, tc.cfmmPoolIdToLinkWith, tc.desiredDenom0, &suite.App.AppKeepers) if tc.expectError != nil { suite.Require().Error(err) @@ -212,6 +213,7 @@ func (suite *ConcentratedUpgradeTestSuite) TestCreateCanonicalConcentratedLiuqid // Note, + 2 becuse we create 2 balancer pools during test setup, and 1 concentrated pool during migration. clPoolInState, err := suite.App.PoolManagerKeeper.GetPool(suite.Ctx, validPoolId+2) suite.Require().NoError(err) + suite.Require().Equal(clPool, clPoolInState) // Validate that CL and balancer pools have the same denoms balancerDenoms, err := suite.App.PoolManagerKeeper.RouteGetPoolDenoms(suite.Ctx, balancerPool.GetId()) diff --git a/app/upgrades/v16/export_test.go b/app/upgrades/v16/export_test.go index a28d3bd8bb4..00a103992a1 100644 --- a/app/upgrades/v16/export_test.go +++ b/app/upgrades/v16/export_test.go @@ -20,7 +20,7 @@ func CreateConcentratedPoolFromCFMM(ctx sdk.Context, cfmmPoolIdToLinkWith uint64 return createConcentratedPoolFromCFMM(ctx, cfmmPoolIdToLinkWith, desiredDenom0, accountKeeper, gammKeeper, poolmanagerKeeper) } -func CreateCanonicalConcentratedLiuqidityPoolAndMigrationLink(ctx sdk.Context, cfmmPoolId uint64, desiredDenom0 string, keepers *keepers.AppKeepers) error { +func CreateCanonicalConcentratedLiquidityPoolAndMigrationLink(ctx sdk.Context, cfmmPoolId uint64, desiredDenom0 string, keepers *keepers.AppKeepers) (poolmanagertypes.PoolI, error) { return createCanonicalConcentratedLiquidityPoolAndMigrationLink(ctx, cfmmPoolId, desiredDenom0, keepers) } diff --git a/app/upgrades/v16/upgrades.go b/app/upgrades/v16/upgrades.go index 939dff202e5..c974be55567 100644 --- a/app/upgrades/v16/upgrades.go +++ b/app/upgrades/v16/upgrades.go @@ -10,6 +10,10 @@ import ( "github.com/osmosis-labs/osmosis/v15/app/keepers" "github.com/osmosis-labs/osmosis/v15/app/upgrades" + distributiontypes "github.com/cosmos/cosmos-sdk/x/distribution/types" + + cltypes "github.com/osmosis-labs/osmosis/v15/x/concentrated-liquidity/types" + superfluidtypes "github.com/osmosis-labs/osmosis/v15/x/superfluid/types" tokenfactorykeeper "github.com/osmosis-labs/osmosis/v15/x/tokenfactory/keeper" tokenfactorytypes "github.com/osmosis-labs/osmosis/v15/x/tokenfactory/types" ) @@ -18,7 +22,7 @@ const ( // DAI/OSMO pool ID // https://app.osmosis.zone/pool/674 // Note, new concentrated liquidity pool - // swap fee is initialized to be the same as the balancers pool swap fee of 0.2%. + // spread factor is initialized to be the same as the balancers pool spread factor of 0.2%. DaiOsmoPoolId = uint64(674) // Denom0 translates to a base asset while denom1 to a quote asset // We want quote asset to be DAI so that when the limit orders on ticks @@ -80,7 +84,45 @@ func CreateUpgradeHandler( defaultConcentratedLiquidityParams.IsPermissionlessPoolCreationEnabled = IsPermissionlessPoolCreationEnabledCL keepers.ConcentratedLiquidityKeeper.SetParams(ctx, defaultConcentratedLiquidityParams) - if err := createCanonicalConcentratedLiquidityPoolAndMigrationLink(ctx, DaiOsmoPoolId, DesiredDenom0, keepers); err != nil { + // Create a concentrated liquidity pool for DAI/OSMO. + // Link the DAI/OSMO balancer pool to the cl pool. + clPool, err := createCanonicalConcentratedLiquidityPoolAndMigrationLink(ctx, DaiOsmoPoolId, DesiredDenom0, keepers) + if err != nil { + return nil, err + } + clPoolId := clPool.GetId() + clPoolDenom := cltypes.GetConcentratedLockupDenomFromPoolId(clPoolId) + + // Create a position to initialize the balancerPool. + + // Get community pool and DAI/OSMO pool address. + communityPoolAddress := keepers.AccountKeeper.GetModuleAddress(distributiontypes.ModuleName) + daiOsmoPool, err := keepers.PoolManagerKeeper.GetPool(ctx, DaiOsmoPoolId) + if err != nil { + return nil, err + } + + // Swap one DAI for OSMO from the community pool. + oneDai := sdk.NewCoin(DAIIBCDenom, sdk.NewInt(1000000)) + tokenInAmt, err := keepers.GAMMKeeper.SwapExactAmountOut(ctx, communityPoolAddress, daiOsmoPool, DesiredDenom0, sdk.NewInt(10000000), oneDai, sdk.ZeroDec()) + if err != nil { + return nil, err + } + + // Create a full range position via the community pool with the funds that were swapped. + fullRangeOsmoDaiCoins := sdk.NewCoins(sdk.NewCoin(DesiredDenom0, tokenInAmt), oneDai) + _, _, _, _, _, err = keepers.ConcentratedLiquidityKeeper.CreateFullRangePosition(ctx, clPoolId, communityPoolAddress, fullRangeOsmoDaiCoins) + if err != nil { + return nil, err + } + + // Add the cl pool's full range denom as an authorized superfluid asset. + superfluidAsset := superfluidtypes.SuperfluidAsset{ + Denom: clPoolDenom, + AssetType: superfluidtypes.SuperfluidAssetTypeConcentratedShare, + } + err = keepers.SuperfluidKeeper.AddNewSuperfluidAsset(ctx, superfluidAsset) + if err != nil { return nil, err } diff --git a/app/upgrades/v16/upgrades_test.go b/app/upgrades/v16/upgrades_test.go index 32f3220fece..7fdb6005a91 100644 --- a/app/upgrades/v16/upgrades_test.go +++ b/app/upgrades/v16/upgrades_test.go @@ -4,12 +4,14 @@ import ( "fmt" "testing" - "github.com/cosmos/cosmos-sdk/store/prefix" sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/cosmos/cosmos-sdk/store/prefix" upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" "github.com/stretchr/testify/suite" abci "github.com/tendermint/tendermint/abci/types" + "github.com/osmosis-labs/osmosis/osmoutils/osmoassert" "github.com/osmosis-labs/osmosis/v15/app/apptesting" v16 "github.com/osmosis-labs/osmosis/v15/app/upgrades/v16" cltypes "github.com/osmosis-labs/osmosis/v15/x/concentrated-liquidity/types" @@ -67,14 +69,21 @@ func (suite *UpgradeTestSuite) TestUpgrade() { } // Create DAI / OSMO pool - suite.PrepareBalancerPoolWithCoins(sdk.NewCoin(v16.DAIIBCDenom, desiredDenom0Coin.Amount), desiredDenom0Coin) + suite.PrepareBalancerPoolWithCoins(daiCoin, desiredDenom0Coin) }, func() { + stakingParams := suite.App.StakingKeeper.GetParams(suite.Ctx) + stakingParams.BondDenom = "uosmo" + suite.App.StakingKeeper.SetParams(suite.Ctx, stakingParams) dummyUpgrade(suite) suite.Require().NotPanics(func() { suite.App.BeginBlocker(suite.Ctx, abci.RequestBeginBlock{}) }) + // Get balancer pool's spot price. + balancerSpotPrice, err := suite.App.GAMMKeeper.CalculateSpotPrice(suite.Ctx, v16.DaiOsmoPoolId, v16.DAIIBCDenom, v16.DesiredDenom0) + suite.Require().NoError(err) + // Validate CL pool was created. concentratedPool, err := suite.App.PoolManagerKeeper.GetPool(suite.Ctx, v16.DaiOsmoPoolId+1) suite.Require().NoError(err) @@ -86,6 +95,9 @@ func (suite *UpgradeTestSuite) TestUpgrade() { suite.Require().Equal(v16.DesiredDenom0, concentratedTypePool.GetToken0()) suite.Require().Equal(v16.DAIIBCDenom, concentratedTypePool.GetToken1()) + // Validate that the spot price of the CL pool is what we expect + osmoassert.DecApproxEq(suite.T(), concentratedTypePool.GetCurrentSqrtPrice().Power(2), balancerSpotPrice, sdk.NewDec(4)) + // Validate that link was created. migrationInfo, err := suite.App.GAMMKeeper.GetAllMigrationInfo(suite.Ctx) suite.Require().Equal(1, len(migrationInfo.BalancerToConcentratedPoolLinks)) diff --git a/app/upgrades/v9/prop214.go b/app/upgrades/v9/prop214.go index 8d0c311dd9d..3b7f27bfd85 100644 --- a/app/upgrades/v9/prop214.go +++ b/app/upgrades/v9/prop214.go @@ -10,7 +10,7 @@ import ( // Executes prop214, https://www.mintscan.io/osmosis/proposals/214 // Run `osmosisd q gov proposal 214` to see the text. // It was voted in, and it has update instructions: -// Voting YES for this proposal would reduce the Pool 1 (OSMO/ATOM) swap fee from 0.3% to 0.2% +// Voting YES for this proposal would reduce the Pool 1 (OSMO/ATOM) spread factor from 0.3% to 0.2% func ExecuteProp214(ctx sdk.Context, gamm *gammkeeper.Keeper) { poolId := 1 pool, err := gamm.GetPoolAndPoke(ctx, uint64(poolId)) diff --git a/app/upgrades/v9/prop214_test.go b/app/upgrades/v9/prop214_test.go index 645d3a1044e..ee9275484d2 100644 --- a/app/upgrades/v9/prop214_test.go +++ b/app/upgrades/v9/prop214_test.go @@ -29,8 +29,8 @@ func (suite *UpgradeTestSuite) TestProp214() { suite.Require().NoError(err) // Kept as comments for recordkeeping. Since SetPool is now private, the changes being tested for can no longer be made: - // swapFee := pool.GetSwapFee(suite.Ctx) - // expectedSwapFee := sdk.MustNewDecFromStr("0.002") + // spreadFactor := pool.GetSpreadFactor(suite.Ctx) + // expectedSpreadFactor := sdk.MustNewDecFromStr("0.002") // - // suite.Require().Equal(expectedSwapFee, swapFee) + // suite.Require().Equal(expectedSpreadFactor, spreadFactor) } diff --git a/client/docs/static/openapi/index.html b/client/docs/static/openapi/index.html index 25016648594..96ae9b1db12 100644 --- a/client/docs/static/openapi/index.html +++ b/client/docs/static/openapi/index.html @@ -466,28 +466,30 @@ -