Skip to content

Commit

Permalink
Merge branch 'main' into chore/ics-v6
Browse files Browse the repository at this point in the history
  • Loading branch information
pr0n00gler committed Nov 1, 2024
2 parents 2e57a23 + 511867e commit 35ca307
Show file tree
Hide file tree
Showing 89 changed files with 3,742 additions and 976 deletions.
15 changes: 10 additions & 5 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import (
feemarkettypes "github.com/skip-mev/feemarket/x/feemarket/types"

"github.com/neutron-org/neutron/v5/x/dynamicfees"
"github.com/neutron-org/neutron/v5/x/ibc-rate-limit"
ibcratelimit "github.com/neutron-org/neutron/v5/x/ibc-rate-limit"

"cosmossdk.io/client/v2/autocli"
"cosmossdk.io/core/appmodule"
Expand Down Expand Up @@ -135,6 +135,7 @@ import (

ibcratelimitkeeper "github.com/neutron-org/neutron/v5/x/ibc-rate-limit/keeper"
ibcratelimittypes "github.com/neutron-org/neutron/v5/x/ibc-rate-limit/types"

//nolint:staticcheck
ibcporttypes "github.com/cosmos/ibc-go/v8/modules/core/05-port/types"
ibchost "github.com/cosmos/ibc-go/v8/modules/core/exported"
Expand Down Expand Up @@ -225,7 +226,9 @@ const (
)

var (
Upgrades = []upgrades.Upgrade{v500.Upgrade}
Upgrades = []upgrades.Upgrade{
v500.Upgrade,
}

// DefaultNodeHome default home directories for the application daemon
DefaultNodeHome string
Expand Down Expand Up @@ -727,7 +730,7 @@ func New(
// NOTE: we need staking feature here even if there is no staking module anymore because cosmwasm-std in the CosmWasm SDK requires this feature
// NOTE: cosmwasm_1_2 feature enables GovMsg::VoteWeighted, which doesn't work with Neutron, because it uses its own custom governance,
// however, cosmwasm_1_2 also enables WasmMsg::Instantiate2, which works as one could expect
supportedFeatures := []string{"iterator", "stargate", "staking", "neutron", "cosmwasm_1_1", "cosmwasm_1_2", "cosmwasm_1_3", "cosmwasm_1_4", "cosmwasm_2_0"}
supportedFeatures := []string{"iterator", "stargate", "staking", "neutron", "cosmwasm_1_1", "cosmwasm_1_2", "cosmwasm_1_3", "cosmwasm_1_4", "cosmwasm_2_0", "cosmwasm_2_1"}

// register the proposal types
adminRouterLegacy := govv1beta1.NewRouter()
Expand Down Expand Up @@ -799,8 +802,10 @@ func New(
app.TransferKeeper,
&app.AdminmoduleKeeper,
app.FeeBurnerKeeper,
app.FeeKeeper, &app.BankKeeper,
app.TokenFactoryKeeper, &app.CronKeeper,
app.FeeKeeper,
&app.BankKeeper,
app.TokenFactoryKeeper,
&app.CronKeeper,
&app.ContractManagerKeeper,
&app.DexKeeper,
app.OracleKeeper,
Expand Down
8 changes: 6 additions & 2 deletions app/upgrades/v5.0.0/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,13 @@ const (
UpgradeName = "v5.0.0"

MarketMapAuthorityMultisig = "neutron1anjpluecd0tdc0n8xzc3l5hua4h93wyq0x7v56"
// RateLimitContract defines the RL contract addr which we set as a contract address in ibc-rate-limit middleware
// MainnetRateLimitContract defines the RL contract addr which we set as a contract address in ibc-rate-limit middleware
// https://neutron.celat.one/neutron-1/contracts/neutron15aqgplxcavqhurr0g5wwtdw6025dknkqwkfh0n46gp2qjl6236cs2yd3nl
RateLimitContract = "neutron15aqgplxcavqhurr0g5wwtdw6025dknkqwkfh0n46gp2qjl6236cs2yd3nl"
MainnetRateLimitContract = "neutron15aqgplxcavqhurr0g5wwtdw6025dknkqwkfh0n46gp2qjl6236cs2yd3nl"

// TestnetRateLimitContract defines the RL contract addr which we set as a contract address in ibc-rate-limit middleware
// https://neutron.celat.one/pion-1/contracts/neutron1ajezjq09w2ajc2j9656edmqaxsqpwmwmwrmmk5lnahmyvf2k68usqdytcx
TestnetRateLimitContract = "neutron1ajezjq09w2ajc2j9656edmqaxsqpwmwmwrmmk5lnahmyvf2k68usqdytcx"
)

var Upgrade = upgrades.Upgrade{
Expand Down
71 changes: 63 additions & 8 deletions app/upgrades/v5.0.0/upgrades.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"fmt"

"cosmossdk.io/math"
upgradetypes "cosmossdk.io/x/upgrade/types"
adminmoduletypes "github.com/cosmos/admin-module/v2/x/adminmodule/types"
"github.com/cosmos/cosmos-sdk/codec"
Expand Down Expand Up @@ -44,18 +45,21 @@ func CreateUpgradeHandler(
}
}

err = upgradePools(ctx, *keepers.DexKeeper)
if err != nil {
return nil, err
}

err = setMarketMapParams(ctx, keepers.MarketmapKeeper)
if err != nil {
return nil, err
}

ctx.Logger().Info("Running ibc-rate-limit upgrades...")
// Only set rate limit contract for mainnet
if ctx.ChainID() == "neutron-1" {
err = upgradeIbcRateLimitSetContract(ctx, *keepers.IbcRateLimitKeeper)
if err != nil {
return nil, err
}

err = upgradeIbcRateLimitSetContract(ctx, *keepers.IbcRateLimitKeeper)
if err != nil {
return nil, err
}

ctx.Logger().Info(fmt.Sprintf("Migration {%s} applied", UpgradeName))
Expand All @@ -79,12 +83,63 @@ func upgradeDexPause(ctx sdk.Context, k dexkeeper.Keeper) error {
return nil
}

func upgradePools(ctx sdk.Context, k dexkeeper.Keeper) error {
// Due to an issue with autoswap logic any pools with multiple shareholders must be withdrawn to ensure correct accounting
ctx.Logger().Info("Migrating Pools...")

allSharesholders := k.GetAllPoolShareholders(ctx)

for poolID, shareholders := range allSharesholders {
if len(shareholders) > 1 {
pool, found := k.GetPoolByID(ctx, poolID)
if !found {
return fmt.Errorf("cannot find pool with ID %d", poolID)
}
for _, shareholder := range shareholders {
addr := sdk.MustAccAddressFromBech32(shareholder.Address)
pairID := pool.LowerTick0.Key.TradePairId.MustPairID()
tick := pool.CenterTickIndexToken1()
fee := pool.Fee()
nShares := shareholder.Shares

reserve0Removed, reserve1Removed, sharesBurned, err := k.WithdrawCore(ctx, pairID, addr, addr, []math.Int{nShares}, []int64{tick}, []uint64{fee})
if err != nil {
return fmt.Errorf("user %s failed to withdraw from pool %d", addr, poolID)
}

ctx.Logger().Info(
"Withdrew user from pool",
"User", addr.String(),
"Pool", poolID,
"SharesBurned", sharesBurned.String(),
"Reserve0Withdrawn", reserve0Removed.String(),
"Reserve1Withdrawn", reserve1Removed.String(),
)

}
}
}

ctx.Logger().Info("Finished migrating Pools...")

return nil
}

func upgradeIbcRateLimitSetContract(ctx sdk.Context, k ibcratelimitkeeper.Keeper) error {
// Set the dex to paused
ctx.Logger().Info("Setting ibc rate limiting contract...")

if err := k.SetParams(ctx, ibcratelimittypes.Params{ContractAddress: RateLimitContract}); err != nil {
return err
switch ctx.ChainID() {
case "neutron-1":
if err := k.SetParams(ctx, ibcratelimittypes.Params{ContractAddress: MainnetRateLimitContract}); err != nil {
return err
}
case "pion-1":
if err := k.SetParams(ctx, ibcratelimittypes.Params{ContractAddress: TestnetRateLimitContract}); err != nil {
return err
}
default:
return fmt.Errorf("unknown chain id %s", ctx.ChainID())
}

ctx.Logger().Info("Rate limit contract is set")
Expand Down
155 changes: 152 additions & 3 deletions app/upgrades/v5.0.0/upgrades_test.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
package v500_test

import (
"fmt"
"testing"

"cosmossdk.io/math"
upgradetypes "cosmossdk.io/x/upgrade/types"
sdk "github.com/cosmos/cosmos-sdk/types"
bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"

Expand All @@ -30,7 +33,7 @@ func (suite *UpgradeTestSuite) SetupTest() {

func (suite *UpgradeTestSuite) TestOracleUpgrade() {
app := suite.GetNeutronZoneApp(suite.ChainA)
ctx := suite.ChainA.GetContext()
ctx := suite.ChainA.GetContext().WithChainID("neutron-1")
t := suite.T()

upgrade := upgradetypes.Plan{
Expand Down Expand Up @@ -84,7 +87,113 @@ func (suite *UpgradeTestSuite) TestUpgradeDexPause() {
suite.ErrorIs(err, dextypes.ErrDexPaused)
}

func (suite *UpgradeTestSuite) TestUpgradeSetRateLimitContract() {
func (suite *UpgradeTestSuite) TestPoolMigrationSingleShareHolder() {
var (
app = suite.GetNeutronZoneApp(suite.ChainA)
ctx = suite.ChainA.GetContext().WithChainID("neutron-1")
alice = []byte("alice")
pairID = &dextypes.PairID{Token0: "TokenA", Token1: "TokenB"}
depositAmount = math.NewInt(10_000)
)

// create a pool with 1 shareholder
FundAccount(app.BankKeeper, ctx, alice, sdk.NewCoins(sdk.NewCoin("TokenA", depositAmount)))
shares, err := suite.makeDeposit(ctx, app.DexKeeper, alice, pairID, depositAmount, math.ZeroInt(), 0, 1)
suite.NoError(err)

// run upgrade
upgrade := upgradetypes.Plan{
Name: v500.UpgradeName,
Info: "some text here",
Height: 100,
}
suite.NoError(app.UpgradeKeeper.ApplyUpgrade(ctx, upgrade))

// assert pool and shareholder balance are unchanged
poolID, err := dextypes.ParsePoolIDFromDenom(shares[0].Denom)
suite.NoError(err)

pool, _ := app.DexKeeper.GetPoolByID(ctx, poolID)

suite.True(pool.LowerTick0.ReservesMakerDenom.Equal(depositAmount), "Pool value changed")
aliceBalance := app.BankKeeper.GetAllBalances(ctx, alice)
suite.True(aliceBalance.Equal(shares))
}

func (suite *UpgradeTestSuite) TestPoolMigrationMultiShareHolder() {
var (
app = suite.GetNeutronZoneApp(suite.ChainA)
ctx = suite.ChainA.GetContext().WithChainID("neutron-1")
alice = []byte("alice")
bob = []byte("bob")
pairID = &dextypes.PairID{Token0: "TokenA", Token1: "TokenB"}
depositAmount = math.NewInt(10_000)
initialBalance = sdk.NewCoins(sdk.NewCoin("TokenA", depositAmount))
)
FundAccount(app.BankKeeper, ctx, alice, initialBalance)
FundAccount(app.BankKeeper, ctx, bob, initialBalance)

// create a pool with 2 shareholders
shares, err := suite.makeDeposit(ctx, app.DexKeeper, alice, pairID, depositAmount, math.ZeroInt(), 0, 1)
suite.NoError(err)
aliceBalance := app.BankKeeper.GetAllBalances(ctx, alice)
suite.True(aliceBalance.Equal(shares))

shares, err = suite.makeDeposit(ctx, app.DexKeeper, bob, pairID, depositAmount, math.ZeroInt(), 0, 1)
suite.NoError(err)
bobBalance := app.BankKeeper.GetAllBalances(ctx, bob)
suite.True(bobBalance.Equal(shares))

// run upgrade
upgrade := upgradetypes.Plan{
Name: v500.UpgradeName,
Info: "some text here",
Height: 100,
}
suite.NoError(app.UpgradeKeeper.ApplyUpgrade(ctx, upgrade))

// assert that all users have withdrawn from the pool
poolID, err := dextypes.ParsePoolIDFromDenom(shares[0].Denom)
suite.NoError(err)

pool, _ := app.DexKeeper.GetPoolByID(ctx, poolID)
suite.True(pool.LowerTick0.ReservesMakerDenom.Equal(math.ZeroInt()), "Pool not withdrawn")

// AND funds are returned to the users
aliceBalance = app.BankKeeper.GetAllBalances(ctx, alice)
suite.True(aliceBalance.Equal(initialBalance))

bobBalance = app.BankKeeper.GetAllBalances(ctx, bob)
suite.True(bobBalance.Equal(initialBalance))
}

func FundAccount(bankKeeper bankkeeper.Keeper, ctx sdk.Context, addr sdk.AccAddress, amounts sdk.Coins) {
if err := bankKeeper.MintCoins(ctx, dextypes.ModuleName, amounts); err != nil {
panic(err)
}

if err := bankKeeper.SendCoinsFromModuleToAccount(ctx, dextypes.ModuleName, addr, amounts); err != nil {
panic(err)
}
}

func (suite *UpgradeTestSuite) makeDeposit(
ctx sdk.Context,
k dexkeeper.Keeper,
addr sdk.AccAddress,
pairID *dextypes.PairID,
amount0, amount1 math.Int,
tick int64,
fee uint64,
) (sharesIssued sdk.Coins, err error) {
deposit0, deposit1, sharesIssued, _, err := k.DepositCore(ctx, pairID, addr, addr, []math.Int{amount0}, []math.Int{amount1}, []int64{tick}, []uint64{fee}, []*dextypes.DepositOptions{{}})
suite.True(deposit0[0].Equal(amount0))
suite.True(deposit1[0].Equal(amount1))

return sharesIssued, err
}

func (suite *UpgradeTestSuite) TestUpgradeSetRateLimitContractMainnet() {
var (
app = suite.GetNeutronZoneApp(suite.ChainA)
ctx = suite.ChainA.GetContext().WithChainID("neutron-1")
Expand All @@ -103,5 +212,45 @@ func (suite *UpgradeTestSuite) TestUpgradeSetRateLimitContract() {

params = app.RateLimitingICS4Wrapper.IbcratelimitKeeper.GetParams(ctx)

suite.Equal(params.ContractAddress, v500.RateLimitContract)
suite.Equal(params.ContractAddress, v500.MainnetRateLimitContract)
}

func (suite *UpgradeTestSuite) TestUpgradeSetRateLimitContractTestnet() {
var (
app = suite.GetNeutronZoneApp(suite.ChainA)
ctx = suite.ChainA.GetContext().WithChainID("pion-1")
)

params := app.RateLimitingICS4Wrapper.IbcratelimitKeeper.GetParams(ctx)

suite.Equal(params.ContractAddress, "")

upgrade := upgradetypes.Plan{
Name: v500.UpgradeName,
Info: "some text here",
Height: 100,
}
suite.NoError(app.UpgradeKeeper.ApplyUpgrade(ctx, upgrade))

params = app.RateLimitingICS4Wrapper.IbcratelimitKeeper.GetParams(ctx)

suite.Equal(params.ContractAddress, v500.TestnetRateLimitContract)
}

func (suite *UpgradeTestSuite) TestUpgradeSetRateLimitContractUnknownChain() {
var (
app = suite.GetNeutronZoneApp(suite.ChainA)
ctx = suite.ChainA.GetContext().WithChainID("unknown-chain")
)

params := app.RateLimitingICS4Wrapper.IbcratelimitKeeper.GetParams(ctx)

suite.Equal(params.ContractAddress, "")

upgrade := upgradetypes.Plan{
Name: v500.UpgradeName,
Info: "some text here",
Height: 100,
}
suite.EqualError(app.UpgradeKeeper.ApplyUpgrade(ctx, upgrade), fmt.Sprintf("unknown chain id %s", ctx.ChainID()))
}
Loading

0 comments on commit 35ca307

Please sign in to comment.