mirror of
				https://github.com/0glabs/0g-chain.git
				synced 2025-11-04 11:17:28 +00:00 
			
		
		
		
	update lend proposals to use community pool (#1460)
* point community pool lend proposals at fee pool * update community pool lend proposal tests * remove unused begin blocker * increase test coverage * fix x/community proposal comments
This commit is contained in:
		
							parent
							
								
									b26e12a579
								
							
						
					
					
						commit
						d05484cf88
					
				@ -1,12 +0,0 @@
 | 
			
		||||
package community
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	sdk "github.com/cosmos/cosmos-sdk/types"
 | 
			
		||||
	"github.com/kava-labs/kava/x/community/keeper"
 | 
			
		||||
	abci "github.com/tendermint/tendermint/abci/types"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// BeginBlocker runs at the start of every block.
 | 
			
		||||
func BeginBlocker(ctx sdk.Context, _ abci.RequestBeginBlock, k keeper.Keeper) {
 | 
			
		||||
	// TODO: process proposals here
 | 
			
		||||
}
 | 
			
		||||
@ -61,3 +61,26 @@ func TestParseWithdrawProposal(t *testing.T) {
 | 
			
		||||
	require.Equal(t, "Withdraw some KAVA from community pool to Lend!", proposal.Description)
 | 
			
		||||
	require.Equal(t, expectedAmount, proposal.Amount)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestParseFileNoExists(t *testing.T) {
 | 
			
		||||
	cdc := codec.NewAminoCodec(codec.NewLegacyAmino())
 | 
			
		||||
	_, err := utils.ParseCommunityPoolLendDepositProposal(cdc, "not-a-file.json")
 | 
			
		||||
	require.ErrorContains(t, err, "no such file or directory")
 | 
			
		||||
	_, err = utils.ParseCommunityPoolLendWithdrawProposal(cdc, "not-a-file.json")
 | 
			
		||||
	require.ErrorContains(t, err, "no such file or directory")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestParseFileMalformed(t *testing.T) {
 | 
			
		||||
	cdc := codec.NewAminoCodec(codec.NewLegacyAmino())
 | 
			
		||||
	malformed := testutil.WriteToNewTempFile(t, `
 | 
			
		||||
{
 | 
			
		||||
	"title": "I'm malformed b/c there's no closing quote,
 | 
			
		||||
	"description": "A description",
 | 
			
		||||
	"amount": [{"denom": "ukava", "amount": "100000000000"}]
 | 
			
		||||
}
 | 
			
		||||
`)
 | 
			
		||||
	_, err := utils.ParseCommunityPoolLendDepositProposal(cdc, malformed.Name())
 | 
			
		||||
	require.ErrorContains(t, err, "invalid character")
 | 
			
		||||
	_, err = utils.ParseCommunityPoolLendWithdrawProposal(cdc, malformed.Name())
 | 
			
		||||
	require.ErrorContains(t, err, "invalid character")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -12,8 +12,6 @@ import (
 | 
			
		||||
	"github.com/kava-labs/kava/x/community/types"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const legacyCommunityPoolAddr = "kava1jv65s3grqf6v6jl3dp4t6c9t9rk99cd8m2splc"
 | 
			
		||||
 | 
			
		||||
type grpcQueryTestSuite struct {
 | 
			
		||||
	KeeperTestSuite
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -8,10 +8,31 @@ import (
 | 
			
		||||
 | 
			
		||||
// HandleCommunityPoolLendDepositProposal is a handler for executing a passed community pool lend deposit proposal.
 | 
			
		||||
func HandleCommunityPoolLendDepositProposal(ctx sdk.Context, k Keeper, p *types.CommunityPoolLendDepositProposal) error {
 | 
			
		||||
	// move funds from community pool to x/community so hard position is held by this module.
 | 
			
		||||
	err := k.distrKeeper.DistributeFromFeePool(ctx, p.Amount, k.moduleAddress)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	// deposit funds into hard
 | 
			
		||||
	return k.hardKeeper.Deposit(ctx, k.moduleAddress, p.Amount)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// HandleCommunityPoolLendWithdrawProposal is a handler for executing a passed community pool lend withdraw proposal.
 | 
			
		||||
func HandleCommunityPoolLendWithdrawProposal(ctx sdk.Context, k Keeper, p *types.CommunityPoolLendWithdrawProposal) error {
 | 
			
		||||
	return k.hardKeeper.Withdraw(ctx, k.moduleAddress, p.Amount)
 | 
			
		||||
	// hard allows attempting to withdraw more funds than there is a deposit for.
 | 
			
		||||
	// this means the amount that gets withdrawn will not necessarily match the amount set in the proposal.
 | 
			
		||||
	// to calculate how much is withdrawn, compare this module's balance before & after withdraw.
 | 
			
		||||
	balanceBefore := k.bankKeeper.GetAllBalances(ctx, k.moduleAddress)
 | 
			
		||||
 | 
			
		||||
	// withdraw funds from x/hard to this module account
 | 
			
		||||
	err := k.hardKeeper.Withdraw(ctx, k.moduleAddress, p.Amount)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	balanceAfter := k.bankKeeper.GetAllBalances(ctx, k.moduleAddress)
 | 
			
		||||
	totalWithdrawn := balanceAfter.Sub(balanceBefore)
 | 
			
		||||
 | 
			
		||||
	// send all withdrawn coins back to community pool
 | 
			
		||||
	return k.distrKeeper.FundCommunityPool(ctx, totalWithdrawn, k.moduleAddress)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -78,16 +78,11 @@ func (suite *proposalTestSuite) SetupTest() {
 | 
			
		||||
 | 
			
		||||
	// give the community pool some funds
 | 
			
		||||
	// ukava
 | 
			
		||||
	err := suite.App.FundModuleAccount(suite.Ctx, types.ModuleAccountName, ukava(1e10))
 | 
			
		||||
	suite.NoError(err)
 | 
			
		||||
 | 
			
		||||
	suite.FundCommunityPool(ukava(1e10))
 | 
			
		||||
	// usdx
 | 
			
		||||
	err = suite.App.FundModuleAccount(suite.Ctx, types.ModuleAccountName, usdx(1e10))
 | 
			
		||||
	suite.NoError(err)
 | 
			
		||||
 | 
			
		||||
	suite.FundCommunityPool(usdx(1e10))
 | 
			
		||||
	// other-denom
 | 
			
		||||
	err = suite.App.FundModuleAccount(suite.Ctx, types.ModuleAccountName, otherdenom(1e10))
 | 
			
		||||
	suite.NoError(err)
 | 
			
		||||
	suite.FundCommunityPool(otherdenom(1e10))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (suite *proposalTestSuite) NextBlock() {
 | 
			
		||||
@ -99,6 +94,27 @@ func (suite *proposalTestSuite) NextBlock() {
 | 
			
		||||
	suite.App.BeginBlocker(suite.Ctx, abcitypes.RequestBeginBlock{})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (suite *proposalTestSuite) FundCommunityPool(coins sdk.Coins) {
 | 
			
		||||
	// mint to ephemeral account
 | 
			
		||||
	ephemeralAcc := app.RandomAddress()
 | 
			
		||||
	suite.NoError(suite.App.FundAccount(suite.Ctx, ephemeralAcc, coins))
 | 
			
		||||
	// fund community pool with newly minted coins
 | 
			
		||||
	suite.NoError(suite.App.GetDistrKeeper().FundCommunityPool(suite.Ctx, coins, ephemeralAcc))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (suite *proposalTestSuite) GetCommunityPoolBalance() sdk.Coins {
 | 
			
		||||
	balance, change := suite.App.GetDistrKeeper().GetFeePoolCommunityCoins(suite.Ctx).TruncateDecimal()
 | 
			
		||||
	// expect no decimal dust
 | 
			
		||||
	suite.True(sdk.NewDecCoins().IsEqual(change), "expected no decimal dust in community pool")
 | 
			
		||||
	return balance
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (suite *proposalTestSuite) CheckCommunityPoolBalance(expected sdk.Coins) {
 | 
			
		||||
	actual := suite.GetCommunityPoolBalance()
 | 
			
		||||
	// check that balance is expected
 | 
			
		||||
	suite.True(expected.IsEqual(actual), fmt.Sprintf("unexpected balance in community pool\nexpected: %s\nactual: %s", expected, actual))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (suite *proposalTestSuite) TestCommunityLendDepositProposal() {
 | 
			
		||||
	testCases := []struct {
 | 
			
		||||
		name             string
 | 
			
		||||
@ -148,7 +164,7 @@ func (suite *proposalTestSuite) TestCommunityLendDepositProposal() {
 | 
			
		||||
					Amount:      ukava(1e11),
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
			expectedErr:      "insufficient funds",
 | 
			
		||||
			expectedErr:      "community pool does not have sufficient coins to distribute",
 | 
			
		||||
			expectedDeposits: []sdk.Coins{},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
@ -280,7 +296,7 @@ func (suite *proposalTestSuite) TestCommunityLendWithdrawProposal() {
 | 
			
		||||
				suite.NoError(err, "unexpected error while seeding lend deposit")
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			beforeBalance := suite.Keeper.GetModuleAccountBalance(suite.Ctx)
 | 
			
		||||
			beforeBalance := suite.GetCommunityPoolBalance()
 | 
			
		||||
 | 
			
		||||
			// run the proposals
 | 
			
		||||
			for i, proposal := range tc.proposals {
 | 
			
		||||
@ -306,7 +322,7 @@ func (suite *proposalTestSuite) TestCommunityLendWithdrawProposal() {
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// expect funds to be distributed back to community pool
 | 
			
		||||
			suite.App.CheckBalance(suite.T(), suite.Ctx, suite.MaccAddress, beforeBalance.Add(tc.expectedWithdrawal...))
 | 
			
		||||
			suite.CheckCommunityPoolBalance(beforeBalance.Add(tc.expectedWithdrawal...))
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -27,5 +27,6 @@ type HardKeeper interface {
 | 
			
		||||
 | 
			
		||||
// DistributionKeeper defines the contract needed to be fulfilled for distribution dependencies.
 | 
			
		||||
type DistributionKeeper interface {
 | 
			
		||||
	GetFeePoolCommunityCoins(ctx sdk.Context) sdk.DecCoins
 | 
			
		||||
	DistributeFromFeePool(ctx sdk.Context, amount sdk.Coins, receiveAddr sdk.AccAddress) error
 | 
			
		||||
	FundCommunityPool(ctx sdk.Context, amount sdk.Coins, sender sdk.AccAddress) error
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user