diff --git a/staker/__TEST_staker_short_warmup_period_external_10_test.gno b/staker/__TEST_staker_short_warmup_period_external_10_test.gno index 61afecdd..9ec0093b 100644 --- a/staker/__TEST_staker_short_warmup_period_external_10_test.gno +++ b/staker/__TEST_staker_short_warmup_period_external_10_test.gno @@ -172,10 +172,8 @@ func testCollectReward(t *testing.T) { CollectReward(1, false) std.TestSkipHeights(1) newBar := bar.BalanceOf(admin) + println("collected bar", newBar-oldBar) - println("newBar", newBar) - println("oldBar", oldBar) - println("newBar-oldBar", newBar-oldBar) // uassert.Equal(t, newBar-oldBar, uint64(481)) // pei := GetPrintExternalInfo() diff --git a/staker/staker.gno b/staker/staker.gno index cfe5087c..6f6ed5fc 100644 --- a/staker/staker.gno +++ b/staker/staker.gno @@ -65,10 +65,53 @@ func (self *Deposits) Size() int { return self.tree.Size() } +type ExternalIncentives struct { + tree *avl.Tree +} + +func NewExternalIncentives() *ExternalIncentives { + return &ExternalIncentives{ + tree: avl.NewTree(), + } +} + +func (self *ExternalIncentives) Get(incentiveId string) *ExternalIncentive { + incentiveI, ok := self.tree.Get(incentiveId) + if !ok { + panic(addDetailToError( + errDataNotFound, + ufmt.Sprintf("incentiveId(%s) not found", incentiveId), + )) + } + + incentive := incentiveI.(*ExternalIncentive) + return incentive +} + +func (self *ExternalIncentives) Set(incentiveId string, incentive *ExternalIncentive) { + self.tree.Set(incentiveId, incentive) +} + +func (self *ExternalIncentives) Has(incentiveId string) bool { + return self.tree.Has(incentiveId) +} + +func (self *ExternalIncentives) Remove(incentiveId string) { + self.tree.Remove(incentiveId) +} + +func (self *ExternalIncentives) Size() int { + return self.tree.Size() +} + var ( /* common */ + // deposits stores deposit information for each tokenId deposits *Deposits = NewDeposits() + + // externalIncenvies stores external incentive information for each incentiveId + externalIncenvies *ExternalIncentives = NewExternalIncentives() ) const ( @@ -314,14 +357,23 @@ func CollectReward(tokenId uint64, unwrapResult bool) string { // update lastCollectHeight to current height deposit.lastCollectHeight = uint64(std.GetHeight()) - println("COLLECT REWARD") + // transfer external rewards to user externalReward := reward.External - println("externalReward", externalReward) + for incentiveId, amount := range externalReward { + incentive := externalIncenvies.Get(incentiveId) + rewardToken := incentive.rewardToken + + // TODO: handle unstaking fee + toUser := handleUnstakingFee(rewardToken, amount, false, tokenId, incentive.targetPoolPath) + + teller := common.GetTokenTeller(rewardToken) + teller.Transfer(deposit.owner, toUser) + } + + // do nothing for external penalty + // it will be stored in staker, and when external ends will be refunded externalPenalty := reward.ExternalPenalty - println("externalPenalty", externalPenalty) - // println(reward) - // println() - // println() + // println("externalPenalty", externalPenalty) // internal reward to user toUser := handleUnstakingFee(consts.GNS_PATH, reward.Internal, true, tokenId, deposit.targetPoolPath) diff --git a/staker/staker_external_incentive.gno b/staker/staker_external_incentive.gno index 2c36ff5b..ed152f4f 100644 --- a/staker/staker_external_incentive.gno +++ b/staker/staker_external_incentive.gno @@ -84,7 +84,10 @@ func CreateExternalIncentive( )) } + caller := std.PrevRealm().Addr() + // incentiveId := incentiveIdCompute(std.PrevRealm().Addr(), targetPoolPath, rewardToken, startTimestamp, endTimestamp, std.GetHeight()) + incentiveId := incentiveIdByTime(uint64(startTimestamp), uint64(endTimestamp), caller, rewardToken) externalDuration := uint64(endTimestamp - startTimestamp) if err := isValidIncentiveDuration(externalDuration); err != nil { @@ -94,12 +97,13 @@ func CreateExternalIncentive( pool := pools.GetOrCreate(targetPoolPath) incentive := NewExternalIncentive( + incentiveId, targetPoolPath, rewardToken, rewardAmount, startTimestamp, endTimestamp, - std.PrevRealm().Addr(), + caller, std.GetHeight(), depositGnsAmount, @@ -107,16 +111,17 @@ func CreateExternalIncentive( gns.GetAvgBlockTimeInMs(), ) + // store external incentive information for each incentiveId + externalIncenvies.Set(incentiveId, incentive) + // deposit gns amount - gns.TransferFrom(a2u(std.PrevRealm().Addr()), a2u(consts.STAKER_ADDR), depositGnsAmount) + gns.TransferFrom(a2u(caller), a2u(consts.STAKER_ADDR), depositGnsAmount) // transfer reward token from user to staker teller := common.GetTokenTeller(rewardToken) - teller.TransferFrom(std.PrevRealm().Addr(), consts.STAKER_ADDR, rewardAmount) + teller.TransferFrom(caller, consts.STAKER_ADDR, rewardAmount) - pool.incentives.create(std.PrevRealm().Addr(), incentive) - - incentiveId := incentiveIdByTime(uint64(startTimestamp), uint64(endTimestamp), std.PrevRealm().Addr(), rewardToken) + pool.incentives.create(caller, incentive) prevAddr, prevRealm := getPrev() std.Emit( @@ -132,8 +137,6 @@ func CreateExternalIncentive( "internal_depositGnsAmount", ufmt.Sprintf("%d", depositGnsAmount), "internal_external", "created", ) - - return } // EndExternalIncentive ends the external incentive and refunds the remaining reward