Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: fix incorrect rewards value for RewardsAuction #103

Merged
merged 1 commit into from
Nov 14, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 17 additions & 10 deletions x/liquidfarming/keeper/auction.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,14 +127,20 @@ func (k Keeper) FinishRewardsAuction(ctx sdk.Context, auction types.RewardsAucti
poolCoinDenom := liquiditytypes.PoolCoinDenom(auction.PoolId)
farmingRewards := k.lpfarmKeeper.Rewards(ctx, liquidFarmReserveAddr, poolCoinDenom)
truncatedRewards, _ := farmingRewards.TruncateDecimal() // TODO: farm module may use sdk.DecCoins for sdk.Coins in the future
withdrawnRewardsReserveAddr := types.WithdrawnRewardsReserveAddress(auction.PoolId)
withdrawnRewardsReserves := k.bankKeeper.SpendableCoins(ctx, withdrawnRewardsReserveAddr)
totalRewards := truncatedRewards.Add(withdrawnRewardsReserves...)

winningBid, found := k.GetWinningBid(ctx, auction.Id, auction.PoolId)
if !found {
k.skipRewardsAuction(ctx, truncatedRewards, feeRate, auction)
k.skipRewardsAuction(ctx, totalRewards, feeRate, auction)
} else {
_, found = k.lpfarmKeeper.GetPosition(ctx, liquidFarmReserveAddr, poolCoinDenom)
if found {
_, fees, err := k.payoutRewards(ctx, auction.PoolId, feeRate, liquidFarmReserveAddr, poolCoinDenom, winningBid)
_, fees, err := k.payoutRewards(
ctx, auction.PoolId, poolCoinDenom, liquidFarmReserveAddr,
withdrawnRewardsReserveAddr, withdrawnRewardsReserves, winningBid, feeRate,
)
if err != nil {
return err
}
Expand All @@ -153,7 +159,7 @@ func (k Keeper) FinishRewardsAuction(ctx sdk.Context, auction types.RewardsAucti

auction.SetWinner(winningBid.Bidder)
auction.SetWinningAmount(winningBid.Amount)
auction.SetRewards(truncatedRewards)
auction.SetRewards(totalRewards)
auction.SetStatus(types.AuctionStatusFinished)
auction.SetFeeRate(feeRate)
k.SetRewardsAuction(ctx, auction)
Expand All @@ -172,10 +178,11 @@ func (k Keeper) getNextAuctionIdWithUpdate(ctx sdk.Context, poolId uint64) uint6
return auctionId
}

// skipRewardsAuction skips rewards auction since there is no bid.
func (k Keeper) skipRewardsAuction(ctx sdk.Context, rewards sdk.Coins, feeRate sdk.Dec, auction types.RewardsAuction) {
auction.SetRewards(rewards)
auction.SetStatus(types.AuctionStatusSkipped)
auction.SetFeeRate(feeRate)
auction.SetStatus(types.AuctionStatusSkipped)
k.SetRewardsAuction(ctx, auction)
k.SetCompoundingRewards(ctx, auction.PoolId, types.CompoundingRewards{
Amount: sdk.ZeroInt(),
Expand Down Expand Up @@ -218,10 +225,12 @@ func (k Keeper) refundAllBids(ctx sdk.Context, auction types.RewardsAuction, inc
func (k Keeper) payoutRewards(
ctx sdk.Context,
poolId uint64,
feeRate sdk.Dec,
liquidFarmReserveAddr sdk.AccAddress,
poolCoinDenom string,
liquidFarmReserveAddr sdk.AccAddress,
withdrawnRewardsReserveAddr sdk.AccAddress,
withdrawnRewardsReserves sdk.Coins,
winningBid types.Bid,
feeRate sdk.Dec,
) (deducted sdk.Coins, fees sdk.Coins, err error) {
withdrawnRewards, err := k.lpfarmKeeper.Harvest(ctx, liquidFarmReserveAddr, poolCoinDenom)
if err != nil {
Expand All @@ -233,14 +242,12 @@ func (k Keeper) payoutRewards(
// when an account executes Farm/Unfarm if the account already has position.
// The module reserves any auto withdrawn rewards in the withdrawn rewards reserve account.
// So, farming rewards must add the balance of withdrawn rewards reserve account.
withdrawnRewardsReserveAddr := types.WithdrawnRewardsReserveAddress(poolId)
spendable := k.bankKeeper.SpendableCoins(ctx, withdrawnRewardsReserveAddr)
totalRewards := spendable.Add(withdrawnRewards...)
totalRewards := withdrawnRewardsReserves.Add(withdrawnRewards...)

if !totalRewards.IsZero() {
deducted, fees = types.DeductFees(totalRewards, feeRate)

if err := k.bankKeeper.SendCoins(ctx, withdrawnRewardsReserveAddr, liquidFarmReserveAddr, spendable); err != nil {
if err := k.bankKeeper.SendCoins(ctx, withdrawnRewardsReserveAddr, liquidFarmReserveAddr, withdrawnRewardsReserves); err != nil {
return sdk.Coins{}, sdk.Coins{}, err
}

Expand Down
46 changes: 46 additions & 0 deletions x/liquidfarming/keeper/auction_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -352,3 +352,49 @@ func (s *KeeperTestSuite) TestFinishRewardsAuction_NoOneFarmed() {
// Ensure that received pool coin amount is greater than the original liquid farm amount
s.Require().True(s.getBalance(s.addr(1), pool.PoolCoinDenom).Amount.GT(sdk.NewInt(50_000_000)))
}

func (s *KeeperTestSuite) TestRewardsAuction_RewardsAndFees() {
pair := s.createPairWithLastPrice(helperAddr, "denom1", "denom2", sdk.NewDec(1))
pool := s.createPool(helperAddr, pair.Id, utils.ParseCoins("100_000_000denom1, 100_000_000denom2"))
plan := s.createPrivatePlan(s.addr(0), []lpfarmtypes.RewardAllocation{
{
PairId: pool.PairId,
RewardsPerDay: utils.ParseCoins("100_000_000stake"),
},
})
s.fundAddr(plan.GetFarmingPoolAddress(), utils.ParseCoins("100_000_000stake"))

// Fee rate is 10%
liquidFarm := s.createLiquidFarm(pool.Id, sdk.ZeroInt(), sdk.ZeroInt(), utils.ParseDec("0.1"))
s.nextBlock()

s.liquidFarm(pool.Id, s.addr(0), utils.ParseCoin("10_000_000pool1"), true)
s.nextBlock()

s.liquidFarm(pool.Id, s.addr(1), utils.ParseCoin("10_000_000pool1"), true)
s.nextBlock()

withdrawnRewardsReserveAddr := types.WithdrawnRewardsReserveAddress(pool.Id)
s.Require().False(s.getBalances(withdrawnRewardsReserveAddr).IsZero())

s.nextAuction()

s.placeBid(pool.Id, s.addr(5), utils.ParseCoin("2_000_000pool1"), true)
s.nextBlock()

liquidFarmReserveAddr := types.LiquidFarmReserveAddress(pool.Id)
farmingRewards := s.app.LPFarmKeeper.Rewards(s.ctx, liquidFarmReserveAddr, pool.PoolCoinDenom)
truncatedRewards, _ := farmingRewards.TruncateDecimal()
spendable := s.app.BankKeeper.SpendableCoins(s.ctx, withdrawnRewardsReserveAddr)
totalRewards := truncatedRewards.Add(spendable...)

deducted, fees := types.DeductFees(totalRewards, liquidFarm.FeeRate)

s.nextAuction()

auction, found := s.keeper.GetRewardsAuction(s.ctx, 1, pool.Id)
s.Require().True(found)

s.Require().True(auction.Rewards.IsEqual(deducted.Add(fees...)))
s.Require().True(auction.Fees.IsEqual(fees))
}