Skip to content

Commit

Permalink
chore: dex apr calculation fix
Browse files Browse the repository at this point in the history
  • Loading branch information
kenta-elys committed Dec 4, 2023
1 parent 25f1a33 commit 949c66b
Show file tree
Hide file tree
Showing 4 changed files with 131 additions and 5 deletions.
8 changes: 4 additions & 4 deletions x/incentive/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -467,7 +467,7 @@ func (k Keeper) UpdateLPRewardsUnclaimed(ctx sdk.Context, lpIncentive types.Ince
// ----------------------------------

// Update APR for amm pools
k.UpdateAmmPoolAPR(ctx, lpIncentive)
k.UpdateAmmPoolAPR(ctx, lpIncentive, totalProxyTVL)

return nil
}
Expand Down Expand Up @@ -592,9 +592,9 @@ func (k Keeper) UpdateAmmPoolAPR(ctx sdk.Context, lpIncentive types.IncentiveInf
poolShare = proxyTVL.Quo(totalProxyTVL)
}

// Dex reward Apr per pool = (total LM Dex reward allocated per day*((tvl of pool * multiplier)/total proxy TVL) ) * 365 / TVL of pool
totalLMDexRewardsAllocatedPerDay := poolInfo.DexRewardAmountGiven.MulInt(lpIncentive.AllocationEpochInBlocks).QuoInt(poolInfo.NumBlocks)
poolInfo.DexApr = totalLMDexRewardsAllocatedPerDay.Mul(poolShare).MulInt(sdk.NewInt(ptypes.DaysPerYear)).Quo(tvl)
// Dex reward Apr per pool = total accumulated usdc rewards for 7 day * 52/ tvl of pool
totalLMDexRewardsAllocatedPerWeek := poolInfo.DexRewardAmountGiven.MulInt(lpIncentive.AllocationEpochInBlocks).MulInt(sdk.NewInt(ptypes.DaysPerWeek)).QuoInt(poolInfo.NumBlocks)
poolInfo.DexApr = totalLMDexRewardsAllocatedPerWeek.MulInt(sdk.NewInt(ptypes.WeeksPerYear)).Quo(tvl)

// Eden reward Apr per pool = (total LM Eden reward allocated per day*((tvl of pool * multiplier)/total proxy TVL) ) * 365 / TVL of pool
totalLMEdenRewardsAllocatedPerDay := poolInfo.EdenRewardAmountGiven.Mul(lpIncentive.AllocationEpochInBlocks).Quo(poolInfo.NumBlocks)
Expand Down
120 changes: 120 additions & 0 deletions x/incentive/keeper/keeper_apr_per_pool_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
package keeper_test

import (
"testing"

tmproto "github.com/cometbft/cometbft/proto/tendermint/types"
sdk "github.com/cosmos/cosmos-sdk/types"
simapp "github.com/elys-network/elys/app"
ammtypes "github.com/elys-network/elys/x/amm/types"
"github.com/elys-network/elys/x/incentive/types"
ptypes "github.com/elys-network/elys/x/parameter/types"
"github.com/stretchr/testify/require"
)

