-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: Tier module fixes and improvements (part 3) (#10)
* Add tier module events and attributes * Emit corresponding events on Lock, Unlock, Redelegate, and CompleteUnlocking * Improve CancelUnlocking to search for unbonding delegation entry by creationHeight * Add IterateValidators and TotalBondedTokens to expected staking keeper, define corresponding mocks * Fix calculation bug in TotalAmountByAddr caused by delAddr shadowing, add TestTotalAmountByAddr * Fix SubtractLockup to remove lockup if subtracting the whole locked amount, add TestHasLockup and TestGetUnlockingLockup * Refactor calculateCredit and related tests * Add SaveLockup, refactor SetLockup, fix GetLockup and removeUnlockingLockup * Add TestGetLockup and TestGetLockups, fix/improve existing tests * Use SaveLockup instead of SetLockup in InitGenesis * Update grpc query tests * Improve CancelUnlocking to support partial unlocks and fix bug in existing logic * Improve TestCancelUnlocking to verify subsequent and partial unlocks, fix/update existing tests * Improve SubtractLockup and SubtractUnlockingLockup logic to handle invalid amounts * Add TestSubtractUnlockingLockup, improve TestSubtractLockup * Improve Lock, Unlock, and Redelegate to handle invalid amounts, fix/improve related tests * Add ErrInvalidAmount * Fix typo in ErrUnauthorized, add setupMsgServer and basic TestMsgServer * Add TestMsgUpdateParams * Add TestMsgLock * Add TestMsgUnlock * Add TestMsgRedelegate * Update TestMsgLock, TestMsgUnlock, and TestMsgUpdateParams, fix error messages * Add TestMsgCancelUnlocking, minor fixes
- Loading branch information
Showing
23 changed files
with
1,495 additions
and
261 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
package keeper | ||
|
||
import ( | ||
"cosmossdk.io/math" | ||
|
||
"github.com/sourcenetwork/sourcehub/x/tier/types" | ||
) | ||
|
||
// calculateCredit calculates the reward earned on the lockingAmt. | ||
// lockingAmt is stacked up on top of the lockedAmt to earn at the highest eligible reward. | ||
func calculateCredit(rateList []types.Rate, lockedAmt, lockingAmt math.Int) math.Int { | ||
credit := math.ZeroInt() | ||
stakedAmt := lockedAmt.Add(lockingAmt) | ||
|
||
// Iterate from the highest reward rate to the lowest. | ||
for _, r := range rateList { | ||
// Continue if the total lock does not reach the current rate requirement. | ||
if stakedAmt.LT(r.Amount) { | ||
continue | ||
} | ||
|
||
lower := math.MaxInt(r.Amount, lockedAmt) | ||
diff := stakedAmt.Sub(lower) | ||
|
||
diffDec := math.LegacyNewDecFromInt(diff) | ||
rateDec := math.LegacyNewDec(r.Rate) | ||
|
||
// rateDec MUST have 2 decimals of precision for the calculation to be correct. | ||
amt := diffDec.Mul(rateDec).Quo(math.LegacyNewDec(100)) | ||
credit = credit.Add(amt.TruncateInt()) | ||
|
||
// Subtract the lock that has been rewarded. | ||
stakedAmt = stakedAmt.Sub(diff) | ||
lockingAmt = lockingAmt.Sub(diff) | ||
|
||
// Break if all the new lock has been rewarded. | ||
if lockingAmt.IsZero() { | ||
break | ||
} | ||
} | ||
|
||
return credit | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
package keeper | ||
|
||
import ( | ||
"fmt" | ||
"reflect" | ||
"testing" | ||
|
||
"cosmossdk.io/math" | ||
|
||
"github.com/sourcenetwork/sourcehub/x/tier/types" | ||
) | ||
|
||
func Test_CalculateCredit(t *testing.T) { | ||
rateList := []types.Rate{ | ||
{Amount: math.NewInt(300), Rate: 150}, | ||
{Amount: math.NewInt(200), Rate: 120}, | ||
{Amount: math.NewInt(100), Rate: 110}, | ||
{Amount: math.NewInt(0), Rate: 100}, | ||
} | ||
|
||
tests := []struct { | ||
lockedAmt int64 | ||
lockingAmt int64 | ||
want int64 | ||
}{ | ||
{ | ||
lockedAmt: 100, | ||
lockingAmt: 0, | ||
want: 0, | ||
}, | ||
{ | ||
lockedAmt: 250, | ||
lockingAmt: 0, | ||
want: 0, | ||
}, | ||
{ | ||
lockedAmt: 0, | ||
lockingAmt: 100, | ||
want: 100, | ||
}, | ||
{ | ||
lockedAmt: 0, | ||
lockingAmt: 200, | ||
want: (100 * 1.0) + (100 * 1.1), | ||
}, | ||
{ | ||
lockedAmt: 0, | ||
lockingAmt: 250, | ||
want: (100 * 1.0) + (100 * 1.1) + (50 * 1.2), | ||
}, | ||
{ | ||
lockedAmt: 0, | ||
lockingAmt: 300, | ||
want: (100 * 1.0) + (100 * 1.1) + (100 * 1.2), | ||
}, | ||
{ | ||
lockedAmt: 0, | ||
lockingAmt: 350, | ||
want: (100 * 1.0) + (100 * 1.1) + (100 * 1.2) + (50 * 1.5), | ||
}, | ||
{ | ||
lockedAmt: 0, | ||
lockingAmt: 600, | ||
want: (100 * 1.0) + (100 * 1.1) + (100 * 1.2) + (300 * 1.5), | ||
}, | ||
{ | ||
lockedAmt: 100, | ||
lockingAmt: 100, | ||
want: (100 * 1.1), | ||
}, | ||
{ | ||
lockedAmt: 200, | ||
lockingAmt: 100, | ||
want: (100 * 1.2), | ||
}, | ||
{ | ||
lockedAmt: 150, | ||
lockingAmt: 150, | ||
want: (50 * 1.1) + (100 * 1.2), | ||
}, | ||
{ | ||
lockedAmt: 50, | ||
lockingAmt: 400, | ||
want: (50 * 1.0) + (100 * 1.1) + (100 * 1.2) + (150 * 1.5), | ||
}, | ||
} | ||
for _, tt := range tests { | ||
name := fmt.Sprintf("%d adds %d", tt.lockedAmt, tt.lockingAmt) | ||
oldLock := math.NewInt(tt.lockedAmt) | ||
newLock := math.NewInt(tt.lockingAmt) | ||
want := math.NewInt(tt.want) | ||
|
||
t.Run(name, func(t *testing.T) { | ||
if got := calculateCredit(rateList, oldLock, newLock); !reflect.DeepEqual(got, want) { | ||
t.Errorf("calculateCredit() = %v, want %v", got, tt.want) | ||
} | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.