diff --git a/CHANGELOG.md b/CHANGELOG.md index f7279f83599..d42a4dd08a5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -50,6 +50,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * [#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. + * [#5281](https://github.com/osmosis-labs/osmosis/pull/5281) Add option to designate Reward Recipient to Lock and Incentives. * [#4827] (https://github.com/osmosis-labs/osmosis/pull/4827) Protorev: Change highest liquidity pool updating from weekly to daily and change dev fee payout from weekly to after every trade. ### Misc Improvements diff --git a/proto/osmosis/lockup/lock.proto b/proto/osmosis/lockup/lock.proto index 9cbb84c15bb..1d79dfb2746 100644 --- a/proto/osmosis/lockup/lock.proto +++ b/proto/osmosis/lockup/lock.proto @@ -42,6 +42,11 @@ message PeriodLock { (gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins" ]; + // Reward Receiver Address is the address that would be receiving rewards for + // the incentives for the lock. This is set to owner by default and can be + // changed via separate msg. + string reward_receiver_address = 6 + [ (gogoproto.moretags) = "yaml:\"reward_receiver_address\"" ]; } // LockQueryType defines the type of the lock query that can diff --git a/proto/osmosis/lockup/tx.proto b/proto/osmosis/lockup/tx.proto index a75b8feb8cd..7c7924be34f 100644 --- a/proto/osmosis/lockup/tx.proto +++ b/proto/osmosis/lockup/tx.proto @@ -21,6 +21,9 @@ service Msg { // MsgEditLockup edits the existing lockups by lock ID rpc ExtendLockup(MsgExtendLockup) returns (MsgExtendLockupResponse); rpc ForceUnlock(MsgForceUnlock) returns (MsgForceUnlockResponse); + // SetRewardReceiverAddress edits the reward receiver for the given lock ID + rpc SetRewardReceiverAddress(MsgSetRewardReceiverAddress) + returns (MsgSetRewardReceiverAddressResponse); } message MsgLockTokens { @@ -95,4 +98,12 @@ message MsgForceUnlock { ]; } -message MsgForceUnlockResponse { bool success = 1; } \ No newline at end of file +message MsgForceUnlockResponse { bool success = 1; } + +message MsgSetRewardReceiverAddress { + string owner = 1 [ (gogoproto.moretags) = "yaml:\"owner\"" ]; + uint64 lockID = 2; + string reward_receiver = 3 + [ (gogoproto.moretags) = "yaml:\"reward_receiver\"" ]; +} +message MsgSetRewardReceiverAddressResponse { bool success = 1; } \ No newline at end of file diff --git a/x/incentives/keeper/distribute.go b/x/incentives/keeper/distribute.go index c980d42343e..4ee63e66f24 100644 --- a/x/incentives/keeper/distribute.go +++ b/x/incentives/keeper/distribute.go @@ -158,39 +158,43 @@ func (k Keeper) FilteredLocksDistributionEst(ctx sdk.Context, gauge types.Gauge, // distributionInfo stores all of the information for pent up sends for rewards distributions. // This enables us to lower the number of events and calls to back. type distributionInfo struct { - nextID int - lockOwnerAddrToID map[string]int - idToBech32Addr []string - idToDecodedAddr []sdk.AccAddress - idToDistrCoins []sdk.Coins + nextID int + lockOwnerAddrToID map[string]int + lockOwnerAddrToRewardReceiver map[string]string + idToBech32Addr []string + idToDecodedRewardReceiverAddr []sdk.AccAddress + idToDistrCoins []sdk.Coins } // newDistributionInfo creates a new distributionInfo struct func newDistributionInfo() distributionInfo { return distributionInfo{ - nextID: 0, - lockOwnerAddrToID: make(map[string]int), - idToBech32Addr: []string{}, - idToDecodedAddr: []sdk.AccAddress{}, - idToDistrCoins: []sdk.Coins{}, + nextID: 0, + lockOwnerAddrToID: make(map[string]int), + lockOwnerAddrToRewardReceiver: make(map[string]string), + idToBech32Addr: []string{}, + idToDecodedRewardReceiverAddr: []sdk.AccAddress{}, + idToDistrCoins: []sdk.Coins{}, } } // addLockRewards adds the provided rewards to the lockID mapped to the provided owner address. -func (d *distributionInfo) addLockRewards(owner string, rewards sdk.Coins) error { +func (d *distributionInfo) addLockRewards(owner, rewardReceiver string, rewards sdk.Coins) error { + // if we have already added current lock owner's info to distribution Info, simply add reward. if id, ok := d.lockOwnerAddrToID[owner]; ok { oldDistrCoins := d.idToDistrCoins[id] d.idToDistrCoins[id] = rewards.Add(oldDistrCoins...) - } else { + } else { // if this is a new owner that we have not added to distributionInfo yet, + // add according information to the distributionInfo maps. id := d.nextID d.nextID += 1 d.lockOwnerAddrToID[owner] = id - decodedOwnerAddr, err := sdk.AccAddressFromBech32(owner) + decodedRewardReceiverAddr, err := sdk.AccAddressFromBech32(rewardReceiver) if err != nil { return err } - d.idToBech32Addr = append(d.idToBech32Addr, owner) - d.idToDecodedAddr = append(d.idToDecodedAddr, decodedOwnerAddr) + d.idToBech32Addr = append(d.idToBech32Addr, rewardReceiver) + d.idToDecodedRewardReceiverAddr = append(d.idToDecodedRewardReceiverAddr, decodedRewardReceiverAddr) d.idToDistrCoins = append(d.idToDistrCoins, rewards) } return nil @@ -198,13 +202,14 @@ func (d *distributionInfo) addLockRewards(owner string, rewards sdk.Coins) error // doDistributionSends utilizes provided distributionInfo to send coins from the module account to various recipients. func (k Keeper) doDistributionSends(ctx sdk.Context, distrs *distributionInfo) error { - numIDs := len(distrs.idToDecodedAddr) + numIDs := len(distrs.idToDecodedRewardReceiverAddr) if numIDs > 0 { ctx.Logger().Debug(fmt.Sprintf("Beginning distribution to %d users", numIDs)) + // send rewards from the gauge to the reward receiver address err := k.bk.SendCoinsFromModuleToManyAccounts( ctx, types.ModuleName, - distrs.idToDecodedAddr, + distrs.idToDecodedRewardReceiverAddr, distrs.idToDistrCoins) if err != nil { return err @@ -324,7 +329,13 @@ func (k Keeper) distributeInternal( continue } // update the amount for that address - err := distrInfo.addLockRewards(lock.Owner, distrCoins) + rewardReceiver := lock.RewardReceiverAddress + + // if the reward receiver stored in state is an empty string, it indicates that the owner is the reward receiver. + if rewardReceiver == "" { + rewardReceiver = lock.Owner + } + err := distrInfo.addLockRewards(lock.Owner, rewardReceiver, distrCoins) if err != nil { return nil, err } diff --git a/x/incentives/keeper/distribute_test.go b/x/incentives/keeper/distribute_test.go index 9ce78319f50..2b1401c086c 100644 --- a/x/incentives/keeper/distribute_test.go +++ b/x/incentives/keeper/distribute_test.go @@ -37,12 +37,14 @@ func (s *KeeperTestSuite) TestDistribute() { noRewardCoins := sdk.Coins{} oneKRewardCoins := sdk.Coins{sdk.NewInt64Coin(defaultRewardDenom, 1000)} twoKRewardCoins := sdk.Coins{sdk.NewInt64Coin(defaultRewardDenom, 2000)} + threeKRewardCoins := sdk.Coins{sdk.NewInt64Coin(defaultRewardDenom, 3000)} fiveKRewardCoins := sdk.Coins{sdk.NewInt64Coin(defaultRewardDenom, 5000)} tests := []struct { - name string - users []userLocks - gauges []perpGaugeDesc - expectedRewards []sdk.Coins + name string + users []userLocks + gauges []perpGaugeDesc + changeRewardReceiver []changeRewardReceiver + expectedRewards []sdk.Coins }{ // gauge 1 gives 3k coins. three locks, all eligible. 1k coins per lock. // 1k should go to oneLockupUser and 2k to twoLockupUser. @@ -78,6 +80,70 @@ func (s *KeeperTestSuite) TestDistribute() { gauges: []perpGaugeDesc{noRewardGauge, defaultGauge}, expectedRewards: []sdk.Coins{oneKRewardCoins, twoKRewardCoins}, }, + // gauge 1 gives 3k coins. three locks, all eligible. 1k coins per lock. + // we change oneLockupUser lock's reward recepient to the twoLockupUser + // none should go to oneLockupUser and 3k to twoLockupUser. + { + name: "Change Reward Receiver: One user with one lockup, another user with two lockups, single default gauge", + users: []userLocks{oneLockupUser, twoLockupUser}, + gauges: []perpGaugeDesc{defaultGauge}, + changeRewardReceiver: []changeRewardReceiver{ + // change first lock's receiver address to the second account + { + lockId: 1, + newReceiverAccIndex: 1, + }, + }, + expectedRewards: []sdk.Coins{sdk.NewCoins(), threeKRewardCoins}, + }, + // gauge 1 gives 3k coins. three locks, all eligible. 1k coins per lock. + // We change oneLockupUser's reward recepient to twoLockupUser, twoLockupUser's reward recepient to OneLockupUser. + // Rewards should be reversed to the original test case, 2k should go to oneLockupUser and 1k to twoLockupUser. + { + name: "Change Reward Receiver: One user with one lockup, another user with two lockups, single default gauge", + users: []userLocks{oneLockupUser, twoLockupUser}, + gauges: []perpGaugeDesc{defaultGauge}, + changeRewardReceiver: []changeRewardReceiver{ + // change first lock's receiver address to the second account + { + lockId: 1, + newReceiverAccIndex: 1, + }, + { + lockId: 2, + newReceiverAccIndex: 0, + }, + { + lockId: 3, + newReceiverAccIndex: 0, + }, + }, + expectedRewards: []sdk.Coins{twoKRewardCoins, oneKRewardCoins}, + }, + // gauge 1 gives 3k coins. three locks, all eligible. + // gauge 2 gives 3k coins. one lock, to twoLockupUser. + // Change all of oneLockupUser's reward recepient to twoLockupUser, vice versa. + // Rewards should be reversed, 5k should to oneLockupUser and 1k to twoLockupUser. + { + name: "Change Reward Receiver: One user with one lockup (default gauge), another user with two lockups (double length gauge)", + users: []userLocks{oneLockupUser, twoLockupUser}, + gauges: []perpGaugeDesc{defaultGauge, doubleLengthGauge}, + changeRewardReceiver: []changeRewardReceiver{ + { + lockId: 1, + newReceiverAccIndex: 1, + }, + { + lockId: 2, + newReceiverAccIndex: 0, + }, + { + lockId: 3, + newReceiverAccIndex: 0, + }, + }, + expectedRewards: []sdk.Coins{fiveKRewardCoins, oneKRewardCoins}, + }, } for _, tc := range tests { s.SetupTest() @@ -85,6 +151,11 @@ func (s *KeeperTestSuite) TestDistribute() { gauges := s.SetupGauges(tc.gauges, defaultLPDenom) addrs := s.SetupUserLocks(tc.users) + // set up reward receiver if not nil + if len(tc.changeRewardReceiver) != 0 { + s.SetupChangeRewardReceiver(tc.changeRewardReceiver, addrs) + } + _, err := s.App.IncentivesKeeper.Distribute(s.Ctx, gauges) s.Require().NoError(err) // check expected rewards against actual rewards received diff --git a/x/incentives/keeper/suite_test.go b/x/incentives/keeper/suite_test.go index d57d2682919..9aa0df5364a 100644 --- a/x/incentives/keeper/suite_test.go +++ b/x/incentives/keeper/suite_test.go @@ -50,6 +50,11 @@ type perpGaugeDesc struct { rewardAmount sdk.Coins } +type changeRewardReceiver struct { + newReceiverAccIndex int + lockId uint64 +} + // setupAddr takes a balance, prefix, and address number. Then returns the respective account address byte array. // If prefix is left blank, it will be replaced with a random prefix. func (s *KeeperTestSuite) setupAddr(addrNum int, prefix string, balance sdk.Coins) sdk.AccAddress { @@ -83,6 +88,16 @@ func (s *KeeperTestSuite) SetupUserLocks(users []userLocks) (accs []sdk.AccAddre return } +func (s *KeeperTestSuite) SetupChangeRewardReceiver(changeRewardReceivers []changeRewardReceiver, accs []sdk.AccAddress) { + for _, changeRewardReceiver := range changeRewardReceivers { + lock, err := s.App.LockupKeeper.GetLockByID(s.Ctx, changeRewardReceiver.lockId) + s.Require().NoError(err) + + err = s.App.LockupKeeper.SetLockRewardReceiverAddress(s.Ctx, changeRewardReceiver.lockId, lock.OwnerAddress(), accs[changeRewardReceiver.newReceiverAccIndex].String()) + s.Require().NoError(err) + } +} + // SetupUserSyntheticLocks takes an array of user locks and creates synthetic locks based on this array, then returns the respective account address byte array. func (s *KeeperTestSuite) SetupUserSyntheticLocks(users []userLocks) (accs []sdk.AccAddress) { accs = make([]sdk.AccAddress, len(users)) diff --git a/x/lockup/keeper/bench_test.go b/x/lockup/keeper/bench_test.go index 50b12933d5d..90de2943f79 100644 --- a/x/lockup/keeper/bench_test.go +++ b/x/lockup/keeper/bench_test.go @@ -69,7 +69,7 @@ func benchmarkResetLogic(b *testing.B, numLockups int) { addr := addrs[r.Int()%numAccts] simCoins := sdk.NewCoins(sdk.NewCoin(denom, sdk.NewInt(r.Int63n(100)))) duration := time.Duration(r.Intn(1*60*60*24*7)) * time.Second - lock := lockuptypes.NewPeriodLock(uint64(i+1), addr, duration, time.Time{}, simCoins) + lock := lockuptypes.NewPeriodLock(uint64(i+1), addr, addr.String(), duration, time.Time{}, simCoins) locks[i] = lock } diff --git a/x/lockup/keeper/genesis_test.go b/x/lockup/keeper/genesis_test.go index 40a8e344bfc..637f975d4cd 100644 --- a/x/lockup/keeper/genesis_test.go +++ b/x/lockup/keeper/genesis_test.go @@ -24,25 +24,28 @@ var ( LastLockId: 10, Locks: []types.PeriodLock{ { - ID: 1, - Owner: acc1.String(), - Duration: time.Second, - EndTime: time.Time{}, - Coins: sdk.Coins{sdk.NewInt64Coin("foo", 10000000)}, + ID: 1, + Owner: acc1.String(), + RewardReceiverAddress: "", + Duration: time.Second, + EndTime: time.Time{}, + Coins: sdk.Coins{sdk.NewInt64Coin("foo", 10000000)}, }, { - ID: 2, - Owner: acc1.String(), - Duration: time.Hour, - EndTime: time.Time{}, - Coins: sdk.Coins{sdk.NewInt64Coin("foo", 15000000)}, + ID: 2, + Owner: acc1.String(), + RewardReceiverAddress: acc2.String(), + Duration: time.Hour, + EndTime: time.Time{}, + Coins: sdk.Coins{sdk.NewInt64Coin("foo", 15000000)}, }, { - ID: 3, - Owner: acc2.String(), - Duration: time.Minute, - EndTime: time.Time{}, - Coins: sdk.Coins{sdk.NewInt64Coin("foo", 5000000)}, + ID: 3, + Owner: acc2.String(), + RewardReceiverAddress: acc1.String(), + Duration: time.Minute, + EndTime: time.Time{}, + Coins: sdk.Coins{sdk.NewInt64Coin("foo", 5000000)}, }, }, } @@ -90,32 +93,36 @@ func TestExportGenesis(t *testing.T) { require.Equal(t, genesisExported.LastLockId, uint64(11)) require.Equal(t, genesisExported.Locks, []types.PeriodLock{ { - ID: 1, - Owner: acc1.String(), - Duration: time.Second, - EndTime: time.Time{}, - Coins: sdk.Coins{sdk.NewInt64Coin("foo", 10000000)}, + ID: 1, + Owner: acc1.String(), + RewardReceiverAddress: "", + Duration: time.Second, + EndTime: time.Time{}, + Coins: sdk.Coins{sdk.NewInt64Coin("foo", 10000000)}, }, { - ID: 11, - Owner: acc2.String(), - Duration: time.Second * 5, - EndTime: time.Time{}, - Coins: sdk.Coins{sdk.NewInt64Coin("foo", 5000000)}, + ID: 11, + Owner: acc2.String(), + RewardReceiverAddress: "", + Duration: time.Second * 5, + EndTime: time.Time{}, + Coins: sdk.Coins{sdk.NewInt64Coin("foo", 5000000)}, }, { - ID: 3, - Owner: acc2.String(), - Duration: time.Minute, - EndTime: time.Time{}, - Coins: sdk.Coins{sdk.NewInt64Coin("foo", 5000000)}, + ID: 3, + Owner: acc2.String(), + RewardReceiverAddress: acc1.String(), + Duration: time.Minute, + EndTime: time.Time{}, + Coins: sdk.Coins{sdk.NewInt64Coin("foo", 5000000)}, }, { - ID: 2, - Owner: acc1.String(), - Duration: time.Hour, - EndTime: time.Time{}, - Coins: sdk.Coins{sdk.NewInt64Coin("foo", 15000000)}, + ID: 2, + Owner: acc1.String(), + RewardReceiverAddress: acc2.String(), + Duration: time.Hour, + EndTime: time.Time{}, + Coins: sdk.Coins{sdk.NewInt64Coin("foo", 15000000)}, }, }) } diff --git a/x/lockup/keeper/lock.go b/x/lockup/keeper/lock.go index 885ab53e38f..838ac71a132 100644 --- a/x/lockup/keeper/lock.go +++ b/x/lockup/keeper/lock.go @@ -146,7 +146,8 @@ func (k Keeper) CreateLockNoSend(ctx sdk.Context, owner sdk.AccAddress, coins sd ID := k.GetLastLockID(ctx) + 1 // unlock time is initially set without a value, gets set as unlock start time + duration // when unlocking starts. - lock := types.NewPeriodLock(ID, owner, duration, time.Time{}, coins) + // the reward receiver is set as the owner by default when creating a lock, and we indicate this by using an empty string. + lock := types.NewPeriodLock(ID, owner, "", duration, time.Time{}, coins) // lock the coins without sending them to the lockup module account err := k.lock(ctx, lock, lock.Coins) @@ -455,6 +456,37 @@ func (k Keeper) unlockMaturedLockInternalLogic(ctx sdk.Context, lock types.Perio return nil } +// SetLockRewardReceiverAddress changes the reward recipient address to the given address. +// Storing an empty string for reward receiver would indicate the owner being reward receiver. +func (k Keeper) SetLockRewardReceiverAddress(ctx sdk.Context, lockID uint64, owner sdk.AccAddress, newReceiverAddress string) error { + lock, err := k.GetLockByID(ctx, lockID) + if err != nil { + return err + } + // check if the lock owner is the method caller. + if lock.GetOwner() != owner.String() { + return types.ErrNotLockOwner + } + + // if the given receiver address is same as the lock owner, we store an empty string instead. + if lock.Owner == newReceiverAddress { + newReceiverAddress = types.DefaultOwnerReceiverPlaceholder + } + + if lock.RewardReceiverAddress == newReceiverAddress { + return types.ErrRewardReceiverIsSame + } + + lock.RewardReceiverAddress = newReceiverAddress + + err = k.setLock(ctx, *lock) + if err != nil { + return err + } + + return nil +} + // ExtendLockup changes the existing lock duration to the given lock duration. // Updating lock duration would fail on either of the following conditions. // 1. Only lock owner is able to change the duration of the lock. @@ -801,7 +833,7 @@ func (k Keeper) SplitLock(ctx sdk.Context, lock types.PeriodLock, coins sdk.Coin splitLockID := k.GetLastLockID(ctx) + 1 k.SetLastLockID(ctx, splitLockID) - splitLock := types.NewPeriodLock(splitLockID, lock.OwnerAddress(), lock.Duration, lock.EndTime, coins) + splitLock := types.NewPeriodLock(splitLockID, lock.OwnerAddress(), lock.RewardReceiverAddress, lock.Duration, lock.EndTime, coins) err = k.setLock(ctx, splitLock) return splitLock, err diff --git a/x/lockup/keeper/lock_test.go b/x/lockup/keeper/lock_test.go index 15f10c958ad..7def8ddf9dc 100644 --- a/x/lockup/keeper/lock_test.go +++ b/x/lockup/keeper/lock_test.go @@ -5,6 +5,8 @@ import ( "strings" "time" + errorsmod "cosmossdk.io/errors" + cl "github.com/osmosis-labs/osmosis/v15/x/concentrated-liquidity" cltypes "github.com/osmosis-labs/osmosis/v15/x/concentrated-liquidity/types" "github.com/osmosis-labs/osmosis/v15/x/lockup/types" @@ -236,7 +238,7 @@ func (s *KeeperTestSuite) TestUnlock() { ctx := s.Ctx addr1 := sdk.AccAddress([]byte("addr1---------------")) - _ = types.NewPeriodLock(1, addr1, time.Second, time.Time{}, tc.fundAcc) + lock := types.NewPeriodLock(1, addr1, addr1.String(), time.Second, time.Time{}, tc.fundAcc) // lock with balance s.FundAcc(addr1, tc.fundAcc) @@ -495,6 +497,7 @@ func (s *KeeperTestSuite) TestCreateLock() { s.Require().Equal(time.Second, lock.Duration) s.Require().Equal(time.Time{}, lock.EndTime) s.Require().Equal(uint64(1), lock.ID) + s.Require().Equal("", lock.RewardReceiverAddress) lockID := s.App.LockupKeeper.GetLastLockID(s.Ctx) s.Require().Equal(uint64(1), lockID) @@ -534,6 +537,87 @@ func (s *KeeperTestSuite) TestCreateLock() { s.Require().Equal(sdk.NewInt(30), balance.Amount) } +func (s *KeeperTestSuite) TestSetLockRewardReceiverAddress() { + testCases := []struct { + name string + isnotOwner bool + lockID uint64 + useNewReceiverAddress bool + exepctedErrorType error + }{ + { + name: "happy case", + isnotOwner: false, + lockID: 1, + useNewReceiverAddress: true, + }, + { + name: "error: caller of the function is not the owner", + isnotOwner: true, + lockID: 1, + useNewReceiverAddress: true, + exepctedErrorType: types.ErrNotLockOwner, + }, + { + name: "error: lock id is invalid", + isnotOwner: false, + lockID: 5, + useNewReceiverAddress: true, + exepctedErrorType: errorsmod.Wrap(types.ErrLockupNotFound, fmt.Sprintf("lock with ID %d does not exist", 5)), + }, + { + name: "error: new receiver address is same as old", + isnotOwner: false, + lockID: 1, + useNewReceiverAddress: false, + exepctedErrorType: types.ErrRewardReceiverIsSame, + }, + } + + for _, tc := range testCases { + s.Run(tc.name, func() { + s.SetupTest() + + addr1 := s.TestAccs[0] + coins := sdk.Coins{sdk.NewInt64Coin("stake", 10)} + + s.FundAcc(addr1, coins) + + lock, err := s.App.LockupKeeper.CreateLock(s.Ctx, addr1, coins, time.Second) + s.Require().NoError(err) + + // check that the reward receiver is the lock owner by default + s.Require().Equal(lock.RewardReceiverAddress, "") + + owner := addr1 + if tc.isnotOwner { + owner = s.TestAccs[1] + } + + newReceiver := addr1 + // if this field is set to true, use different account as input + if tc.useNewReceiverAddress { + newReceiver = s.TestAccs[1] + } + + // System under test + // now change the reward receiver state + err = s.App.LockupKeeper.SetLockRewardReceiverAddress(s.Ctx, tc.lockID, owner, newReceiver.String()) + if tc.exepctedErrorType != nil { + s.Require().Error(err) + s.Require().ErrorContains(tc.exepctedErrorType, err.Error()) + } else { + s.Require().NoError(err) + lock, err := s.App.LockupKeeper.GetLockByID(s.Ctx, lock.ID) + s.Require().NoError(err) + s.Require().Equal(lock.RewardReceiverAddress, newReceiver.String()) + } + + }) + } + +} + func (s *KeeperTestSuite) TestCreateLockNoSend() { s.SetupTest() @@ -805,6 +889,109 @@ func (s *KeeperTestSuite) TestLock() { balance = s.App.BankKeeper.GetBalance(s.Ctx, acc.GetAddress(), "stake") s.Require().Equal(sdk.NewInt(0).String(), balance.Amount.String()) } +func (s *KeeperTestSuite) TestSplitLock() { + defaultAmount := sdk.NewCoins(sdk.NewCoin("foo", sdk.NewInt(100)), sdk.NewCoin("bar", sdk.NewInt(200))) + defaultHalfAmount := sdk.NewCoins(sdk.NewCoin("foo", sdk.NewInt(40)), sdk.NewCoin("bar", sdk.NewInt(110))) + testCases := []struct { + name string + amountToSplit sdk.Coins + isUnlocking bool + isForceUnlock bool + useDifferentRewardAddress bool + expectedErr bool + }{ + { + "happy path: split half amount", + defaultHalfAmount, + false, + false, + false, + false, + }, + { + "happy path: split full amount", + defaultAmount, + false, + false, + false, + false, + }, + { + "happy path: try using reward address with different reward receiver", + defaultAmount, + false, + false, + true, + false, + }, + { + "error: unlocking lock", + defaultAmount, + true, + false, + false, + true, + }, + { + "error: force unlock", + defaultAmount, + true, + false, + false, + true, + }, + } + for _, tc := range testCases { + s.SetupTest() + defaultDuration := time.Minute + defaultEndTime := time.Time{} + lock := types.NewPeriodLock( + 1, + s.TestAccs[0], + s.TestAccs[0].String(), + defaultDuration, + defaultEndTime, + defaultAmount, + ) + if tc.isUnlocking { + lock.EndTime = s.Ctx.BlockTime() + } + if tc.useDifferentRewardAddress { + lock.RewardReceiverAddress = s.TestAccs[1].String() + } + + // manually set last lock id to 1 + s.App.LockupKeeper.SetLastLockID(s.Ctx, 1) + // System under test + newLock, err := s.App.LockupKeeper.SplitLock(s.Ctx, lock, tc.amountToSplit, tc.isForceUnlock) + if tc.expectedErr { + s.Require().Error(err) + return + } + s.Require().NoError(err) + + // check if the new lock has correct states + s.Require().Equal(newLock.ID, lock.ID+1) + s.Require().Equal(newLock.Owner, lock.Owner) + s.Require().Equal(newLock.Duration, lock.Duration) + s.Require().Equal(newLock.EndTime, lock.EndTime) + s.Require().Equal(newLock.RewardReceiverAddress, lock.RewardReceiverAddress) + s.Require().True(newLock.Coins.IsEqual(tc.amountToSplit)) + + // now check if the old lock has correctly updated state + updatedOriginalLock, err := s.App.LockupKeeper.GetLockByID(s.Ctx, lock.ID) + s.Require().Equal(updatedOriginalLock.ID, lock.ID) + s.Require().Equal(updatedOriginalLock.Owner, lock.Owner) + s.Require().Equal(updatedOriginalLock.Duration, lock.Duration) + s.Require().Equal(updatedOriginalLock.EndTime, lock.EndTime) + s.Require().Equal(updatedOriginalLock.RewardReceiverAddress, lock.RewardReceiverAddress) + s.Require().True(updatedOriginalLock.Coins.IsEqual(lock.Coins.Sub(tc.amountToSplit))) + + // check that last lock id has incremented properly + lastLockId := s.App.LockupKeeper.GetLastLockID(s.Ctx) + s.Require().Equal(lastLockId, newLock.ID) + } +} func (s *KeeperTestSuite) AddTokensToLockForSynth() { s.SetupTest() diff --git a/x/lockup/keeper/migration.go b/x/lockup/keeper/migration.go index e8ac644ed7d..ee69f062cb4 100644 --- a/x/lockup/keeper/migration.go +++ b/x/lockup/keeper/migration.go @@ -37,6 +37,8 @@ func normalizeDuration(baselineDurations []time.Duration, allowedDiff time.Durat // If a lockup is far from any base duration, we don't change anything about it. // We define a lockup length as a "Similar duration to base duration D", if: // D <= lockup length <= D + durationDiff. +// Any locks with different reward receiver and lock owner would not be merged. +// NOTE: This method has been outdated, please make new migration code if there is a need to merge locks with similar duration. func MergeLockupsForSimilarDurations( ctx sdk.Context, k Keeper, @@ -65,6 +67,13 @@ func MergeLockupsForSimilarDurations( continue } coin := lock.Coins[0] + + // check if the reward receiver is the lock owner. + // if not, we do not normalize the lock. + if lock.RewardReceiverAddress != "" { + continue + } + // In this pass, add lock to normals if exact match key := addr.String() + "/" + coin.Denom + "/" + strconv.FormatInt(int64(normalizedDuration), 10) _, normalExists := normals[key] @@ -94,7 +103,7 @@ func MergeLockupsForSimilarDurations( } // create a normalized lock that will absorb the locks in the duration window normalID = k.GetLastLockID(ctx) + 1 - normalLock = types.NewPeriodLock(normalID, owner, normalizedDuration, time.Time{}, lock.Coins) + normalLock = types.NewPeriodLock(normalID, owner, lock.RewardReceiverAddress, normalizedDuration, time.Time{}, lock.Coins) err = k.addLockRefs(ctx, normalLock) if err != nil { panic(err) diff --git a/x/lockup/keeper/msg_server.go b/x/lockup/keeper/msg_server.go index 160acf0037a..2ee51b2084c 100644 --- a/x/lockup/keeper/msg_server.go +++ b/x/lockup/keeper/msg_server.go @@ -226,3 +226,24 @@ func (server msgServer) ForceUnlock(goCtx context.Context, msg *types.MsgForceUn return &types.MsgForceUnlockResponse{Success: true}, nil } + +func (server msgServer) SetRewardReceiverAddress(goCtx context.Context, msg *types.MsgSetRewardReceiverAddress) (*types.MsgSetRewardReceiverAddressResponse, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + + owner, err := sdk.AccAddressFromBech32(msg.Owner) + if err != nil { + return nil, err + } + + newRewardRecepient, err := sdk.AccAddressFromBech32(msg.RewardReceiver) + if err != nil { + return nil, err + } + + err = server.keeper.SetLockRewardReceiverAddress(ctx, msg.LockID, owner, newRewardRecepient.String()) + if err != nil { + return &types.MsgSetRewardReceiverAddressResponse{Success: false}, errorsmod.Wrap(sdkerrors.ErrInvalidRequest, err.Error()) + } + + return &types.MsgSetRewardReceiverAddressResponse{Success: true}, nil +} diff --git a/x/lockup/keeper/msg_server_test.go b/x/lockup/keeper/msg_server_test.go index 2dddf21c0f9..b22191239d0 100644 --- a/x/lockup/keeper/msg_server_test.go +++ b/x/lockup/keeper/msg_server_test.go @@ -455,3 +455,97 @@ func (s *KeeperTestSuite) TestMsgForceUnlock() { } } } + +func (s *KeeperTestSuite) TestSetRewardReceiverAddress() { + type param struct { + isOwner bool + isRewardReceiverAddressOwner bool + isLockOwner bool + } + + tests := []struct { + name string + param param + expectPass bool + }{ + { + name: "happy path: change reward receiver address to another address", + param: param{ + isOwner: true, + isRewardReceiverAddressOwner: false, + isLockOwner: true, + }, + expectPass: true, + }, + { + name: "error: attempt to try changing to same owner", + param: param{ + isOwner: false, + isRewardReceiverAddressOwner: true, + isLockOwner: true, + }, + expectPass: false, + }, + { + name: "error: sender is not the owner of the lock", + param: param{ + isOwner: false, + isRewardReceiverAddressOwner: false, + isLockOwner: true, + }, + expectPass: false, + }, + } + + for _, test := range tests { + s.SetupTest() + + defaultAmountInLock := sdk.NewCoins(sdk.NewInt64Coin("foo", 100)) + s.FundAcc(s.TestAccs[0], defaultAmountInLock) + + lock, err := s.App.LockupKeeper.CreateLock(s.Ctx, s.TestAccs[0], defaultAmountInLock, time.Minute) + s.Require().NoError(err) + + // lock reward receiver address should initially be an empty string + s.Require().Equal(lock.RewardReceiverAddress, "") + + msgServer := keeper.NewMsgServerImpl(s.App.LockupKeeper) + c := sdk.WrapSDKContext(s.Ctx) + + owner := s.TestAccs[0] + if !test.param.isOwner { + owner = s.TestAccs[1] + } + + rewardReceiver := s.TestAccs[0] + if !test.param.isRewardReceiverAddressOwner { + rewardReceiver = s.TestAccs[1] + } + + lockId := lock.ID + if !test.param.isLockOwner { + lockId = lockId + 1 + } + // System under test + msg := types.NewMsgSetRewardReceiverAddress(owner, rewardReceiver, lockId) + resp, err := msgServer.SetRewardReceiverAddress(c, msg) + if !test.expectPass { + s.Require().Error(err) + s.Require().Equal(resp.Success, false) + return + } + + s.Require().NoError(err) + s.Require().Equal(resp.Success, true) + + // now check if the reward receiver address has been changed + newLock, err := s.App.LockupKeeper.GetLockByID(s.Ctx, lock.ID) + s.Require().NoError(err) + if test.param.isRewardReceiverAddressOwner { + s.Require().Equal(newLock.RewardReceiverAddress, "") + } else { + s.Require().Equal(s.TestAccs[1].String(), newLock.RewardReceiverAddress) + } + + } +} diff --git a/x/lockup/keeper/synthetic_lock_test.go b/x/lockup/keeper/synthetic_lock_test.go index 9cc16207b8c..7fb02c12b48 100644 --- a/x/lockup/keeper/synthetic_lock_test.go +++ b/x/lockup/keeper/synthetic_lock_test.go @@ -59,11 +59,12 @@ func (s *KeeperTestSuite) TestSyntheticLockupCreateGetDeleteAccumulation() { expectedLocks := []types.PeriodLock{ { - ID: 1, - Owner: addr1.String(), - Duration: time.Second, - EndTime: time.Time{}, - Coins: coins, + ID: 1, + Owner: addr1.String(), + RewardReceiverAddress: "", + Duration: time.Second, + EndTime: time.Time{}, + Coins: coins, }, } // check locks diff --git a/x/lockup/keeper/utils_test.go b/x/lockup/keeper/utils_test.go index c8d3cc18108..b6d2067cb2c 100644 --- a/x/lockup/keeper/utils_test.go +++ b/x/lockup/keeper/utils_test.go @@ -44,26 +44,26 @@ func TestGetDurationKey(t *testing.T) { func TestLockRefKeys(t *testing.T) { addr1 := sdk.AccAddress([]byte("addr1---------------")) // empty address and 1 coin - lock1 := types.NewPeriodLock(1, sdk.AccAddress{}, time.Second, time.Now(), sdk.Coins{sdk.NewInt64Coin("stake", 10)}) + lock1 := types.NewPeriodLock(1, sdk.AccAddress{}, sdk.AccAddress{}.String(), time.Second, time.Now(), sdk.Coins{sdk.NewInt64Coin("stake", 10)}) _, err := lockRefKeys(lock1) require.Error(t, err) // empty address and 2 coins - lock2 := types.NewPeriodLock(1, sdk.AccAddress{}, time.Second, time.Now(), sdk.Coins{sdk.NewInt64Coin("stake", 10), sdk.NewInt64Coin("atom", 1)}) + lock2 := types.NewPeriodLock(1, sdk.AccAddress{}, sdk.AccAddress{}.String(), time.Second, time.Now(), sdk.Coins{sdk.NewInt64Coin("stake", 10), sdk.NewInt64Coin("atom", 1)}) _, err = lockRefKeys(lock2) require.Error(t, err) // not empty address and 1 coin - lock3 := types.NewPeriodLock(1, addr1, time.Second, time.Now(), sdk.Coins{sdk.NewInt64Coin("stake", 10)}) + lock3 := types.NewPeriodLock(1, addr1, addr1.String(), time.Second, time.Now(), sdk.Coins{sdk.NewInt64Coin("stake", 10)}) keys3, err := lockRefKeys(lock3) require.NoError(t, err) require.Len(t, keys3, 8) // not empty address and empty coin - lock4 := types.NewPeriodLock(1, addr1, time.Second, time.Now(), sdk.Coins{sdk.NewInt64Coin("stake", 10)}) + lock4 := types.NewPeriodLock(1, addr1, addr1.String(), time.Second, time.Now(), sdk.Coins{sdk.NewInt64Coin("stake", 10)}) keys4, err := lockRefKeys(lock4) require.NoError(t, err) require.Len(t, keys4, 8) // not empty address and 2 coins - lock5 := types.NewPeriodLock(1, addr1, time.Second, time.Now(), sdk.Coins{sdk.NewInt64Coin("stake", 10), sdk.NewInt64Coin("atom", 1)}) + lock5 := types.NewPeriodLock(1, addr1, addr1.String(), time.Second, time.Now(), sdk.Coins{sdk.NewInt64Coin("stake", 10), sdk.NewInt64Coin("atom", 1)}) keys5, err := lockRefKeys(lock5) require.NoError(t, err) require.Len(t, keys5, 12) diff --git a/x/lockup/types/errors.go b/x/lockup/types/errors.go index 5a16cbada2e..cb06e7061f7 100644 --- a/x/lockup/types/errors.go +++ b/x/lockup/types/errors.go @@ -12,4 +12,5 @@ var ( ErrSyntheticLockupAlreadyExists = errorsmod.Register(ModuleName, 2, "synthetic lockup already exists for same lock") ErrSyntheticDurationLongerThanNative = errorsmod.Register(ModuleName, 3, "synthetic lockup duration should be shorter than native lockup duration") ErrLockupNotFound = errorsmod.Register(ModuleName, 4, "lockup not found") + ErrRewardReceiverIsSame = errorsmod.Register(ModuleName, 5, "reward receiver is the same") ) diff --git a/x/lockup/types/lock.go b/x/lockup/types/lock.go index aa53681c9be..0de9a5975f3 100644 --- a/x/lockup/types/lock.go +++ b/x/lockup/types/lock.go @@ -8,14 +8,24 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" ) +// defaultOwnerReceiverPlaceholder is used as a place holder for default owner receiver for the +// reward receiver field. +// Using this as the value for reward receiver would indicate that the lock's reward receiver is the owner. +const DefaultOwnerReceiverPlaceholder = "" + // NewPeriodLock returns a new instance of period lock. -func NewPeriodLock(ID uint64, owner sdk.AccAddress, duration time.Duration, endTime time.Time, coins sdk.Coins) PeriodLock { +func NewPeriodLock(ID uint64, owner sdk.AccAddress, reward_address string, duration time.Duration, endTime time.Time, coins sdk.Coins) PeriodLock { + // sanity check once more to ensure if reward_address == owner, we store empty string + if owner.String() == reward_address { + reward_address = DefaultOwnerReceiverPlaceholder + } return PeriodLock{ - ID: ID, - Owner: owner.String(), - Duration: duration, - EndTime: endTime, - Coins: coins, + ID: ID, + Owner: owner.String(), + RewardReceiverAddress: reward_address, + Duration: duration, + EndTime: endTime, + Coins: coins, } } diff --git a/x/lockup/types/lock.pb.go b/x/lockup/types/lock.pb.go index 996119cbb19..3942780af20 100644 --- a/x/lockup/types/lock.pb.go +++ b/x/lockup/types/lock.pb.go @@ -78,6 +78,10 @@ type PeriodLock struct { EndTime time.Time `protobuf:"bytes,4,opt,name=end_time,json=endTime,proto3,stdtime" json:"end_time" yaml:"end_time"` // Coins are the tokens locked within the lock, kept in the module account. Coins github_com_cosmos_cosmos_sdk_types.Coins `protobuf:"bytes,5,rep,name=coins,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.Coins" json:"coins"` + // Reward Receiver Address is the address that would be receiving rewards for + // the incentives for the lock. This is set to owner by default and can be + // changed via separate msg. + RewardReceiverAddress string `protobuf:"bytes,6,opt,name=reward_receiver_address,json=rewardReceiverAddress,proto3" json:"reward_receiver_address,omitempty" yaml:"reward_receiver_address"` } func (m *PeriodLock) Reset() { *m = PeriodLock{} } @@ -148,6 +152,13 @@ func (m *PeriodLock) GetCoins() github_com_cosmos_cosmos_sdk_types.Coins { return nil } +func (m *PeriodLock) GetRewardReceiverAddress() string { + if m != nil { + return m.RewardReceiverAddress + } + return "" +} + // QueryCondition is a struct used for querying locks upon different conditions. // Duration field and timestamp fields could be optional, depending on the // LockQueryType. @@ -317,45 +328,47 @@ func init() { func init() { proto.RegisterFile("osmosis/lockup/lock.proto", fileDescriptor_7e9d7527a237b489) } var fileDescriptor_7e9d7527a237b489 = []byte{ - // 595 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x54, 0xbf, 0x6f, 0xd3, 0x40, - 0x14, 0xb6, 0xdd, 0xa4, 0xb4, 0x57, 0x92, 0x46, 0xa7, 0x0e, 0x69, 0x00, 0x3b, 0xf2, 0x80, 0x22, - 0xd4, 0xda, 0x24, 0x88, 0x85, 0xd1, 0x0d, 0x43, 0xa4, 0x0e, 0x60, 0x2a, 0x06, 0x96, 0xc8, 0x3f, - 0x0e, 0xe7, 0x14, 0xdb, 0x67, 0xfc, 0xa3, 0xe0, 0xff, 0x80, 0xb1, 0x23, 0x48, 0x6c, 0x6c, 0xfc, - 0x25, 0x1d, 0x3b, 0x32, 0xa5, 0x28, 0x11, 0x0b, 0x63, 0xff, 0x02, 0x74, 0x77, 0xbe, 0x24, 0x2d, - 0x42, 0xea, 0x00, 0xd3, 0xf9, 0xdd, 0xf7, 0xde, 0xf7, 0xde, 0x7d, 0xef, 0x93, 0xc1, 0x3e, 0xc9, - 0x22, 0x92, 0xe1, 0xcc, 0x0c, 0x89, 0x37, 0x2d, 0x12, 0x76, 0x18, 0x49, 0x4a, 0x72, 0x02, 0x9b, - 0x15, 0x64, 0x70, 0xa8, 0xb3, 0x17, 0x90, 0x80, 0x30, 0xc8, 0xa4, 0x5f, 0x3c, 0xab, 0xa3, 0x06, - 0x84, 0x04, 0x21, 0x32, 0x59, 0xe4, 0x16, 0x6f, 0x4d, 0xbf, 0x48, 0x9d, 0x1c, 0x93, 0xb8, 0xc2, - 0xb5, 0x9b, 0x78, 0x8e, 0x23, 0x94, 0xe5, 0x4e, 0x94, 0x08, 0x02, 0x8f, 0xf5, 0x31, 0x5d, 0x27, - 0x43, 0xe6, 0x69, 0xdf, 0x45, 0xb9, 0xd3, 0x37, 0x3d, 0x82, 0x2b, 0x02, 0xfd, 0xa7, 0x02, 0xc0, - 0x0b, 0x94, 0x62, 0xe2, 0x1f, 0x13, 0x6f, 0x0a, 0x9b, 0x40, 0x19, 0x0d, 0xdb, 0x72, 0x57, 0xee, - 0xd5, 0x6c, 0x65, 0x34, 0x84, 0x0f, 0x41, 0x9d, 0xbc, 0x8f, 0x51, 0xda, 0x56, 0xba, 0x72, 0x6f, - 0xdb, 0x6a, 0x5d, 0xcd, 0xb4, 0xbb, 0xa5, 0x13, 0x85, 0xcf, 0x74, 0x76, 0xad, 0xdb, 0x1c, 0x86, - 0x13, 0xb0, 0x25, 0x26, 0x6b, 0x6f, 0x74, 0xe5, 0xde, 0xce, 0x60, 0xdf, 0xe0, 0xa3, 0x19, 0x62, - 0x34, 0x63, 0x58, 0x25, 0x58, 0xfd, 0xf3, 0x99, 0x26, 0xfd, 0x9a, 0x69, 0x50, 0x94, 0x1c, 0x90, - 0x08, 0xe7, 0x28, 0x4a, 0xf2, 0xf2, 0x6a, 0xa6, 0xed, 0x72, 0x7e, 0x81, 0xe9, 0x9f, 0x2e, 0x35, - 0xd9, 0x5e, 0xb2, 0x43, 0x1b, 0x6c, 0xa1, 0xd8, 0x1f, 0xd3, 0x77, 0xb6, 0x6b, 0xac, 0x53, 0xe7, - 0x8f, 0x4e, 0x27, 0x42, 0x04, 0xeb, 0x1e, 0x6d, 0xb5, 0x22, 0x15, 0x95, 0xfa, 0x19, 0x25, 0xbd, - 0x83, 0x62, 0x9f, 0xa6, 0x42, 0x07, 0xd4, 0xa9, 0x24, 0x59, 0xbb, 0xde, 0xdd, 0x60, 0xa3, 0x73, - 0xd1, 0x0c, 0x2a, 0x9a, 0x51, 0x89, 0x66, 0x1c, 0x11, 0x1c, 0x5b, 0x8f, 0x29, 0xdf, 0xb7, 0x4b, - 0xad, 0x17, 0xe0, 0x7c, 0x52, 0xb8, 0x86, 0x47, 0x22, 0xb3, 0x52, 0x98, 0x1f, 0x87, 0x99, 0x3f, - 0x35, 0xf3, 0x32, 0x41, 0x19, 0x2b, 0xc8, 0x6c, 0xce, 0xac, 0x7f, 0x56, 0x40, 0xf3, 0x65, 0x81, - 0xd2, 0xf2, 0x88, 0xc4, 0x3e, 0x66, 0x2f, 0x79, 0x0e, 0x76, 0xe9, 0xee, 0xc7, 0xef, 0xe8, 0xf5, - 0x98, 0xd6, 0x30, 0xe1, 0x9b, 0x83, 0x07, 0xc6, 0x75, 0x6f, 0x18, 0x74, 0x35, 0xac, 0xf8, 0xa4, - 0x4c, 0x90, 0xdd, 0x08, 0xd7, 0x43, 0xb8, 0x07, 0xea, 0x3e, 0x8a, 0x49, 0xc4, 0x57, 0x64, 0xf3, - 0x80, 0xca, 0x74, 0xfb, 0x85, 0xdc, 0x50, 0xe9, 0x6f, 0xd2, 0xbf, 0x06, 0xdb, 0x4b, 0x7b, 0xdd, - 0x42, 0xfb, 0xfb, 0x15, 0x6b, 0x8b, 0xb3, 0x2e, 0x4b, 0xb9, 0xf8, 0x2b, 0x2a, 0xfd, 0x8b, 0x02, - 0x1a, 0xaf, 0xca, 0x38, 0x9f, 0xa0, 0x1c, 0x7b, 0xcc, 0x86, 0x07, 0x00, 0x16, 0xb1, 0x8f, 0xd2, - 0xb0, 0xc4, 0x71, 0x30, 0x66, 0x2a, 0x61, 0xbf, 0xb2, 0x65, 0x6b, 0x85, 0xd0, 0xdc, 0x91, 0x0f, - 0x35, 0xb0, 0x93, 0xd1, 0xf2, 0xf1, 0xba, 0x0e, 0x80, 0x5d, 0x0d, 0x85, 0x18, 0x4b, 0xcf, 0x6c, - 0xfc, 0x23, 0xcf, 0xac, 0x3b, 0xbe, 0xf6, 0x3f, 0x1d, 0xff, 0xa8, 0x0f, 0x1a, 0xd7, 0x0c, 0x00, - 0x9b, 0x00, 0x58, 0xa5, 0xe0, 0x6e, 0x49, 0x10, 0x80, 0x4d, 0xab, 0xa4, 0x43, 0xb5, 0xe4, 0x4e, - 0xed, 0xe3, 0x57, 0x55, 0xb2, 0x8e, 0xcf, 0xe7, 0xaa, 0x7c, 0x31, 0x57, 0xe5, 0x1f, 0x73, 0x55, - 0x3e, 0x5b, 0xa8, 0xd2, 0xc5, 0x42, 0x95, 0xbe, 0x2f, 0x54, 0xe9, 0xcd, 0x60, 0xcd, 0xb8, 0x95, - 0xcb, 0x0e, 0x43, 0xc7, 0xcd, 0x44, 0x60, 0x9e, 0xf6, 0x9f, 0x9a, 0x1f, 0xc4, 0xff, 0x8a, 0x19, - 0xd9, 0xdd, 0x64, 0x0f, 0x7a, 0xf2, 0x3b, 0x00, 0x00, 0xff, 0xff, 0x05, 0x2d, 0xf1, 0x63, 0xce, - 0x04, 0x00, 0x00, + // 640 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x54, 0x3f, 0x6f, 0xd4, 0x30, + 0x1c, 0xbd, 0xdc, 0x9f, 0xd2, 0xba, 0xf4, 0x7a, 0xb2, 0x8a, 0x48, 0x0f, 0x48, 0x4e, 0x19, 0xd0, + 0x09, 0xb5, 0x09, 0x57, 0xc4, 0xc2, 0x46, 0x7a, 0x0c, 0x95, 0x3a, 0x40, 0xa8, 0x18, 0xba, 0x44, + 0x49, 0x6c, 0x52, 0xab, 0x49, 0x1c, 0xe2, 0xa4, 0x25, 0xdf, 0x80, 0xb1, 0x23, 0x48, 0x6c, 0x6c, + 0x7c, 0x0b, 0xb6, 0x8e, 0x1d, 0x99, 0xae, 0xa8, 0xdd, 0x18, 0xfb, 0x09, 0x90, 0xed, 0xe4, 0x7a, + 0x2d, 0xaa, 0xd4, 0x01, 0xa6, 0x9c, 0xfd, 0x7e, 0xbf, 0xe7, 0x9f, 0xdf, 0x7b, 0x3e, 0xb0, 0x4a, + 0x59, 0x4c, 0x19, 0x61, 0x56, 0x44, 0x83, 0xfd, 0x22, 0x15, 0x1f, 0x33, 0xcd, 0x68, 0x4e, 0x61, + 0xb7, 0x82, 0x4c, 0x09, 0xf5, 0x57, 0x42, 0x1a, 0x52, 0x01, 0x59, 0xfc, 0x97, 0xac, 0xea, 0x6b, + 0x21, 0xa5, 0x61, 0x84, 0x2d, 0xb1, 0xf2, 0x8b, 0xf7, 0x16, 0x2a, 0x32, 0x2f, 0x27, 0x34, 0xa9, + 0x70, 0xfd, 0x3a, 0x9e, 0x93, 0x18, 0xb3, 0xdc, 0x8b, 0xd3, 0x9a, 0x20, 0x10, 0xe7, 0x58, 0xbe, + 0xc7, 0xb0, 0x75, 0x30, 0xf2, 0x71, 0xee, 0x8d, 0xac, 0x80, 0x92, 0x8a, 0xc0, 0xf8, 0xd1, 0x02, + 0xe0, 0x35, 0xce, 0x08, 0x45, 0xdb, 0x34, 0xd8, 0x87, 0x5d, 0xd0, 0xdc, 0x1a, 0xab, 0xca, 0x40, + 0x19, 0xb6, 0x9d, 0xe6, 0xd6, 0x18, 0x3e, 0x06, 0x1d, 0x7a, 0x98, 0xe0, 0x4c, 0x6d, 0x0e, 0x94, + 0xe1, 0x82, 0xdd, 0xbb, 0x98, 0xe8, 0x77, 0x4b, 0x2f, 0x8e, 0x5e, 0x18, 0x62, 0xdb, 0x70, 0x24, + 0x0c, 0xf7, 0xc0, 0x7c, 0x3d, 0x99, 0xda, 0x1a, 0x28, 0xc3, 0xc5, 0x8d, 0x55, 0x53, 0x8e, 0x66, + 0xd6, 0xa3, 0x99, 0xe3, 0xaa, 0xc0, 0x1e, 0x1d, 0x4f, 0xf4, 0xc6, 0xef, 0x89, 0x0e, 0xeb, 0x96, + 0x35, 0x1a, 0x93, 0x1c, 0xc7, 0x69, 0x5e, 0x5e, 0x4c, 0xf4, 0x65, 0xc9, 0x5f, 0x63, 0xc6, 0xe7, + 0x53, 0x5d, 0x71, 0xa6, 0xec, 0xd0, 0x01, 0xf3, 0x38, 0x41, 0x2e, 0xbf, 0xa7, 0xda, 0x16, 0x27, + 0xf5, 0xff, 0x3a, 0x69, 0xa7, 0x16, 0xc1, 0x7e, 0xc0, 0x8f, 0xba, 0x24, 0xad, 0x3b, 0x8d, 0x23, + 0x4e, 0x7a, 0x07, 0x27, 0x88, 0x97, 0x42, 0x0f, 0x74, 0xb8, 0x24, 0x4c, 0xed, 0x0c, 0x5a, 0x62, + 0x74, 0x29, 0x9a, 0xc9, 0x45, 0x33, 0x2b, 0xd1, 0xcc, 0x4d, 0x4a, 0x12, 0xfb, 0x29, 0xe7, 0xfb, + 0x7e, 0xaa, 0x0f, 0x43, 0x92, 0xef, 0x15, 0xbe, 0x19, 0xd0, 0xd8, 0xaa, 0x14, 0x96, 0x9f, 0x75, + 0x86, 0xf6, 0xad, 0xbc, 0x4c, 0x31, 0x13, 0x0d, 0xcc, 0x91, 0xcc, 0x70, 0x17, 0xdc, 0xcf, 0xf0, + 0xa1, 0x97, 0x21, 0x37, 0xc3, 0x01, 0x26, 0x07, 0x38, 0x73, 0x3d, 0x84, 0x32, 0xcc, 0x98, 0x3a, + 0x27, 0xa4, 0x35, 0x2e, 0x26, 0xba, 0x26, 0xa7, 0xbc, 0xa1, 0xd0, 0x70, 0xee, 0x49, 0xc4, 0xa9, + 0x80, 0x97, 0xd5, 0xfe, 0x97, 0x26, 0xe8, 0xbe, 0x29, 0x70, 0x56, 0x6e, 0xd2, 0x04, 0x11, 0xa1, + 0xd2, 0x2b, 0xb0, 0xcc, 0x73, 0xe5, 0x7e, 0xe0, 0xdb, 0x2e, 0x9f, 0x47, 0x98, 0xda, 0xdd, 0x78, + 0x64, 0x5e, 0xcd, 0x9d, 0xc9, 0x6d, 0x17, 0xcd, 0x3b, 0x65, 0x8a, 0x9d, 0xa5, 0x68, 0x76, 0x09, + 0x57, 0x40, 0x07, 0xe1, 0x84, 0xc6, 0xd2, 0x7e, 0x47, 0x2e, 0xb8, 0x05, 0xb7, 0x37, 0xfb, 0x9a, + 0x03, 0x37, 0xd9, 0xfa, 0x0e, 0x2c, 0x4c, 0xa3, 0x7b, 0x0b, 0x5f, 0x1f, 0x56, 0xac, 0x3d, 0xc9, + 0x3a, 0x6d, 0x95, 0xc6, 0x5e, 0x52, 0x19, 0x5f, 0x9b, 0x60, 0xe9, 0x6d, 0x99, 0xe4, 0x7b, 0x38, + 0x27, 0x81, 0x88, 0xf8, 0x1a, 0x80, 0x45, 0x82, 0x70, 0x16, 0x95, 0x24, 0x09, 0x5d, 0xa1, 0x12, + 0x41, 0x55, 0xe4, 0x7b, 0x97, 0x08, 0xaf, 0xdd, 0x42, 0x50, 0x07, 0x8b, 0x8c, 0xb7, 0xbb, 0xb3, + 0x3a, 0x00, 0xb1, 0x35, 0xae, 0xc5, 0x98, 0xe6, 0xb1, 0xf5, 0x8f, 0xf2, 0x38, 0xfb, 0x9a, 0xda, + 0xff, 0xf3, 0x35, 0x3d, 0x19, 0x81, 0xa5, 0x2b, 0x01, 0x80, 0x5d, 0x00, 0xec, 0xb2, 0xe6, 0xee, + 0x35, 0x20, 0x00, 0x73, 0x76, 0xc9, 0x87, 0xea, 0x29, 0xfd, 0xf6, 0xa7, 0x6f, 0x5a, 0xc3, 0xde, + 0x3e, 0x3e, 0xd3, 0x94, 0x93, 0x33, 0x4d, 0xf9, 0x75, 0xa6, 0x29, 0x47, 0xe7, 0x5a, 0xe3, 0xe4, + 0x5c, 0x6b, 0xfc, 0x3c, 0xd7, 0x1a, 0xbb, 0x1b, 0x33, 0x8f, 0xa2, 0x4a, 0xd9, 0x7a, 0xe4, 0xf9, + 0xac, 0x5e, 0x58, 0x07, 0xa3, 0xe7, 0xd6, 0xc7, 0xfa, 0xbf, 0x50, 0x3c, 0x12, 0x7f, 0x4e, 0x5c, + 0xe8, 0xd9, 0x9f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x81, 0x6e, 0xd4, 0xf2, 0x2a, 0x05, 0x00, 0x00, } func (m *PeriodLock) Marshal() (dAtA []byte, err error) { @@ -378,6 +391,13 @@ func (m *PeriodLock) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.RewardReceiverAddress) > 0 { + i -= len(m.RewardReceiverAddress) + copy(dAtA[i:], m.RewardReceiverAddress) + i = encodeVarintLock(dAtA, i, uint64(len(m.RewardReceiverAddress))) + i-- + dAtA[i] = 0x32 + } if len(m.Coins) > 0 { for iNdEx := len(m.Coins) - 1; iNdEx >= 0; iNdEx-- { { @@ -559,6 +579,10 @@ func (m *PeriodLock) Size() (n int) { n += 1 + l + sovLock(uint64(l)) } } + l = len(m.RewardReceiverAddress) + if l > 0 { + n += 1 + l + sovLock(uint64(l)) + } return n } @@ -788,6 +812,38 @@ func (m *PeriodLock) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field RewardReceiverAddress", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLock + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthLock + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthLock + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.RewardReceiverAddress = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipLock(dAtA[iNdEx:]) diff --git a/x/lockup/types/msgs.go b/x/lockup/types/msgs.go index 2085818a455..5ab999905d7 100644 --- a/x/lockup/types/msgs.go +++ b/x/lockup/types/msgs.go @@ -11,11 +11,12 @@ import ( // constants. const ( - TypeMsgLockTokens = "lock_tokens" - TypeMsgBeginUnlockingAll = "begin_unlocking_all" - TypeMsgBeginUnlocking = "begin_unlocking" - TypeMsgExtendLockup = "edit_lockup" - TypeForceUnlock = "force_unlock" + TypeMsgLockTokens = "lock_tokens" + TypeMsgBeginUnlockingAll = "begin_unlocking_all" + TypeMsgBeginUnlocking = "begin_unlocking" + TypeMsgExtendLockup = "edit_lockup" + TypeForceUnlock = "force_unlock" + TypeMsgSetRewardReceiverAddress = "set_reward_receiver_address" ) var _ sdk.Msg = &MsgLockTokens{} @@ -170,7 +171,7 @@ func (m MsgExtendLockup) GetSigners() []sdk.AccAddress { var _ sdk.Msg = &MsgForceUnlock{} -// NewMsgBeginUnlockingAll creates a message to begin unlocking tokens. +// NewMsgForceUnlock creates a message to force unlock tokens. func NewMsgForceUnlock(owner sdk.AccAddress, id uint64, coins sdk.Coins) *MsgForceUnlock { return &MsgForceUnlock{ Owner: owner.String(), @@ -180,7 +181,7 @@ func NewMsgForceUnlock(owner sdk.AccAddress, id uint64, coins sdk.Coins) *MsgFor } func (m MsgForceUnlock) Route() string { return RouterKey } -func (m MsgForceUnlock) Type() string { return TypeMsgBeginUnlockingAll } +func (m MsgForceUnlock) Type() string { return TypeForceUnlock } func (m MsgForceUnlock) ValidateBasic() error { _, err := sdk.AccAddressFromBech32(m.Owner) if err != nil { @@ -205,3 +206,39 @@ func (m MsgForceUnlock) GetSigners() []sdk.AccAddress { owner, _ := sdk.AccAddressFromBech32(m.Owner) return []sdk.AccAddress{owner} } + +// NewMsgSetRewardReceiverAddress creates a message for setting reward receiver address +func NewMsgSetRewardReceiverAddress(owner, rewardReceiver sdk.AccAddress, lockId uint64) *MsgSetRewardReceiverAddress { + return &MsgSetRewardReceiverAddress{ + Owner: owner.String(), + RewardReceiver: rewardReceiver.String(), + LockID: lockId, + } +} + +func (m MsgSetRewardReceiverAddress) Route() string { return RouterKey } +func (m MsgSetRewardReceiverAddress) Type() string { return TypeMsgSetRewardReceiverAddress } +func (m MsgSetRewardReceiverAddress) ValidateBasic() error { + _, err := sdk.AccAddressFromBech32(m.Owner) + if err != nil { + return errorsmod.Wrapf(sdkerrors.ErrInvalidAddress, "Invalid owner address (%s)", err) + } + _, err = sdk.AccAddressFromBech32(m.RewardReceiver) + if err != nil { + return errorsmod.Wrapf(sdkerrors.ErrInvalidAddress, "Invalid reward receiver address (%s)", err) + } + + if m.LockID <= 0 { + return errorsmod.Wrapf(sdkerrors.ErrInvalidRequest, "lock id should be larger than zero, was (%s)", err) + } + return nil +} + +func (m MsgSetRewardReceiverAddress) GetSignBytes() []byte { + return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(&m)) +} + +func (m MsgSetRewardReceiverAddress) GetSigners() []sdk.AccAddress { + owner, _ := sdk.AccAddressFromBech32(m.Owner) + return []sdk.AccAddress{owner} +} diff --git a/x/lockup/types/tx.pb.go b/x/lockup/types/tx.pb.go index 7ec63c60e7f..7943929a818 100644 --- a/x/lockup/types/tx.pb.go +++ b/x/lockup/types/tx.pb.go @@ -555,6 +555,110 @@ func (m *MsgForceUnlockResponse) GetSuccess() bool { return false } +type MsgSetRewardReceiverAddress struct { + Owner string `protobuf:"bytes,1,opt,name=owner,proto3" json:"owner,omitempty" yaml:"owner"` + LockID uint64 `protobuf:"varint,2,opt,name=lockID,proto3" json:"lockID,omitempty"` + RewardReceiver string `protobuf:"bytes,3,opt,name=reward_receiver,json=rewardReceiver,proto3" json:"reward_receiver,omitempty" yaml:"reward_receiver"` +} + +func (m *MsgSetRewardReceiverAddress) Reset() { *m = MsgSetRewardReceiverAddress{} } +func (m *MsgSetRewardReceiverAddress) String() string { return proto.CompactTextString(m) } +func (*MsgSetRewardReceiverAddress) ProtoMessage() {} +func (*MsgSetRewardReceiverAddress) Descriptor() ([]byte, []int) { + return fileDescriptor_bcdad5af0d24735f, []int{10} +} +func (m *MsgSetRewardReceiverAddress) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgSetRewardReceiverAddress) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgSetRewardReceiverAddress.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgSetRewardReceiverAddress) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgSetRewardReceiverAddress.Merge(m, src) +} +func (m *MsgSetRewardReceiverAddress) XXX_Size() int { + return m.Size() +} +func (m *MsgSetRewardReceiverAddress) XXX_DiscardUnknown() { + xxx_messageInfo_MsgSetRewardReceiverAddress.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgSetRewardReceiverAddress proto.InternalMessageInfo + +func (m *MsgSetRewardReceiverAddress) GetOwner() string { + if m != nil { + return m.Owner + } + return "" +} + +func (m *MsgSetRewardReceiverAddress) GetLockID() uint64 { + if m != nil { + return m.LockID + } + return 0 +} + +func (m *MsgSetRewardReceiverAddress) GetRewardReceiver() string { + if m != nil { + return m.RewardReceiver + } + return "" +} + +type MsgSetRewardReceiverAddressResponse struct { + Success bool `protobuf:"varint,1,opt,name=success,proto3" json:"success,omitempty"` +} + +func (m *MsgSetRewardReceiverAddressResponse) Reset() { *m = MsgSetRewardReceiverAddressResponse{} } +func (m *MsgSetRewardReceiverAddressResponse) String() string { return proto.CompactTextString(m) } +func (*MsgSetRewardReceiverAddressResponse) ProtoMessage() {} +func (*MsgSetRewardReceiverAddressResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_bcdad5af0d24735f, []int{11} +} +func (m *MsgSetRewardReceiverAddressResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgSetRewardReceiverAddressResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgSetRewardReceiverAddressResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgSetRewardReceiverAddressResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgSetRewardReceiverAddressResponse.Merge(m, src) +} +func (m *MsgSetRewardReceiverAddressResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgSetRewardReceiverAddressResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgSetRewardReceiverAddressResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgSetRewardReceiverAddressResponse proto.InternalMessageInfo + +func (m *MsgSetRewardReceiverAddressResponse) GetSuccess() bool { + if m != nil { + return m.Success + } + return false +} + func init() { proto.RegisterType((*MsgLockTokens)(nil), "osmosis.lockup.MsgLockTokens") proto.RegisterType((*MsgLockTokensResponse)(nil), "osmosis.lockup.MsgLockTokensResponse") @@ -566,56 +670,64 @@ func init() { proto.RegisterType((*MsgExtendLockupResponse)(nil), "osmosis.lockup.MsgExtendLockupResponse") proto.RegisterType((*MsgForceUnlock)(nil), "osmosis.lockup.MsgForceUnlock") proto.RegisterType((*MsgForceUnlockResponse)(nil), "osmosis.lockup.MsgForceUnlockResponse") + proto.RegisterType((*MsgSetRewardReceiverAddress)(nil), "osmosis.lockup.MsgSetRewardReceiverAddress") + proto.RegisterType((*MsgSetRewardReceiverAddressResponse)(nil), "osmosis.lockup.MsgSetRewardReceiverAddressResponse") } func init() { proto.RegisterFile("osmosis/lockup/tx.proto", fileDescriptor_bcdad5af0d24735f) } var fileDescriptor_bcdad5af0d24735f = []byte{ - // 696 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x55, 0xcd, 0x6e, 0xd3, 0x4c, - 0x14, 0x8d, 0x93, 0xaf, 0x5f, 0xcb, 0x6d, 0x49, 0xa9, 0x55, 0x68, 0x6a, 0x81, 0x5d, 0x46, 0xd0, - 0x04, 0xd4, 0x78, 0x48, 0x0a, 0x9b, 0xee, 0x08, 0x05, 0xa9, 0x52, 0x23, 0x21, 0xab, 0x95, 0x10, - 0x0b, 0x50, 0xec, 0x0e, 0x53, 0x2b, 0x89, 0xc7, 0xca, 0xd8, 0xa5, 0x7d, 0x05, 0x56, 0x2c, 0x79, - 0x01, 0x36, 0xb0, 0x41, 0xe2, 0x25, 0xba, 0xac, 0xc4, 0x86, 0x05, 0x4a, 0x51, 0xbb, 0x40, 0x62, - 0xd9, 0x27, 0x40, 0x33, 0x8e, 0x2d, 0xe7, 0x47, 0x4d, 0x85, 0x04, 0x62, 0x13, 0x7b, 0xe6, 0xdc, - 0x7b, 0xe6, 0x9e, 0x93, 0x7b, 0xc7, 0xb0, 0xc0, 0x78, 0x9b, 0x71, 0x97, 0xe3, 0x16, 0x73, 0x9a, - 0xa1, 0x8f, 0x83, 0x7d, 0xd3, 0xef, 0xb0, 0x80, 0xa9, 0xf9, 0x1e, 0x60, 0x46, 0x80, 0x36, 0x4f, - 0x19, 0x65, 0x12, 0xc2, 0xe2, 0x2d, 0x8a, 0xd2, 0xe6, 0x1a, 0x6d, 0xd7, 0x63, 0x58, 0xfe, 0xf6, - 0xb6, 0x74, 0xca, 0x18, 0x6d, 0x11, 0x2c, 0x57, 0x76, 0xf8, 0x0a, 0xef, 0x84, 0x9d, 0x46, 0xe0, - 0x32, 0x2f, 0xc6, 0x1d, 0xc9, 0x8c, 0xed, 0x06, 0x27, 0x78, 0xaf, 0x62, 0x93, 0xa0, 0x51, 0xc1, - 0x0e, 0x73, 0x63, 0x7c, 0x71, 0xa0, 0x22, 0xf1, 0x88, 0x20, 0xf4, 0x3e, 0x0b, 0x97, 0xeb, 0x9c, - 0x6e, 0x32, 0xa7, 0xb9, 0xc5, 0x9a, 0xc4, 0xe3, 0xea, 0x32, 0x4c, 0xb0, 0xd7, 0x1e, 0xe9, 0x14, - 0x94, 0x25, 0xa5, 0x74, 0xa9, 0x76, 0xe5, 0xac, 0x6b, 0xcc, 0x1c, 0x34, 0xda, 0xad, 0x35, 0x24, - 0xb7, 0x91, 0x15, 0xc1, 0xea, 0x2e, 0x4c, 0xc5, 0x65, 0x14, 0xb2, 0x4b, 0x4a, 0x69, 0xba, 0xba, - 0x68, 0x46, 0x75, 0x9a, 0x71, 0x9d, 0xe6, 0x7a, 0x2f, 0xa0, 0x56, 0x39, 0xec, 0x1a, 0x99, 0x9f, - 0x5d, 0x43, 0x8d, 0x53, 0x56, 0x58, 0xdb, 0x0d, 0x48, 0xdb, 0x0f, 0x0e, 0xce, 0xba, 0xc6, 0x6c, - 0xc4, 0x1f, 0x63, 0xe8, 0xdd, 0xb1, 0xa1, 0x58, 0x09, 0xbb, 0xda, 0x80, 0x09, 0x21, 0x86, 0x17, - 0x72, 0x4b, 0x39, 0x79, 0x4c, 0x24, 0xd7, 0x14, 0x72, 0xcd, 0x9e, 0x5c, 0xf3, 0x11, 0x73, 0xbd, - 0xda, 0x3d, 0x71, 0xcc, 0x87, 0x63, 0xa3, 0x44, 0xdd, 0x60, 0x37, 0xb4, 0x4d, 0x87, 0xb5, 0x71, - 0xcf, 0x9b, 0xe8, 0x51, 0xe6, 0x3b, 0x4d, 0x1c, 0x1c, 0xf8, 0x84, 0xcb, 0x04, 0x6e, 0x45, 0xcc, - 0x6b, 0xc6, 0x9b, 0x1f, 0x9f, 0xee, 0x6a, 0x23, 0x6c, 0x2a, 0x07, 0xd2, 0x15, 0x54, 0x84, 0xab, - 0x7d, 0x36, 0x59, 0x84, 0xfb, 0xcc, 0xe3, 0x44, 0xcd, 0x43, 0x76, 0x63, 0x5d, 0x7a, 0xf5, 0x9f, - 0x95, 0xdd, 0x58, 0x47, 0x14, 0xe6, 0xeb, 0x9c, 0xd6, 0x08, 0x75, 0xbd, 0x6d, 0x4f, 0x30, 0xb8, - 0x1e, 0x7d, 0xd8, 0x6a, 0x5d, 0xd4, 0xd6, 0xb5, 0xa2, 0xa8, 0x04, 0x0d, 0x54, 0x62, 0x0b, 0xba, - 0x72, 0xe8, 0xa5, 0x2b, 0xda, 0x82, 0xeb, 0xa3, 0x0e, 0x4a, 0x0a, 0xbb, 0x0f, 0x93, 0x51, 0x02, - 0x2f, 0x28, 0xd2, 0x37, 0xcd, 0xec, 0xef, 0x3f, 0xf3, 0x29, 0xe9, 0xb8, 0x6c, 0x47, 0x68, 0xb2, - 0xe2, 0x50, 0xf4, 0x4d, 0x81, 0xb9, 0x21, 0xda, 0x0b, 0xf7, 0x44, 0x64, 0x46, 0x36, 0x36, 0xe3, - 0x6f, 0xfc, 0x73, 0x2b, 0xc2, 0xaf, 0xe2, 0x79, 0x7e, 0xf9, 0x52, 0x66, 0x59, 0xbc, 0xa3, 0x97, - 0xb0, 0x38, 0xa4, 0x2e, 0x71, 0xac, 0x00, 0x93, 0x3c, 0x74, 0x1c, 0xc2, 0xb9, 0xd4, 0x39, 0x65, - 0xc5, 0x4b, 0xb5, 0x04, 0xb3, 0x61, 0x1c, 0x2e, 0xfc, 0x4a, 0x44, 0x0e, 0x6e, 0xa3, 0xcf, 0x0a, - 0xcc, 0xd6, 0x39, 0x7d, 0xbc, 0x1f, 0x10, 0x4f, 0x5a, 0x1b, 0xfa, 0xbf, 0xed, 0x5e, 0x7a, 0xc2, - 0x72, 0x7f, 0x72, 0xc2, 0xd0, 0x2a, 0x2c, 0x0c, 0x14, 0x3d, 0xde, 0x14, 0xf4, 0x51, 0x81, 0x7c, - 0x9d, 0xd3, 0x27, 0xac, 0xe3, 0x90, 0xc8, 0xcc, 0x7f, 0xb8, 0x4f, 0x50, 0x15, 0xae, 0xf5, 0x17, - 0x3b, 0x5e, 0x61, 0xf5, 0x4b, 0x0e, 0x72, 0x75, 0x4e, 0x55, 0x0b, 0x20, 0x75, 0x41, 0xde, 0x18, - 0x9c, 0xa3, 0xbe, 0x8b, 0x41, 0xbb, 0x7d, 0x2e, 0x9c, 0x9c, 0x4a, 0x61, 0x6e, 0xf8, 0x92, 0xb8, - 0x35, 0x22, 0x77, 0x28, 0x4a, 0x5b, 0xb9, 0x48, 0x54, 0x72, 0xd0, 0x0b, 0xc8, 0x0f, 0x4c, 0xf3, - 0xcd, 0xb1, 0xf9, 0xda, 0x9d, 0xb1, 0x21, 0x09, 0xff, 0x33, 0x98, 0xe9, 0xeb, 0x76, 0x63, 0x44, - 0x6a, 0x3a, 0x40, 0x2b, 0x8e, 0x09, 0x48, 0x98, 0xb7, 0x61, 0x3a, 0xdd, 0x5c, 0xfa, 0x88, 0xbc, - 0x14, 0xae, 0x2d, 0x9f, 0x8f, 0xc7, 0xb4, 0xb5, 0xcd, 0xc3, 0x13, 0x5d, 0x39, 0x3a, 0xd1, 0x95, - 0xef, 0x27, 0xba, 0xf2, 0xf6, 0x54, 0xcf, 0x1c, 0x9d, 0xea, 0x99, 0xaf, 0xa7, 0x7a, 0xe6, 0x79, - 0x35, 0xd5, 0x54, 0x3d, 0xae, 0x72, 0xab, 0x61, 0xf3, 0x78, 0x81, 0xf7, 0x2a, 0x0f, 0xf0, 0x7e, - 0xf2, 0x5d, 0x17, 0x4d, 0x66, 0xff, 0x2f, 0x47, 0x71, 0xf5, 0x57, 0x00, 0x00, 0x00, 0xff, 0xff, - 0x0f, 0x58, 0x00, 0x5a, 0xf6, 0x07, 0x00, 0x00, + // 791 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x56, 0x4d, 0x6f, 0xd3, 0x48, + 0x18, 0x8e, 0x93, 0x7e, 0xbe, 0xed, 0x26, 0x5b, 0xab, 0xdb, 0xa6, 0xde, 0x5d, 0xbb, 0xeb, 0xdd, + 0x6d, 0xb2, 0xbb, 0x8d, 0xbd, 0x49, 0xe1, 0xd2, 0x0b, 0x6a, 0x5a, 0x90, 0x2a, 0x35, 0x12, 0x32, + 0xad, 0x84, 0x38, 0x50, 0x39, 0xce, 0x30, 0xb5, 0x92, 0x78, 0x22, 0x8f, 0xdd, 0x0f, 0x89, 0x5f, + 0xc0, 0x89, 0x23, 0x67, 0x24, 0x2e, 0x70, 0x41, 0xe2, 0x4f, 0xf4, 0x58, 0x6e, 0x1c, 0x50, 0x8a, + 0xda, 0x03, 0x12, 0xc7, 0xfe, 0x02, 0xe4, 0xf1, 0x87, 0x9c, 0x8f, 0x26, 0x01, 0x09, 0xc4, 0xa5, + 0xf6, 0xcc, 0xfb, 0xbc, 0xcf, 0x3c, 0xcf, 0xe3, 0x99, 0x69, 0x60, 0x91, 0xd0, 0x26, 0xa1, 0x26, + 0x55, 0x1b, 0xc4, 0xa8, 0xbb, 0x2d, 0xd5, 0x39, 0x56, 0x5a, 0x36, 0x71, 0x08, 0x9f, 0x0e, 0x0a, + 0x8a, 0x5f, 0x10, 0xe6, 0x31, 0xc1, 0x84, 0x95, 0x54, 0xef, 0xcd, 0x47, 0x09, 0x73, 0x7a, 0xd3, + 0xb4, 0x88, 0xca, 0xfe, 0x06, 0x53, 0x22, 0x26, 0x04, 0x37, 0x90, 0xca, 0x46, 0x55, 0xf7, 0x91, + 0x5a, 0x73, 0x6d, 0xdd, 0x31, 0x89, 0x15, 0xd6, 0x0d, 0xc6, 0xac, 0x56, 0x75, 0x8a, 0xd4, 0xc3, + 0x62, 0x15, 0x39, 0x7a, 0x51, 0x35, 0x88, 0x19, 0xd6, 0x97, 0xba, 0x14, 0x79, 0x0f, 0xbf, 0x24, + 0xbf, 0x48, 0xc2, 0x4f, 0x15, 0x8a, 0x77, 0x88, 0x51, 0xdf, 0x25, 0x75, 0x64, 0x51, 0x7e, 0x05, + 0xc6, 0xc9, 0x91, 0x85, 0xec, 0x2c, 0xb7, 0xcc, 0xe5, 0xa7, 0xcb, 0x3f, 0x5f, 0xb5, 0xa5, 0xd9, + 0x13, 0xbd, 0xd9, 0x58, 0x97, 0xd9, 0xb4, 0xac, 0xf9, 0x65, 0xfe, 0x00, 0xa6, 0x42, 0x19, 0xd9, + 0xe4, 0x32, 0x97, 0x9f, 0x29, 0x2d, 0x29, 0xbe, 0x4e, 0x25, 0xd4, 0xa9, 0x6c, 0x05, 0x80, 0x72, + 0xf1, 0xb4, 0x2d, 0x25, 0x3e, 0xb5, 0x25, 0x3e, 0x6c, 0x59, 0x25, 0x4d, 0xd3, 0x41, 0xcd, 0x96, + 0x73, 0x72, 0xd5, 0x96, 0x32, 0x3e, 0x7f, 0x58, 0x93, 0x9f, 0x9d, 0x4b, 0x9c, 0x16, 0xb1, 0xf3, + 0x3a, 0x8c, 0x7b, 0x66, 0x68, 0x36, 0xb5, 0x9c, 0x62, 0xcb, 0xf8, 0x76, 0x15, 0xcf, 0xae, 0x12, + 0xd8, 0x55, 0x36, 0x89, 0x69, 0x95, 0xff, 0xf7, 0x96, 0x79, 0x79, 0x2e, 0xe5, 0xb1, 0xe9, 0x1c, + 0xb8, 0x55, 0xc5, 0x20, 0x4d, 0x35, 0xc8, 0xc6, 0x7f, 0x14, 0x68, 0xad, 0xae, 0x3a, 0x27, 0x2d, + 0x44, 0x59, 0x03, 0xd5, 0x7c, 0xe6, 0x75, 0xe9, 0xc9, 0xc7, 0xd7, 0xff, 0x0a, 0x7d, 0x62, 0x2a, + 0x38, 0x2c, 0x15, 0x39, 0x07, 0xbf, 0x74, 0xc4, 0xa4, 0x21, 0xda, 0x22, 0x16, 0x45, 0x7c, 0x1a, + 0x92, 0xdb, 0x5b, 0x2c, 0xab, 0x31, 0x2d, 0xb9, 0xbd, 0x25, 0x63, 0x98, 0xaf, 0x50, 0x5c, 0x46, + 0xd8, 0xb4, 0xf6, 0x2c, 0x8f, 0xc1, 0xb4, 0xf0, 0x46, 0xa3, 0x31, 0x6a, 0xac, 0xeb, 0x39, 0x4f, + 0x89, 0xdc, 0xa5, 0xa4, 0xea, 0xd1, 0x15, 0x5c, 0x2b, 0xae, 0x68, 0x17, 0x7e, 0xeb, 0xb7, 0x50, + 0x24, 0xec, 0x06, 0x4c, 0xfa, 0x0d, 0x34, 0xcb, 0xb1, 0xdc, 0x04, 0xa5, 0x73, 0xff, 0x29, 0x77, + 0x91, 0x6d, 0x92, 0x9a, 0xe7, 0x49, 0x0b, 0xa1, 0xf2, 0x7b, 0x0e, 0xe6, 0x7a, 0x68, 0x47, 0xde, + 0x13, 0x7e, 0x18, 0xc9, 0x30, 0x8c, 0xef, 0xf1, 0xe5, 0x56, 0xbd, 0xbc, 0x72, 0x83, 0xf2, 0x6a, + 0x31, 0x9b, 0x05, 0xef, 0x5d, 0xde, 0x87, 0xa5, 0x1e, 0x77, 0x51, 0x62, 0x59, 0x98, 0xa4, 0xae, + 0x61, 0x20, 0x4a, 0x99, 0xcf, 0x29, 0x2d, 0x1c, 0xf2, 0x79, 0xc8, 0xb8, 0x21, 0xdc, 0xcb, 0x2b, + 0x32, 0xd9, 0x3d, 0x2d, 0xbf, 0xe1, 0x20, 0x53, 0xa1, 0xf8, 0xf6, 0xb1, 0x83, 0x2c, 0x16, 0xad, + 0xdb, 0xfa, 0xea, 0xf4, 0xe2, 0x27, 0x2c, 0xf5, 0x2d, 0x4f, 0x98, 0xbc, 0x06, 0x8b, 0x5d, 0xa2, + 0x87, 0x87, 0x22, 0xbf, 0xe2, 0x20, 0x5d, 0xa1, 0xf8, 0x0e, 0xb1, 0x0d, 0xe4, 0x87, 0xf9, 0x03, + 0xef, 0x13, 0xb9, 0x04, 0x0b, 0x9d, 0x62, 0x47, 0x70, 0xf8, 0x9c, 0x83, 0x5f, 0x2b, 0x14, 0xdf, + 0x43, 0x8e, 0x86, 0x8e, 0x74, 0xbb, 0xa6, 0x21, 0x03, 0x99, 0x87, 0xc8, 0xde, 0xa8, 0xd5, 0x6c, + 0x6f, 0x5b, 0x8c, 0x6a, 0x77, 0x01, 0x26, 0x1a, 0xf1, 0x5d, 0x13, 0x8c, 0xf8, 0x4d, 0xc8, 0xd8, + 0x8c, 0x78, 0xdf, 0x0e, 0x98, 0xd9, 0x77, 0x9e, 0x2e, 0x0b, 0x57, 0x6d, 0x69, 0xc1, 0x67, 0xea, + 0x02, 0xc8, 0x5a, 0xda, 0xee, 0xd0, 0x22, 0xdf, 0x82, 0x3f, 0x07, 0x68, 0x1c, 0xee, 0xb2, 0xf4, + 0x76, 0x0c, 0x52, 0x15, 0x8a, 0x79, 0x0d, 0x20, 0xf6, 0x6f, 0xe0, 0xf7, 0xee, 0xdb, 0xa2, 0xe3, + 0xfa, 0x13, 0xfe, 0x1e, 0x58, 0x8e, 0x56, 0xc5, 0x30, 0xd7, 0x7b, 0x15, 0xfe, 0xd5, 0xa7, 0xb7, + 0x07, 0x25, 0xac, 0x8e, 0x82, 0x8a, 0x16, 0x7a, 0x08, 0xe9, 0xae, 0x3b, 0xeb, 0x8f, 0xa1, 0xfd, + 0xc2, 0x3f, 0x43, 0x21, 0x11, 0xff, 0x7d, 0x98, 0xed, 0x38, 0xd3, 0x52, 0x9f, 0xd6, 0x38, 0x40, + 0xc8, 0x0d, 0x01, 0x44, 0xcc, 0x7b, 0x30, 0x13, 0x3f, 0x42, 0x62, 0x9f, 0xbe, 0x58, 0x5d, 0x58, + 0x19, 0x5c, 0x8f, 0x68, 0x1f, 0x43, 0xf6, 0xda, 0x7d, 0xfb, 0x5f, 0x1f, 0x8e, 0xeb, 0xc0, 0xc2, + 0xda, 0x17, 0x80, 0xc3, 0xd5, 0xcb, 0x3b, 0xa7, 0x17, 0x22, 0x77, 0x76, 0x21, 0x72, 0x1f, 0x2e, + 0x44, 0xee, 0xe9, 0xa5, 0x98, 0x38, 0xbb, 0x14, 0x13, 0xef, 0x2e, 0xc5, 0xc4, 0x83, 0x52, 0xec, + 0xe0, 0x06, 0xc4, 0x85, 0x86, 0x5e, 0xa5, 0xe1, 0x40, 0x3d, 0x2c, 0xde, 0x54, 0x8f, 0xa3, 0xdf, + 0x4e, 0xde, 0x41, 0xae, 0x4e, 0xb0, 0xeb, 0x6e, 0xed, 0x73, 0x00, 0x00, 0x00, 0xff, 0xff, 0x88, + 0xbd, 0xd0, 0x58, 0x5a, 0x09, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -639,6 +751,8 @@ type MsgClient interface { // MsgEditLockup edits the existing lockups by lock ID ExtendLockup(ctx context.Context, in *MsgExtendLockup, opts ...grpc.CallOption) (*MsgExtendLockupResponse, error) ForceUnlock(ctx context.Context, in *MsgForceUnlock, opts ...grpc.CallOption) (*MsgForceUnlockResponse, error) + // SetRewardReceiverAddress edits the reward receiver for the given lock ID + SetRewardReceiverAddress(ctx context.Context, in *MsgSetRewardReceiverAddress, opts ...grpc.CallOption) (*MsgSetRewardReceiverAddressResponse, error) } type msgClient struct { @@ -694,6 +808,15 @@ func (c *msgClient) ForceUnlock(ctx context.Context, in *MsgForceUnlock, opts .. return out, nil } +func (c *msgClient) SetRewardReceiverAddress(ctx context.Context, in *MsgSetRewardReceiverAddress, opts ...grpc.CallOption) (*MsgSetRewardReceiverAddressResponse, error) { + out := new(MsgSetRewardReceiverAddressResponse) + err := c.cc.Invoke(ctx, "/osmosis.lockup.Msg/SetRewardReceiverAddress", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // MsgServer is the server API for Msg service. type MsgServer interface { // LockTokens lock tokens @@ -705,6 +828,8 @@ type MsgServer interface { // MsgEditLockup edits the existing lockups by lock ID ExtendLockup(context.Context, *MsgExtendLockup) (*MsgExtendLockupResponse, error) ForceUnlock(context.Context, *MsgForceUnlock) (*MsgForceUnlockResponse, error) + // SetRewardReceiverAddress edits the reward receiver for the given lock ID + SetRewardReceiverAddress(context.Context, *MsgSetRewardReceiverAddress) (*MsgSetRewardReceiverAddressResponse, error) } // UnimplementedMsgServer can be embedded to have forward compatible implementations. @@ -726,6 +851,9 @@ func (*UnimplementedMsgServer) ExtendLockup(ctx context.Context, req *MsgExtendL func (*UnimplementedMsgServer) ForceUnlock(ctx context.Context, req *MsgForceUnlock) (*MsgForceUnlockResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method ForceUnlock not implemented") } +func (*UnimplementedMsgServer) SetRewardReceiverAddress(ctx context.Context, req *MsgSetRewardReceiverAddress) (*MsgSetRewardReceiverAddressResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method SetRewardReceiverAddress not implemented") +} func RegisterMsgServer(s grpc1.Server, srv MsgServer) { s.RegisterService(&_Msg_serviceDesc, srv) @@ -821,6 +949,24 @@ func _Msg_ForceUnlock_Handler(srv interface{}, ctx context.Context, dec func(int return interceptor(ctx, in, info, handler) } +func _Msg_SetRewardReceiverAddress_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgSetRewardReceiverAddress) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).SetRewardReceiverAddress(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/osmosis.lockup.Msg/SetRewardReceiverAddress", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).SetRewardReceiverAddress(ctx, req.(*MsgSetRewardReceiverAddress)) + } + return interceptor(ctx, in, info, handler) +} + var _Msg_serviceDesc = grpc.ServiceDesc{ ServiceName: "osmosis.lockup.Msg", HandlerType: (*MsgServer)(nil), @@ -845,6 +991,10 @@ var _Msg_serviceDesc = grpc.ServiceDesc{ MethodName: "ForceUnlock", Handler: _Msg_ForceUnlock_Handler, }, + { + MethodName: "SetRewardReceiverAddress", + Handler: _Msg_SetRewardReceiverAddress_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "osmosis/lockup/tx.proto", @@ -1242,6 +1392,81 @@ func (m *MsgForceUnlockResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) return len(dAtA) - i, nil } +func (m *MsgSetRewardReceiverAddress) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgSetRewardReceiverAddress) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgSetRewardReceiverAddress) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.RewardReceiver) > 0 { + i -= len(m.RewardReceiver) + copy(dAtA[i:], m.RewardReceiver) + i = encodeVarintTx(dAtA, i, uint64(len(m.RewardReceiver))) + i-- + dAtA[i] = 0x1a + } + if m.LockID != 0 { + i = encodeVarintTx(dAtA, i, uint64(m.LockID)) + i-- + dAtA[i] = 0x10 + } + if len(m.Owner) > 0 { + i -= len(m.Owner) + copy(dAtA[i:], m.Owner) + i = encodeVarintTx(dAtA, i, uint64(len(m.Owner))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgSetRewardReceiverAddressResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgSetRewardReceiverAddressResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgSetRewardReceiverAddressResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Success { + i-- + if m.Success { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + func encodeVarintTx(dAtA []byte, offset int, v uint64) int { offset -= sovTx(v) base := offset @@ -1415,6 +1640,38 @@ func (m *MsgForceUnlockResponse) Size() (n int) { return n } +func (m *MsgSetRewardReceiverAddress) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Owner) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + if m.LockID != 0 { + n += 1 + sovTx(uint64(m.LockID)) + } + l = len(m.RewardReceiver) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + return n +} + +func (m *MsgSetRewardReceiverAddressResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Success { + n += 2 + } + return n +} + func sovTx(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -2438,6 +2695,209 @@ func (m *MsgForceUnlockResponse) Unmarshal(dAtA []byte) error { } return nil } +func (m *MsgSetRewardReceiverAddress) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgSetRewardReceiverAddress: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgSetRewardReceiverAddress: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Owner", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Owner = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field LockID", wireType) + } + m.LockID = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.LockID |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field RewardReceiver", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.RewardReceiver = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgSetRewardReceiverAddressResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgSetRewardReceiverAddressResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgSetRewardReceiverAddressResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Success", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Success = bool(v != 0) + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipTx(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0