func TestAPRCalculationPerPool(t *testing.T) {
app := simapp.InitElysTestApp(initChain)
ctx := app.BaseApp.NewContext(initChain, tmproto.Header{})

ik, amm, oracle := app.IncentiveKeeper, app.AmmKeeper, app.OracleKeeper

// Setup coin prices
SetupStableCoinPrices(ctx, oracle)

// Generate 1 random account with 1000stake balanced
addr := simapp.AddTestAddrs(app, ctx, 2, sdk.NewInt(1000000))

// Create a pool
// Mint 100000USDC
usdcToken := sdk.NewCoins(sdk.NewCoin(ptypes.BaseCurrency, sdk.NewInt(100000)))

err := app.BankKeeper.MintCoins(ctx, ammtypes.ModuleName, usdcToken)
require.NoError(t, err)
err = app.BankKeeper.SendCoinsFromModuleToAccount(ctx, ammtypes.ModuleName, addr[0], usdcToken)
require.NoError(t, err)

poolAssets := []ammtypes.PoolAsset{
{
Weight: sdk.NewInt(50),
Token: sdk.NewCoin(ptypes.Elys, sdk.NewInt(100000)),
},
{
Weight: sdk.NewInt(50),
Token: sdk.NewCoin(ptypes.BaseCurrency, sdk.NewInt(10000)),
},
}

argSwapFee := sdk.MustNewDecFromStr("0.0")
argExitFee := sdk.MustNewDecFromStr("0.0")

poolParams := &ammtypes.PoolParams{
SwapFee: argSwapFee,
ExitFee: argExitFee,
}

msg := ammtypes.NewMsgCreatePool(
addr[0].String(),
poolParams,
poolAssets,
)

// Create a Elys+USDC pool
poolId, err := amm.CreatePool(ctx, msg)
require.NoError(t, err)
require.Equal(t, poolId, uint64(1))

pools := amm.GetAllPool(ctx)

// check length of pools
require.Equal(t, len(pools), 1)

// check block height
require.Equal(t, int64(0), ctx.BlockHeight())

lpIncentive := types.IncentiveInfo{
// reward amount in eden for 1 year
EdenAmountPerYear: sdk.NewInt(1000000000),
// starting block height of the distribution
DistributionStartBlock: sdk.NewInt(1),
// distribution duration - block number per year
TotalBlocksPerYear: sdk.NewInt(10000),
// we set block numbers in 24 hrs
AllocationEpochInBlocks: sdk.NewInt(100),
// maximum eden allocation per day that won't exceed 30% apr
MaxEdenPerAllocation: sdk.NewInt(100),
// number of block intervals that distribute rewards.
DistributionEpochInBlocks: sdk.NewInt(10),
// current epoch in block number
CurrentEpochInBlocks: sdk.NewInt(1),
// eden boost apr (0-1) range
EdenBoostApr: sdk.NewDec(1),
}

ctx = ctx.WithBlockHeight(lpIncentive.DistributionEpochInBlocks.Int64())
ik.UpdateLPRewardsUnclaimed(ctx, lpIncentive)

// Get pool info from incentive param
poolInfo, found := ik.GetPoolInfo(ctx, poolId)
require.Equal(t, found, true)
require.GreaterOrEqual(t, poolInfo.EdenApr.MulInt(sdk.NewInt(100)).TruncateInt().Int64(), int64(90))

// Get dex rewards per pool
revenueAddress := ammtypes.NewPoolRevenueAddress(poolId)

// Feed dex rewards
usdcToken = sdk.NewCoins(sdk.NewCoin(ptypes.BaseCurrency, sdk.NewInt(1000)))
err = app.BankKeeper.MintCoins(ctx, ammtypes.ModuleName, usdcToken)
require.NoError(t, err)
err = app.BankKeeper.SendCoinsFromModuleToAccount(ctx, ammtypes.ModuleName, revenueAddress, usdcToken)
require.NoError(t, err)

// 1 week later.
ctx = ctx.WithBlockHeight(lpIncentive.AllocationEpochInBlocks.Mul(sdk.NewInt(ptypes.DaysPerWeek)).Int64())
poolInfo.NumBlocks = sdk.NewInt(ctx.BlockHeight())
ik.SetPoolInfo(ctx, poolId, poolInfo)

ik.UpdateLPRewardsUnclaimed(ctx, lpIncentive)
poolInfo, found = ik.GetPoolInfo(ctx, poolId)
require.Equal(t, found, true)
require.GreaterOrEqual(t, poolInfo.DexApr.MulInt(sdk.NewInt(100)).TruncateInt().Int64(), int64(90))
}
2 changes: 1 addition & 1 deletion x/incentive/keeper/keeper_fees_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -222,5 +222,5 @@ func TestCollectDEXRevenueToIncentiveModule(t *testing.T) {
// It should be 3000=1000+2000 usdc
require.Equal(t, collectedAmt, sdk.Coins{sdk.NewCoin(ptypes.BaseCurrency, sdk.NewInt(3000))})
// It should be 1950=3000*0.65 usdc
require.Equal(t, rewardForLpsAmt, sdk.DecCoins{sdk.NewDecCoin(ptypes.BaseCurrency, sdk.NewInt(1950))})
require.Equal(t, rewardForLpsAmt, sdk.DecCoins{sdk.NewDecCoin(ptypes.BaseCurrency, sdk.NewInt(1800))})
}
6 changes: 6 additions & 0 deletions x/parameter/types/keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,12 @@ const (
// Days per year
DaysPerYear = 365

// Weeks per year
WeeksPerYear = 52

// Days per week
DaysPerWeek = 7

// Return ok
RES_OK = uint64(200)
)
Expand Down

0 comments on commit 949c66b

Please sign in to comment.