2022-09-12 16:23:26 +00:00
|
|
|
package keeper_test
|
|
|
|
|
|
|
|
import (
|
|
|
|
"testing"
|
|
|
|
|
2023-04-05 23:21:59 +00:00
|
|
|
sdkmath "cosmossdk.io/math"
|
2022-09-12 16:23:26 +00:00
|
|
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
"github.com/stretchr/testify/suite"
|
|
|
|
|
|
|
|
"github.com/kava-labs/kava/x/earn/testutil"
|
|
|
|
"github.com/kava-labs/kava/x/earn/types"
|
|
|
|
)
|
|
|
|
|
|
|
|
type vaultShareTestSuite struct {
|
|
|
|
testutil.Suite
|
|
|
|
}
|
|
|
|
|
|
|
|
func (suite *vaultShareTestSuite) SetupTest() {
|
|
|
|
suite.Suite.SetupTest()
|
|
|
|
suite.Keeper.SetParams(suite.Ctx, types.DefaultParams())
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestVaultShareTestSuite(t *testing.T) {
|
|
|
|
suite.Run(t, new(vaultShareTestSuite))
|
|
|
|
}
|
|
|
|
|
|
|
|
func (suite *vaultShareTestSuite) TestConvertToShares() {
|
|
|
|
vaultDenom := "usdx"
|
|
|
|
|
|
|
|
tests := []struct {
|
|
|
|
name string
|
|
|
|
beforeConvert func()
|
|
|
|
giveAmount sdk.Coin
|
|
|
|
wantShares types.VaultShare
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
name: "initial 1:1",
|
|
|
|
beforeConvert: func() {},
|
2023-04-05 23:21:59 +00:00
|
|
|
giveAmount: sdk.NewCoin(vaultDenom, sdkmath.NewInt(100)),
|
2022-09-12 16:23:26 +00:00
|
|
|
wantShares: types.NewVaultShare(vaultDenom, sdk.NewDec(100)),
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "value doubled",
|
|
|
|
|
|
|
|
beforeConvert: func() {
|
|
|
|
// set total shares set total value for hard
|
|
|
|
// value is double than shares
|
|
|
|
// shares is 2x price now
|
2023-04-05 23:21:59 +00:00
|
|
|
suite.addTotalShareAndValue(vaultDenom, sdk.NewDec(100), sdkmath.NewInt(200))
|
2022-09-12 16:23:26 +00:00
|
|
|
},
|
2023-04-05 23:21:59 +00:00
|
|
|
giveAmount: sdk.NewCoin(vaultDenom, sdkmath.NewInt(100)),
|
2022-09-12 16:23:26 +00:00
|
|
|
wantShares: types.NewVaultShare(vaultDenom, sdk.NewDec(50)),
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "truncate",
|
|
|
|
|
|
|
|
beforeConvert: func() {
|
2023-04-05 23:21:59 +00:00
|
|
|
suite.addTotalShareAndValue(vaultDenom, sdk.NewDec(1000), sdkmath.NewInt(1001))
|
2022-09-12 16:23:26 +00:00
|
|
|
},
|
2023-04-05 23:21:59 +00:00
|
|
|
giveAmount: sdk.NewCoin(vaultDenom, sdkmath.NewInt(100)),
|
2022-09-12 16:23:26 +00:00
|
|
|
// 100 * 100 / 101 = 99.0099something
|
|
|
|
wantShares: types.NewVaultShare(vaultDenom, sdk.NewDec(100).MulInt64(1000).QuoInt64(1001)),
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, tt := range tests {
|
|
|
|
suite.Run(tt.name, func() {
|
|
|
|
// Reset state
|
|
|
|
suite.Suite.SetupTest()
|
2022-09-12 17:29:35 +00:00
|
|
|
suite.CreateVault(vaultDenom, types.StrategyTypes{types.STRATEGY_TYPE_HARD}, false, nil)
|
2022-09-12 16:23:26 +00:00
|
|
|
err := suite.App.FundModuleAccount(
|
|
|
|
suite.Ctx,
|
|
|
|
types.ModuleName,
|
|
|
|
sdk.NewCoins(sdk.NewInt64Coin(vaultDenom, 10000)),
|
|
|
|
)
|
|
|
|
suite.Require().NoError(err)
|
|
|
|
|
|
|
|
// Run any deposits or any other setup
|
|
|
|
tt.beforeConvert()
|
|
|
|
|
|
|
|
issuedShares, err := suite.Keeper.ConvertToShares(suite.Ctx, tt.giveAmount)
|
|
|
|
suite.Require().NoError(err)
|
|
|
|
|
|
|
|
suite.Equal(tt.wantShares, issuedShares)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (suite *vaultShareTestSuite) addTotalShareAndValue(
|
|
|
|
vaultDenom string,
|
|
|
|
vaultShares sdk.Dec,
|
2023-04-05 23:21:59 +00:00
|
|
|
hardDeposit sdkmath.Int,
|
2022-09-12 16:23:26 +00:00
|
|
|
) {
|
|
|
|
macc := suite.AccountKeeper.GetModuleAccount(suite.Ctx, types.ModuleName)
|
|
|
|
|
|
|
|
vaultRecord, found := suite.Keeper.GetVaultRecord(suite.Ctx, vaultDenom)
|
|
|
|
if !found {
|
|
|
|
vaultRecord = types.NewVaultRecord(vaultDenom, sdk.ZeroDec())
|
|
|
|
}
|
|
|
|
|
|
|
|
// Add to vault record
|
|
|
|
vaultRecord.TotalShares.Amount = vaultRecord.TotalShares.Amount.Add(vaultShares)
|
|
|
|
|
|
|
|
// set total shares
|
|
|
|
suite.Keeper.UpdateVaultRecord(
|
|
|
|
suite.Ctx,
|
|
|
|
vaultRecord,
|
|
|
|
)
|
|
|
|
// add value for hard -- this does not set
|
|
|
|
err := suite.HardKeeper.Deposit(
|
|
|
|
suite.Ctx,
|
|
|
|
macc.GetAddress(),
|
|
|
|
sdk.NewCoins(sdk.NewCoin(vaultDenom, hardDeposit)),
|
|
|
|
)
|
|
|
|
suite.Require().NoError(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestPrecisionMulQuoOrder(t *testing.T) {
|
|
|
|
assetAmount := sdk.NewDec(100)
|
|
|
|
totalShares := sdk.NewDec(100)
|
|
|
|
totalValue := sdk.NewDec(105)
|
|
|
|
|
|
|
|
// issuedShares = assetAmount * (totalValue / totalShares)
|
|
|
|
// = (assetAmount * totalShares) / totalValue
|
|
|
|
mulFirst := assetAmount.Mul(totalShares).QuoTruncate(totalValue)
|
|
|
|
quoFirst := assetAmount.Mul(totalShares.QuoTruncate(totalValue))
|
|
|
|
|
|
|
|
assert.Equal(t, sdk.MustNewDecFromStr("95.238095238095238095"), mulFirst)
|
|
|
|
assert.Equal(t, sdk.MustNewDecFromStr("95.238095238095238000"), quoFirst)
|
|
|
|
|
|
|
|
assert.NotEqual(t, mulFirst, quoFirst)
|
|
|
|
}
|