From 7c87c876d7b54ea9318671f24937b5f8d01c45f5 Mon Sep 17 00:00:00 2001 From: mattverse Date: Wed, 24 May 2023 23:10:39 +0900 Subject: [PATCH 01/17] Add Reward Recepient to lock --- proto/osmosis/lockup/lock.proto | 11 +- proto/osmosis/lockup/tx.proto | 13 +- x/incentives/keeper/distribute.go | 32 +- x/incentives/keeper/distribute_test.go | 79 +++- x/incentives/keeper/suite_test.go | 15 + x/lockup/keeper/bench_test.go | 2 +- x/lockup/keeper/genesis_test.go | 77 ++-- x/lockup/keeper/lock.go | 31 +- x/lockup/keeper/lock_test.go | 85 +++- x/lockup/keeper/migration.go | 2 +- x/lockup/keeper/msg_server.go | 21 + x/lockup/keeper/synthetic_lock_test.go | 11 +- x/lockup/keeper/utils_test.go | 10 +- x/lockup/types/errors.go | 1 + x/lockup/types/lock.go | 13 +- x/lockup/types/lock.pb.go | 151 ++++--- x/lockup/types/msgs.go | 51 ++- x/lockup/types/tx.pb.go | 550 +++++++++++++++++++++++-- 18 files changed, 976 insertions(+), 179 deletions(-) diff --git a/proto/osmosis/lockup/lock.proto b/proto/osmosis/lockup/lock.proto index 9cbb84c15bb..dfcf6c039e2 100644 --- a/proto/osmosis/lockup/lock.proto +++ b/proto/osmosis/lockup/lock.proto @@ -21,9 +21,14 @@ message PeriodLock { // Owner is the account address of the lock owner. // Only the owner can modify the state of the lock. string owner = 2 [ (gogoproto.moretags) = "yaml:\"owner\"" ]; + // 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 = 3 + [ (gogoproto.moretags) = "yaml:\"reward_address\"" ]; // Duration is the time needed for a lock to mature after unlocking has // started. - google.protobuf.Duration duration = 3 [ + google.protobuf.Duration duration = 4 [ (gogoproto.nullable) = false, (gogoproto.stdduration) = true, (gogoproto.jsontag) = "duration,omitempty", @@ -32,13 +37,13 @@ message PeriodLock { // EndTime refers to the time at which the lock would mature and get deleted. // This value is first initialized when an unlock has started for the lock, // end time being block time + duration. - google.protobuf.Timestamp end_time = 4 [ + google.protobuf.Timestamp end_time = 5 [ (gogoproto.stdtime) = true, (gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"end_time\"" ]; // Coins are the tokens locked within the lock, kept in the module account. - repeated cosmos.base.v1beta1.Coin coins = 5 [ + repeated cosmos.base.v1beta1.Coin coins = 6 [ (gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins" ]; 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..3a54211e41b 100644 --- a/x/incentives/keeper/distribute.go +++ b/x/incentives/keeper/distribute.go @@ -158,38 +158,38 @@ 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 + rewardRecevierAddrToID map[string]int + idToBech32Addr []string + idToDecodedAddr []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, + rewardRecevierAddrToID: make(map[string]int), + idToBech32Addr: []string{}, + idToDecodedAddr: []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 { - if id, ok := d.lockOwnerAddrToID[owner]; ok { +func (d *distributionInfo) addLockRewards(rewardReceiver string, rewards sdk.Coins) error { + if id, ok := d.rewardRecevierAddrToID[rewardReceiver]; ok { oldDistrCoins := d.idToDistrCoins[id] d.idToDistrCoins[id] = rewards.Add(oldDistrCoins...) } else { id := d.nextID d.nextID += 1 - d.lockOwnerAddrToID[owner] = id - decodedOwnerAddr, err := sdk.AccAddressFromBech32(owner) + d.rewardRecevierAddrToID[rewardReceiver] = id + decodedOwnerAddr, err := sdk.AccAddressFromBech32(rewardReceiver) if err != nil { return err } - d.idToBech32Addr = append(d.idToBech32Addr, owner) + d.idToBech32Addr = append(d.idToBech32Addr, rewardReceiver) d.idToDecodedAddr = append(d.idToDecodedAddr, decodedOwnerAddr) d.idToDistrCoins = append(d.idToDistrCoins, rewards) } @@ -324,7 +324,7 @@ func (k Keeper) distributeInternal( continue } // update the amount for that address - err := distrInfo.addLockRewards(lock.Owner, distrCoins) + err := distrInfo.addLockRewards(lock.RewardReceiverAddress, 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..4c422368c79 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]) + 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..fd13de8ae0b 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, 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..5ad9d0efb4d 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: acc1.String(), + 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: acc1.String(), + 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: acc2.String(), + 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 16ec390dcba..e2ac491d6d4 100644 --- a/x/lockup/keeper/lock.go +++ b/x/lockup/keeper/lock.go @@ -144,7 +144,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. + lock := types.NewPeriodLock(ID, owner, owner, duration, time.Time{}, coins) // lock the coins without sending them to the lockup module account err := k.lock(ctx, lock, lock.Coins) @@ -448,6 +449,32 @@ func (k Keeper) unlockMaturedLockInternalLogic(ctx sdk.Context, lock types.Perio return nil } +// SetLockReceiver changes the reward recipient address to the given address. +func (k Keeper) SetLockRewardReceiverAddress(ctx sdk.Context, lockID uint64, owner, newRecepientAddress sdk.AccAddress) 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 lock.RewardReceiverAddress == newRecepientAddress.String() { + return types.ErrRewardReceiverIsSame + } + + lock.RewardReceiverAddress = newRecepientAddress.String() + + 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. @@ -793,7 +820,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.OwnerAddress(), 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 c1433f60211..31e4222f143 100644 --- a/x/lockup/keeper/lock_test.go +++ b/x/lockup/keeper/lock_test.go @@ -235,7 +235,7 @@ func (s *KeeperTestSuite) TestUnlock() { ctx := s.Ctx addr1 := sdk.AccAddress([]byte("addr1---------------")) - _ = types.NewPeriodLock(1, addr1, time.Second, time.Time{}, tc.fundAcc) + _ = types.NewPeriodLock(1, addr1, addr1, time.Second, time.Time{}, tc.fundAcc) // lock with balance s.FundAcc(addr1, tc.fundAcc) @@ -494,6 +494,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(addr1.String(), lock.RewardReceiverAddress) lockID := s.App.LockupKeeper.GetLastLockID(s.Ctx) s.Require().Equal(uint64(1), lockID) @@ -533,6 +534,88 @@ 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 + expectedError bool + }{ + { + name: "happy case", + isnotOwner: false, + lockID: 1, + useNewReceiverAddress: true, + expectedError: false, + }, + { + name: "error: caller of the function is not the owner", + isnotOwner: true, + lockID: 1, + useNewReceiverAddress: true, + expectedError: true, + }, + { + name: "error: lock id is invalid", + isnotOwner: false, + lockID: 2, + useNewReceiverAddress: true, + expectedError: true, + }, + { + name: "error: new receiver address is same as old", + isnotOwner: false, + lockID: 1, + useNewReceiverAddress: false, + expectedError: true, + }, + } + + 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) + + // create an account first + 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, addr1.String()) + + 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) + if tc.expectedError { + s.Require().Error(err) + } 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() diff --git a/x/lockup/keeper/migration.go b/x/lockup/keeper/migration.go index e8ac644ed7d..590eec3ff7a 100644 --- a/x/lockup/keeper/migration.go +++ b/x/lockup/keeper/migration.go @@ -94,7 +94,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, owner, 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 35755b464d6..c95e9c25e76 100644 --- a/x/lockup/keeper/msg_server.go +++ b/x/lockup/keeper/msg_server.go @@ -223,3 +223,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.Owner) + if err != nil { + return nil, err + } + + err = server.keeper.SetLockRewardReceiverAddress(ctx, msg.LockID, owner, newRewardRecepient) + 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/synthetic_lock_test.go b/x/lockup/keeper/synthetic_lock_test.go index 92781c184b6..17b866f3cac 100644 --- a/x/lockup/keeper/synthetic_lock_test.go +++ b/x/lockup/keeper/synthetic_lock_test.go @@ -49,11 +49,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: addr1.String(), + 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..99284a58260 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{}, 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{}, 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, 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, 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, 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 ee98a1ff567..29be95df8c2 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 and suffix") 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 24cd878115c..250f21bca0e 100644 --- a/x/lockup/types/lock.go +++ b/x/lockup/types/lock.go @@ -9,13 +9,14 @@ import ( ) // 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, reward_address sdk.AccAddress, duration time.Duration, endTime time.Time, coins sdk.Coins) PeriodLock { return PeriodLock{ - ID: ID, - Owner: owner.String(), - Duration: duration, - EndTime: endTime, - Coins: coins, + ID: ID, + Owner: owner.String(), + RewardReceiverAddress: reward_address.String(), + Duration: duration, + EndTime: endTime, + Coins: coins, } } diff --git a/x/lockup/types/lock.pb.go b/x/lockup/types/lock.pb.go index 996119cbb19..9a76d54b272 100644 --- a/x/lockup/types/lock.pb.go +++ b/x/lockup/types/lock.pb.go @@ -69,15 +69,19 @@ type PeriodLock struct { // Owner is the account address of the lock owner. // Only the owner can modify the state of the lock. Owner string `protobuf:"bytes,2,opt,name=owner,proto3" json:"owner,omitempty" yaml:"owner"` + // 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,3,opt,name=reward_receiver_address,json=rewardReceiverAddress,proto3" json:"reward_receiver_address,omitempty" yaml:"reward_address"` // Duration is the time needed for a lock to mature after unlocking has // started. - Duration time.Duration `protobuf:"bytes,3,opt,name=duration,proto3,stdduration" json:"duration,omitempty" yaml:"duration"` + Duration time.Duration `protobuf:"bytes,4,opt,name=duration,proto3,stdduration" json:"duration,omitempty" yaml:"duration"` // EndTime refers to the time at which the lock would mature and get deleted. // This value is first initialized when an unlock has started for the lock, // end time being block time + duration. - EndTime time.Time `protobuf:"bytes,4,opt,name=end_time,json=endTime,proto3,stdtime" json:"end_time" yaml:"end_time"` + EndTime time.Time `protobuf:"bytes,5,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"` + Coins github_com_cosmos_cosmos_sdk_types.Coins `protobuf:"bytes,6,rep,name=coins,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.Coins" json:"coins"` } func (m *PeriodLock) Reset() { *m = PeriodLock{} } @@ -127,6 +131,13 @@ func (m *PeriodLock) GetOwner() string { return "" } +func (m *PeriodLock) GetRewardReceiverAddress() string { + if m != nil { + return m.RewardReceiverAddress + } + return "" +} + func (m *PeriodLock) GetDuration() time.Duration { if m != nil { return m.Duration @@ -317,45 +328,48 @@ 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, + // 642 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x54, 0x3d, 0x6f, 0xd3, 0x40, + 0x18, 0x8e, 0x93, 0xa6, 0xb4, 0x57, 0x9a, 0x46, 0xa7, 0x56, 0xa4, 0x01, 0xec, 0xc8, 0x03, 0x8a, + 0x50, 0x6b, 0x93, 0x22, 0x16, 0x36, 0xdc, 0x30, 0x54, 0xea, 0x40, 0x4d, 0xc5, 0xc0, 0x62, 0xd9, + 0xbe, 0xc3, 0x3d, 0xd5, 0xf6, 0x19, 0x9f, 0xdd, 0xe2, 0x7f, 0xc0, 0xd8, 0x11, 0x24, 0x36, 0x36, + 0x7e, 0x01, 0x3f, 0xa1, 0x63, 0x47, 0xa6, 0x14, 0xb5, 0x1b, 0x63, 0x7f, 0x01, 0xba, 0x0f, 0xa7, + 0x1f, 0x08, 0x58, 0x10, 0x93, 0x73, 0xf7, 0xbe, 0xcf, 0xf3, 0xde, 0xfb, 0x3c, 0x8f, 0x02, 0x56, + 0x29, 0x4b, 0x28, 0x23, 0xcc, 0x8e, 0x69, 0xb8, 0x5f, 0x66, 0xe2, 0x63, 0x65, 0x39, 0x2d, 0x28, + 0xec, 0xa8, 0x92, 0x25, 0x4b, 0xfd, 0xe5, 0x88, 0x46, 0x54, 0x94, 0x6c, 0xfe, 0x4b, 0x76, 0xf5, + 0xf5, 0x88, 0xd2, 0x28, 0xc6, 0xb6, 0x38, 0x05, 0xe5, 0x1b, 0x1b, 0x95, 0xb9, 0x5f, 0x10, 0x9a, + 0xaa, 0xba, 0x71, 0xb3, 0x5e, 0x90, 0x04, 0xb3, 0xc2, 0x4f, 0xb2, 0x9a, 0x20, 0x14, 0x73, 0xec, + 0xc0, 0x67, 0xd8, 0x3e, 0x18, 0x05, 0xb8, 0xf0, 0x47, 0x76, 0x48, 0x89, 0x22, 0x30, 0xbf, 0xb6, + 0x00, 0x78, 0x81, 0x73, 0x42, 0xd1, 0x36, 0x0d, 0xf7, 0x61, 0x07, 0x34, 0xb7, 0xc6, 0x3d, 0x6d, + 0xa0, 0x0d, 0x67, 0xdc, 0xe6, 0xd6, 0x18, 0x3e, 0x00, 0x6d, 0x7a, 0x98, 0xe2, 0xbc, 0xd7, 0x1c, + 0x68, 0xc3, 0x79, 0xa7, 0x7b, 0x31, 0x31, 0x6e, 0x57, 0x7e, 0x12, 0x3f, 0x35, 0xc5, 0xb5, 0xe9, + 0xca, 0x32, 0xdc, 0x01, 0x77, 0x72, 0x7c, 0xe8, 0xe7, 0xc8, 0xcb, 0x71, 0x88, 0xc9, 0x01, 0xce, + 0x3d, 0x1f, 0xa1, 0x1c, 0x33, 0xd6, 0x6b, 0x09, 0xe4, 0xea, 0xc5, 0xc4, 0x58, 0x91, 0x48, 0xd5, + 0xa8, 0xea, 0xa6, 0xbb, 0x22, 0x2f, 0x5c, 0x05, 0x7c, 0x26, 0xef, 0xe1, 0x1e, 0x98, 0xab, 0x97, + 0xed, 0xcd, 0x0c, 0xb4, 0xe1, 0xc2, 0xc6, 0xaa, 0x25, 0xb7, 0xb5, 0xea, 0x6d, 0xad, 0xb1, 0x6a, + 0x70, 0x46, 0xc7, 0x13, 0xa3, 0xf1, 0x63, 0x62, 0xc0, 0x1a, 0xb2, 0x46, 0x13, 0x52, 0xe0, 0x24, + 0x2b, 0xaa, 0x8b, 0x89, 0xb1, 0x24, 0x07, 0xd7, 0x35, 0xf3, 0xc3, 0xa9, 0xa1, 0xb9, 0x53, 0x76, + 0xe8, 0x82, 0x39, 0x9c, 0x22, 0x8f, 0x4b, 0xd7, 0x6b, 0x8b, 0x49, 0xfd, 0x5f, 0x26, 0xed, 0xd6, + 0xba, 0x3a, 0x77, 0xf9, 0xa8, 0x4b, 0xd2, 0x1a, 0x69, 0x1e, 0x71, 0xd2, 0x5b, 0x38, 0x45, 0xbc, + 0x15, 0xfa, 0xa0, 0xcd, 0x55, 0x66, 0xbd, 0xd9, 0x41, 0x4b, 0x3c, 0x5d, 0xfa, 0x60, 0x71, 0x1f, + 0x2c, 0xe5, 0x83, 0xb5, 0x49, 0x49, 0xea, 0x3c, 0xe2, 0x7c, 0x5f, 0x4e, 0x8d, 0x61, 0x44, 0x8a, + 0xbd, 0x32, 0xb0, 0x42, 0x9a, 0xd8, 0xca, 0x34, 0xf9, 0x59, 0x67, 0x68, 0xdf, 0x2e, 0xaa, 0x0c, + 0x33, 0x01, 0x60, 0xae, 0x64, 0x36, 0x3f, 0x36, 0x41, 0x67, 0xa7, 0xc4, 0x79, 0xb5, 0x49, 0x53, + 0x44, 0xc4, 0x26, 0xcf, 0xc1, 0x12, 0x8f, 0x93, 0xf7, 0x96, 0x5f, 0x7b, 0x1c, 0x23, 0xbc, 0xec, + 0x6c, 0xdc, 0xb7, 0xae, 0xc7, 0xcd, 0xe2, 0x6e, 0x0b, 0xf0, 0x6e, 0x95, 0x61, 0x77, 0x31, 0xbe, + 0x7a, 0x84, 0xcb, 0xa0, 0x8d, 0x70, 0x4a, 0x13, 0xe9, 0xba, 0x2b, 0x0f, 0x5c, 0xa6, 0xa9, 0x21, + 0xad, 0xbf, 0x19, 0x72, 0x43, 0xa5, 0xdf, 0x49, 0xff, 0x0a, 0xcc, 0x4f, 0x13, 0xab, 0x5c, 0xfe, + 0x93, 0xf6, 0xf7, 0x14, 0x6b, 0x57, 0xb2, 0x4e, 0xa1, 0x52, 0xfc, 0x4b, 0x2a, 0xf3, 0x53, 0x13, + 0x2c, 0xbe, 0xac, 0xd2, 0x62, 0x0f, 0x17, 0x24, 0x14, 0xc9, 0x5e, 0x03, 0xb0, 0x4c, 0x11, 0xce, + 0xe3, 0x8a, 0xa4, 0x91, 0x27, 0x54, 0x22, 0x48, 0x25, 0xbd, 0x7b, 0x59, 0xe1, 0xbd, 0x5b, 0x08, + 0x1a, 0x60, 0x81, 0x71, 0xb8, 0x77, 0x55, 0x07, 0x20, 0xae, 0xc6, 0xb5, 0x18, 0xd3, 0xcc, 0xb4, + 0xfe, 0x51, 0x66, 0xfe, 0x5b, 0xe2, 0x1f, 0x8e, 0xc0, 0xe2, 0xb5, 0x00, 0xc0, 0x0e, 0x00, 0x4e, + 0x55, 0x73, 0x77, 0x1b, 0x10, 0x80, 0x59, 0xa7, 0xe2, 0x8f, 0xea, 0x6a, 0xfd, 0x99, 0xf7, 0x9f, + 0xf5, 0x86, 0xb3, 0x7d, 0x7c, 0xa6, 0x6b, 0x27, 0x67, 0xba, 0xf6, 0xfd, 0x4c, 0xd7, 0x8e, 0xce, + 0xf5, 0xc6, 0xc9, 0xb9, 0xde, 0xf8, 0x76, 0xae, 0x37, 0x5e, 0x6f, 0x5c, 0x09, 0xae, 0x4a, 0xd9, + 0x7a, 0xec, 0x07, 0xac, 0x3e, 0xd8, 0x07, 0xa3, 0x27, 0xf6, 0xbb, 0xfa, 0x2f, 0x50, 0x04, 0x39, + 0x98, 0x15, 0x0b, 0x3d, 0xfe, 0x19, 0x00, 0x00, 0xff, 0xff, 0x22, 0xa6, 0xf3, 0xd7, 0x21, 0x05, + 0x00, 0x00, } func (m *PeriodLock) Marshal() (dAtA []byte, err error) { @@ -389,7 +403,7 @@ func (m *PeriodLock) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintLock(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x2a + dAtA[i] = 0x32 } } n1, err1 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.EndTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.EndTime):]) @@ -399,7 +413,7 @@ func (m *PeriodLock) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= n1 i = encodeVarintLock(dAtA, i, uint64(n1)) i-- - dAtA[i] = 0x22 + dAtA[i] = 0x2a n2, err2 := github_com_gogo_protobuf_types.StdDurationMarshalTo(m.Duration, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdDuration(m.Duration):]) if err2 != nil { return 0, err2 @@ -407,7 +421,14 @@ func (m *PeriodLock) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= n2 i = encodeVarintLock(dAtA, i, uint64(n2)) i-- - dAtA[i] = 0x1a + dAtA[i] = 0x22 + 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] = 0x1a + } if len(m.Owner) > 0 { i -= len(m.Owner) copy(dAtA[i:], m.Owner) @@ -549,6 +570,10 @@ func (m *PeriodLock) Size() (n int) { if l > 0 { n += 1 + l + sovLock(uint64(l)) } + l = len(m.RewardReceiverAddress) + if l > 0 { + n += 1 + l + sovLock(uint64(l)) + } l = github_com_gogo_protobuf_types.SizeOfStdDuration(m.Duration) n += 1 + l + sovLock(uint64(l)) l = github_com_gogo_protobuf_types.SizeOfStdTime(m.EndTime) @@ -689,6 +714,38 @@ func (m *PeriodLock) Unmarshal(dAtA []byte) error { m.Owner = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 3: + 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 + case 4: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Duration", wireType) } @@ -721,7 +778,7 @@ func (m *PeriodLock) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 4: + case 5: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field EndTime", wireType) } @@ -754,7 +811,7 @@ func (m *PeriodLock) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 5: + case 6: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Coins", wireType) } diff --git a/x/lockup/types/msgs.go b/x/lockup/types/msgs.go index 2085818a455..0c2f7187e8b 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} } + +// NewMsgBeginUnlockingAll creates a message to begin unlocking tokens. +func NewMsgMsgSetRewardReceiverAddress(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 owner address (%s)", err) + } + + if m.LockID <= 0 { + return errorsmod.Wrapf(sdkerrors.ErrInvalidRequest, "lock id should be bigger than 1 (%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 From 6b03538b54d8bcc565ba4cc8cf8c22374fcea822 Mon Sep 17 00:00:00 2001 From: mattverse Date: Wed, 24 May 2023 23:16:10 +0900 Subject: [PATCH 02/17] Add changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7e605d96a7e..25a6ccc8a62 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. ### Misc Improvements From a4b81a1c4c7eb9a9ecc36141a919f925c4252dd8 Mon Sep 17 00:00:00 2001 From: mattverse Date: Thu, 25 May 2023 16:24:42 +0900 Subject: [PATCH 03/17] Store receiver if receiver is lock owner --- x/incentives/keeper/distribute.go | 8 +++++++- x/incentives/keeper/suite_test.go | 2 +- x/lockup/keeper/bench_test.go | 2 +- x/lockup/keeper/genesis_test.go | 6 +++--- x/lockup/keeper/lock.go | 18 ++++++++++++------ x/lockup/keeper/lock_test.go | 8 ++++---- x/lockup/keeper/migration.go | 2 +- x/lockup/keeper/msg_server.go | 2 +- x/lockup/keeper/synthetic_lock_test.go | 2 +- x/lockup/keeper/utils_test.go | 10 +++++----- x/lockup/types/lock.go | 4 ++-- 11 files changed, 38 insertions(+), 26 deletions(-) diff --git a/x/incentives/keeper/distribute.go b/x/incentives/keeper/distribute.go index 3a54211e41b..aee6a277578 100644 --- a/x/incentives/keeper/distribute.go +++ b/x/incentives/keeper/distribute.go @@ -324,7 +324,13 @@ func (k Keeper) distributeInternal( continue } // update the amount for that address - err := distrInfo.addLockRewards(lock.RewardReceiverAddress, 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(rewardReceiver, distrCoins) if err != nil { return nil, err } diff --git a/x/incentives/keeper/suite_test.go b/x/incentives/keeper/suite_test.go index 4c422368c79..9aa0df5364a 100644 --- a/x/incentives/keeper/suite_test.go +++ b/x/incentives/keeper/suite_test.go @@ -93,7 +93,7 @@ func (s *KeeperTestSuite) SetupChangeRewardReceiver(changeRewardReceivers []chan 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]) + err = s.App.LockupKeeper.SetLockRewardReceiverAddress(s.Ctx, changeRewardReceiver.lockId, lock.OwnerAddress(), accs[changeRewardReceiver.newReceiverAccIndex].String()) s.Require().NoError(err) } } diff --git a/x/lockup/keeper/bench_test.go b/x/lockup/keeper/bench_test.go index fd13de8ae0b..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, 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 5ad9d0efb4d..637f975d4cd 100644 --- a/x/lockup/keeper/genesis_test.go +++ b/x/lockup/keeper/genesis_test.go @@ -26,7 +26,7 @@ var ( { ID: 1, Owner: acc1.String(), - RewardReceiverAddress: acc1.String(), + RewardReceiverAddress: "", Duration: time.Second, EndTime: time.Time{}, Coins: sdk.Coins{sdk.NewInt64Coin("foo", 10000000)}, @@ -95,7 +95,7 @@ func TestExportGenesis(t *testing.T) { { ID: 1, Owner: acc1.String(), - RewardReceiverAddress: acc1.String(), + RewardReceiverAddress: "", Duration: time.Second, EndTime: time.Time{}, Coins: sdk.Coins{sdk.NewInt64Coin("foo", 10000000)}, @@ -103,7 +103,7 @@ func TestExportGenesis(t *testing.T) { { ID: 11, Owner: acc2.String(), - RewardReceiverAddress: acc2.String(), + RewardReceiverAddress: "", Duration: time.Second * 5, EndTime: time.Time{}, Coins: sdk.Coins{sdk.NewInt64Coin("foo", 5000000)}, diff --git a/x/lockup/keeper/lock.go b/x/lockup/keeper/lock.go index e2ac491d6d4..7b19684edf0 100644 --- a/x/lockup/keeper/lock.go +++ b/x/lockup/keeper/lock.go @@ -144,8 +144,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. - // the reward receiver is set as the owner by default when creating a lock. - lock := types.NewPeriodLock(ID, owner, 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) @@ -450,7 +450,8 @@ func (k Keeper) unlockMaturedLockInternalLogic(ctx sdk.Context, lock types.Perio } // SetLockReceiver changes the reward recipient address to the given address. -func (k Keeper) SetLockRewardReceiverAddress(ctx sdk.Context, lockID uint64, owner, newRecepientAddress sdk.AccAddress) error { +// 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 @@ -461,11 +462,16 @@ func (k Keeper) SetLockRewardReceiverAddress(ctx sdk.Context, lockID uint64, own return types.ErrNotLockOwner } - if lock.RewardReceiverAddress == newRecepientAddress.String() { + // if the given receiver address is same as the lock owner, we store an empty string instead. + if lock.Owner == newReceiverAddress { + newReceiverAddress = "" + } + + if lock.RewardReceiverAddress == newReceiverAddress { return types.ErrRewardReceiverIsSame } - lock.RewardReceiverAddress = newRecepientAddress.String() + lock.RewardReceiverAddress = newReceiverAddress err = k.setLock(ctx, *lock) if err != nil { @@ -820,7 +826,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.OwnerAddress(), lock.Duration, lock.EndTime, coins) + splitLock := types.NewPeriodLock(splitLockID, lock.OwnerAddress(), lock.OwnerAddress().String(), 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 31e4222f143..4568f14eaef 100644 --- a/x/lockup/keeper/lock_test.go +++ b/x/lockup/keeper/lock_test.go @@ -235,7 +235,7 @@ func (s *KeeperTestSuite) TestUnlock() { ctx := s.Ctx addr1 := sdk.AccAddress([]byte("addr1---------------")) - _ = types.NewPeriodLock(1, addr1, addr1, time.Second, time.Time{}, tc.fundAcc) + _ = types.NewPeriodLock(1, addr1, addr1.String(), time.Second, time.Time{}, tc.fundAcc) // lock with balance s.FundAcc(addr1, tc.fundAcc) @@ -494,7 +494,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(addr1.String(), lock.RewardReceiverAddress) + s.Require().Equal("", lock.RewardReceiverAddress) lockID := s.App.LockupKeeper.GetLastLockID(s.Ctx) s.Require().Equal(uint64(1), lockID) @@ -586,7 +586,7 @@ func (s *KeeperTestSuite) TestSetLockRewardReceiverAddress() { s.Require().NoError(err) // check that the reward receiver is the lock owner by default - s.Require().Equal(lock.RewardReceiverAddress, addr1.String()) + s.Require().Equal(lock.RewardReceiverAddress, "") owner := addr1 if tc.isnotOwner { @@ -601,7 +601,7 @@ func (s *KeeperTestSuite) TestSetLockRewardReceiverAddress() { // System under test // now change the reward receiver state - err = s.App.LockupKeeper.SetLockRewardReceiverAddress(s.Ctx, tc.lockID, owner, newReceiver) + err = s.App.LockupKeeper.SetLockRewardReceiverAddress(s.Ctx, tc.lockID, owner, newReceiver.String()) if tc.expectedError { s.Require().Error(err) } else { diff --git a/x/lockup/keeper/migration.go b/x/lockup/keeper/migration.go index 590eec3ff7a..e8bd2c99be4 100644 --- a/x/lockup/keeper/migration.go +++ b/x/lockup/keeper/migration.go @@ -94,7 +94,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, owner, normalizedDuration, time.Time{}, lock.Coins) + normalLock = types.NewPeriodLock(normalID, owner, owner.String(), 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 c95e9c25e76..812109f5a29 100644 --- a/x/lockup/keeper/msg_server.go +++ b/x/lockup/keeper/msg_server.go @@ -237,7 +237,7 @@ func (server msgServer) SetRewardReceiverAddress(goCtx context.Context, msg *typ return nil, err } - err = server.keeper.SetLockRewardReceiverAddress(ctx, msg.LockID, owner, newRewardRecepient) + err = server.keeper.SetLockRewardReceiverAddress(ctx, msg.LockID, owner, newRewardRecepient.String()) if err != nil { return &types.MsgSetRewardReceiverAddressResponse{Success: false}, errorsmod.Wrap(sdkerrors.ErrInvalidRequest, err.Error()) } diff --git a/x/lockup/keeper/synthetic_lock_test.go b/x/lockup/keeper/synthetic_lock_test.go index 17b866f3cac..bd3953d82e8 100644 --- a/x/lockup/keeper/synthetic_lock_test.go +++ b/x/lockup/keeper/synthetic_lock_test.go @@ -51,7 +51,7 @@ func (s *KeeperTestSuite) TestSyntheticLockupCreateGetDeleteAccumulation() { { ID: 1, Owner: addr1.String(), - RewardReceiverAddress: addr1.String(), + RewardReceiverAddress: "", Duration: time.Second, EndTime: time.Time{}, Coins: coins, diff --git a/x/lockup/keeper/utils_test.go b/x/lockup/keeper/utils_test.go index 99284a58260..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{}, 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{}, 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, 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, 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, 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/lock.go b/x/lockup/types/lock.go index 250f21bca0e..9f60cf80528 100644 --- a/x/lockup/types/lock.go +++ b/x/lockup/types/lock.go @@ -9,11 +9,11 @@ import ( ) // NewPeriodLock returns a new instance of period lock. -func NewPeriodLock(ID uint64, owner, reward_address 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 { return PeriodLock{ ID: ID, Owner: owner.String(), - RewardReceiverAddress: reward_address.String(), + RewardReceiverAddress: reward_address, Duration: duration, EndTime: endTime, Coins: coins, From 74e21924ba055524c4d51199acfaa21017354177 Mon Sep 17 00:00:00 2001 From: mattverse Date: Fri, 26 May 2023 00:23:25 +0900 Subject: [PATCH 04/17] Add defense in depth --- x/lockup/types/lock.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/x/lockup/types/lock.go b/x/lockup/types/lock.go index 9f60cf80528..16333257c1c 100644 --- a/x/lockup/types/lock.go +++ b/x/lockup/types/lock.go @@ -10,6 +10,10 @@ import ( // NewPeriodLock returns a new instance of period lock. 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 = "" + } return PeriodLock{ ID: ID, Owner: owner.String(), From a46f00a602e02559ffd74bb05cca2d07f7675d19 Mon Sep 17 00:00:00 2001 From: mattverse Date: Fri, 26 May 2023 14:28:22 +0900 Subject: [PATCH 05/17] Debuggoing.. --- x/incentives/keeper/distribute.go | 3 +++ x/lockup/keeper/lock.go | 1 + x/lockup/keeper/store.go | 8 ++++++++ 3 files changed, 12 insertions(+) diff --git a/x/incentives/keeper/distribute.go b/x/incentives/keeper/distribute.go index aee6a277578..a2f005cf2d4 100644 --- a/x/incentives/keeper/distribute.go +++ b/x/incentives/keeper/distribute.go @@ -230,6 +230,7 @@ func (k Keeper) doDistributionSends(ctx sdk.Context, distrs *distributionInfo) e func (k Keeper) distributeSyntheticInternal( ctx sdk.Context, gauge types.Gauge, locks []lockuptypes.PeriodLock, distrInfo *distributionInfo, ) (sdk.Coins, error) { + ctx.Logger().Error("HERE") qualifiedLocks := k.lk.GetLocksLongerThanDurationDenom(ctx, gauge.DistributeTo.Denom, gauge.DistributeTo.Duration) // map from lockID to present index in resultant list @@ -422,7 +423,9 @@ func (k Keeper) Distribute(ctx sdk.Context, gauges []types.Gauge) (sdk.Coins, er // send based on synthetic lockup coins if it's distributing to synthetic lockups var err error if lockuptypes.IsSyntheticDenom(gauge.DistributeTo.Denom) { + ctx.Logger().Error(fmt.Sprintf("gauge is %s", gauge.DistributeTo.Duration.String())) // TODO: add test case to cover this + ctx.Logger().Error("here") gaugeDistributedCoins, err = k.distributeSyntheticInternal(ctx, gauge, filteredLocks, &distrInfo) } else { gaugeDistributedCoins, err = k.distributeInternal(ctx, gauge, filteredLocks, &distrInfo) diff --git a/x/lockup/keeper/lock.go b/x/lockup/keeper/lock.go index 7b19684edf0..f458e538bb5 100644 --- a/x/lockup/keeper/lock.go +++ b/x/lockup/keeper/lock.go @@ -772,6 +772,7 @@ func (k Keeper) removeTokensFromLock(ctx sdk.Context, lock *types.PeriodLock, co // setLock is a utility to store lock object into the store. func (k Keeper) setLock(ctx sdk.Context, lock types.PeriodLock) error { + ctx.Logger().Error(fmt.Sprintf("setting lock with id and durtion of %d %s", lock.ID, lock.Duration.String())) store := ctx.KVStore(k.storeKey) bz, err := proto.Marshal(&lock) if err != nil { diff --git a/x/lockup/keeper/store.go b/x/lockup/keeper/store.go index ff7494c2f44..51aa969af22 100644 --- a/x/lockup/keeper/store.go +++ b/x/lockup/keeper/store.go @@ -230,6 +230,14 @@ func (k Keeper) GetLockedDenom(ctx sdk.Context, denom string, duration time.Dura // GetLocksLongerThanDurationDenom Returns the locks whose unlock duration is longer than duration. func (k Keeper) GetLocksLongerThanDurationDenom(ctx sdk.Context, denom string, duration time.Duration) []types.PeriodLock { + lastId := k.GetLastLockID(ctx) + for i := uint64(0); i < lastId; i++ { + lock, err := k.GetLockByID(ctx, i) + if err != nil { + ctx.Logger().Error(fmt.Sprintf("ERR!!!! %s", err.Error())) + } + ctx.Logger().Error(fmt.Sprintf("lock is id %d duration %s", lock.ID, lock.Duration.String())) + } // returns both unlocking started and not started unlockings := k.getLocksFromIterator(ctx, k.LockIteratorLongerThanDurationDenom(ctx, true, denom, duration)) notUnlockings := k.getLocksFromIterator(ctx, k.LockIteratorLongerThanDurationDenom(ctx, false, denom, duration)) From 5c9db52b1161fbc2c26f84c9de49de6adf84a8bc Mon Sep 17 00:00:00 2001 From: mattverse Date: Fri, 26 May 2023 14:54:41 +0900 Subject: [PATCH 06/17] Add debug --- x/lockup/keeper/lock.go | 1 + 1 file changed, 1 insertion(+) diff --git a/x/lockup/keeper/lock.go b/x/lockup/keeper/lock.go index f458e538bb5..3758e8d1e6b 100644 --- a/x/lockup/keeper/lock.go +++ b/x/lockup/keeper/lock.go @@ -551,6 +551,7 @@ func (k Keeper) ExtendLockup(ctx sdk.Context, lockID uint64, owner sdk.AccAddres // them all correctly. This utilizes batch optimizations to improve efficiency, // as this becomes a bottleneck at chain initialization & upgrades. func (k Keeper) InitializeAllLocks(ctx sdk.Context, locks []types.PeriodLock) error { + ctx.Logger().Error("INITIALIZING ALL LOCKS") // index by coin.Denom, them duration -> amt // We accumulate the accumulation store entries separately, // to avoid hitting the myriad of slowdowns in the SDK iterator creation process. From 4454c4246c39e5c0bc3ef608427fff472299a650 Mon Sep 17 00:00:00 2001 From: mattverse Date: Fri, 26 May 2023 18:16:38 +0900 Subject: [PATCH 07/17] More logs --- x/incentives/keeper/distribute.go | 43 ++++++++++++++----------- x/lockup/keeper/iterator.go | 2 ++ x/lockup/keeper/lock.go | 1 - x/lockup/keeper/lock_test.go | 4 ++- x/lockup/keeper/migration.go | 2 +- x/lockup/keeper/store.go | 14 ++++----- x/superfluid/keeper/migrate_test.go | 49 ++++++++++++++++------------- 7 files changed, 64 insertions(+), 51 deletions(-) diff --git a/x/incentives/keeper/distribute.go b/x/incentives/keeper/distribute.go index a2f005cf2d4..e52cc51c0c5 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 - rewardRecevierAddrToID 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, - rewardRecevierAddrToID: 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(rewardReceiver string, rewards sdk.Coins) error { - if id, ok := d.rewardRecevierAddrToID[rewardReceiver]; ok { +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.rewardRecevierAddrToID[rewardReceiver] = id - decodedOwnerAddr, err := sdk.AccAddressFromBech32(rewardReceiver) + d.lockOwnerAddrToID[owner] = id + decodedRewardReceiverAddr, err := sdk.AccAddressFromBech32(rewardReceiver) if err != nil { return err } d.idToBech32Addr = append(d.idToBech32Addr, rewardReceiver) - d.idToDecodedAddr = append(d.idToDecodedAddr, decodedOwnerAddr) + d.idToDecodedRewardReceiverAddr = append(d.idToDecodedRewardReceiverAddr, decodedRewardReceiverAddr) d.idToDistrCoins = append(d.idToDistrCoins, rewards) } return nil @@ -198,13 +202,14 @@ func (d *distributionInfo) addLockRewards(rewardReceiver string, rewards sdk.Coi // 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 @@ -331,7 +336,7 @@ func (k Keeper) distributeInternal( if rewardReceiver == "" { rewardReceiver = lock.Owner } - err := distrInfo.addLockRewards(rewardReceiver, distrCoins) + err := distrInfo.addLockRewards(lock.Owner, rewardReceiver, distrCoins) if err != nil { return nil, err } diff --git a/x/lockup/keeper/iterator.go b/x/lockup/keeper/iterator.go index 31a22088b2d..76e608f94aa 100644 --- a/x/lockup/keeper/iterator.go +++ b/x/lockup/keeper/iterator.go @@ -1,6 +1,7 @@ package keeper import ( + "fmt" "time" db "github.com/tendermint/tm-db" @@ -184,6 +185,7 @@ func (k Keeper) getLocksFromIterator(ctx sdk.Context, iterator db.Iterator) []ty defer iterator.Close() for ; iterator.Valid(); iterator.Next() { lockID := sdk.BigEndianToUint64(iterator.Value()) + ctx.Logger().Error(fmt.Sprintf("getting locks from iterator with lock id: %d", lockID)) lock, err := k.GetLockByID(ctx, lockID) if err != nil { panic(err) diff --git a/x/lockup/keeper/lock.go b/x/lockup/keeper/lock.go index 3758e8d1e6b..d49950ab78a 100644 --- a/x/lockup/keeper/lock.go +++ b/x/lockup/keeper/lock.go @@ -773,7 +773,6 @@ func (k Keeper) removeTokensFromLock(ctx sdk.Context, lock *types.PeriodLock, co // setLock is a utility to store lock object into the store. func (k Keeper) setLock(ctx sdk.Context, lock types.PeriodLock) error { - ctx.Logger().Error(fmt.Sprintf("setting lock with id and durtion of %d %s", lock.ID, lock.Duration.String())) store := ctx.KVStore(k.storeKey) bz, err := proto.Marshal(&lock) if err != nil { diff --git a/x/lockup/keeper/lock_test.go b/x/lockup/keeper/lock_test.go index 4568f14eaef..272e9b9c82d 100644 --- a/x/lockup/keeper/lock_test.go +++ b/x/lockup/keeper/lock_test.go @@ -235,7 +235,9 @@ func (s *KeeperTestSuite) TestUnlock() { ctx := s.Ctx addr1 := sdk.AccAddress([]byte("addr1---------------")) - _ = types.NewPeriodLock(1, addr1, addr1.String(), time.Second, time.Time{}, tc.fundAcc) + lock := types.NewPeriodLock(1, addr1, addr1.String(), time.Second, time.Time{}, tc.fundAcc) + fmt.Println("----") + fmt.Println(lock.String()) // lock with balance s.FundAcc(addr1, tc.fundAcc) diff --git a/x/lockup/keeper/migration.go b/x/lockup/keeper/migration.go index e8bd2c99be4..9b470317b94 100644 --- a/x/lockup/keeper/migration.go +++ b/x/lockup/keeper/migration.go @@ -94,7 +94,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, owner.String(), 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/store.go b/x/lockup/keeper/store.go index 51aa969af22..46cb5ecd2b2 100644 --- a/x/lockup/keeper/store.go +++ b/x/lockup/keeper/store.go @@ -230,14 +230,14 @@ func (k Keeper) GetLockedDenom(ctx sdk.Context, denom string, duration time.Dura // GetLocksLongerThanDurationDenom Returns the locks whose unlock duration is longer than duration. func (k Keeper) GetLocksLongerThanDurationDenom(ctx sdk.Context, denom string, duration time.Duration) []types.PeriodLock { - lastId := k.GetLastLockID(ctx) - for i := uint64(0); i < lastId; i++ { - lock, err := k.GetLockByID(ctx, i) - if err != nil { - ctx.Logger().Error(fmt.Sprintf("ERR!!!! %s", err.Error())) - } - ctx.Logger().Error(fmt.Sprintf("lock is id %d duration %s", lock.ID, lock.Duration.String())) + ctx.Logger().Error(fmt.Sprintf("get locks longer than duration denom has been called with denom and duration of %s %s", denom, duration.String())) + lock, err := k.GetLockByID(ctx, 2) + if err != nil { + ctx.Logger().Error("Err is not nil") + ctx.Logger().Error(err.Error()) } + ctx.Logger().Error(lock.String()) + // returns both unlocking started and not started unlockings := k.getLocksFromIterator(ctx, k.LockIteratorLongerThanDurationDenom(ctx, true, denom, duration)) notUnlockings := k.getLocksFromIterator(ctx, k.LockIteratorLongerThanDurationDenom(ctx, false, denom, duration)) diff --git a/x/superfluid/keeper/migrate_test.go b/x/superfluid/keeper/migrate_test.go index e5fd70a5c98..237c940edad 100644 --- a/x/superfluid/keeper/migrate_test.go +++ b/x/superfluid/keeper/migrate_test.go @@ -260,28 +260,28 @@ func (s *KeeperTestSuite) TestMigrateSuperfluidBondedBalancerToConcentrated() { "lock that is superfluid delegated, not unlocking (full shares)": { percentOfSharesToMigrate: sdk.MustNewDecFromStr("1"), }, - "lock that is superfluid delegated, not unlocking (partial shares)": { - percentOfSharesToMigrate: sdk.MustNewDecFromStr("0.5"), - }, - "error: migrate more shares than lock has": { - percentOfSharesToMigrate: sdk.MustNewDecFromStr("1.1"), - expectedError: types.MigrateMoreSharesThanLockHasError{SharesToMigrate: "55000000000000000000", SharesInLock: "50000000000000000000"}, - }, - "error: invalid validator address": { - overwriteValidatorAddress: true, - percentOfSharesToMigrate: sdk.MustNewDecFromStr("1"), - expectedError: fmt.Errorf("decoding bech32 failed: invalid checksum"), - }, - "error: non-existent lock ID": { - overwriteLockId: true, - percentOfSharesToMigrate: sdk.MustNewDecFromStr("1"), - expectedError: lockuptypes.ErrLockupNotFound, - }, - "error: lock that is superfluid delegated, not unlocking (full shares), token out mins is more than exit coins": { - percentOfSharesToMigrate: sdk.MustNewDecFromStr("1"), - tokenOutMins: sdk.NewCoins(sdk.NewCoin("foo", sdk.NewInt(100000))), - expectedError: gammtypes.ErrLimitMinAmount, - }, + // "lock that is superfluid delegated, not unlocking (partial shares)": { + // percentOfSharesToMigrate: sdk.MustNewDecFromStr("0.5"), + // }, + // "error: migrate more shares than lock has": { + // percentOfSharesToMigrate: sdk.MustNewDecFromStr("1.1"), + // expectedError: types.MigrateMoreSharesThanLockHasError{SharesToMigrate: "55000000000000000000", SharesInLock: "50000000000000000000"}, + // }, + // "error: invalid validator address": { + // overwriteValidatorAddress: true, + // percentOfSharesToMigrate: sdk.MustNewDecFromStr("1"), + // expectedError: fmt.Errorf("decoding bech32 failed: invalid checksum"), + // }, + // "error: non-existent lock ID": { + // overwriteLockId: true, + // percentOfSharesToMigrate: sdk.MustNewDecFromStr("1"), + // expectedError: lockuptypes.ErrLockupNotFound, + // }, + // "error: lock that is superfluid delegated, not unlocking (full shares), token out mins is more than exit coins": { + // percentOfSharesToMigrate: sdk.MustNewDecFromStr("1"), + // tokenOutMins: sdk.NewCoins(sdk.NewCoin("foo", sdk.NewInt(100000))), + // expectedError: gammtypes.ErrLimitMinAmount, + // }, } for name, tc := range testCases { @@ -405,6 +405,11 @@ func (s *KeeperTestSuite) TestMigrateSuperfluidBondedBalancerToConcentrated() { s.Require().Equal(concentratedLockId, clSynthLock.UnderlyingLockId) // Run slashing logic and check if the new and old locks are slashed. + // lastLockId := s.App.LockupKeeper.GetLastLockID(s.Ctx) + // fmt.Println("last lock id in test is: ", lastLockId) + lock, err := s.App.LockupKeeper.GetLockByID(s.Ctx, 2) + s.Require().NoError(err) + fmt.Println(lock.String()) s.SlashAndValidateResult(ctx, originalGammLockId, concentratedLockId, clPoolId, tc.percentOfSharesToMigrate, valAddr, *balancerLock, true) }) } From 1f7c18cc1801e20dc603c64811b09d6b5504af4b Mon Sep 17 00:00:00 2001 From: mattverse Date: Fri, 26 May 2023 19:05:08 +0900 Subject: [PATCH 08/17] Fixed --- proto/osmosis/lockup/lock.proto | 16 +-- x/incentives/keeper/distribute.go | 2 - x/lockup/keeper/iterator.go | 2 - x/lockup/keeper/lock.go | 1 - x/lockup/keeper/store.go | 8 -- x/lockup/types/lock.pb.go | 179 +++++++++++++++--------------- 6 files changed, 97 insertions(+), 111 deletions(-) diff --git a/proto/osmosis/lockup/lock.proto b/proto/osmosis/lockup/lock.proto index dfcf6c039e2..1d79dfb2746 100644 --- a/proto/osmosis/lockup/lock.proto +++ b/proto/osmosis/lockup/lock.proto @@ -21,14 +21,9 @@ message PeriodLock { // Owner is the account address of the lock owner. // Only the owner can modify the state of the lock. string owner = 2 [ (gogoproto.moretags) = "yaml:\"owner\"" ]; - // 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 = 3 - [ (gogoproto.moretags) = "yaml:\"reward_address\"" ]; // Duration is the time needed for a lock to mature after unlocking has // started. - google.protobuf.Duration duration = 4 [ + google.protobuf.Duration duration = 3 [ (gogoproto.nullable) = false, (gogoproto.stdduration) = true, (gogoproto.jsontag) = "duration,omitempty", @@ -37,16 +32,21 @@ message PeriodLock { // EndTime refers to the time at which the lock would mature and get deleted. // This value is first initialized when an unlock has started for the lock, // end time being block time + duration. - google.protobuf.Timestamp end_time = 5 [ + google.protobuf.Timestamp end_time = 4 [ (gogoproto.stdtime) = true, (gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"end_time\"" ]; // Coins are the tokens locked within the lock, kept in the module account. - repeated cosmos.base.v1beta1.Coin coins = 6 [ + repeated cosmos.base.v1beta1.Coin coins = 5 [ (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/x/incentives/keeper/distribute.go b/x/incentives/keeper/distribute.go index e52cc51c0c5..5609e95065e 100644 --- a/x/incentives/keeper/distribute.go +++ b/x/incentives/keeper/distribute.go @@ -428,9 +428,7 @@ func (k Keeper) Distribute(ctx sdk.Context, gauges []types.Gauge) (sdk.Coins, er // send based on synthetic lockup coins if it's distributing to synthetic lockups var err error if lockuptypes.IsSyntheticDenom(gauge.DistributeTo.Denom) { - ctx.Logger().Error(fmt.Sprintf("gauge is %s", gauge.DistributeTo.Duration.String())) // TODO: add test case to cover this - ctx.Logger().Error("here") gaugeDistributedCoins, err = k.distributeSyntheticInternal(ctx, gauge, filteredLocks, &distrInfo) } else { gaugeDistributedCoins, err = k.distributeInternal(ctx, gauge, filteredLocks, &distrInfo) diff --git a/x/lockup/keeper/iterator.go b/x/lockup/keeper/iterator.go index 76e608f94aa..31a22088b2d 100644 --- a/x/lockup/keeper/iterator.go +++ b/x/lockup/keeper/iterator.go @@ -1,7 +1,6 @@ package keeper import ( - "fmt" "time" db "github.com/tendermint/tm-db" @@ -185,7 +184,6 @@ func (k Keeper) getLocksFromIterator(ctx sdk.Context, iterator db.Iterator) []ty defer iterator.Close() for ; iterator.Valid(); iterator.Next() { lockID := sdk.BigEndianToUint64(iterator.Value()) - ctx.Logger().Error(fmt.Sprintf("getting locks from iterator with lock id: %d", lockID)) lock, err := k.GetLockByID(ctx, lockID) if err != nil { panic(err) diff --git a/x/lockup/keeper/lock.go b/x/lockup/keeper/lock.go index 4ec4cf13b09..8cc539dc956 100644 --- a/x/lockup/keeper/lock.go +++ b/x/lockup/keeper/lock.go @@ -558,7 +558,6 @@ func (k Keeper) ExtendLockup(ctx sdk.Context, lockID uint64, owner sdk.AccAddres // them all correctly. This utilizes batch optimizations to improve efficiency, // as this becomes a bottleneck at chain initialization & upgrades. func (k Keeper) InitializeAllLocks(ctx sdk.Context, locks []types.PeriodLock) error { - ctx.Logger().Error("INITIALIZING ALL LOCKS") // index by coin.Denom, them duration -> amt // We accumulate the accumulation store entries separately, // to avoid hitting the myriad of slowdowns in the SDK iterator creation process. diff --git a/x/lockup/keeper/store.go b/x/lockup/keeper/store.go index 46cb5ecd2b2..ff7494c2f44 100644 --- a/x/lockup/keeper/store.go +++ b/x/lockup/keeper/store.go @@ -230,14 +230,6 @@ func (k Keeper) GetLockedDenom(ctx sdk.Context, denom string, duration time.Dura // GetLocksLongerThanDurationDenom Returns the locks whose unlock duration is longer than duration. func (k Keeper) GetLocksLongerThanDurationDenom(ctx sdk.Context, denom string, duration time.Duration) []types.PeriodLock { - ctx.Logger().Error(fmt.Sprintf("get locks longer than duration denom has been called with denom and duration of %s %s", denom, duration.String())) - lock, err := k.GetLockByID(ctx, 2) - if err != nil { - ctx.Logger().Error("Err is not nil") - ctx.Logger().Error(err.Error()) - } - ctx.Logger().Error(lock.String()) - // returns both unlocking started and not started unlockings := k.getLocksFromIterator(ctx, k.LockIteratorLongerThanDurationDenom(ctx, true, denom, duration)) notUnlockings := k.getLocksFromIterator(ctx, k.LockIteratorLongerThanDurationDenom(ctx, false, denom, duration)) diff --git a/x/lockup/types/lock.pb.go b/x/lockup/types/lock.pb.go index 9a76d54b272..3942780af20 100644 --- a/x/lockup/types/lock.pb.go +++ b/x/lockup/types/lock.pb.go @@ -69,19 +69,19 @@ type PeriodLock struct { // Owner is the account address of the lock owner. // Only the owner can modify the state of the lock. Owner string `protobuf:"bytes,2,opt,name=owner,proto3" json:"owner,omitempty" yaml:"owner"` - // 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,3,opt,name=reward_receiver_address,json=rewardReceiverAddress,proto3" json:"reward_receiver_address,omitempty" yaml:"reward_address"` // Duration is the time needed for a lock to mature after unlocking has // started. - Duration time.Duration `protobuf:"bytes,4,opt,name=duration,proto3,stdduration" json:"duration,omitempty" yaml:"duration"` + Duration time.Duration `protobuf:"bytes,3,opt,name=duration,proto3,stdduration" json:"duration,omitempty" yaml:"duration"` // EndTime refers to the time at which the lock would mature and get deleted. // This value is first initialized when an unlock has started for the lock, // end time being block time + duration. - EndTime time.Time `protobuf:"bytes,5,opt,name=end_time,json=endTime,proto3,stdtime" json:"end_time" yaml:"end_time"` + 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,6,rep,name=coins,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.Coins" json:"coins"` + 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{} } @@ -131,13 +131,6 @@ func (m *PeriodLock) GetOwner() string { return "" } -func (m *PeriodLock) GetRewardReceiverAddress() string { - if m != nil { - return m.RewardReceiverAddress - } - return "" -} - func (m *PeriodLock) GetDuration() time.Duration { if m != nil { return m.Duration @@ -159,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. @@ -328,48 +328,47 @@ func init() { func init() { proto.RegisterFile("osmosis/lockup/lock.proto", fileDescriptor_7e9d7527a237b489) } var fileDescriptor_7e9d7527a237b489 = []byte{ - // 642 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x54, 0x3d, 0x6f, 0xd3, 0x40, - 0x18, 0x8e, 0x93, 0xa6, 0xb4, 0x57, 0x9a, 0x46, 0xa7, 0x56, 0xa4, 0x01, 0xec, 0xc8, 0x03, 0x8a, - 0x50, 0x6b, 0x93, 0x22, 0x16, 0x36, 0xdc, 0x30, 0x54, 0xea, 0x40, 0x4d, 0xc5, 0xc0, 0x62, 0xd9, - 0xbe, 0xc3, 0x3d, 0xd5, 0xf6, 0x19, 0x9f, 0xdd, 0xe2, 0x7f, 0xc0, 0xd8, 0x11, 0x24, 0x36, 0x36, - 0x7e, 0x01, 0x3f, 0xa1, 0x63, 0x47, 0xa6, 0x14, 0xb5, 0x1b, 0x63, 0x7f, 0x01, 0xba, 0x0f, 0xa7, - 0x1f, 0x08, 0x58, 0x10, 0x93, 0x73, 0xf7, 0xbe, 0xcf, 0xf3, 0xde, 0xfb, 0x3c, 0x8f, 0x02, 0x56, - 0x29, 0x4b, 0x28, 0x23, 0xcc, 0x8e, 0x69, 0xb8, 0x5f, 0x66, 0xe2, 0x63, 0x65, 0x39, 0x2d, 0x28, - 0xec, 0xa8, 0x92, 0x25, 0x4b, 0xfd, 0xe5, 0x88, 0x46, 0x54, 0x94, 0x6c, 0xfe, 0x4b, 0x76, 0xf5, - 0xf5, 0x88, 0xd2, 0x28, 0xc6, 0xb6, 0x38, 0x05, 0xe5, 0x1b, 0x1b, 0x95, 0xb9, 0x5f, 0x10, 0x9a, - 0xaa, 0xba, 0x71, 0xb3, 0x5e, 0x90, 0x04, 0xb3, 0xc2, 0x4f, 0xb2, 0x9a, 0x20, 0x14, 0x73, 0xec, - 0xc0, 0x67, 0xd8, 0x3e, 0x18, 0x05, 0xb8, 0xf0, 0x47, 0x76, 0x48, 0x89, 0x22, 0x30, 0xbf, 0xb6, - 0x00, 0x78, 0x81, 0x73, 0x42, 0xd1, 0x36, 0x0d, 0xf7, 0x61, 0x07, 0x34, 0xb7, 0xc6, 0x3d, 0x6d, - 0xa0, 0x0d, 0x67, 0xdc, 0xe6, 0xd6, 0x18, 0x3e, 0x00, 0x6d, 0x7a, 0x98, 0xe2, 0xbc, 0xd7, 0x1c, - 0x68, 0xc3, 0x79, 0xa7, 0x7b, 0x31, 0x31, 0x6e, 0x57, 0x7e, 0x12, 0x3f, 0x35, 0xc5, 0xb5, 0xe9, - 0xca, 0x32, 0xdc, 0x01, 0x77, 0x72, 0x7c, 0xe8, 0xe7, 0xc8, 0xcb, 0x71, 0x88, 0xc9, 0x01, 0xce, - 0x3d, 0x1f, 0xa1, 0x1c, 0x33, 0xd6, 0x6b, 0x09, 0xe4, 0xea, 0xc5, 0xc4, 0x58, 0x91, 0x48, 0xd5, - 0xa8, 0xea, 0xa6, 0xbb, 0x22, 0x2f, 0x5c, 0x05, 0x7c, 0x26, 0xef, 0xe1, 0x1e, 0x98, 0xab, 0x97, - 0xed, 0xcd, 0x0c, 0xb4, 0xe1, 0xc2, 0xc6, 0xaa, 0x25, 0xb7, 0xb5, 0xea, 0x6d, 0xad, 0xb1, 0x6a, - 0x70, 0x46, 0xc7, 0x13, 0xa3, 0xf1, 0x63, 0x62, 0xc0, 0x1a, 0xb2, 0x46, 0x13, 0x52, 0xe0, 0x24, - 0x2b, 0xaa, 0x8b, 0x89, 0xb1, 0x24, 0x07, 0xd7, 0x35, 0xf3, 0xc3, 0xa9, 0xa1, 0xb9, 0x53, 0x76, - 0xe8, 0x82, 0x39, 0x9c, 0x22, 0x8f, 0x4b, 0xd7, 0x6b, 0x8b, 0x49, 0xfd, 0x5f, 0x26, 0xed, 0xd6, - 0xba, 0x3a, 0x77, 0xf9, 0xa8, 0x4b, 0xd2, 0x1a, 0x69, 0x1e, 0x71, 0xd2, 0x5b, 0x38, 0x45, 0xbc, - 0x15, 0xfa, 0xa0, 0xcd, 0x55, 0x66, 0xbd, 0xd9, 0x41, 0x4b, 0x3c, 0x5d, 0xfa, 0x60, 0x71, 0x1f, - 0x2c, 0xe5, 0x83, 0xb5, 0x49, 0x49, 0xea, 0x3c, 0xe2, 0x7c, 0x5f, 0x4e, 0x8d, 0x61, 0x44, 0x8a, - 0xbd, 0x32, 0xb0, 0x42, 0x9a, 0xd8, 0xca, 0x34, 0xf9, 0x59, 0x67, 0x68, 0xdf, 0x2e, 0xaa, 0x0c, - 0x33, 0x01, 0x60, 0xae, 0x64, 0x36, 0x3f, 0x36, 0x41, 0x67, 0xa7, 0xc4, 0x79, 0xb5, 0x49, 0x53, - 0x44, 0xc4, 0x26, 0xcf, 0xc1, 0x12, 0x8f, 0x93, 0xf7, 0x96, 0x5f, 0x7b, 0x1c, 0x23, 0xbc, 0xec, - 0x6c, 0xdc, 0xb7, 0xae, 0xc7, 0xcd, 0xe2, 0x6e, 0x0b, 0xf0, 0x6e, 0x95, 0x61, 0x77, 0x31, 0xbe, - 0x7a, 0x84, 0xcb, 0xa0, 0x8d, 0x70, 0x4a, 0x13, 0xe9, 0xba, 0x2b, 0x0f, 0x5c, 0xa6, 0xa9, 0x21, - 0xad, 0xbf, 0x19, 0x72, 0x43, 0xa5, 0xdf, 0x49, 0xff, 0x0a, 0xcc, 0x4f, 0x13, 0xab, 0x5c, 0xfe, - 0x93, 0xf6, 0xf7, 0x14, 0x6b, 0x57, 0xb2, 0x4e, 0xa1, 0x52, 0xfc, 0x4b, 0x2a, 0xf3, 0x53, 0x13, - 0x2c, 0xbe, 0xac, 0xd2, 0x62, 0x0f, 0x17, 0x24, 0x14, 0xc9, 0x5e, 0x03, 0xb0, 0x4c, 0x11, 0xce, - 0xe3, 0x8a, 0xa4, 0x91, 0x27, 0x54, 0x22, 0x48, 0x25, 0xbd, 0x7b, 0x59, 0xe1, 0xbd, 0x5b, 0x08, - 0x1a, 0x60, 0x81, 0x71, 0xb8, 0x77, 0x55, 0x07, 0x20, 0xae, 0xc6, 0xb5, 0x18, 0xd3, 0xcc, 0xb4, - 0xfe, 0x51, 0x66, 0xfe, 0x5b, 0xe2, 0x1f, 0x8e, 0xc0, 0xe2, 0xb5, 0x00, 0xc0, 0x0e, 0x00, 0x4e, - 0x55, 0x73, 0x77, 0x1b, 0x10, 0x80, 0x59, 0xa7, 0xe2, 0x8f, 0xea, 0x6a, 0xfd, 0x99, 0xf7, 0x9f, - 0xf5, 0x86, 0xb3, 0x7d, 0x7c, 0xa6, 0x6b, 0x27, 0x67, 0xba, 0xf6, 0xfd, 0x4c, 0xd7, 0x8e, 0xce, - 0xf5, 0xc6, 0xc9, 0xb9, 0xde, 0xf8, 0x76, 0xae, 0x37, 0x5e, 0x6f, 0x5c, 0x09, 0xae, 0x4a, 0xd9, - 0x7a, 0xec, 0x07, 0xac, 0x3e, 0xd8, 0x07, 0xa3, 0x27, 0xf6, 0xbb, 0xfa, 0x2f, 0x50, 0x04, 0x39, - 0x98, 0x15, 0x0b, 0x3d, 0xfe, 0x19, 0x00, 0x00, 0xff, 0xff, 0x22, 0xa6, 0xf3, 0xd7, 0x21, 0x05, - 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) { @@ -392,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-- { { @@ -403,7 +409,7 @@ func (m *PeriodLock) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintLock(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x32 + dAtA[i] = 0x2a } } n1, err1 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.EndTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.EndTime):]) @@ -413,7 +419,7 @@ func (m *PeriodLock) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= n1 i = encodeVarintLock(dAtA, i, uint64(n1)) i-- - dAtA[i] = 0x2a + dAtA[i] = 0x22 n2, err2 := github_com_gogo_protobuf_types.StdDurationMarshalTo(m.Duration, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdDuration(m.Duration):]) if err2 != nil { return 0, err2 @@ -421,14 +427,7 @@ func (m *PeriodLock) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= n2 i = encodeVarintLock(dAtA, i, uint64(n2)) i-- - dAtA[i] = 0x22 - 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] = 0x1a - } + dAtA[i] = 0x1a if len(m.Owner) > 0 { i -= len(m.Owner) copy(dAtA[i:], m.Owner) @@ -570,10 +569,6 @@ func (m *PeriodLock) Size() (n int) { if l > 0 { n += 1 + l + sovLock(uint64(l)) } - l = len(m.RewardReceiverAddress) - if l > 0 { - n += 1 + l + sovLock(uint64(l)) - } l = github_com_gogo_protobuf_types.SizeOfStdDuration(m.Duration) n += 1 + l + sovLock(uint64(l)) l = github_com_gogo_protobuf_types.SizeOfStdTime(m.EndTime) @@ -584,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 } @@ -715,9 +714,9 @@ func (m *PeriodLock) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field RewardReceiverAddress", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Duration", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowLock @@ -727,27 +726,28 @@ func (m *PeriodLock) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthLock } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthLock } if postIndex > l { return io.ErrUnexpectedEOF } - m.RewardReceiverAddress = string(dAtA[iNdEx:postIndex]) + if err := github_com_gogo_protobuf_types.StdDurationUnmarshal(&m.Duration, dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Duration", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field EndTime", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -774,13 +774,13 @@ func (m *PeriodLock) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := github_com_gogo_protobuf_types.StdDurationUnmarshal(&m.Duration, dAtA[iNdEx:postIndex]); err != nil { + if err := github_com_gogo_protobuf_types.StdTimeUnmarshal(&m.EndTime, dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex case 5: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field EndTime", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Coins", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -807,15 +807,16 @@ func (m *PeriodLock) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := github_com_gogo_protobuf_types.StdTimeUnmarshal(&m.EndTime, dAtA[iNdEx:postIndex]); err != nil { + m.Coins = append(m.Coins, types1.Coin{}) + if err := m.Coins[len(m.Coins)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex case 6: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Coins", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field RewardReceiverAddress", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowLock @@ -825,25 +826,23 @@ func (m *PeriodLock) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthLock } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthLock } if postIndex > l { return io.ErrUnexpectedEOF } - m.Coins = append(m.Coins, types1.Coin{}) - if err := m.Coins[len(m.Coins)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.RewardReceiverAddress = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex From 22af2f307fce29b16feeacf3e436cea0099d4dee Mon Sep 17 00:00:00 2001 From: Adam Tucker Date: Fri, 26 May 2023 14:57:27 -0500 Subject: [PATCH 09/17] Update x/incentives/keeper/distribute.go --- x/incentives/keeper/distribute.go | 1 - 1 file changed, 1 deletion(-) diff --git a/x/incentives/keeper/distribute.go b/x/incentives/keeper/distribute.go index 5609e95065e..4ee63e66f24 100644 --- a/x/incentives/keeper/distribute.go +++ b/x/incentives/keeper/distribute.go @@ -235,7 +235,6 @@ func (k Keeper) doDistributionSends(ctx sdk.Context, distrs *distributionInfo) e func (k Keeper) distributeSyntheticInternal( ctx sdk.Context, gauge types.Gauge, locks []lockuptypes.PeriodLock, distrInfo *distributionInfo, ) (sdk.Coins, error) { - ctx.Logger().Error("HERE") qualifiedLocks := k.lk.GetLocksLongerThanDurationDenom(ctx, gauge.DistributeTo.Denom, gauge.DistributeTo.Duration) // map from lockID to present index in resultant list From 285eaf736bbd96d2a8a0f97544f7d324235eddc4 Mon Sep 17 00:00:00 2001 From: Adam Tucker Date: Fri, 26 May 2023 14:57:33 -0500 Subject: [PATCH 10/17] Update x/lockup/keeper/lock.go --- x/lockup/keeper/lock.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/lockup/keeper/lock.go b/x/lockup/keeper/lock.go index 8cc539dc956..a27a48b725b 100644 --- a/x/lockup/keeper/lock.go +++ b/x/lockup/keeper/lock.go @@ -456,7 +456,7 @@ func (k Keeper) unlockMaturedLockInternalLogic(ctx sdk.Context, lock types.Perio return nil } -// SetLockReceiver changes the reward recipient address to the given address. +// 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) From ec8b1c361dd84addcc2b4b9377b49cd3bdb7e1ac Mon Sep 17 00:00:00 2001 From: "Matt, Park" <45252226+mattverse@users.noreply.github.com> Date: Sat, 27 May 2023 18:20:08 +0900 Subject: [PATCH 11/17] Update x/lockup/keeper/lock_test.go Co-authored-by: Adam Tucker --- x/lockup/keeper/lock_test.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/x/lockup/keeper/lock_test.go b/x/lockup/keeper/lock_test.go index af3a10d5e2b..8e2f0747f40 100644 --- a/x/lockup/keeper/lock_test.go +++ b/x/lockup/keeper/lock_test.go @@ -237,8 +237,6 @@ func (s *KeeperTestSuite) TestUnlock() { addr1 := sdk.AccAddress([]byte("addr1---------------")) lock := types.NewPeriodLock(1, addr1, addr1.String(), time.Second, time.Time{}, tc.fundAcc) - fmt.Println("----") - fmt.Println(lock.String()) // lock with balance s.FundAcc(addr1, tc.fundAcc) From f55cc968c8d6109eed434ec34c5bac511cdcd9e7 Mon Sep 17 00:00:00 2001 From: "Matt, Park" <45252226+mattverse@users.noreply.github.com> Date: Sat, 27 May 2023 18:20:15 +0900 Subject: [PATCH 12/17] Update x/lockup/types/msgs.go Co-authored-by: Adam Tucker --- x/lockup/types/msgs.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/lockup/types/msgs.go b/x/lockup/types/msgs.go index 0c2f7187e8b..86651004c6b 100644 --- a/x/lockup/types/msgs.go +++ b/x/lockup/types/msgs.go @@ -225,7 +225,7 @@ func (m MsgSetRewardReceiverAddress) ValidateBasic() error { } _, err = sdk.AccAddressFromBech32(m.RewardReceiver) if err != nil { - return errorsmod.Wrapf(sdkerrors.ErrInvalidAddress, "Invalid owner address (%s)", err) + return errorsmod.Wrapf(sdkerrors.ErrInvalidAddress, "Invalid reward receiver address (%s)", err) } if m.LockID <= 0 { From 22bf4a68ef42e7f3dc234d11fc69efa774fffd7c Mon Sep 17 00:00:00 2001 From: "Matt, Park" <45252226+mattverse@users.noreply.github.com> Date: Sat, 27 May 2023 18:20:45 +0900 Subject: [PATCH 13/17] Update x/lockup/types/msgs.go Co-authored-by: Adam Tucker --- x/lockup/types/msgs.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/lockup/types/msgs.go b/x/lockup/types/msgs.go index 86651004c6b..217c1e46cec 100644 --- a/x/lockup/types/msgs.go +++ b/x/lockup/types/msgs.go @@ -229,7 +229,7 @@ func (m MsgSetRewardReceiverAddress) ValidateBasic() error { } if m.LockID <= 0 { - return errorsmod.Wrapf(sdkerrors.ErrInvalidRequest, "lock id should be bigger than 1 (%s)", err) + return errorsmod.Wrapf(sdkerrors.ErrInvalidRequest, "lock id should be larger than zero, was (%s)", err) } return nil } From 2d6aa3066c634f7dadc3feea7f9ce4c85dc14ae9 Mon Sep 17 00:00:00 2001 From: mattverse Date: Sun, 28 May 2023 02:14:51 +0900 Subject: [PATCH 14/17] Adams review --- x/lockup/keeper/lock.go | 2 +- x/lockup/keeper/lock_test.go | 103 ++++++++++++++++++++++++++++ x/lockup/keeper/migration.go | 9 +++ x/lockup/keeper/msg_server.go | 2 +- x/lockup/keeper/msg_server_test.go | 94 +++++++++++++++++++++++++ x/lockup/types/msgs.go | 4 +- x/superfluid/keeper/migrate_test.go | 49 ++++++------- 7 files changed, 232 insertions(+), 31 deletions(-) diff --git a/x/lockup/keeper/lock.go b/x/lockup/keeper/lock.go index a27a48b725b..9d2b463f104 100644 --- a/x/lockup/keeper/lock.go +++ b/x/lockup/keeper/lock.go @@ -834,7 +834,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.OwnerAddress().String(), 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 8e2f0747f40..46d06b82d2f 100644 --- a/x/lockup/keeper/lock_test.go +++ b/x/lockup/keeper/lock_test.go @@ -888,6 +888,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 9b470317b94..c31bef19436 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.Owner != 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] diff --git a/x/lockup/keeper/msg_server.go b/x/lockup/keeper/msg_server.go index 2f5383ff388..2ee51b2084c 100644 --- a/x/lockup/keeper/msg_server.go +++ b/x/lockup/keeper/msg_server.go @@ -235,7 +235,7 @@ func (server msgServer) SetRewardReceiverAddress(goCtx context.Context, msg *typ return nil, err } - newRewardRecepient, err := sdk.AccAddressFromBech32(msg.Owner) + newRewardRecepient, err := sdk.AccAddressFromBech32(msg.RewardReceiver) if err != nil { return nil, err } diff --git a/x/lockup/keeper/msg_server_test.go b/x/lockup/keeper/msg_server_test.go index 2dddf21c0f9..3d471f7cfc9 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(newLock.RewardReceiverAddress, s.TestAccs[1].String()) + } + + } +} diff --git a/x/lockup/types/msgs.go b/x/lockup/types/msgs.go index 217c1e46cec..5ab999905d7 100644 --- a/x/lockup/types/msgs.go +++ b/x/lockup/types/msgs.go @@ -207,8 +207,8 @@ func (m MsgForceUnlock) GetSigners() []sdk.AccAddress { return []sdk.AccAddress{owner} } -// NewMsgBeginUnlockingAll creates a message to begin unlocking tokens. -func NewMsgMsgSetRewardReceiverAddress(owner, rewardReceiver sdk.AccAddress, lockId uint64) *MsgSetRewardReceiverAddress { +// 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(), diff --git a/x/superfluid/keeper/migrate_test.go b/x/superfluid/keeper/migrate_test.go index f3a41137b36..2375937a7f1 100644 --- a/x/superfluid/keeper/migrate_test.go +++ b/x/superfluid/keeper/migrate_test.go @@ -260,28 +260,28 @@ func (s *KeeperTestSuite) TestMigrateSuperfluidBondedBalancerToConcentrated() { "lock that is superfluid delegated, not unlocking (full shares)": { percentOfSharesToMigrate: sdk.MustNewDecFromStr("1"), }, - // "lock that is superfluid delegated, not unlocking (partial shares)": { - // percentOfSharesToMigrate: sdk.MustNewDecFromStr("0.5"), - // }, - // "error: migrate more shares than lock has": { - // percentOfSharesToMigrate: sdk.MustNewDecFromStr("1.1"), - // expectedError: types.MigrateMoreSharesThanLockHasError{SharesToMigrate: "55000000000000000000", SharesInLock: "50000000000000000000"}, - // }, - // "error: invalid validator address": { - // overwriteValidatorAddress: true, - // percentOfSharesToMigrate: sdk.MustNewDecFromStr("1"), - // expectedError: fmt.Errorf("decoding bech32 failed: invalid checksum"), - // }, - // "error: non-existent lock ID": { - // overwriteLockId: true, - // percentOfSharesToMigrate: sdk.MustNewDecFromStr("1"), - // expectedError: lockuptypes.ErrLockupNotFound, - // }, - // "error: lock that is superfluid delegated, not unlocking (full shares), token out mins is more than exit coins": { - // percentOfSharesToMigrate: sdk.MustNewDecFromStr("1"), - // tokenOutMins: sdk.NewCoins(sdk.NewCoin("foo", sdk.NewInt(100000))), - // expectedError: gammtypes.ErrLimitMinAmount, - // }, + "lock that is superfluid delegated, not unlocking (partial shares)": { + percentOfSharesToMigrate: sdk.MustNewDecFromStr("0.5"), + }, + "error: migrate more shares than lock has": { + percentOfSharesToMigrate: sdk.MustNewDecFromStr("1.1"), + expectedError: types.MigrateMoreSharesThanLockHasError{SharesToMigrate: "55000000000000000000", SharesInLock: "50000000000000000000"}, + }, + "error: invalid validator address": { + overwriteValidatorAddress: true, + percentOfSharesToMigrate: sdk.MustNewDecFromStr("1"), + expectedError: fmt.Errorf("decoding bech32 failed: invalid checksum"), + }, + "error: non-existent lock ID": { + overwriteLockId: true, + percentOfSharesToMigrate: sdk.MustNewDecFromStr("1"), + expectedError: lockuptypes.ErrLockupNotFound, + }, + "error: lock that is superfluid delegated, not unlocking (full shares), token out mins is more than exit coins": { + percentOfSharesToMigrate: sdk.MustNewDecFromStr("1"), + tokenOutMins: sdk.NewCoins(sdk.NewCoin("foo", sdk.NewInt(100000))), + expectedError: gammtypes.ErrLimitMinAmount, + }, } for name, tc := range testCases { @@ -405,11 +405,6 @@ func (s *KeeperTestSuite) TestMigrateSuperfluidBondedBalancerToConcentrated() { s.Require().Equal(concentratedLockId, clSynthLock.UnderlyingLockId) // Run slashing logic and check if the new and old locks are slashed. - // lastLockId := s.App.LockupKeeper.GetLastLockID(s.Ctx) - // fmt.Println("last lock id in test is: ", lastLockId) - lock, err := s.App.LockupKeeper.GetLockByID(s.Ctx, 2) - s.Require().NoError(err) - fmt.Println(lock.String()) s.SlashAndValidateResult(ctx, originalGammLockId, concentratedLockId, clPoolId, tc.percentOfSharesToMigrate, valAddr, *balancerLock, true) }) } From 229436d083886ff142c2b2dcf99493c7cb39d786 Mon Sep 17 00:00:00 2001 From: mattverse Date: Sun, 28 May 2023 02:17:21 +0900 Subject: [PATCH 15/17] Adam's review --- x/lockup/keeper/lock_test.go | 1 - 1 file changed, 1 deletion(-) diff --git a/x/lockup/keeper/lock_test.go b/x/lockup/keeper/lock_test.go index 46d06b82d2f..3d834e9fb95 100644 --- a/x/lockup/keeper/lock_test.go +++ b/x/lockup/keeper/lock_test.go @@ -582,7 +582,6 @@ func (s *KeeperTestSuite) TestSetLockRewardReceiverAddress() { s.FundAcc(addr1, coins) - // create an account first lock, err := s.App.LockupKeeper.CreateLock(s.Ctx, addr1, coins, time.Second) s.Require().NoError(err) From 88798c164aea0d94530fa97dc1ba8b6a76ec5647 Mon Sep 17 00:00:00 2001 From: mattverse Date: Sun, 28 May 2023 12:25:10 +0900 Subject: [PATCH 16/17] Fix test --- x/lockup/keeper/migration.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/lockup/keeper/migration.go b/x/lockup/keeper/migration.go index c31bef19436..ee69f062cb4 100644 --- a/x/lockup/keeper/migration.go +++ b/x/lockup/keeper/migration.go @@ -70,7 +70,7 @@ func MergeLockupsForSimilarDurations( // check if the reward receiver is the lock owner. // if not, we do not normalize the lock. - if lock.Owner != lock.RewardReceiverAddress { + if lock.RewardReceiverAddress != "" { continue } From 80b11f5b33ad87b407ed876e98ece45f4bfa6191 Mon Sep 17 00:00:00 2001 From: mattverse Date: Mon, 29 May 2023 16:02:49 +0900 Subject: [PATCH 17/17] Add romans comment --- x/lockup/keeper/lock.go | 3 +-- x/lockup/keeper/lock_test.go | 16 +++++++++------- x/lockup/keeper/msg_server_test.go | 2 +- x/lockup/types/lock.go | 7 ++++++- 4 files changed, 17 insertions(+), 11 deletions(-) diff --git a/x/lockup/keeper/lock.go b/x/lockup/keeper/lock.go index 9d2b463f104..838ac71a132 100644 --- a/x/lockup/keeper/lock.go +++ b/x/lockup/keeper/lock.go @@ -463,7 +463,6 @@ func (k Keeper) SetLockRewardReceiverAddress(ctx sdk.Context, lockID uint64, own if err != nil { return err } - // check if the lock owner is the method caller. if lock.GetOwner() != owner.String() { return types.ErrNotLockOwner @@ -471,7 +470,7 @@ func (k Keeper) SetLockRewardReceiverAddress(ctx sdk.Context, lockID uint64, own // if the given receiver address is same as the lock owner, we store an empty string instead. if lock.Owner == newReceiverAddress { - newReceiverAddress = "" + newReceiverAddress = types.DefaultOwnerReceiverPlaceholder } if lock.RewardReceiverAddress == newReceiverAddress { diff --git a/x/lockup/keeper/lock_test.go b/x/lockup/keeper/lock_test.go index 3d834e9fb95..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" @@ -541,35 +543,34 @@ func (s *KeeperTestSuite) TestSetLockRewardReceiverAddress() { isnotOwner bool lockID uint64 useNewReceiverAddress bool - expectedError bool + exepctedErrorType error }{ { name: "happy case", isnotOwner: false, lockID: 1, useNewReceiverAddress: true, - expectedError: false, }, { name: "error: caller of the function is not the owner", isnotOwner: true, lockID: 1, useNewReceiverAddress: true, - expectedError: true, + exepctedErrorType: types.ErrNotLockOwner, }, { name: "error: lock id is invalid", isnotOwner: false, - lockID: 2, + lockID: 5, useNewReceiverAddress: true, - expectedError: 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, - expectedError: true, + exepctedErrorType: types.ErrRewardReceiverIsSame, }, } @@ -602,8 +603,9 @@ func (s *KeeperTestSuite) TestSetLockRewardReceiverAddress() { // System under test // now change the reward receiver state err = s.App.LockupKeeper.SetLockRewardReceiverAddress(s.Ctx, tc.lockID, owner, newReceiver.String()) - if tc.expectedError { + 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) diff --git a/x/lockup/keeper/msg_server_test.go b/x/lockup/keeper/msg_server_test.go index 3d471f7cfc9..b22191239d0 100644 --- a/x/lockup/keeper/msg_server_test.go +++ b/x/lockup/keeper/msg_server_test.go @@ -544,7 +544,7 @@ func (s *KeeperTestSuite) TestSetRewardReceiverAddress() { if test.param.isRewardReceiverAddressOwner { s.Require().Equal(newLock.RewardReceiverAddress, "") } else { - s.Require().Equal(newLock.RewardReceiverAddress, s.TestAccs[1].String()) + s.Require().Equal(s.TestAccs[1].String(), newLock.RewardReceiverAddress) } } diff --git a/x/lockup/types/lock.go b/x/lockup/types/lock.go index 153a8906afd..0de9a5975f3 100644 --- a/x/lockup/types/lock.go +++ b/x/lockup/types/lock.go @@ -8,11 +8,16 @@ 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, 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 = "" + reward_address = DefaultOwnerReceiverPlaceholder } return PeriodLock{ ID: ID,