remove useless modules

This commit is contained in:
Solovyov1796 2024-05-01 11:46:33 +08:00 committed by 0g-wh
parent 3b75c9a3db
commit 47d31239d2
687 changed files with 1607 additions and 170648 deletions

View File

@ -32,14 +32,9 @@ import (
"github.com/cosmos/cosmos-sdk/x/staking"
"github.com/cosmos/cosmos-sdk/x/supply"
"github.com/0glabs/0g-chain/x/auction"
"github.com/0glabs/0g-chain/x/bep3"
"github.com/0glabs/0g-chain/x/cdp"
"github.com/0glabs/0g-chain/x/committee"
"github.com/0glabs/0g-chain/x/incentive"
"github.com/0glabs/0g-chain/x/kavadist"
"github.com/0glabs/0g-chain/x/pricefeed"
"github.com/0glabs/0g-chain/x/swap"
validatorvesting "github.com/0glabs/0g-chain/x/validator-vesting"
)

View File

@ -34,11 +34,9 @@ import (
"github.com/stretchr/testify/suite"
"github.com/0glabs/0g-chain/app"
cdptypes "github.com/0glabs/0g-chain/x/cdp/types"
evmutilkeeper "github.com/0glabs/0g-chain/x/evmutil/keeper"
evmutiltestutil "github.com/0glabs/0g-chain/x/evmutil/testutil"
evmutiltypes "github.com/0glabs/0g-chain/x/evmutil/types"
hardtypes "github.com/0glabs/0g-chain/x/hard/types"
pricefeedtypes "github.com/0glabs/0g-chain/x/pricefeed/types"
)
@ -173,47 +171,6 @@ func (suite *EIP712TestSuite) SetupTest() {
feemarketGenesis.Params.EnableHeight = 1
feemarketGenesis.Params.NoBaseFee = false
cdpGenState := cdptypes.DefaultGenesisState()
cdpGenState.Params.GlobalDebtLimit = sdk.NewInt64Coin("usdx", 53000000000000)
cdpGenState.Params.CollateralParams = cdptypes.CollateralParams{
{
Denom: USDCCoinDenom,
Type: USDCCDPType,
LiquidationRatio: sdk.MustNewDecFromStr("1.01"),
DebtLimit: sdk.NewInt64Coin("usdx", 500000000000),
StabilityFee: sdk.OneDec(),
AuctionSize: sdkmath.NewIntFromUint64(10000000000),
LiquidationPenalty: sdk.MustNewDecFromStr("0.05"),
CheckCollateralizationIndexCount: sdkmath.NewInt(10),
KeeperRewardPercentage: sdk.MustNewDecFromStr("0.01"),
SpotMarketID: "usdc:usd",
LiquidationMarketID: "usdc:usd:30",
ConversionFactor: sdkmath.NewInt(18),
},
}
hardGenState := hardtypes.DefaultGenesisState()
hardGenState.Params.MoneyMarkets = []hardtypes.MoneyMarket{
{
Denom: "usdx",
BorrowLimit: hardtypes.BorrowLimit{
HasMaxLimit: true,
MaximumLimit: sdk.MustNewDecFromStr("100000000000"),
LoanToValue: sdk.MustNewDecFromStr("1"),
},
SpotMarketID: "usdx:usd",
ConversionFactor: sdkmath.NewInt(1_000_000),
InterestRateModel: hardtypes.InterestRateModel{
BaseRateAPY: sdk.MustNewDecFromStr("0.05"),
BaseMultiplier: sdk.MustNewDecFromStr("2"),
Kink: sdk.MustNewDecFromStr("0.8"),
JumpMultiplier: sdk.MustNewDecFromStr("10"),
},
ReserveFactor: sdk.MustNewDecFromStr("0.05"),
KeeperRewardPercentage: sdk.ZeroDec(),
},
}
pricefeedGenState := pricefeedtypes.DefaultGenesisState()
pricefeedGenState.Params.Markets = []pricefeedtypes.Market{
{
@ -262,8 +219,6 @@ func (suite *EIP712TestSuite) SetupTest() {
genState := app.GenesisState{
evmtypes.ModuleName: cdc.MustMarshalJSON(evmGs),
feemarkettypes.ModuleName: cdc.MustMarshalJSON(feemarketGenesis),
cdptypes.ModuleName: cdc.MustMarshalJSON(&cdpGenState),
hardtypes.ModuleName: cdc.MustMarshalJSON(&hardGenState),
pricefeedtypes.ModuleName: cdc.MustMarshalJSON(&pricefeedGenState),
}
@ -607,21 +562,9 @@ func (suite *EIP712TestSuite) TestEIP712Tx() {
suite.usdcEVMAddr,
usdcAmt,
)
usdxAmt := sdkmath.NewInt(1_000_000).Mul(sdkmath.NewInt(tc.usdxToMintAmt))
mintMsg := cdptypes.NewMsgCreateCDP(
suite.testAddr,
sdk.NewCoin(USDCCoinDenom, usdcAmt),
sdk.NewCoin(cdptypes.DefaultStableDenom, usdxAmt),
USDCCDPType,
)
lendMsg := hardtypes.NewMsgDeposit(
suite.testAddr,
sdk.NewCoins(sdk.NewCoin(cdptypes.DefaultStableDenom, usdxAmt)),
)
msgs := []sdk.Msg{
&convertMsg,
&mintMsg,
&lendMsg,
}
if tc.updateMsgs != nil {
msgs = tc.updateMsgs(msgs)
@ -665,17 +608,17 @@ func (suite *EIP712TestSuite) TestEIP712Tx() {
suite.Require().Equal(sdk.ZeroInt(), amt.Amount)
// validate cdp
cdp, found := suite.tApp.GetCDPKeeper().GetCdpByOwnerAndCollateralType(suite.ctx, suite.testAddr, USDCCDPType)
suite.Require().True(found)
suite.Require().Equal(suite.testAddr, cdp.Owner)
suite.Require().Equal(sdk.NewCoin(USDCCoinDenom, suite.getEVMAmount(100)), cdp.Collateral)
suite.Require().Equal(sdk.NewCoin("usdx", sdkmath.NewInt(99_000_000)), cdp.Principal)
// cdp, found := suite.tApp.GetCDPKeeper().GetCdpByOwnerAndCollateralType(suite.ctx, suite.testAddr, USDCCDPType)
// suite.Require().True(found)
// suite.Require().Equal(suite.testAddr, cdp.Owner)
// suite.Require().Equal(sdk.NewCoin(USDCCoinDenom, suite.getEVMAmount(100)), cdp.Collateral)
// suite.Require().Equal(sdk.NewCoin("usdx", sdkmath.NewInt(99_000_000)), cdp.Principal)
// validate hard
hardDeposit, found := suite.tApp.GetHardKeeper().GetDeposit(suite.ctx, suite.testAddr)
suite.Require().True(found)
suite.Require().Equal(suite.testAddr, hardDeposit.Depositor)
suite.Require().Equal(sdk.NewCoins(sdk.NewCoin("usdx", sdkmath.NewInt(99_000_000))), hardDeposit.Amount)
// hardDeposit, found := suite.tApp.GetHardKeeper().GetDeposit(suite.ctx, suite.testAddr)
// suite.Require().True(found)
// suite.Require().Equal(suite.testAddr, hardDeposit.Depositor)
// suite.Require().Equal(sdk.NewCoins(sdk.NewCoin("usdx", sdkmath.NewInt(99_000_000))), hardDeposit.Amount)
} else {
suite.Require().NotEqual(resDeliverTx.Code, uint32(0), resCheckTx.Log)
suite.Require().Contains(resDeliverTx.Log, tc.errMsg)
@ -695,21 +638,9 @@ func (suite *EIP712TestSuite) TestEIP712Tx_DepositAndWithdraw() {
suite.usdcEVMAddr,
usdcAmt,
)
usdxAmt := sdkmath.NewInt(1_000_000).Mul(sdkmath.NewInt(99))
mintMsg := cdptypes.NewMsgCreateCDP(
suite.testAddr,
sdk.NewCoin(USDCCoinDenom, usdcAmt),
sdk.NewCoin(cdptypes.DefaultStableDenom, usdxAmt),
USDCCDPType,
)
lendMsg := hardtypes.NewMsgDeposit(
suite.testAddr,
sdk.NewCoins(sdk.NewCoin(cdptypes.DefaultStableDenom, usdxAmt)),
)
depositMsgs := []sdk.Msg{
&convertMsg,
&mintMsg,
&lendMsg,
}
// deliver deposit msg
@ -727,10 +658,10 @@ func (suite *EIP712TestSuite) TestEIP712Tx_DepositAndWithdraw() {
suite.Require().Equal(resDeliverTx.Code, uint32(0), resDeliverTx.Log)
// validate hard
hardDeposit, found := suite.tApp.GetHardKeeper().GetDeposit(suite.ctx, suite.testAddr)
suite.Require().True(found)
suite.Require().Equal(suite.testAddr, hardDeposit.Depositor)
suite.Require().Equal(sdk.NewCoins(sdk.NewCoin("usdx", sdkmath.NewInt(99_000_000))), hardDeposit.Amount)
// hardDeposit, found := suite.tApp.GetHardKeeper().GetDeposit(suite.ctx, suite.testAddr)
// suite.Require().True(found)
// suite.Require().Equal(suite.testAddr, hardDeposit.Depositor)
// suite.Require().Equal(sdk.NewCoins(sdk.NewCoin("usdx", sdkmath.NewInt(99_000_000))), hardDeposit.Amount)
// validate erc20 balance
coinBal, err := suite.evmutilKeeper.QueryERC20BalanceOf(suite.ctx, suite.usdcEVMAddr, suite.testEVMAddr)
@ -743,18 +674,7 @@ func (suite *EIP712TestSuite) TestEIP712Tx_DepositAndWithdraw() {
suite.testEVMAddr.String(),
sdk.NewCoin(USDCCoinDenom, usdcAmt),
)
cdpWithdrawMsg := cdptypes.NewMsgRepayDebt(
suite.testAddr,
USDCCDPType,
sdk.NewCoin(cdptypes.DefaultStableDenom, usdxAmt),
)
hardWithdrawMsg := hardtypes.NewMsgWithdraw(
suite.testAddr,
sdk.NewCoins(sdk.NewCoin(cdptypes.DefaultStableDenom, usdxAmt)),
)
withdrawMsgs := []sdk.Msg{
&hardWithdrawMsg,
&cdpWithdrawMsg,
&withdrawConvertMsg,
}
@ -772,10 +692,10 @@ func (suite *EIP712TestSuite) TestEIP712Tx_DepositAndWithdraw() {
suite.Require().Equal(resDeliverTx.Code, uint32(0), resDeliverTx.Log)
// validate hard & cdp should be repayed
_, found = suite.tApp.GetHardKeeper().GetDeposit(suite.ctx, suite.testAddr)
suite.Require().False(found)
_, found = suite.tApp.GetCDPKeeper().GetCdpByOwnerAndCollateralType(suite.ctx, suite.testAddr, USDCCDPType)
suite.Require().False(found)
// _, found = suite.tApp.GetHardKeeper().GetDeposit(suite.ctx, suite.testAddr)
// suite.Require().False(found)
// _, found = suite.tApp.GetCDPKeeper().GetCdpByOwnerAndCollateralType(suite.ctx, suite.testAddr, USDCCDPType)
// suite.Require().False(found)
// validate user cosmos erc20/usd balance
bk := suite.tApp.GetBankKeeper()

View File

@ -105,62 +105,29 @@ import (
feemarkettypes "github.com/evmos/ethermint/x/feemarket/types"
"github.com/gorilla/mux"
abci "github.com/tendermint/tendermint/abci/types"
tmjson "github.com/tendermint/tendermint/libs/json"
tmlog "github.com/tendermint/tendermint/libs/log"
dbm "github.com/tendermint/tm-db"
"github.com/0glabs/0g-chain/app/ante"
kavaparams "github.com/0glabs/0g-chain/app/params"
"github.com/0glabs/0g-chain/x/auction"
auctionkeeper "github.com/0glabs/0g-chain/x/auction/keeper"
auctiontypes "github.com/0glabs/0g-chain/x/auction/types"
"github.com/0glabs/0g-chain/x/bep3"
bep3keeper "github.com/0glabs/0g-chain/x/bep3/keeper"
bep3types "github.com/0glabs/0g-chain/x/bep3/types"
"github.com/0glabs/0g-chain/x/cdp"
cdpkeeper "github.com/0glabs/0g-chain/x/cdp/keeper"
cdptypes "github.com/0glabs/0g-chain/x/cdp/types"
"github.com/0glabs/0g-chain/x/committee"
committeeclient "github.com/0glabs/0g-chain/x/committee/client"
committeekeeper "github.com/0glabs/0g-chain/x/committee/keeper"
committeetypes "github.com/0glabs/0g-chain/x/committee/types"
"github.com/0glabs/0g-chain/x/community"
communityclient "github.com/0glabs/0g-chain/x/community/client"
communitykeeper "github.com/0glabs/0g-chain/x/community/keeper"
communitytypes "github.com/0glabs/0g-chain/x/community/types"
earn "github.com/0glabs/0g-chain/x/earn"
earnclient "github.com/0glabs/0g-chain/x/earn/client"
earnkeeper "github.com/0glabs/0g-chain/x/earn/keeper"
earntypes "github.com/0glabs/0g-chain/x/earn/types"
evmutil "github.com/0glabs/0g-chain/x/evmutil"
evmutilkeeper "github.com/0glabs/0g-chain/x/evmutil/keeper"
evmutiltypes "github.com/0glabs/0g-chain/x/evmutil/types"
"github.com/0glabs/0g-chain/x/hard"
hardkeeper "github.com/0glabs/0g-chain/x/hard/keeper"
hardtypes "github.com/0glabs/0g-chain/x/hard/types"
"github.com/0glabs/0g-chain/x/incentive"
incentivekeeper "github.com/0glabs/0g-chain/x/incentive/keeper"
incentivetypes "github.com/0glabs/0g-chain/x/incentive/types"
issuance "github.com/0glabs/0g-chain/x/issuance"
issuancekeeper "github.com/0glabs/0g-chain/x/issuance/keeper"
issuancetypes "github.com/0glabs/0g-chain/x/issuance/types"
"github.com/0glabs/0g-chain/x/kavadist"
kavadistclient "github.com/0glabs/0g-chain/x/kavadist/client"
kavadistkeeper "github.com/0glabs/0g-chain/x/kavadist/keeper"
kavadisttypes "github.com/0glabs/0g-chain/x/kavadist/types"
"github.com/0glabs/0g-chain/x/liquid"
liquidkeeper "github.com/0glabs/0g-chain/x/liquid/keeper"
liquidtypes "github.com/0glabs/0g-chain/x/liquid/types"
metrics "github.com/0glabs/0g-chain/x/metrics"
metricstypes "github.com/0glabs/0g-chain/x/metrics/types"
pricefeed "github.com/0glabs/0g-chain/x/pricefeed"
pricefeedkeeper "github.com/0glabs/0g-chain/x/pricefeed/keeper"
pricefeedtypes "github.com/0glabs/0g-chain/x/pricefeed/types"
"github.com/0glabs/0g-chain/x/router"
routerkeeper "github.com/0glabs/0g-chain/x/router/keeper"
routertypes "github.com/0glabs/0g-chain/x/router/types"
savings "github.com/0glabs/0g-chain/x/savings"
savingskeeper "github.com/0glabs/0g-chain/x/savings/keeper"
savingstypes "github.com/0glabs/0g-chain/x/savings/types"
"github.com/0glabs/0g-chain/x/swap"
swapkeeper "github.com/0glabs/0g-chain/x/swap/keeper"
swaptypes "github.com/0glabs/0g-chain/x/swap/types"
validatorvesting "github.com/0glabs/0g-chain/x/validator-vesting"
validatorvestingrest "github.com/0glabs/0g-chain/x/validator-vesting/client/rest"
validatorvestingtypes "github.com/0glabs/0g-chain/x/validator-vesting/types"
@ -189,12 +156,7 @@ var (
upgradeclient.LegacyCancelProposalHandler,
ibcclientclient.UpdateClientProposalHandler,
ibcclientclient.UpgradeProposalHandler,
kavadistclient.ProposalHandler,
committeeclient.ProposalHandler,
earnclient.DepositProposalHandler,
earnclient.WithdrawProposalHandler,
communityclient.LendDepositProposalHandler,
communityclient.LendWithdrawProposalHandler,
}),
params.AppModuleBasic{},
crisis.AppModuleBasic{},
@ -210,26 +172,13 @@ var (
vesting.AppModuleBasic{},
evm.AppModuleBasic{},
feemarket.AppModuleBasic{},
kavadist.AppModuleBasic{},
auction.AppModuleBasic{},
issuance.AppModuleBasic{},
bep3.AppModuleBasic{},
pricefeed.AppModuleBasic{},
swap.AppModuleBasic{},
cdp.AppModuleBasic{},
hard.AppModuleBasic{},
committee.AppModuleBasic{},
incentive.AppModuleBasic{},
savings.AppModuleBasic{},
validatorvesting.AppModuleBasic{},
evmutil.AppModuleBasic{},
liquid.AppModuleBasic{},
earn.AppModuleBasic{},
router.AppModuleBasic{},
mint.AppModuleBasic{},
community.AppModuleBasic{},
metrics.AppModuleBasic{},
consensus.AppModuleBasic{},
)
// module account permissions
@ -244,20 +193,9 @@ var (
ibctransfertypes.ModuleName: {authtypes.Minter, authtypes.Burner},
evmtypes.ModuleName: {authtypes.Minter, authtypes.Burner}, // used for secure addition and subtraction of balance using module account
evmutiltypes.ModuleName: {authtypes.Minter, authtypes.Burner},
kavadisttypes.KavaDistMacc: {authtypes.Minter},
auctiontypes.ModuleName: nil,
issuancetypes.ModuleAccountName: {authtypes.Minter, authtypes.Burner},
bep3types.ModuleName: {authtypes.Burner, authtypes.Minter},
swaptypes.ModuleName: nil,
cdptypes.ModuleName: {authtypes.Minter, authtypes.Burner},
cdptypes.LiquidatorMacc: {authtypes.Minter, authtypes.Burner},
hardtypes.ModuleAccountName: {authtypes.Minter},
savingstypes.ModuleAccountName: nil,
liquidtypes.ModuleAccountName: {authtypes.Minter, authtypes.Burner},
earntypes.ModuleAccountName: nil,
kavadisttypes.FundModuleAccount: nil,
minttypes.ModuleName: {authtypes.Minter},
communitytypes.ModuleName: nil,
}
)
@ -276,7 +214,6 @@ type Options struct {
MempoolAuthAddresses []sdk.AccAddress
EVMTrace string
EVMMaxGasWanted uint64
TelemetryOptions metricstypes.TelemetryOptions
}
// DefaultOptions is a sensible default Options value.
@ -384,7 +321,7 @@ func NewApp(
govtypes.StoreKey, paramstypes.StoreKey, ibcexported.StoreKey,
upgradetypes.StoreKey, evidencetypes.StoreKey, ibctransfertypes.StoreKey,
evmtypes.StoreKey, feemarkettypes.StoreKey, authzkeeper.StoreKey,
capabilitytypes.StoreKey, kavadisttypes.StoreKey, auctiontypes.StoreKey,
capabilitytypes.StoreKey,
issuancetypes.StoreKey, bep3types.StoreKey, pricefeedtypes.StoreKey,
swaptypes.StoreKey, cdptypes.StoreKey, hardtypes.StoreKey, communitytypes.StoreKey,
committeetypes.StoreKey, incentivetypes.StoreKey, evmutiltypes.StoreKey,
@ -422,8 +359,6 @@ func NewApp(
slashingSubspace := app.paramsKeeper.Subspace(slashingtypes.ModuleName)
govSubspace := app.paramsKeeper.Subspace(govtypes.ModuleName).WithKeyTable(govv1.ParamKeyTable())
crisisSubspace := app.paramsKeeper.Subspace(crisistypes.ModuleName)
kavadistSubspace := app.paramsKeeper.Subspace(kavadisttypes.ModuleName)
auctionSubspace := app.paramsKeeper.Subspace(auctiontypes.ModuleName)
issuanceSubspace := app.paramsKeeper.Subspace(issuancetypes.ModuleName)
bep3Subspace := app.paramsKeeper.Subspace(bep3types.ModuleName)
pricefeedSubspace := app.paramsKeeper.Subspace(pricefeedtypes.ModuleName)
@ -438,7 +373,6 @@ func NewApp(
feemarketSubspace := app.paramsKeeper.Subspace(feemarkettypes.ModuleName)
evmSubspace := app.paramsKeeper.Subspace(evmtypes.ModuleName)
evmutilSubspace := app.paramsKeeper.Subspace(evmutiltypes.ModuleName)
earnSubspace := app.paramsKeeper.Subspace(earntypes.ModuleName)
mintSubspace := app.paramsKeeper.Subspace(minttypes.ModuleName)
// set the BaseApp's parameter store
@ -602,13 +536,6 @@ func NewApp(
ibcRouter.AddRoute(ibctransfertypes.ModuleName, transferStack)
app.ibcKeeper.SetRouter(ibcRouter)
app.auctionKeeper = auctionkeeper.NewKeeper(
appCodec,
keys[auctiontypes.StoreKey],
auctionSubspace,
app.bankKeeper,
app.accountKeeper,
)
app.issuanceKeeper = issuancekeeper.NewKeeper(
appCodec,
keys[issuancetypes.StoreKey],
@ -744,7 +671,6 @@ func NewApp(
committeeGovRouter := govv1beta1.NewRouter()
committeeGovRouter.
AddRoute(govtypes.RouterKey, govv1beta1.ProposalHandler).
AddRoute(communitytypes.RouterKey, community.NewCommunityPoolProposalHandler(app.communityKeeper)).
AddRoute(paramproposal.RouterKey, params.NewParamChangeProposalHandler(app.paramsKeeper)).
AddRoute(upgradetypes.RouterKey, upgrade.NewSoftwareUpgradeProposalHandler(&app.upgradeKeeper))
// Note: the committee proposal handler is not registered on the committee router. This means committees cannot create or update other committees.
@ -766,12 +692,6 @@ func NewApp(
app.incentiveKeeper.Hooks(),
))
app.swapKeeper = *swapKeeper.SetHooks(app.incentiveKeeper.Hooks())
app.cdpKeeper = *cdpKeeper.SetHooks(cdptypes.NewMultiCDPHooks(app.incentiveKeeper.Hooks()))
app.hardKeeper = *hardKeeper.SetHooks(hardtypes.NewMultiHARDHooks(app.incentiveKeeper.Hooks()))
app.savingsKeeper = savingsKeeper // savings incentive hooks disabled
app.earnKeeper = *earnKeeper.SetHooks(app.incentiveKeeper.Hooks())
// create gov keeper with router
// NOTE this must be done after any keepers referenced in the gov router (ie committee) are defined
govRouter := govv1beta1.NewRouter()
@ -780,9 +700,9 @@ func NewApp(
AddRoute(paramproposal.RouterKey, params.NewParamChangeProposalHandler(app.paramsKeeper)).
AddRoute(upgradetypes.RouterKey, upgrade.NewSoftwareUpgradeProposalHandler(&app.upgradeKeeper)).
AddRoute(ibcclienttypes.RouterKey, ibcclient.NewClientProposalHandler(app.ibcKeeper.ClientKeeper)).
AddRoute(kavadisttypes.RouterKey, kavadist.NewCommunityPoolMultiSpendProposalHandler(app.kavadistKeeper)).
AddRoute(earntypes.RouterKey, earn.NewCommunityPoolProposalHandler(app.earnKeeper)).
AddRoute(communitytypes.RouterKey, community.NewCommunityPoolProposalHandler(app.communityKeeper)).
AddRoute(distrtypes.RouterKey, distr.NewCommunityPoolSpendProposalHandler(app.distrKeeper)).
AddRoute(committeetypes.RouterKey, committee.NewProposalHandler(app.committeeKeeper))
govConfig := govtypes.DefaultConfig()
@ -829,22 +749,12 @@ func NewApp(
transferModule,
vesting.NewAppModule(app.accountKeeper, app.bankKeeper),
authzmodule.NewAppModule(appCodec, app.authzKeeper, app.accountKeeper, app.bankKeeper, app.interfaceRegistry),
kavadist.NewAppModule(app.kavadistKeeper, app.accountKeeper),
auction.NewAppModule(app.auctionKeeper, app.accountKeeper, app.bankKeeper),
issuance.NewAppModule(app.issuanceKeeper, app.accountKeeper, app.bankKeeper),
bep3.NewAppModule(app.bep3Keeper, app.accountKeeper, app.bankKeeper),
pricefeed.NewAppModule(app.pricefeedKeeper, app.accountKeeper),
validatorvesting.NewAppModule(app.bankKeeper),
swap.NewAppModule(app.swapKeeper, app.accountKeeper),
cdp.NewAppModule(app.cdpKeeper, app.accountKeeper, app.pricefeedKeeper, app.bankKeeper),
hard.NewAppModule(app.hardKeeper, app.accountKeeper, app.bankKeeper, app.pricefeedKeeper),
committee.NewAppModule(app.committeeKeeper, app.accountKeeper),
incentive.NewAppModule(app.incentiveKeeper, app.accountKeeper, app.bankKeeper, app.cdpKeeper),
evmutil.NewAppModule(app.evmutilKeeper, app.bankKeeper, app.accountKeeper),
savings.NewAppModule(app.savingsKeeper, app.accountKeeper, app.bankKeeper),
liquid.NewAppModule(app.liquidKeeper),
earn.NewAppModule(app.earnKeeper, app.accountKeeper, app.bankKeeper),
router.NewAppModule(app.routerKeeper),
// nil InflationCalculationFn, use SDK's default inflation function
mint.NewAppModule(appCodec, app.mintKeeper, app.accountKeeper, nil, mintSubspace),
community.NewAppModule(app.communityKeeper, app.accountKeeper),
@ -853,7 +763,6 @@ func NewApp(
// Warning: Some begin blockers must run before others. Ensure the dependencies are understood before modifying this list.
app.mm.SetOrderBeginBlockers(
metricstypes.ModuleName,
// Upgrade begin blocker runs migrations on the first block after an upgrade. It should run before any other module.
upgradetypes.ModuleName,
// Capability begin blocker runs non state changing initialization.
@ -863,7 +772,6 @@ func NewApp(
committeetypes.ModuleName,
// Community begin blocker should run before x/mint and x/kavadist since
// the disable inflation upgrade will update those modules' params.
communitytypes.ModuleName,
minttypes.ModuleName,
distrtypes.ModuleName,
// During begin block slashing happens after distr.BeginBlocker so that
@ -874,18 +782,13 @@ func NewApp(
stakingtypes.ModuleName,
feemarkettypes.ModuleName,
evmtypes.ModuleName,
kavadisttypes.ModuleName,
// Auction begin blocker will close out expired auctions and pay debt back to cdp.
// It should be run before cdp begin blocker which cancels out debt with stable and starts more auctions.
auctiontypes.ModuleName,
cdptypes.ModuleName,
bep3types.ModuleName,
hardtypes.ModuleName,
issuancetypes.ModuleName,
incentivetypes.ModuleName,
ibcexported.ModuleName,
// Add all remaining modules with an empty begin blocker below since cosmos 0.45.0 requires it
swaptypes.ModuleName,
vestingtypes.ModuleName,
pricefeedtypes.ModuleName,
validatorvestingtypes.ModuleName,
@ -917,19 +820,13 @@ func NewApp(
pricefeedtypes.ModuleName,
// Add all remaining modules with an empty end blocker below since cosmos 0.45.0 requires it
capabilitytypes.ModuleName,
incentivetypes.ModuleName,
issuancetypes.ModuleName,
slashingtypes.ModuleName,
distrtypes.ModuleName,
auctiontypes.ModuleName,
bep3types.ModuleName,
cdptypes.ModuleName,
hardtypes.ModuleName,
committeetypes.ModuleName,
upgradetypes.ModuleName,
evidencetypes.ModuleName,
kavadisttypes.ModuleName,
swaptypes.ModuleName,
vestingtypes.ModuleName,
ibcexported.ModuleName,
validatorvestingtypes.ModuleName,
@ -940,10 +837,6 @@ func NewApp(
paramstypes.ModuleName,
authz.ModuleName,
evmutiltypes.ModuleName,
savingstypes.ModuleName,
liquidtypes.ModuleName,
earntypes.ModuleName,
routertypes.ModuleName,
minttypes.ModuleName,
communitytypes.ModuleName,
metricstypes.ModuleName,
@ -967,20 +860,11 @@ func NewApp(
ibctransfertypes.ModuleName,
evmtypes.ModuleName,
feemarkettypes.ModuleName,
kavadisttypes.ModuleName,
auctiontypes.ModuleName,
issuancetypes.ModuleName,
savingstypes.ModuleName,
bep3types.ModuleName,
pricefeedtypes.ModuleName,
swaptypes.ModuleName,
cdptypes.ModuleName, // reads market prices, so must run after pricefeed genesis
hardtypes.ModuleName,
incentivetypes.ModuleName, // reads cdp params, so must run after cdp genesis
committeetypes.ModuleName,
evmutiltypes.ModuleName,
earntypes.ModuleName,
communitytypes.ModuleName,
genutiltypes.ModuleName, // runs arbitrary txs included in genisis state, so run after modules have been initialized
// Add all remaining modules with an empty InitGenesis below since cosmos 0.45.0 requires it
vestingtypes.ModuleName,
@ -1197,16 +1081,6 @@ func (app *App) RegisterNodeService(clientCtx client.Context) {
func (app *App) loadBlockedMaccAddrs() map[string]bool {
modAccAddrs := app.ModuleAccountAddrs()
allowedMaccs := map[string]bool{
// kavadist
app.accountKeeper.GetModuleAddress(kavadisttypes.ModuleName).String(): true,
// earn
app.accountKeeper.GetModuleAddress(earntypes.ModuleName).String(): true,
// liquid
app.accountKeeper.GetModuleAddress(liquidtypes.ModuleName).String(): true,
// kavadist fund
app.accountKeeper.GetModuleAddress(kavadisttypes.FundModuleAccount).String(): true,
// community
app.accountKeeper.GetModuleAddress(communitytypes.ModuleAccountName).String(): true,
// NOTE: if adding evmutil, adjust the cosmos-coins-fully-backed-invariant accordingly.
}

View File

@ -2,10 +2,6 @@ package app
import (
sdkmath "cosmossdk.io/math"
earnkeeper "github.com/0glabs/0g-chain/x/earn/keeper"
liquidkeeper "github.com/0glabs/0g-chain/x/liquid/keeper"
liquidtypes "github.com/0glabs/0g-chain/x/liquid/types"
savingskeeper "github.com/0glabs/0g-chain/x/savings/keeper"
sdk "github.com/cosmos/cosmos-sdk/types"
bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper"
govkeeper "github.com/cosmos/cosmos-sdk/x/gov/keeper"
@ -20,23 +16,16 @@ var _ govv1.TallyHandler = TallyHandler{}
type TallyHandler struct {
gk govkeeper.Keeper
stk stakingkeeper.Keeper
svk savingskeeper.Keeper
ek earnkeeper.Keeper
lk liquidkeeper.Keeper
bk bankkeeper.Keeper
}
// NewTallyHandler creates a new tally handler.
func NewTallyHandler(
gk govkeeper.Keeper, stk stakingkeeper.Keeper, svk savingskeeper.Keeper,
ek earnkeeper.Keeper, lk liquidkeeper.Keeper, bk bankkeeper.Keeper,
gk govkeeper.Keeper, stk stakingkeeper.Keeper, bk bankkeeper.Keeper,
) TallyHandler {
return TallyHandler{
gk: gk,
stk: stk,
svk: svk,
ek: ek,
lk: lk,
bk: bk,
}
}
@ -105,34 +94,34 @@ func (th TallyHandler) Tally(
})
// get voter bkava and update total voting power and results
addrBkava := th.getAddrBkava(ctx, voter).toCoins()
for _, coin := range addrBkava {
valAddr, err := liquidtypes.ParseLiquidStakingTokenDenom(coin.Denom)
if err != nil {
break
}
// addrBkava := th.getAddrBkava(ctx, voter).toCoins()
// for _, coin := range addrBkava {
// valAddr, err := liquidtypes.ParseLiquidStakingTokenDenom(coin.Denom)
// if err != nil {
// break
// }
// reduce delegator shares by the amount of voter bkava for the validator
valAddrStr := valAddr.String()
if val, ok := currValidators[valAddrStr]; ok {
val.DelegatorDeductions = val.DelegatorDeductions.Add(sdk.NewDecFromInt(coin.Amount))
currValidators[valAddrStr] = val
}
// // reduce delegator shares by the amount of voter bkava for the validator
// valAddrStr := valAddr.String()
// if val, ok := currValidators[valAddrStr]; ok {
// val.DelegatorDeductions = val.DelegatorDeductions.Add(sdk.NewDecFromInt(coin.Amount))
// currValidators[valAddrStr] = val
// }
// votingPower = amount of ukava coin
stakedCoins, err := th.lk.GetStakedTokensForDerivatives(ctx, sdk.NewCoins(coin))
if err != nil {
// error is returned only if the bkava denom is incorrect, which should never happen here.
panic(err)
}
votingPower := sdk.NewDecFromInt(stakedCoins.Amount)
// // votingPower = amount of ukava coin
// stakedCoins, err := th.lk.GetStakedTokensForDerivatives(ctx, sdk.NewCoins(coin))
// if err != nil {
// // error is returned only if the bkava denom is incorrect, which should never happen here.
// panic(err)
// }
// votingPower := sdk.NewDecFromInt(stakedCoins.Amount)
for _, option := range vote.Options {
subPower := votingPower.Mul(sdk.MustNewDecFromStr(option.Weight))
results[option.Option] = results[option.Option].Add(subPower)
}
totalVotingPower = totalVotingPower.Add(votingPower)
}
// for _, option := range vote.Options {
// subPower := votingPower.Mul(sdk.MustNewDecFromStr(option.Weight))
// results[option.Option] = results[option.Option].Add(subPower)
// }
// totalVotingPower = totalVotingPower.Add(votingPower)
// }
th.gk.DeleteVote(ctx, vote.ProposalId, voter)
return false
@ -219,38 +208,38 @@ func (th TallyHandler) getAddrBkava(ctx sdk.Context, addr sdk.AccAddress) bkavaB
// addBkavaFromWallet adds all addr balances of bkava in x/bank.
func (th TallyHandler) addBkavaFromWallet(ctx sdk.Context, addr sdk.AccAddress, bkava bkavaByDenom) {
coins := th.bk.GetAllBalances(ctx, addr)
for _, coin := range coins {
if th.lk.IsDerivativeDenom(ctx, coin.Denom) {
bkava.add(coin)
}
}
// coins := th.bk.GetAllBalances(ctx, addr)
// for _, coin := range coins {
// if th.lk.IsDerivativeDenom(ctx, coin.Denom) {
// bkava.add(coin)
// }
// }
}
// addBkavaFromSavings adds all addr deposits of bkava in x/savings.
func (th TallyHandler) addBkavaFromSavings(ctx sdk.Context, addr sdk.AccAddress, bkava bkavaByDenom) {
deposit, found := th.svk.GetDeposit(ctx, addr)
if !found {
return
}
for _, coin := range deposit.Amount {
if th.lk.IsDerivativeDenom(ctx, coin.Denom) {
bkava.add(coin)
}
}
// deposit, found := th.svk.GetDeposit(ctx, addr)
// if !found {
// return
// }
// for _, coin := range deposit.Amount {
// if th.lk.IsDerivativeDenom(ctx, coin.Denom) {
// bkava.add(coin)
// }
// }
}
// addBkavaFromEarn adds all addr deposits of bkava in x/earn.
func (th TallyHandler) addBkavaFromEarn(ctx sdk.Context, addr sdk.AccAddress, bkava bkavaByDenom) {
shares, found := th.ek.GetVaultAccountShares(ctx, addr)
if !found {
return
}
for _, share := range shares {
if th.lk.IsDerivativeDenom(ctx, share.Denom) {
if coin, err := th.ek.ConvertToAssets(ctx, share); err == nil {
bkava.add(coin)
}
}
}
// shares, found := th.ek.GetVaultAccountShares(ctx, addr)
// if !found {
// return
// }
// for _, share := range shares {
// if th.lk.IsDerivativeDenom(ctx, share.Denom) {
// if coin, err := th.ek.ConvertToAssets(ctx, share); err == nil {
// bkava.add(coin)
// }
// }
// }
}

View File

@ -17,8 +17,7 @@ import (
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
"github.com/stretchr/testify/suite"
earntypes "github.com/0glabs/0g-chain/x/earn/types"
liquidtypes "github.com/0glabs/0g-chain/x/liquid/types"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
)
// d is an alias for sdk.MustNewDecFromStr
@ -271,39 +270,40 @@ func (suite *tallyHandlerSuite) newBondCoin(amount sdkmath.Int) sdk.Coin {
}
func (suite *tallyHandlerSuite) allowBKavaEarnDeposits() {
ek := suite.app.GetEarnKeeper()
earnParams := ek.GetParams(suite.ctx)
// ek := suite.app.GetEarnKeeper()
// earnParams := ek.GetParams(suite.ctx)
vault := earntypes.NewAllowedVault(
liquidtypes.DefaultDerivativeDenom,
earntypes.StrategyTypes{earntypes.STRATEGY_TYPE_SAVINGS},
false,
nil,
)
// vault := earntypes.NewAllowedVault(
// liquidtypes.DefaultDerivativeDenom,
// earntypes.StrategyTypes{earntypes.STRATEGY_TYPE_SAVINGS},
// false,
// nil,
// )
earnParams.AllowedVaults = append(earnParams.AllowedVaults, vault)
ek.SetParams(suite.ctx, earnParams)
// earnParams.AllowedVaults = append(earnParams.AllowedVaults, vault)
// ek.SetParams(suite.ctx, earnParams)
sk := suite.app.GetSavingsKeeper()
savingsParams := sk.GetParams(suite.ctx)
savingsParams.SupportedDenoms = append(savingsParams.SupportedDenoms, liquidtypes.DefaultDerivativeDenom)
sk.SetParams(suite.ctx, savingsParams)
// sk := suite.app.GetSavingsKeeper()
// savingsParams := sk.GetParams(suite.ctx)
// savingsParams.SupportedDenoms = append(savingsParams.SupportedDenoms, liquidtypes.DefaultDerivativeDenom)
// sk.SetParams(suite.ctx, savingsParams)
}
func (suite *tallyHandlerSuite) earnDeposit(owner sdk.AccAddress, derivative sdk.Coin) {
ek := suite.app.GetEarnKeeper()
// ek := suite.app.GetEarnKeeper()
err := ek.Deposit(suite.ctx, owner, derivative, earntypes.STRATEGY_TYPE_SAVINGS)
suite.Require().NoError(err)
// err := ek.Deposit(suite.ctx, owner, derivative, earntypes.STRATEGY_TYPE_SAVINGS)
// suite.Require().NoError(err)
}
func (suite *tallyHandlerSuite) mintDerivative(owner sdk.AccAddress, validator sdk.ValAddress, amount sdkmath.Int) sdk.Coin {
lk := suite.app.GetLiquidKeeper()
// lk := suite.app.GetLiquidKeeper()
minted, err := lk.MintDerivative(suite.ctx, owner, validator, suite.newBondCoin(amount))
suite.Require().NoError(err)
// minted, err := lk.MintDerivative(suite.ctx, owner, validator, suite.newBondCoin(amount))
// suite.Require().NoError(err)
return minted
// return minted
return sdk.NewCoin("ukava", amount)
}
func (suite *tallyHandlerSuite) delegateToNewBondedValidator(delegator sdk.AccAddress, amount sdkmath.Int) stakingtypes.ValidatorI {

View File

@ -41,22 +41,11 @@ import (
feemarketkeeper "github.com/evmos/ethermint/x/feemarket/keeper"
"github.com/stretchr/testify/require"
auctionkeeper "github.com/0glabs/0g-chain/x/auction/keeper"
bep3keeper "github.com/0glabs/0g-chain/x/bep3/keeper"
cdpkeeper "github.com/0glabs/0g-chain/x/cdp/keeper"
committeekeeper "github.com/0glabs/0g-chain/x/committee/keeper"
communitykeeper "github.com/0glabs/0g-chain/x/community/keeper"
earnkeeper "github.com/0glabs/0g-chain/x/earn/keeper"
evmutilkeeper "github.com/0glabs/0g-chain/x/evmutil/keeper"
hardkeeper "github.com/0glabs/0g-chain/x/hard/keeper"
incentivekeeper "github.com/0glabs/0g-chain/x/incentive/keeper"
issuancekeeper "github.com/0glabs/0g-chain/x/issuance/keeper"
kavadistkeeper "github.com/0glabs/0g-chain/x/kavadist/keeper"
liquidkeeper "github.com/0glabs/0g-chain/x/liquid/keeper"
pricefeedkeeper "github.com/0glabs/0g-chain/x/pricefeed/keeper"
routerkeeper "github.com/0glabs/0g-chain/x/router/keeper"
savingskeeper "github.com/0glabs/0g-chain/x/savings/keeper"
swapkeeper "github.com/0glabs/0g-chain/x/swap/keeper"
)
var (
@ -117,24 +106,13 @@ func (tApp TestApp) GetDistrKeeper() distkeeper.Keeper { return tApp.di
func (tApp TestApp) GetGovKeeper() govkeeper.Keeper { return tApp.govKeeper }
func (tApp TestApp) GetCrisisKeeper() crisiskeeper.Keeper { return tApp.crisisKeeper }
func (tApp TestApp) GetParamsKeeper() paramskeeper.Keeper { return tApp.paramsKeeper }
func (tApp TestApp) GetKavadistKeeper() kavadistkeeper.Keeper { return tApp.kavadistKeeper }
func (tApp TestApp) GetAuctionKeeper() auctionkeeper.Keeper { return tApp.auctionKeeper }
func (tApp TestApp) GetIssuanceKeeper() issuancekeeper.Keeper { return tApp.issuanceKeeper }
func (tApp TestApp) GetBep3Keeper() bep3keeper.Keeper { return tApp.bep3Keeper }
func (tApp TestApp) GetPriceFeedKeeper() pricefeedkeeper.Keeper { return tApp.pricefeedKeeper }
func (tApp TestApp) GetSwapKeeper() swapkeeper.Keeper { return tApp.swapKeeper }
func (tApp TestApp) GetCDPKeeper() cdpkeeper.Keeper { return tApp.cdpKeeper }
func (tApp TestApp) GetHardKeeper() hardkeeper.Keeper { return tApp.hardKeeper }
func (tApp TestApp) GetCommitteeKeeper() committeekeeper.Keeper { return tApp.committeeKeeper }
func (tApp TestApp) GetIncentiveKeeper() incentivekeeper.Keeper { return tApp.incentiveKeeper }
func (tApp TestApp) GetEvmutilKeeper() evmutilkeeper.Keeper { return tApp.evmutilKeeper }
func (tApp TestApp) GetEvmKeeper() *evmkeeper.Keeper { return tApp.evmKeeper }
func (tApp TestApp) GetSavingsKeeper() savingskeeper.Keeper { return tApp.savingsKeeper }
func (tApp TestApp) GetFeeMarketKeeper() feemarketkeeper.Keeper { return tApp.feeMarketKeeper }
func (tApp TestApp) GetLiquidKeeper() liquidkeeper.Keeper { return tApp.liquidKeeper }
func (tApp TestApp) GetEarnKeeper() earnkeeper.Keeper { return tApp.earnKeeper }
func (tApp TestApp) GetRouterKeeper() routerkeeper.Keeper { return tApp.routerKeeper }
func (tApp TestApp) GetCommunityKeeper() communitykeeper.Keeper { return tApp.communityKeeper }
func (tApp TestApp) GetKVStoreKey(key string) *storetypes.KVStoreKey {
return tApp.keys[key]

View File

@ -4,9 +4,7 @@ import (
"testing"
"time"
sdkmath "cosmossdk.io/math"
"github.com/0glabs/0g-chain/app"
incentivetypes "github.com/0glabs/0g-chain/x/incentive/types"
sdk "github.com/cosmos/cosmos-sdk/types"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
"github.com/evmos/ethermint/crypto/ethsecp256k1"
@ -15,37 +13,37 @@ import (
tmtime "github.com/tendermint/tendermint/types/time"
)
func TestUpgradeCommunityParams_Mainnet(t *testing.T) {
require.Equal(
t,
sdkmath.LegacyZeroDec().String(),
app.CommunityParams_Mainnet.StakingRewardsPerSecond.String(),
)
// func TestUpgradeCommunityParams_Mainnet(t *testing.T) {
// require.Equal(
// t,
// sdkmath.LegacyZeroDec().String(),
// app.CommunityParams_Mainnet.StakingRewardsPerSecond.String(),
// )
require.Equal(
t,
// Manually confirmed
"317097.919837645865043125",
app.CommunityParams_Mainnet.UpgradeTimeSetStakingRewardsPerSecond.String(),
"mainnet kava per second should be correct",
)
}
// require.Equal(
// t,
// // Manually confirmed
// "317097.919837645865043125",
// app.CommunityParams_Mainnet.UpgradeTimeSetStakingRewardsPerSecond.String(),
// "mainnet kava per second should be correct",
// )
// }
func TestUpgradeCommunityParams_Testnet(t *testing.T) {
require.Equal(
t,
sdkmath.LegacyZeroDec().String(),
app.CommunityParams_Testnet.StakingRewardsPerSecond.String(),
)
// func TestUpgradeCommunityParams_Testnet(t *testing.T) {
// require.Equal(
// t,
// sdkmath.LegacyZeroDec().String(),
// app.CommunityParams_Testnet.StakingRewardsPerSecond.String(),
// )
require.Equal(
t,
// Manually confirmed
"475646879756.468797564687975646",
app.CommunityParams_Testnet.UpgradeTimeSetStakingRewardsPerSecond.String(),
"testnet kava per second should be correct",
)
}
// require.Equal(
// t,
// // Manually confirmed
// "475646879756.468797564687975646",
// app.CommunityParams_Testnet.UpgradeTimeSetStakingRewardsPerSecond.String(),
// "testnet kava per second should be correct",
// )
// }
func TestUpdateValidatorMinimumCommission(t *testing.T) {
tApp := app.NewTestApp()
@ -171,63 +169,63 @@ func TestUpdateValidatorMinimumCommission(t *testing.T) {
}
}
func TestUpdateIncentiveParams(t *testing.T) {
tApp := app.NewTestApp()
tApp.InitializeFromGenesisStates()
ctx := tApp.NewContext(true, tmproto.Header{Height: 1, Time: tmtime.Now()})
// func TestUpdateIncentiveParams(t *testing.T) {
// tApp := app.NewTestApp()
// tApp.InitializeFromGenesisStates()
// ctx := tApp.NewContext(true, tmproto.Header{Height: 1, Time: tmtime.Now()})
ik := tApp.GetIncentiveKeeper()
params := ik.GetParams(ctx)
// ik := tApp.GetIncentiveKeeper()
// params := ik.GetParams(ctx)
startPeriod := time.Date(2021, 10, 26, 15, 0, 0, 0, time.UTC)
endPeriod := time.Date(2022, 10, 26, 15, 0, 0, 0, time.UTC)
// startPeriod := time.Date(2021, 10, 26, 15, 0, 0, 0, time.UTC)
// endPeriod := time.Date(2022, 10, 26, 15, 0, 0, 0, time.UTC)
params.EarnRewardPeriods = incentivetypes.MultiRewardPeriods{
incentivetypes.NewMultiRewardPeriod(
true,
"bkava",
startPeriod,
endPeriod,
sdk.NewCoins(
sdk.NewCoin("ukava", sdk.NewInt(159459)),
),
),
}
ik.SetParams(ctx, params)
// params.EarnRewardPeriods = incentivetypes.MultiRewardPeriods{
// incentivetypes.NewMultiRewardPeriod(
// true,
// "bkava",
// startPeriod,
// endPeriod,
// sdk.NewCoins(
// sdk.NewCoin("ukava", sdk.NewInt(159459)),
// ),
// ),
// }
// ik.SetParams(ctx, params)
beforeParams := ik.GetParams(ctx)
require.Equal(t, params, beforeParams, "initial incentive params should be set")
// beforeParams := ik.GetParams(ctx)
// require.Equal(t, params, beforeParams, "initial incentive params should be set")
// -- UPGRADE
app.UpdateIncentiveParams(ctx, tApp.App)
// // -- UPGRADE
// app.UpdateIncentiveParams(ctx, tApp.App)
// -- After
afterParams := ik.GetParams(ctx)
// // -- After
// afterParams := ik.GetParams(ctx)
require.Len(
t,
afterParams.EarnRewardPeriods[0].RewardsPerSecond,
1,
"bkava earn reward period should only contain 1 coin",
)
require.Equal(
t,
// Manual calculation of
// 600,000 * 1000,000 / (365 * 24 * 60 * 60)
sdk.NewCoin("ukava", sdkmath.NewInt(19025)),
afterParams.EarnRewardPeriods[0].RewardsPerSecond[0],
"bkava earn reward period should be updated",
)
// require.Len(
// t,
// afterParams.EarnRewardPeriods[0].RewardsPerSecond,
// 1,
// "bkava earn reward period should only contain 1 coin",
// )
// require.Equal(
// t,
// // Manual calculation of
// // 600,000 * 1000,000 / (365 * 24 * 60 * 60)
// sdk.NewCoin("ukava", sdkmath.NewInt(19025)),
// afterParams.EarnRewardPeriods[0].RewardsPerSecond[0],
// "bkava earn reward period should be updated",
// )
// Check that other params are not changed
afterParams.EarnRewardPeriods[0].RewardsPerSecond[0] = beforeParams.EarnRewardPeriods[0].RewardsPerSecond[0]
require.Equal(
t,
beforeParams,
afterParams,
"other param values should not be changed",
)
}
// // Check that other params are not changed
// afterParams.EarnRewardPeriods[0].RewardsPerSecond[0] = beforeParams.EarnRewardPeriods[0].RewardsPerSecond[0]
// require.Equal(
// t,
// beforeParams,
// afterParams,
// "other param values should not be changed",
// )
// }
func generateConsKey(
t *testing.T,

View File

@ -25,7 +25,6 @@ import (
"github.com/0glabs/0g-chain/app"
"github.com/0glabs/0g-chain/app/params"
metricstypes "github.com/0glabs/0g-chain/x/metrics/types"
)
const (
@ -118,7 +117,6 @@ func (ac appCreator) newApp(
MempoolAuthAddresses: mempoolAuthAddresses,
EVMTrace: cast.ToString(appOpts.Get(ethermintflags.EVMTracer)),
EVMMaxGasWanted: cast.ToUint64(appOpts.Get(ethermintflags.EVMMaxTxGasWanted)),
TelemetryOptions: metricstypes.TelemetryOptionsFromAppOpts(appOpts),
},
baseapp.SetPruning(pruningOpts),
baseapp.SetMinGasPrices(strings.Replace(cast.ToString(appOpts.Get(server.FlagMinGasPrices)), ";", ",", -1)),

1
go.mod
View File

@ -179,7 +179,6 @@ require (
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/status-im/keycard-go v0.2.0 // indirect
github.com/stretchr/objx v0.5.0 // indirect
github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect
github.com/tendermint/go-amino v0.16.0 // indirect
github.com/tidwall/btree v1.6.0 // indirect

View File

@ -1,98 +0,0 @@
syntax = "proto3";
package kava.auction.v1beta1;
import "cosmos/base/v1beta1/coin.proto";
import "cosmos_proto/cosmos.proto";
import "gogoproto/gogo.proto";
import "google/protobuf/timestamp.proto";
option go_package = "github.com/0glabs/0g-chain/x/auction/types";
option (gogoproto.goproto_getters_all) = false;
// BaseAuction defines common attributes of all auctions
message BaseAuction {
option (cosmos_proto.implements_interface) = "Auction";
uint64 id = 1 [(gogoproto.customname) = "ID"];
string initiator = 2;
cosmos.base.v1beta1.Coin lot = 3 [(gogoproto.nullable) = false];
bytes bidder = 4 [
(cosmos_proto.scalar) = "cosmos.AddressBytes",
(gogoproto.casttype) = "github.com/cosmos/cosmos-sdk/types.AccAddress"
];
cosmos.base.v1beta1.Coin bid = 5 [(gogoproto.nullable) = false];
bool has_received_bids = 6;
google.protobuf.Timestamp end_time = 7 [
(gogoproto.nullable) = false,
(gogoproto.stdtime) = true
];
google.protobuf.Timestamp max_end_time = 8 [
(gogoproto.nullable) = false,
(gogoproto.stdtime) = true
];
}
// SurplusAuction is a forward auction that burns what it receives from bids.
// It is normally used to sell off excess pegged asset acquired by the CDP system.
message SurplusAuction {
option (cosmos_proto.implements_interface) = "Auction";
BaseAuction base_auction = 1 [
(gogoproto.embed) = true,
(gogoproto.nullable) = false
];
}
// DebtAuction is a reverse auction that mints what it pays out.
// It is normally used to acquire pegged asset to cover the CDP system's debts that were not covered by selling
// collateral.
message DebtAuction {
option (cosmos_proto.implements_interface) = "Auction";
BaseAuction base_auction = 1 [
(gogoproto.embed) = true,
(gogoproto.nullable) = false
];
cosmos.base.v1beta1.Coin corresponding_debt = 2 [(gogoproto.nullable) = false];
}
// CollateralAuction is a two phase auction.
// Initially, in forward auction phase, bids can be placed up to a max bid.
// Then it switches to a reverse auction phase, where the initial amount up for auction is bid down.
// Unsold Lot is sent to LotReturns, being divided among the addresses by weight.
// Collateral auctions are normally used to sell off collateral seized from CDPs.
message CollateralAuction {
option (cosmos_proto.implements_interface) = "Auction";
BaseAuction base_auction = 1 [
(gogoproto.embed) = true,
(gogoproto.nullable) = false
];
cosmos.base.v1beta1.Coin corresponding_debt = 2 [(gogoproto.nullable) = false];
cosmos.base.v1beta1.Coin max_bid = 3 [(gogoproto.nullable) = false];
WeightedAddresses lot_returns = 4 [(gogoproto.nullable) = false];
}
// WeightedAddresses is a type for storing some addresses and associated weights.
message WeightedAddresses {
repeated bytes addresses = 1 [
(cosmos_proto.scalar) = "cosmos.AddressBytes",
(gogoproto.casttype) = "github.com/cosmos/cosmos-sdk/types.AccAddress"
];
repeated bytes weights = 2 [
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
(gogoproto.nullable) = false
];
}

View File

@ -1,55 +0,0 @@
syntax = "proto3";
package kava.auction.v1beta1;
import "cosmos_proto/cosmos.proto";
import "gogoproto/gogo.proto";
import "google/protobuf/any.proto";
import "google/protobuf/duration.proto";
option go_package = "github.com/0glabs/0g-chain/x/auction/types";
option (gogoproto.goproto_getters_all) = false;
// GenesisState defines the auction module's genesis state.
message GenesisState {
uint64 next_auction_id = 1;
Params params = 2 [(gogoproto.nullable) = false];
// Genesis auctions
repeated google.protobuf.Any auctions = 3 [(cosmos_proto.accepts_interface) = "GenesisAuction"];
}
// Params defines the parameters for the issuance module.
message Params {
reserved 2;
reserved "bid_duration";
google.protobuf.Duration max_auction_duration = 1 [
(gogoproto.nullable) = false,
(gogoproto.stdduration) = true
];
google.protobuf.Duration forward_bid_duration = 6 [
(gogoproto.nullable) = false,
(gogoproto.stdduration) = true
];
google.protobuf.Duration reverse_bid_duration = 7 [
(gogoproto.nullable) = false,
(gogoproto.stdduration) = true
];
bytes increment_surplus = 3 [
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.nullable) = false
];
bytes increment_debt = 4 [
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.nullable) = false
];
bytes increment_collateral = 5 [
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.nullable) = false
];
}

View File

@ -1,84 +0,0 @@
syntax = "proto3";
package kava.auction.v1beta1;
import "cosmos/base/query/v1beta1/pagination.proto";
import "gogoproto/gogo.proto";
import "google/api/annotations.proto";
import "google/protobuf/any.proto";
import "kava/auction/v1beta1/genesis.proto";
option go_package = "github.com/0glabs/0g-chain/x/auction/types";
// Query defines the gRPC querier service for auction module
service Query {
// Params queries all parameters of the auction module.
rpc Params(QueryParamsRequest) returns (QueryParamsResponse) {
option (google.api.http).get = "/kava/auction/v1beta1/params";
}
// Auction queries an individual Auction by auction ID
rpc Auction(QueryAuctionRequest) returns (QueryAuctionResponse) {
option (google.api.http).get = "/kava/auction/v1beta1/auctions/{auction_id}";
}
// Auctions queries auctions filtered by asset denom, owner address, phase, and auction type
rpc Auctions(QueryAuctionsRequest) returns (QueryAuctionsResponse) {
option (google.api.http).get = "/kava/auction/v1beta1/auctions";
}
// NextAuctionID queries the next auction ID
rpc NextAuctionID(QueryNextAuctionIDRequest) returns (QueryNextAuctionIDResponse) {
option (google.api.http).get = "/kava/auction/v1beta1/next-auction-id";
}
}
// QueryParamsRequest defines the request type for querying x/auction parameters.
message QueryParamsRequest {}
// QueryParamsResponse defines the response type for querying x/auction parameters.
message QueryParamsResponse {
Params params = 1 [(gogoproto.nullable) = false];
}
// QueryAuctionRequest is the request type for the Query/Auction RPC method.
message QueryAuctionRequest {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;
uint64 auction_id = 1;
}
// QueryAuctionResponse is the response type for the Query/Auction RPC method.
message QueryAuctionResponse {
google.protobuf.Any auction = 1;
}
// QueryAuctionsRequest is the request type for the Query/Auctions RPC method.
message QueryAuctionsRequest {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;
string type = 1;
string owner = 2;
string denom = 3;
string phase = 4;
// pagination defines an optional pagination for the request.
cosmos.base.query.v1beta1.PageRequest pagination = 5;
}
// QueryAuctionsResponse is the response type for the Query/Auctions RPC method.
message QueryAuctionsResponse {
repeated google.protobuf.Any auctions = 1;
// pagination defines the pagination in the response.
cosmos.base.query.v1beta1.PageResponse pagination = 2;
}
// QueryNextAuctionIDRequest defines the request type for querying x/auction next auction ID.
message QueryNextAuctionIDRequest {}
// QueryNextAuctionIDResponse defines the response type for querying x/auction next auction ID.
message QueryNextAuctionIDResponse {
uint64 id = 1;
}

View File

@ -1,28 +0,0 @@
syntax = "proto3";
package kava.auction.v1beta1;
import "cosmos/base/v1beta1/coin.proto";
import "gogoproto/gogo.proto";
option go_package = "github.com/0glabs/0g-chain/x/auction/types";
// Msg defines the auction Msg service.
service Msg {
// PlaceBid message type used by bidders to place bids on auctions
rpc PlaceBid(MsgPlaceBid) returns (MsgPlaceBidResponse);
}
// MsgPlaceBid represents a message used by bidders to place bids on auctions
message MsgPlaceBid {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;
uint64 auction_id = 1;
string bidder = 2;
cosmos.base.v1beta1.Coin amount = 3 [(gogoproto.nullable) = false];
}
// MsgPlaceBidResponse defines the Msg/PlaceBid response type.
message MsgPlaceBidResponse {}

View File

@ -1,59 +0,0 @@
syntax = "proto3";
package kava.cdp.v1beta1;
import "cosmos/base/v1beta1/coin.proto";
import "cosmos_proto/cosmos.proto";
import "gogoproto/gogo.proto";
import "google/protobuf/timestamp.proto";
option go_package = "github.com/0glabs/0g-chain/x/cdp/types";
option (gogoproto.goproto_getters_all) = false;
// CDP defines the state of a single collateralized debt position.
message CDP {
uint64 id = 1 [(gogoproto.customname) = "ID"];
bytes owner = 2 [
(cosmos_proto.scalar) = "cosmos.AddressBytes",
(gogoproto.casttype) = "github.com/cosmos/cosmos-sdk/types.AccAddress"
];
string type = 3;
cosmos.base.v1beta1.Coin collateral = 4 [(gogoproto.nullable) = false];
cosmos.base.v1beta1.Coin principal = 5 [(gogoproto.nullable) = false];
cosmos.base.v1beta1.Coin accumulated_fees = 6 [(gogoproto.nullable) = false];
google.protobuf.Timestamp fees_updated = 7 [
(gogoproto.stdtime) = true,
(gogoproto.nullable) = false
];
string interest_factor = 8 [
(cosmos_proto.scalar) = "cosmos.Dec",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.nullable) = false
];
}
// Deposit defines an amount of coins deposited by an account to a cdp
message Deposit {
uint64 cdp_id = 1 [(gogoproto.customname) = "CdpID"];
string depositor = 2 [
(cosmos_proto.scalar) = "cosmos.AddressBytes",
(gogoproto.casttype) = "github.com/cosmos/cosmos-sdk/types.AccAddress"
];
cosmos.base.v1beta1.Coin amount = 3 [(gogoproto.nullable) = false];
}
// TotalPrincipal defines the total principal of a given collateral type
message TotalPrincipal {
string collateral_type = 1;
cosmos.base.v1beta1.Coin amount = 2 [(gogoproto.nullable) = false];
}
// TotalCollateral defines the total collateral of a given collateral type
message TotalCollateral {
string collateral_type = 1;
cosmos.base.v1beta1.Coin amount = 2 [(gogoproto.nullable) = false];
}
// OwnerCDPIndex defines the cdp ids for a single cdp owner
message OwnerCDPIndex {
repeated uint64 cdp_ids = 1 [(gogoproto.customname) = "CdpIDs"];
}

View File

@ -1,155 +0,0 @@
syntax = "proto3";
package kava.cdp.v1beta1;
import "cosmos/base/v1beta1/coin.proto";
import "cosmos_proto/cosmos.proto";
import "gogoproto/gogo.proto";
import "google/protobuf/timestamp.proto";
import "kava/cdp/v1beta1/cdp.proto";
option go_package = "github.com/0glabs/0g-chain/x/cdp/types";
// GenesisState defines the cdp module's genesis state.
message GenesisState {
// params defines all the parameters of the module.
Params params = 1 [(gogoproto.nullable) = false];
repeated CDP cdps = 2 [
(gogoproto.customname) = "CDPs",
(gogoproto.castrepeated) = "CDPs",
(gogoproto.nullable) = false
];
repeated Deposit deposits = 3 [
(gogoproto.castrepeated) = "Deposits",
(gogoproto.nullable) = false
];
uint64 starting_cdp_id = 4 [(gogoproto.customname) = "StartingCdpID"];
string debt_denom = 5;
string gov_denom = 6;
repeated GenesisAccumulationTime previous_accumulation_times = 7 [
(gogoproto.castrepeated) = "GenesisAccumulationTimes",
(gogoproto.nullable) = false
];
repeated GenesisTotalPrincipal total_principals = 8 [
(gogoproto.castrepeated) = "GenesisTotalPrincipals",
(gogoproto.nullable) = false
];
}
// Params defines the parameters for the cdp module.
message Params {
repeated CollateralParam collateral_params = 1 [
(gogoproto.castrepeated) = "CollateralParams",
(gogoproto.nullable) = false
];
DebtParam debt_param = 2 [(gogoproto.nullable) = false];
cosmos.base.v1beta1.Coin global_debt_limit = 3 [(gogoproto.nullable) = false];
string surplus_auction_threshold = 4 [
(cosmos_proto.scalar) = "cosmos.Int",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
(gogoproto.nullable) = false
];
string surplus_auction_lot = 5 [
(cosmos_proto.scalar) = "cosmos.Int",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
(gogoproto.nullable) = false
];
string debt_auction_threshold = 6 [
(cosmos_proto.scalar) = "cosmos.Int",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
(gogoproto.nullable) = false
];
string debt_auction_lot = 7 [
(cosmos_proto.scalar) = "cosmos.Int",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
(gogoproto.nullable) = false
];
bool circuit_breaker = 8;
int64 liquidation_block_interval = 9;
}
// DebtParam defines governance params for debt assets
message DebtParam {
string denom = 1;
string reference_asset = 2;
string conversion_factor = 3 [
(cosmos_proto.scalar) = "cosmos.Int",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
(gogoproto.nullable) = false
];
string debt_floor = 4 [
(cosmos_proto.scalar) = "cosmos.Int",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
(gogoproto.nullable) = false
];
}
// CollateralParam defines governance parameters for each collateral type within the cdp module
message CollateralParam {
string denom = 1;
string type = 2;
string liquidation_ratio = 3 [
(cosmos_proto.scalar) = "cosmos.Dec",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.nullable) = false
];
cosmos.base.v1beta1.Coin debt_limit = 4 [(gogoproto.nullable) = false];
string stability_fee = 5 [
(cosmos_proto.scalar) = "cosmos.Dec",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.nullable) = false
];
string auction_size = 6 [
(cosmos_proto.scalar) = "cosmos.Int",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
(gogoproto.nullable) = false
];
string liquidation_penalty = 7 [
(cosmos_proto.scalar) = "cosmos.Dec",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.nullable) = false
];
string spot_market_id = 8 [(gogoproto.customname) = "SpotMarketID"];
string liquidation_market_id = 9 [(gogoproto.customname) = "LiquidationMarketID"];
string keeper_reward_percentage = 10 [
(cosmos_proto.scalar) = "cosmos.Dec",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.nullable) = false
];
string check_collateralization_index_count = 11 [
(cosmos_proto.scalar) = "cosmos.Int",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
(gogoproto.nullable) = false
];
string conversion_factor = 12 [
(cosmos_proto.scalar) = "cosmos.Int",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
(gogoproto.nullable) = false
];
}
// GenesisAccumulationTime defines the previous distribution time and its corresponding denom
message GenesisAccumulationTime {
string collateral_type = 1;
google.protobuf.Timestamp previous_accumulation_time = 2 [
(gogoproto.stdtime) = true,
(gogoproto.nullable) = false
];
string interest_factor = 3 [
(cosmos_proto.scalar) = "cosmos.Dec",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.nullable) = false
];
}
// GenesisTotalPrincipal defines the total principal and its corresponding collateral type
message GenesisTotalPrincipal {
string collateral_type = 1;
string total_principal = 2 [
(cosmos_proto.scalar) = "cosmos.Int",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
(gogoproto.nullable) = false
];
}

View File

@ -1,160 +0,0 @@
syntax = "proto3";
package kava.cdp.v1beta1;
import "cosmos/auth/v1beta1/auth.proto";
import "cosmos/base/query/v1beta1/pagination.proto";
import "cosmos/base/v1beta1/coin.proto";
import "cosmos_proto/cosmos.proto";
import "gogoproto/gogo.proto";
import "google/api/annotations.proto";
import "google/protobuf/timestamp.proto";
import "kava/cdp/v1beta1/cdp.proto";
import "kava/cdp/v1beta1/genesis.proto";
option go_package = "github.com/0glabs/0g-chain/x/cdp/types";
// Query defines the gRPC querier service for cdp module
service Query {
// Params queries all parameters of the cdp module.
rpc Params(QueryParamsRequest) returns (QueryParamsResponse) {
option (google.api.http).get = "/kava/cdp/v1beta1/params";
}
// Accounts queries the CDP module accounts.
rpc Accounts(QueryAccountsRequest) returns (QueryAccountsResponse) {
option (google.api.http).get = "/kava/cdp/v1beta1/accounts";
}
// TotalPrincipal queries the total principal of a given collateral type.
rpc TotalPrincipal(QueryTotalPrincipalRequest) returns (QueryTotalPrincipalResponse) {
option (google.api.http).get = "/kava/cdp/v1beta1/totalPrincipal";
}
// TotalCollateral queries the total collateral of a given collateral type.
rpc TotalCollateral(QueryTotalCollateralRequest) returns (QueryTotalCollateralResponse) {
option (google.api.http).get = "/kava/cdp/v1beta1/totalCollateral";
}
// Cdps queries all active CDPs.
rpc Cdps(QueryCdpsRequest) returns (QueryCdpsResponse) {
option (google.api.http).get = "/kava/cdp/v1beta1/cdps";
}
// Cdp queries a CDP with the input owner address and collateral type.
rpc Cdp(QueryCdpRequest) returns (QueryCdpResponse) {
option (google.api.http).get = "/kava/cdp/v1beta1/cdps/{owner}/{collateral_type}";
}
// Deposits queries deposits associated with the CDP owned by an address for a collateral type.
rpc Deposits(QueryDepositsRequest) returns (QueryDepositsResponse) {
option (google.api.http).get = "/kava/cdp/v1beta1/cdps/deposits/{owner}/{collateral_type}";
}
}
// QueryParamsRequest defines the request type for the Query/Params RPC method.
message QueryParamsRequest {}
// QueryParamsResponse defines the response type for the Query/Params RPC method.
message QueryParamsResponse {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;
Params params = 1 [(gogoproto.nullable) = false];
}
// QueryAccountsRequest defines the request type for the Query/Accounts RPC method.
message QueryAccountsRequest {}
// QueryAccountsResponse defines the response type for the Query/Accounts RPC method.
message QueryAccountsResponse {
repeated cosmos.auth.v1beta1.ModuleAccount accounts = 1 [(gogoproto.nullable) = false];
}
// QueryCdpRequest defines the request type for the Query/Cdp RPC method.
message QueryCdpRequest {
string collateral_type = 1;
string owner = 2 [(cosmos_proto.scalar) = "cosmos.AddressString"];
}
// QueryCdpResponse defines the response type for the Query/Cdp RPC method.
message QueryCdpResponse {
CDPResponse cdp = 1 [(gogoproto.nullable) = false];
}
// QueryCdpsRequest is the params for a filtered CDP query, the request type for the Query/Cdps RPC method.
message QueryCdpsRequest {
string collateral_type = 1;
string owner = 2 [(cosmos_proto.scalar) = "cosmos.AddressString"];
uint64 id = 3 [(gogoproto.customname) = "ID"];
// sdk.Dec as a string
string ratio = 4;
cosmos.base.query.v1beta1.PageRequest pagination = 5;
}
// QueryCdpsResponse defines the response type for the Query/Cdps RPC method.
message QueryCdpsResponse {
repeated CDPResponse cdps = 1 [
(gogoproto.castrepeated) = "CDPResponses",
(gogoproto.nullable) = false
];
cosmos.base.query.v1beta1.PageResponse pagination = 2;
}
// QueryDepositsRequest defines the request type for the Query/Deposits RPC method.
message QueryDepositsRequest {
string collateral_type = 1;
string owner = 2 [(cosmos_proto.scalar) = "cosmos.AddressString"];
}
// QueryDepositsResponse defines the response type for the Query/Deposits RPC method.
message QueryDepositsResponse {
repeated Deposit deposits = 1 [
(gogoproto.castrepeated) = "Deposits",
(gogoproto.nullable) = false
];
}
// QueryTotalPrincipalRequest defines the request type for the Query/TotalPrincipal RPC method.
message QueryTotalPrincipalRequest {
string collateral_type = 1;
}
// QueryTotalPrincipalResponse defines the response type for the Query/TotalPrincipal RPC method.
message QueryTotalPrincipalResponse {
repeated TotalPrincipal total_principal = 1 [
(gogoproto.castrepeated) = "TotalPrincipals",
(gogoproto.nullable) = false
];
}
// QueryTotalCollateralRequest defines the request type for the Query/TotalCollateral RPC method.
message QueryTotalCollateralRequest {
string collateral_type = 1;
}
// QueryTotalCollateralResponse defines the response type for the Query/TotalCollateral RPC method.
message QueryTotalCollateralResponse {
repeated TotalCollateral total_collateral = 1 [
(gogoproto.castrepeated) = "TotalCollaterals",
(gogoproto.nullable) = false
];
}
// CDPResponse defines the state of a single collateralized debt position.
message CDPResponse {
uint64 id = 1 [(gogoproto.customname) = "ID"];
string owner = 2;
string type = 3;
cosmos.base.v1beta1.Coin collateral = 4 [(gogoproto.nullable) = false];
cosmos.base.v1beta1.Coin principal = 5 [(gogoproto.nullable) = false];
cosmos.base.v1beta1.Coin accumulated_fees = 6 [(gogoproto.nullable) = false];
google.protobuf.Timestamp fees_updated = 7 [
(gogoproto.stdtime) = true,
(gogoproto.nullable) = false
];
string interest_factor = 8;
cosmos.base.v1beta1.Coin collateral_value = 9 [(gogoproto.nullable) = false];
string collateralization_ratio = 10;
}

View File

@ -1,91 +0,0 @@
syntax = "proto3";
package kava.cdp.v1beta1;
import "cosmos/base/v1beta1/coin.proto";
import "cosmos_proto/cosmos.proto";
import "gogoproto/gogo.proto";
option go_package = "github.com/0glabs/0g-chain/x/cdp/types";
// Msg defines the cdp Msg service.
service Msg {
// CreateCDP defines a method to create a new CDP.
rpc CreateCDP(MsgCreateCDP) returns (MsgCreateCDPResponse);
// Deposit defines a method to deposit to a CDP.
rpc Deposit(MsgDeposit) returns (MsgDepositResponse);
// Withdraw defines a method to withdraw collateral from a CDP.
rpc Withdraw(MsgWithdraw) returns (MsgWithdrawResponse);
// DrawDebt defines a method to draw debt from a CDP.
rpc DrawDebt(MsgDrawDebt) returns (MsgDrawDebtResponse);
// RepayDebt defines a method to repay debt from a CDP.
rpc RepayDebt(MsgRepayDebt) returns (MsgRepayDebtResponse);
// Liquidate defines a method to attempt to liquidate a CDP whos
// collateralization ratio is under its liquidation ratio.
rpc Liquidate(MsgLiquidate) returns (MsgLiquidateResponse);
}
// MsgCreateCDP defines a message to create a new CDP.
message MsgCreateCDP {
string sender = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];
cosmos.base.v1beta1.Coin collateral = 2 [(gogoproto.nullable) = false];
cosmos.base.v1beta1.Coin principal = 3 [(gogoproto.nullable) = false];
string collateral_type = 4;
}
// MsgCreateCDPResponse defines the Msg/CreateCDP response type.
message MsgCreateCDPResponse {
uint64 cdp_id = 1 [(gogoproto.customname) = "CdpID"];
}
// MsgDeposit defines a message to deposit to a CDP.
message MsgDeposit {
string depositor = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];
string owner = 2 [(cosmos_proto.scalar) = "cosmos.AddressString"];
cosmos.base.v1beta1.Coin collateral = 3 [(gogoproto.nullable) = false];
string collateral_type = 4;
}
// MsgDepositResponse defines the Msg/Deposit response type.
message MsgDepositResponse {}
// MsgWithdraw defines a message to withdraw collateral from a CDP.
message MsgWithdraw {
string depositor = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];
string owner = 2 [(cosmos_proto.scalar) = "cosmos.AddressString"];
cosmos.base.v1beta1.Coin collateral = 3 [(gogoproto.nullable) = false];
string collateral_type = 4;
}
// MsgWithdrawResponse defines the Msg/Withdraw response type.
message MsgWithdrawResponse {}
// MsgDrawDebt defines a message to draw debt from a CDP.
message MsgDrawDebt {
string sender = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];
string collateral_type = 2;
cosmos.base.v1beta1.Coin principal = 3 [(gogoproto.nullable) = false];
}
// MsgDrawDebtResponse defines the Msg/DrawDebt response type.
message MsgDrawDebtResponse {}
// MsgRepayDebt defines a message to repay debt from a CDP.
message MsgRepayDebt {
string sender = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];
string collateral_type = 2;
cosmos.base.v1beta1.Coin payment = 3 [(gogoproto.nullable) = false];
}
// MsgRepayDebtResponse defines the Msg/RepayDebt response type.
message MsgRepayDebtResponse {}
// MsgLiquidate defines a message to attempt to liquidate a CDP whos
// collateralization ratio is under its liquidation ratio.
message MsgLiquidate {
string keeper = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];
string borrower = 2 [(cosmos_proto.scalar) = "cosmos.AddressString"];
string collateral_type = 3;
}
// MsgLiquidateResponse defines the Msg/Liquidate response type.
message MsgLiquidateResponse {}

View File

@ -1,18 +0,0 @@
syntax = "proto3";
package kava.community.v1beta1;
import "gogoproto/gogo.proto";
import "kava/community/v1beta1/params.proto";
import "kava/community/v1beta1/staking.proto";
option go_package = "github.com/0glabs/0g-chain/x/community/types";
// GenesisState defines the community module's genesis state.
message GenesisState {
// params defines all the parameters related to commmunity
Params params = 1 [(gogoproto.nullable) = false];
// StakingRewardsState stores the internal staking reward data required to
// track staking rewards across blocks
StakingRewardsState staking_rewards_state = 2 [(gogoproto.nullable) = false];
}

View File

@ -1,35 +0,0 @@
syntax = "proto3";
package kava.community.v1beta1;
import "cosmos_proto/cosmos.proto";
import "gogoproto/gogo.proto";
import "google/protobuf/timestamp.proto";
option go_package = "github.com/0glabs/0g-chain/x/community/types";
// Params defines the parameters of the community module.
message Params {
option (gogoproto.equal) = true;
// upgrade_time_disable_inflation is the time at which to disable mint and kavadist module inflation.
// If set to 0, inflation will be disabled from block 1.
google.protobuf.Timestamp upgrade_time_disable_inflation = 1 [
(gogoproto.stdtime) = true,
(gogoproto.nullable) = false
];
// staking_rewards_per_second is the amount paid out to delegators each block from the community account
string staking_rewards_per_second = 2 [
(cosmos_proto.scalar) = "cosmos.Dec",
(gogoproto.customtype) = "cosmossdk.io/math.LegacyDec",
(gogoproto.nullable) = false
];
// upgrade_time_set_staking_rewards_per_second is the initial staking_rewards_per_second to set
// and use when the disable inflation time is reached
string upgrade_time_set_staking_rewards_per_second = 3 [
(cosmos_proto.scalar) = "cosmos.Dec",
(gogoproto.customtype) = "cosmossdk.io/math.LegacyDec",
(gogoproto.nullable) = false
];
}

View File

@ -1,57 +0,0 @@
syntax = "proto3";
package kava.community.v1beta1;
import "cosmos/base/v1beta1/coin.proto";
import "gogoproto/gogo.proto";
option go_package = "github.com/0glabs/0g-chain/x/community/types";
// CommunityPoolLendDepositProposal deposits from the community pool into lend
message CommunityPoolLendDepositProposal {
option (gogoproto.goproto_stringer) = false;
option (gogoproto.goproto_getters) = false;
string title = 1;
string description = 2;
repeated cosmos.base.v1beta1.Coin amount = 3 [
(gogoproto.nullable) = false,
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"
];
}
// CommunityPoolLendWithdrawProposal withdraws a lend position back to the community pool
message CommunityPoolLendWithdrawProposal {
option (gogoproto.goproto_stringer) = false;
option (gogoproto.goproto_getters) = false;
string title = 1;
string description = 2;
repeated cosmos.base.v1beta1.Coin amount = 3 [
(gogoproto.nullable) = false,
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"
];
}
// CommunityCDPRepayDebtProposal repays a cdp debt position owned by the community module
// This proposal exists primarily to allow committees to repay community module cdp debts.
message CommunityCDPRepayDebtProposal {
option (gogoproto.goproto_stringer) = false;
option (gogoproto.goproto_getters) = false;
string title = 1;
string description = 2;
string collateral_type = 3;
cosmos.base.v1beta1.Coin payment = 4 [(gogoproto.nullable) = false];
}
// CommunityCDPWithdrawCollateralProposal withdraws cdp collateral owned by the community module
// This proposal exists primarily to allow committees to withdraw community module cdp collateral.
message CommunityCDPWithdrawCollateralProposal {
option (gogoproto.goproto_stringer) = false;
option (gogoproto.goproto_getters) = false;
string title = 1;
string description = 2;
string collateral_type = 3;
cosmos.base.v1beta1.Coin collateral = 4 [(gogoproto.nullable) = false];
}

View File

@ -1,81 +0,0 @@
syntax = "proto3";
package kava.community.v1beta1;
import "cosmos/base/v1beta1/coin.proto";
import "cosmos_proto/cosmos.proto";
import "gogoproto/gogo.proto";
import "google/api/annotations.proto";
import "kava/community/v1beta1/params.proto";
option go_package = "github.com/0glabs/0g-chain/x/community/types";
// Query defines the gRPC querier service for x/community.
service Query {
// Params queires the module params.
rpc Params(QueryParamsRequest) returns (QueryParamsResponse) {
option (google.api.http).get = "/kava/community/v1beta1/params";
}
// Balance queries the balance of all coins of x/community module.
rpc Balance(QueryBalanceRequest) returns (QueryBalanceResponse) {
option (google.api.http).get = "/kava/community/v1beta1/balance";
}
// TotalBalance queries the balance of all coins, including x/distribution,
// x/community, and supplied balances.
rpc TotalBalance(QueryTotalBalanceRequest) returns (QueryTotalBalanceResponse) {
option (google.api.http).get = "/kava/community/v1beta1/total_balance";
}
// AnnualizedRewards calculates and returns the current annualized reward percentages,
// like staking rewards, for the chain.
rpc AnnualizedRewards(QueryAnnualizedRewardsRequest) returns (QueryAnnualizedRewardsResponse) {
option (google.api.http).get = "/kava/community/v1beta1/annualized_rewards";
}
}
// QueryParams defines the request type for querying x/community params.
message QueryParamsRequest {}
// QueryParamsResponse defines the response type for querying x/community params.
message QueryParamsResponse {
// params represents the community module parameters
Params params = 1 [(gogoproto.nullable) = false];
}
// QueryBalanceRequest defines the request type for querying x/community balance.
message QueryBalanceRequest {}
// QueryBalanceResponse defines the response type for querying x/community balance.
message QueryBalanceResponse {
repeated cosmos.base.v1beta1.Coin coins = 1 [
(gogoproto.nullable) = false,
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"
];
}
// QueryTotalBalanceRequest defines the request type for querying total community pool balance.
message QueryTotalBalanceRequest {}
// QueryTotalBalanceResponse defines the response type for querying total
// community pool balance. This matches the x/distribution CommunityPool query response.
message QueryTotalBalanceResponse {
// pool defines community pool's coins.
repeated cosmos.base.v1beta1.DecCoin pool = 1 [
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.DecCoins",
(gogoproto.nullable) = false
];
}
// QueryAnnualizedRewardsRequest defines the request type for querying the annualized rewards.
message QueryAnnualizedRewardsRequest {}
// QueryAnnualizedRewardsResponse defines the response type for querying the annualized rewards.
message QueryAnnualizedRewardsResponse {
// staking_rewards is the calculated annualized staking rewards percentage rate
string staking_rewards = 1 [
(cosmos_proto.scalar) = "cosmos.Dec",
(gogoproto.customtype) = "cosmossdk.io/math.LegacyDec",
(gogoproto.nullable) = false
];
}

View File

@ -1,26 +0,0 @@
syntax = "proto3";
package kava.community.v1beta1;
import "cosmos_proto/cosmos.proto";
import "gogoproto/gogo.proto";
import "google/protobuf/timestamp.proto";
option go_package = "github.com/0glabs/0g-chain/x/community/types";
// StakingRewardsState represents the state of staking reward accumulation between blocks.
message StakingRewardsState {
// last_accumulation_time represents the last block time which rewards where calculated and distributed.
// This may be zero to signal accumulation should start on the next interval.
google.protobuf.Timestamp last_accumulation_time = 1 [
(gogoproto.stdtime) = true,
(gogoproto.nullable) = false
];
// accumulated_truncation_error represents the sum of previous errors due to truncation on payout
// This value will always be on the interval [0, 1).
string last_truncation_error = 2 [
(cosmos_proto.scalar) = "cosmos.Dec",
(gogoproto.customtype) = "cosmossdk.io/math.LegacyDec",
(gogoproto.nullable) = false
];
}

View File

@ -1,47 +0,0 @@
syntax = "proto3";
package kava.community.v1beta1;
import "cosmos/base/v1beta1/coin.proto";
import "cosmos_proto/cosmos.proto";
import "gogoproto/gogo.proto";
import "kava/community/v1beta1/params.proto";
option go_package = "github.com/0glabs/0g-chain/x/community/types";
option (gogoproto.equal_all) = true;
// Msg defines the community Msg service.
service Msg {
// FundCommunityPool defines a method to allow an account to directly fund the community module account.
rpc FundCommunityPool(MsgFundCommunityPool) returns (MsgFundCommunityPoolResponse);
// UpdateParams defines a method to allow an account to update the community module parameters.
rpc UpdateParams(MsgUpdateParams) returns (MsgUpdateParamsResponse);
}
// MsgFundCommunityPool allows an account to directly fund the community module account.
message MsgFundCommunityPool {
option (gogoproto.goproto_getters) = false;
repeated cosmos.base.v1beta1.Coin amount = 1 [
(gogoproto.nullable) = false,
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"
];
string depositor = 2 [(cosmos_proto.scalar) = "cosmos.AddressString"];
}
// MsgFundCommunityPoolResponse defines the Msg/FundCommunityPool response type.
message MsgFundCommunityPoolResponse {}
// MsgUpdateParams allows an account to update the community module parameters.
message MsgUpdateParams {
option (gogoproto.goproto_getters) = false;
// authority is the address that controls the module (defaults to x/gov unless overwritten).
string authority = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];
// params defines the x/community parameters to update.
Params params = 2 [(gogoproto.nullable) = false];
}
// MsgUpdateParamsResponse defines the Msg/UpdateParams response type.
message MsgUpdateParamsResponse {}

View File

@ -1,24 +0,0 @@
syntax = "proto3";
package kava.earn.v1beta1;
import "gogoproto/gogo.proto";
import "kava/earn/v1beta1/params.proto";
import "kava/earn/v1beta1/vault.proto";
option go_package = "github.com/0glabs/0g-chain/x/earn/types";
// GenesisState defines the earn module's genesis state.
message GenesisState {
// params defines all the parameters related to earn
Params params = 1 [(gogoproto.nullable) = false];
// vault_records defines the available vaults
repeated VaultRecord vault_records = 2 [
(gogoproto.castrepeated) = "VaultRecords",
(gogoproto.nullable) = false
];
// share_records defines the owned shares of each vault
repeated VaultShareRecord vault_share_records = 3 [
(gogoproto.castrepeated) = "VaultShareRecords",
(gogoproto.nullable) = false
];
}

View File

@ -1,15 +0,0 @@
syntax = "proto3";
package kava.earn.v1beta1;
import "gogoproto/gogo.proto";
import "kava/earn/v1beta1/vault.proto";
option go_package = "github.com/0glabs/0g-chain/x/earn/types";
// Params defines the parameters of the earn module.
message Params {
repeated AllowedVault allowed_vaults = 1 [
(gogoproto.castrepeated) = "AllowedVaults",
(gogoproto.nullable) = false
];
}

View File

@ -1,55 +0,0 @@
syntax = "proto3";
package kava.earn.v1beta1;
import "cosmos/base/v1beta1/coin.proto";
import "gogoproto/gogo.proto";
option go_package = "github.com/0glabs/0g-chain/x/earn/types";
// CommunityPoolDepositProposal deposits from the community pool into an earn vault
message CommunityPoolDepositProposal {
option (gogoproto.goproto_stringer) = false;
option (gogoproto.goproto_getters) = false;
string title = 1;
string description = 2;
cosmos.base.v1beta1.Coin amount = 3 [(gogoproto.nullable) = false];
}
// CommunityPoolDepositProposalJSON defines a CommunityPoolDepositProposal with a deposit
message CommunityPoolDepositProposalJSON {
option (gogoproto.goproto_stringer) = true;
option (gogoproto.goproto_getters) = false;
string title = 1;
string description = 2;
cosmos.base.v1beta1.Coin amount = 3 [(gogoproto.nullable) = false];
repeated cosmos.base.v1beta1.Coin deposit = 4 [
(gogoproto.nullable) = false,
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"
];
}
// CommunityPoolWithdrawProposal withdraws from an earn vault back to community pool
message CommunityPoolWithdrawProposal {
option (gogoproto.goproto_stringer) = false;
option (gogoproto.goproto_getters) = false;
string title = 1;
string description = 2;
cosmos.base.v1beta1.Coin amount = 3 [(gogoproto.nullable) = false];
}
// CommunityPoolWithdrawProposalJSON defines a CommunityPoolWithdrawProposal with a deposit
message CommunityPoolWithdrawProposalJSON {
option (gogoproto.goproto_stringer) = true;
option (gogoproto.goproto_getters) = false;
string title = 1;
string description = 2;
cosmos.base.v1beta1.Coin amount = 3 [(gogoproto.nullable) = false];
repeated cosmos.base.v1beta1.Coin deposit = 4 [
(gogoproto.nullable) = false,
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"
];
}

View File

@ -1,160 +0,0 @@
syntax = "proto3";
package kava.earn.v1beta1;
import "cosmos/base/query/v1beta1/pagination.proto";
import "cosmos/base/v1beta1/coin.proto";
import "cosmos_proto/cosmos.proto";
import "gogoproto/gogo.proto";
import "google/api/annotations.proto";
import "kava/earn/v1beta1/params.proto";
import "kava/earn/v1beta1/strategy.proto";
import "kava/earn/v1beta1/vault.proto";
option go_package = "github.com/0glabs/0g-chain/x/earn/types";
option (gogoproto.goproto_getters_all) = false;
// Query defines the gRPC querier service for earn module
service Query {
// Params queries all parameters of the earn module.
rpc Params(QueryParamsRequest) returns (QueryParamsResponse) {
option (google.api.http).get = "/kava/earn/v1beta1/params";
}
// Vaults queries all vaults
rpc Vaults(QueryVaultsRequest) returns (QueryVaultsResponse) {
option (google.api.http).get = "/kava/earn/v1beta1/vaults";
}
// Vault queries a single vault based on the vault denom
rpc Vault(QueryVaultRequest) returns (QueryVaultResponse) {
option (google.api.http).get = "/kava/earn/v1beta1/vaults/{denom=**}";
}
// Deposits queries deposit details based on depositor address and vault
rpc Deposits(QueryDepositsRequest) returns (QueryDepositsResponse) {
option (google.api.http).get = "/kava/earn/v1beta1/deposits";
}
// TotalSupply returns the total sum of all coins currently locked into the earn module.
rpc TotalSupply(QueryTotalSupplyRequest) returns (QueryTotalSupplyResponse) {
option (google.api.http).get = "/kava/earn/v1beta1/total_supply";
}
}
// QueryParamsRequest defines the request type for querying x/earn parameters.
message QueryParamsRequest {}
// QueryParamsResponse defines the response type for querying x/earn parameters.
message QueryParamsResponse {
// params represents the earn module parameters
Params params = 1 [(gogoproto.nullable) = false];
}
// QueryVaultsRequest is the request type for the Query/Vaults RPC method.
message QueryVaultsRequest {}
// QueryVaultsResponse is the response type for the Query/Vaults RPC method.
message QueryVaultsResponse {
// vaults represents the earn module vaults
repeated VaultResponse vaults = 1 [(gogoproto.nullable) = false];
}
// QueryVaultRequest is the request type for the Query/Vault RPC method.
message QueryVaultRequest {
// vault filters vault by denom
string denom = 1;
}
// QueryVaultResponse is the response type for the Query/Vault RPC method.
message QueryVaultResponse {
// vault represents the queried earn module vault
VaultResponse vault = 1 [(gogoproto.nullable) = false];
}
// VaultResponse is the response type for a vault.
message VaultResponse {
// denom represents the denom of the vault
string denom = 1;
// VaultStrategy is the strategy used for this vault.
repeated StrategyType strategies = 2 [(gogoproto.castrepeated) = "StrategyTypes"];
// IsPrivateVault is true if the vault only allows depositors contained in
// AllowedDepositors.
bool is_private_vault = 3;
// AllowedDepositors is a list of addresses that are allowed to deposit to
// this vault if IsPrivateVault is true. Addresses not contained in this list
// are not allowed to deposit into this vault. If IsPrivateVault is false,
// this should be empty and ignored.
repeated string allowed_depositors = 4 [(cosmos_proto.scalar) = "cosmos.AddressString"];
// TotalShares is the total amount of shares issued to depositors.
string total_shares = 5;
// TotalValue is the total value of denom coins supplied to the vault if the
// vault were to be liquidated.
string total_value = 6 [
(cosmos_proto.scalar) = "cosmos.Int",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
(gogoproto.nullable) = false
];
}
// QueryDepositsRequest is the request type for the Query/Deposits RPC method.
message QueryDepositsRequest {
// depositor optionally filters deposits by depositor
string depositor = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];
// denom optionally filters deposits by vault denom
string denom = 2;
// respond with vault value in ukava for bkava vaults
bool value_in_staked_tokens = 3;
// pagination defines an optional pagination for the request.
cosmos.base.query.v1beta1.PageRequest pagination = 4;
}
// QueryDepositsResponse is the response type for the Query/Deposits RPC method.
message QueryDepositsResponse {
// deposits returns the deposits matching the requested parameters
repeated DepositResponse deposits = 1 [(gogoproto.nullable) = false];
// pagination defines the pagination in the response.
cosmos.base.query.v1beta1.PageResponse pagination = 2;
}
// DepositResponse defines a deposit query response type.
message DepositResponse {
// depositor represents the owner of the deposit.
string depositor = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];
// Shares represent the issued shares from their corresponding vaults.
repeated VaultShare shares = 2 [
(gogoproto.castrepeated) = "VaultShares",
(gogoproto.nullable) = false
];
// Value represents the total accumulated value of denom coins supplied to
// vaults. This may be greater than or equal to amount_supplied depending on
// the strategy.
repeated cosmos.base.v1beta1.Coin value = 3 [
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins",
(gogoproto.nullable) = false
];
}
// QueryTotalSupplyRequest defines the request type for Query/TotalSupply method.
message QueryTotalSupplyRequest {}
// TotalSupplyResponse defines the response type for the Query/TotalSupply method.
message QueryTotalSupplyResponse {
// Height is the block height at which these totals apply
int64 height = 1;
// Result is a list of coins supplied to earn
repeated cosmos.base.v1beta1.Coin result = 2 [
(gogoproto.nullable) = false,
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"
];
}

View File

@ -1,20 +0,0 @@
syntax = "proto3";
package kava.earn.v1beta1;
import "gogoproto/gogo.proto";
option go_package = "github.com/0glabs/0g-chain/x/earn/types";
// StrategyType is the type of strategy that a vault uses to optimize yields.
enum StrategyType {
option (gogoproto.goproto_enum_prefix) = false;
// STRATEGY_TYPE_UNSPECIFIED represents an unspecified or invalid strategy type.
STRATEGY_TYPE_UNSPECIFIED = 0;
// STRATEGY_TYPE_HARD represents the strategy that deposits assets in the Hard
// module.
STRATEGY_TYPE_HARD = 1;
// STRATEGY_TYPE_SAVINGS represents the strategy that deposits assets in the
// Savings module.
STRATEGY_TYPE_SAVINGS = 2;
}

View File

@ -1,57 +0,0 @@
syntax = "proto3";
package kava.earn.v1beta1;
import "cosmos/base/v1beta1/coin.proto";
import "cosmos_proto/cosmos.proto";
import "gogoproto/gogo.proto";
import "kava/earn/v1beta1/strategy.proto";
import "kava/earn/v1beta1/vault.proto";
option go_package = "github.com/0glabs/0g-chain/x/earn/types";
// Msg defines the earn Msg service.
service Msg {
// Deposit defines a method for depositing assets into a vault
rpc Deposit(MsgDeposit) returns (MsgDepositResponse);
// Withdraw defines a method for withdrawing assets into a vault
rpc Withdraw(MsgWithdraw) returns (MsgWithdrawResponse);
}
// MsgDeposit represents a message for depositing assedts into a vault
message MsgDeposit {
option (gogoproto.goproto_getters) = false;
// depositor represents the address to deposit funds from
string depositor = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];
// Amount represents the token to deposit. The vault corresponds to the denom
// of the amount coin.
cosmos.base.v1beta1.Coin amount = 2 [(gogoproto.nullable) = false];
// Strategy is the vault strategy to use.
StrategyType strategy = 3;
}
// MsgDepositResponse defines the Msg/Deposit response type.
message MsgDepositResponse {
VaultShare shares = 1 [(gogoproto.nullable) = false];
}
// MsgWithdraw represents a message for withdrawing liquidity from a vault
message MsgWithdraw {
option (gogoproto.goproto_getters) = false;
// from represents the address we are withdrawing for
string from = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];
// Amount represents the token to withdraw. The vault corresponds to the denom
// of the amount coin.
cosmos.base.v1beta1.Coin amount = 2 [(gogoproto.nullable) = false];
// Strategy is the vault strategy to use.
StrategyType strategy = 3;
}
// MsgWithdrawResponse defines the Msg/Withdraw response type.
message MsgWithdrawResponse {
VaultShare shares = 1 [(gogoproto.nullable) = false];
}

View File

@ -1,63 +0,0 @@
syntax = "proto3";
package kava.earn.v1beta1;
import "cosmos_proto/cosmos.proto";
import "gogoproto/gogo.proto";
import "kava/earn/v1beta1/strategy.proto";
option go_package = "github.com/0glabs/0g-chain/x/earn/types";
// AllowedVault is a vault that is allowed to be created. These can be
// modified via parameter governance.
message AllowedVault {
// Denom is the only supported denomination of the vault for deposits and withdrawals.
string denom = 1;
// VaultStrategy is the strategy used for this vault.
repeated StrategyType strategies = 2 [(gogoproto.castrepeated) = "StrategyTypes"];
// IsPrivateVault is true if the vault only allows depositors contained in
// AllowedDepositors.
bool is_private_vault = 3;
// AllowedDepositors is a list of addresses that are allowed to deposit to
// this vault if IsPrivateVault is true. Addresses not contained in this list
// are not allowed to deposit into this vault. If IsPrivateVault is false,
// this should be empty and ignored.
repeated bytes allowed_depositors = 4 [
(cosmos_proto.scalar) = "cosmos.AddressBytes",
(gogoproto.casttype) = "github.com/cosmos/cosmos-sdk/types.AccAddress"
];
}
// VaultRecord is the state of a vault.
message VaultRecord {
// TotalShares is the total distributed number of shares in the vault.
VaultShare total_shares = 1 [(gogoproto.nullable) = false];
}
// VaultShareRecord defines the vault shares owned by a depositor.
message VaultShareRecord {
// Depositor represents the owner of the shares
bytes depositor = 1 [
(cosmos_proto.scalar) = "cosmos.AddressBytes",
(gogoproto.casttype) = "github.com/cosmos/cosmos-sdk/types.AccAddress"
];
// Shares represent the vault shares owned by the depositor.
repeated VaultShare shares = 2 [
(gogoproto.castrepeated) = "VaultShares",
(gogoproto.nullable) = false
];
}
// VaultShare defines shares of a vault owned by a depositor.
message VaultShare {
option (gogoproto.goproto_stringer) = false;
string denom = 1;
string amount = 2 [
(cosmos_proto.scalar) = "cosmos.Dec",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.nullable) = false
];
}

View File

@ -1,58 +0,0 @@
syntax = "proto3";
package kava.hard.v1beta1;
import "cosmos/base/v1beta1/coin.proto";
import "cosmos_proto/cosmos.proto";
import "gogoproto/gogo.proto";
import "google/protobuf/timestamp.proto";
import "kava/hard/v1beta1/hard.proto";
option go_package = "github.com/0glabs/0g-chain/x/hard/types";
// GenesisState defines the hard module's genesis state.
message GenesisState {
Params params = 1 [(gogoproto.nullable) = false];
repeated GenesisAccumulationTime previous_accumulation_times = 2 [
(gogoproto.castrepeated) = "GenesisAccumulationTimes",
(gogoproto.nullable) = false
];
repeated Deposit deposits = 3 [
(gogoproto.castrepeated) = "Deposits",
(gogoproto.nullable) = false
];
repeated Borrow borrows = 4 [
(gogoproto.castrepeated) = "Borrows",
(gogoproto.nullable) = false
];
repeated cosmos.base.v1beta1.Coin total_supplied = 5 [
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins",
(gogoproto.nullable) = false
];
repeated cosmos.base.v1beta1.Coin total_borrowed = 6 [
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins",
(gogoproto.nullable) = false
];
repeated cosmos.base.v1beta1.Coin total_reserves = 7 [
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins",
(gogoproto.nullable) = false
];
}
// GenesisAccumulationTime stores the previous distribution time and its corresponding denom.
message GenesisAccumulationTime {
string collateral_type = 1;
google.protobuf.Timestamp previous_accumulation_time = 2 [
(gogoproto.stdtime) = true,
(gogoproto.nullable) = false
];
string supply_interest_factor = 3 [
(cosmos_proto.scalar) = "cosmos.Dec",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.nullable) = false
];
string borrow_interest_factor = 4 [
(cosmos_proto.scalar) = "cosmos.Dec",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.nullable) = false
];
}

View File

@ -1,146 +0,0 @@
syntax = "proto3";
package kava.hard.v1beta1;
import "cosmos/base/v1beta1/coin.proto";
import "cosmos_proto/cosmos.proto";
import "gogoproto/gogo.proto";
option go_package = "github.com/0glabs/0g-chain/x/hard/types";
option (gogoproto.goproto_getters_all) = false;
// Params defines the parameters for the hard module.
message Params {
repeated MoneyMarket money_markets = 1 [
(gogoproto.castrepeated) = "MoneyMarkets",
(gogoproto.nullable) = false
];
string minimum_borrow_usd_value = 2 [
(gogoproto.customname) = "MinimumBorrowUSDValue",
(cosmos_proto.scalar) = "cosmos.Dec",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.nullable) = false
];
}
// MoneyMarket is a money market for an individual asset.
message MoneyMarket {
string denom = 1;
BorrowLimit borrow_limit = 2 [(gogoproto.nullable) = false];
string spot_market_id = 3 [(gogoproto.customname) = "SpotMarketID"];
string conversion_factor = 4 [
(cosmos_proto.scalar) = "cosmos.Int",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
(gogoproto.nullable) = false
];
InterestRateModel interest_rate_model = 5 [(gogoproto.nullable) = false];
string reserve_factor = 6 [
(cosmos_proto.scalar) = "cosmos.Dec",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.nullable) = false
];
string keeper_reward_percentage = 7 [
(cosmos_proto.scalar) = "cosmos.Dec",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.nullable) = false
];
}
// BorrowLimit enforces restrictions on a money market.
message BorrowLimit {
bool has_max_limit = 1 [(gogoproto.jsontag) = "has_max_limit"];
string maximum_limit = 2 [
(cosmos_proto.scalar) = "cosmos.Dec",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.nullable) = false
];
string loan_to_value = 3 [
(cosmos_proto.scalar) = "cosmos.Dec",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.nullable) = false
];
}
// InterestRateModel contains information about an asset's interest rate.
message InterestRateModel {
string base_rate_apy = 1 [
(gogoproto.customname) = "BaseRateAPY",
(cosmos_proto.scalar) = "cosmos.Dec",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.nullable) = false
];
string base_multiplier = 2 [
(cosmos_proto.scalar) = "cosmos.Dec",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.nullable) = false
];
string kink = 3 [
(cosmos_proto.scalar) = "cosmos.Dec",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.nullable) = false
];
string jump_multiplier = 4 [
(cosmos_proto.scalar) = "cosmos.Dec",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.nullable) = false
];
}
// Deposit defines an amount of coins deposited into a hard module account.
message Deposit {
string depositor = 1 [
(cosmos_proto.scalar) = "cosmos.AddressBytes",
(gogoproto.casttype) = "github.com/cosmos/cosmos-sdk/types.AccAddress"
];
repeated cosmos.base.v1beta1.Coin amount = 2 [
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins",
(gogoproto.nullable) = false
];
repeated SupplyInterestFactor index = 3 [
(gogoproto.castrepeated) = "SupplyInterestFactors",
(gogoproto.nullable) = false
];
}
// Borrow defines an amount of coins borrowed from a hard module account.
message Borrow {
string borrower = 1 [
(cosmos_proto.scalar) = "cosmos.AddressBytes",
(gogoproto.casttype) = "github.com/cosmos/cosmos-sdk/types.AccAddress"
];
repeated cosmos.base.v1beta1.Coin amount = 2 [
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins",
(gogoproto.nullable) = false
];
repeated BorrowInterestFactor index = 3 [
(gogoproto.castrepeated) = "BorrowInterestFactors",
(gogoproto.nullable) = false
];
}
// SupplyInterestFactor defines an individual borrow interest factor.
message SupplyInterestFactor {
string denom = 1;
string value = 2 [
(cosmos_proto.scalar) = "cosmos.Dec",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.nullable) = false
];
}
// BorrowInterestFactor defines an individual borrow interest factor.
message BorrowInterestFactor {
string denom = 1;
string value = 2 [
(cosmos_proto.scalar) = "cosmos.Dec",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.nullable) = false
];
}
// CoinsProto defines a Protobuf wrapper around a Coins slice
message CoinsProto {
repeated cosmos.base.v1beta1.Coin coins = 1 [
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins",
(gogoproto.nullable) = false
];
}

View File

@ -1,281 +0,0 @@
syntax = "proto3";
package kava.hard.v1beta1;
import "cosmos/auth/v1beta1/auth.proto";
import "cosmos/base/query/v1beta1/pagination.proto";
import "cosmos/base/v1beta1/coin.proto";
import "cosmos_proto/cosmos.proto";
import "gogoproto/gogo.proto";
import "google/api/annotations.proto";
import "kava/hard/v1beta1/hard.proto";
option go_package = "github.com/0glabs/0g-chain/x/hard/types";
// Query defines the gRPC querier service for bep3 module.
service Query {
// Params queries module params.
rpc Params(QueryParamsRequest) returns (QueryParamsResponse) {
option (google.api.http).get = "/kava/hard/v1beta1/params";
}
// Accounts queries module accounts.
rpc Accounts(QueryAccountsRequest) returns (QueryAccountsResponse) {
option (google.api.http).get = "/kava/hard/v1beta1/accounts";
}
// Deposits queries hard deposits.
rpc Deposits(QueryDepositsRequest) returns (QueryDepositsResponse) {
option (google.api.http).get = "/kava/hard/v1beta1/deposits";
}
// UnsyncedDeposits queries unsynced deposits.
rpc UnsyncedDeposits(QueryUnsyncedDepositsRequest) returns (QueryUnsyncedDepositsResponse) {
option (google.api.http).get = "/kava/hard/v1beta1/unsynced-deposits";
}
// TotalDeposited queries total coins deposited to hard liquidity pools.
rpc TotalDeposited(QueryTotalDepositedRequest) returns (QueryTotalDepositedResponse) {
option (google.api.http).get = "/kava/hard/v1beta1/total-deposited";
}
// Borrows queries hard borrows.
rpc Borrows(QueryBorrowsRequest) returns (QueryBorrowsResponse) {
option (google.api.http).get = "/kava/hard/v1beta1/borrows";
}
// UnsyncedBorrows queries unsynced borrows.
rpc UnsyncedBorrows(QueryUnsyncedBorrowsRequest) returns (QueryUnsyncedBorrowsResponse) {
option (google.api.http).get = "/kava/hard/v1beta1/unsynced-borrows";
}
// TotalBorrowed queries total coins borrowed from hard liquidity pools.
rpc TotalBorrowed(QueryTotalBorrowedRequest) returns (QueryTotalBorrowedResponse) {
option (google.api.http).get = "/kava/hard/v1beta1/total-borrowed";
}
// InterestRate queries the hard module interest rates.
rpc InterestRate(QueryInterestRateRequest) returns (QueryInterestRateResponse) {
option (google.api.http).get = "/kava/hard/v1beta1/interest-rate";
}
// Reserves queries total hard reserve coins.
rpc Reserves(QueryReservesRequest) returns (QueryReservesResponse) {
option (google.api.http).get = "/kava/hard/v1beta1/reserves";
}
// InterestFactors queries hard module interest factors.
rpc InterestFactors(QueryInterestFactorsRequest) returns (QueryInterestFactorsResponse) {
option (google.api.http).get = "/kava/hard/v1beta1/interest-factors";
}
}
// QueryParamsRequest is the request type for the Query/Params RPC method.
message QueryParamsRequest {}
// QueryParamsResponse is the response type for the Query/Params RPC method.
message QueryParamsResponse {
Params params = 1 [(gogoproto.nullable) = false];
}
// QueryAccountsRequest is the request type for the Query/Accounts RPC method.
message QueryAccountsRequest {}
// QueryAccountsResponse is the response type for the Query/Accounts RPC method.
message QueryAccountsResponse {
repeated cosmos.auth.v1beta1.ModuleAccount accounts = 1 [(gogoproto.nullable) = false];
}
// QueryDepositsRequest is the request type for the Query/Deposits RPC method.
message QueryDepositsRequest {
string denom = 1;
string owner = 2 [(cosmos_proto.scalar) = "cosmos.AddressString"];
cosmos.base.query.v1beta1.PageRequest pagination = 3;
}
// QueryDepositsResponse is the response type for the Query/Deposits RPC method.
message QueryDepositsResponse {
repeated DepositResponse deposits = 1 [
(gogoproto.castrepeated) = "DepositResponses",
(gogoproto.nullable) = false
];
cosmos.base.query.v1beta1.PageResponse pagination = 2;
}
// QueryUnsyncedDepositsRequest is the request type for the Query/UnsyncedDeposits RPC method.
message QueryUnsyncedDepositsRequest {
string denom = 1;
string owner = 2 [(cosmos_proto.scalar) = "cosmos.AddressString"];
cosmos.base.query.v1beta1.PageRequest pagination = 3;
}
// QueryUnsyncedDepositsResponse is the response type for the Query/UnsyncedDeposits RPC method.
message QueryUnsyncedDepositsResponse {
repeated DepositResponse deposits = 1 [
(gogoproto.castrepeated) = "DepositResponses",
(gogoproto.nullable) = false
];
cosmos.base.query.v1beta1.PageResponse pagination = 2;
}
// QueryTotalDepositedRequest is the request type for the Query/TotalDeposited RPC method.
message QueryTotalDepositedRequest {
string denom = 1;
}
// QueryTotalDepositedResponse is the response type for the Query/TotalDeposited RPC method.
message QueryTotalDepositedResponse {
repeated cosmos.base.v1beta1.Coin supplied_coins = 2 [
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins",
(gogoproto.nullable) = false
];
}
// QueryBorrowsRequest is the request type for the Query/Borrows RPC method.
message QueryBorrowsRequest {
string denom = 1;
string owner = 2 [(cosmos_proto.scalar) = "cosmos.AddressString"];
cosmos.base.query.v1beta1.PageRequest pagination = 3;
}
// QueryBorrowsResponse is the response type for the Query/Borrows RPC method.
message QueryBorrowsResponse {
repeated BorrowResponse borrows = 1 [
(gogoproto.castrepeated) = "BorrowResponses",
(gogoproto.nullable) = false
];
cosmos.base.query.v1beta1.PageResponse pagination = 2;
}
// QueryUnsyncedBorrowsRequest is the request type for the Query/UnsyncedBorrows RPC method.
message QueryUnsyncedBorrowsRequest {
string denom = 1;
string owner = 2 [(cosmos_proto.scalar) = "cosmos.AddressString"];
cosmos.base.query.v1beta1.PageRequest pagination = 3;
}
// QueryUnsyncedBorrowsResponse is the response type for the Query/UnsyncedBorrows RPC method.
message QueryUnsyncedBorrowsResponse {
repeated BorrowResponse borrows = 1 [
(gogoproto.castrepeated) = "BorrowResponses",
(gogoproto.nullable) = false
];
cosmos.base.query.v1beta1.PageResponse pagination = 2;
}
// QueryTotalBorrowedRequest is the request type for the Query/TotalBorrowed RPC method.
message QueryTotalBorrowedRequest {
string denom = 1;
}
// QueryTotalBorrowedResponse is the response type for the Query/TotalBorrowed RPC method.
message QueryTotalBorrowedResponse {
repeated cosmos.base.v1beta1.Coin borrowed_coins = 2 [
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins",
(gogoproto.nullable) = false
];
}
// QueryInterestRateRequest is the request type for the Query/InterestRate RPC method.
message QueryInterestRateRequest {
string denom = 1;
}
// QueryInterestRateResponse is the response type for the Query/InterestRate RPC method.
message QueryInterestRateResponse {
repeated MoneyMarketInterestRate interest_rates = 1 [
(gogoproto.castrepeated) = "MoneyMarketInterestRates",
(gogoproto.nullable) = false
];
}
// QueryReservesRequest is the request type for the Query/Reserves RPC method.
message QueryReservesRequest {
string denom = 1;
}
// QueryReservesResponse is the response type for the Query/Reserves RPC method.
message QueryReservesResponse {
repeated cosmos.base.v1beta1.Coin amount = 2 [
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins",
(gogoproto.nullable) = false
];
}
// QueryInterestFactorsRequest is the request type for the Query/InterestFactors RPC method.
message QueryInterestFactorsRequest {
string denom = 1;
}
// QueryInterestFactorsResponse is the response type for the Query/InterestFactors RPC method.
message QueryInterestFactorsResponse {
repeated InterestFactor interest_factors = 1 [
(gogoproto.castrepeated) = "InterestFactors",
(gogoproto.nullable) = false
];
}
// DepositResponse defines an amount of coins deposited into a hard module account.
message DepositResponse {
string depositor = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];
repeated cosmos.base.v1beta1.Coin amount = 2 [
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins",
(gogoproto.nullable) = false
];
repeated SupplyInterestFactorResponse index = 3 [
(gogoproto.castrepeated) = "SupplyInterestFactorResponses",
(gogoproto.nullable) = false
];
}
// SupplyInterestFactorResponse defines an individual borrow interest factor.
message SupplyInterestFactorResponse {
string denom = 1;
// sdk.Dec as string
string value = 2;
}
// BorrowResponse defines an amount of coins borrowed from a hard module account.
message BorrowResponse {
string borrower = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];
repeated cosmos.base.v1beta1.Coin amount = 2 [
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins",
(gogoproto.nullable) = false
];
repeated BorrowInterestFactorResponse index = 3 [
(gogoproto.castrepeated) = "BorrowInterestFactorResponses",
(gogoproto.nullable) = false
];
}
// BorrowInterestFactorResponse defines an individual borrow interest factor.
message BorrowInterestFactorResponse {
string denom = 1;
// sdk.Dec as string
string value = 2;
}
// MoneyMarketInterestRate is a unique type returned by interest rate queries
message MoneyMarketInterestRate {
string denom = 1;
// sdk.Dec as String
string supply_interest_rate = 2;
// sdk.Dec as String
string borrow_interest_rate = 3;
}
// InterestFactor is a unique type returned by interest factor queries
message InterestFactor {
string denom = 1;
// sdk.Dec as String
string borrow_interest_factor = 2;
// sdk.Dec as String
string supply_interest_factor = 3;
}

View File

@ -1,80 +0,0 @@
syntax = "proto3";
package kava.hard.v1beta1;
import "cosmos/base/v1beta1/coin.proto";
import "cosmos_proto/cosmos.proto";
import "gogoproto/gogo.proto";
option go_package = "github.com/0glabs/0g-chain/x/hard/types";
// Msg defines the hard Msg service.
service Msg {
// Deposit defines a method for depositing funds to hard liquidity pool.
rpc Deposit(MsgDeposit) returns (MsgDepositResponse);
// Withdraw defines a method for withdrawing funds from hard liquidity pool.
rpc Withdraw(MsgWithdraw) returns (MsgWithdrawResponse);
// Borrow defines a method for borrowing funds from hard liquidity pool.
rpc Borrow(MsgBorrow) returns (MsgBorrowResponse);
// Repay defines a method for repaying funds borrowed from hard liquidity pool.
rpc Repay(MsgRepay) returns (MsgRepayResponse);
// Liquidate defines a method for attempting to liquidate a borrower that is over their loan-to-value.
rpc Liquidate(MsgLiquidate) returns (MsgLiquidateResponse);
}
// MsgDeposit defines the Msg/Deposit request type.
message MsgDeposit {
string depositor = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];
repeated cosmos.base.v1beta1.Coin amount = 2 [
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins",
(gogoproto.nullable) = false
];
}
// MsgDepositResponse defines the Msg/Deposit response type.
message MsgDepositResponse {}
// MsgWithdraw defines the Msg/Withdraw request type.
message MsgWithdraw {
string depositor = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];
repeated cosmos.base.v1beta1.Coin amount = 2 [
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins",
(gogoproto.nullable) = false
];
}
// MsgWithdrawResponse defines the Msg/Withdraw response type.
message MsgWithdrawResponse {}
// MsgBorrow defines the Msg/Borrow request type.
message MsgBorrow {
string borrower = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];
repeated cosmos.base.v1beta1.Coin amount = 2 [
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins",
(gogoproto.nullable) = false
];
}
// MsgBorrowResponse defines the Msg/Borrow response type.
message MsgBorrowResponse {}
// MsgRepay defines the Msg/Repay request type.
message MsgRepay {
string sender = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];
string owner = 2 [(cosmos_proto.scalar) = "cosmos.AddressString"];
repeated cosmos.base.v1beta1.Coin amount = 3 [
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins",
(gogoproto.nullable) = false
];
}
// MsgRepayResponse defines the Msg/Repay response type.
message MsgRepayResponse {}
// MsgLiquidate defines the Msg/Liquidate request type.
message MsgLiquidate {
string keeper = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];
string borrower = 2 [(cosmos_proto.scalar) = "cosmos.AddressString"];
}
// MsgLiquidateResponse defines the Msg/Liquidate response type.
message MsgLiquidateResponse {}

View File

@ -1,18 +0,0 @@
syntax = "proto3";
package kava.incentive.v1beta1;
import "cosmos_proto/cosmos.proto";
import "gogoproto/gogo.proto";
option go_package = "github.com/0glabs/0g-chain/x/incentive/types";
// Apy contains the calculated APY for a given collateral type at a specific
// instant in time.
message Apy {
string collateral_type = 1;
string apy = 2 [
(cosmos_proto.scalar) = "cosmos.Dec",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.nullable) = false
];
}

View File

@ -1,171 +0,0 @@
syntax = "proto3";
package kava.incentive.v1beta1;
import "cosmos/base/v1beta1/coin.proto";
import "cosmos_proto/cosmos.proto";
import "gogoproto/gogo.proto";
option go_package = "github.com/0glabs/0g-chain/x/incentive/types";
option (gogoproto.goproto_getters_all) = false;
// -------------- Base Claim Types, Reward Indexes --------------
// BaseClaim is a claim with a single reward coin types
message BaseClaim {
option (cosmos_proto.implements_interface) = "Claim";
bytes owner = 1 [
(cosmos_proto.scalar) = "cosmos.AddressBytes",
(gogoproto.casttype) = "github.com/cosmos/cosmos-sdk/types.AccAddress"
];
cosmos.base.v1beta1.Coin reward = 2 [(gogoproto.nullable) = false];
}
// BaseMultiClaim is a claim with multiple reward coin types
message BaseMultiClaim {
option (cosmos_proto.implements_interface) = "Claim";
bytes owner = 1 [
(cosmos_proto.scalar) = "cosmos.AddressBytes",
(gogoproto.casttype) = "github.com/cosmos/cosmos-sdk/types.AccAddress"
];
repeated cosmos.base.v1beta1.Coin reward = 2 [
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins",
(gogoproto.nullable) = false
];
}
// RewardIndex stores reward accumulation information
message RewardIndex {
string collateral_type = 1;
bytes reward_factor = 2 [
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.nullable) = false
];
}
// RewardIndexesProto defines a Protobuf wrapper around a RewardIndexes slice
message RewardIndexesProto {
repeated RewardIndex reward_indexes = 1 [
(gogoproto.castrepeated) = "RewardIndexes",
(gogoproto.nullable) = false
];
}
// MultiRewardIndex stores reward accumulation information on multiple reward types
message MultiRewardIndex {
string collateral_type = 1;
repeated RewardIndex reward_indexes = 2 [
(gogoproto.castrepeated) = "RewardIndexes",
(gogoproto.nullable) = false
];
}
// MultiRewardIndexesProto defines a Protobuf wrapper around a MultiRewardIndexes slice
message MultiRewardIndexesProto {
repeated MultiRewardIndex multi_reward_indexes = 1 [
(gogoproto.castrepeated) = "MultiRewardIndexes",
(gogoproto.nullable) = false
];
}
// -------------- Custom Claim Types --------------
// USDXMintingClaim is for USDX minting rewards
message USDXMintingClaim {
option (cosmos_proto.implements_interface) = "Claim";
BaseClaim base_claim = 1 [
(gogoproto.embed) = true,
(gogoproto.nullable) = false
];
repeated RewardIndex reward_indexes = 2 [
(gogoproto.castrepeated) = "RewardIndexes",
(gogoproto.nullable) = false
];
}
// HardLiquidityProviderClaim stores the hard liquidity provider rewards that can be claimed by owner
message HardLiquidityProviderClaim {
option (cosmos_proto.implements_interface) = "Claim";
BaseMultiClaim base_claim = 1 [
(gogoproto.embed) = true,
(gogoproto.nullable) = false
];
repeated MultiRewardIndex supply_reward_indexes = 2 [
(gogoproto.castrepeated) = "MultiRewardIndexes",
(gogoproto.nullable) = false
];
repeated MultiRewardIndex borrow_reward_indexes = 3 [
(gogoproto.castrepeated) = "MultiRewardIndexes",
(gogoproto.nullable) = false
];
}
// DelegatorClaim stores delegation rewards that can be claimed by owner
message DelegatorClaim {
option (cosmos_proto.implements_interface) = "Claim";
BaseMultiClaim base_claim = 1 [
(gogoproto.embed) = true,
(gogoproto.nullable) = false
];
repeated MultiRewardIndex reward_indexes = 2 [
(gogoproto.castrepeated) = "MultiRewardIndexes",
(gogoproto.nullable) = false
];
}
// SwapClaim stores the swap rewards that can be claimed by owner
message SwapClaim {
option (cosmos_proto.implements_interface) = "Claim";
BaseMultiClaim base_claim = 1 [
(gogoproto.embed) = true,
(gogoproto.nullable) = false
];
repeated MultiRewardIndex reward_indexes = 2 [
(gogoproto.castrepeated) = "MultiRewardIndexes",
(gogoproto.nullable) = false
];
}
// SavingsClaim stores the savings rewards that can be claimed by owner
message SavingsClaim {
option (cosmos_proto.implements_interface) = "Claim";
BaseMultiClaim base_claim = 1 [
(gogoproto.embed) = true,
(gogoproto.nullable) = false
];
repeated MultiRewardIndex reward_indexes = 2 [
(gogoproto.castrepeated) = "MultiRewardIndexes",
(gogoproto.nullable) = false
];
}
// EarnClaim stores the earn rewards that can be claimed by owner
message EarnClaim {
option (cosmos_proto.implements_interface) = "Claim";
BaseMultiClaim base_claim = 1 [
(gogoproto.embed) = true,
(gogoproto.nullable) = false
];
repeated MultiRewardIndex reward_indexes = 2 [
(gogoproto.castrepeated) = "MultiRewardIndexes",
(gogoproto.nullable) = false
];
}

View File

@ -1,89 +0,0 @@
syntax = "proto3";
package kava.incentive.v1beta1;
import "gogoproto/gogo.proto";
import "google/protobuf/timestamp.proto";
import "kava/incentive/v1beta1/claims.proto";
import "kava/incentive/v1beta1/params.proto";
// import "cosmos/base/v1beta1/coin.proto";
// import "cosmos/base/v1beta1/coins.proto";
option go_package = "github.com/0glabs/0g-chain/x/incentive/types";
option (gogoproto.goproto_getters_all) = false;
// AccumulationTime stores the previous reward distribution time and its corresponding collateral type
message AccumulationTime {
string collateral_type = 1;
google.protobuf.Timestamp previous_accumulation_time = 2 [
(gogoproto.nullable) = false,
(gogoproto.stdtime) = true
];
}
// GenesisRewardState groups together the global state for a particular reward so it can be exported in genesis.
message GenesisRewardState {
repeated AccumulationTime accumulation_times = 1 [
(gogoproto.castrepeated) = "AccumulationTimes",
(gogoproto.nullable) = false
];
repeated MultiRewardIndex multi_reward_indexes = 2 [
(gogoproto.castrepeated) = "MultiRewardIndexes",
(gogoproto.nullable) = false
];
}
// GenesisState is the state that must be provided at genesis.
message GenesisState {
Params params = 1 [(gogoproto.nullable) = false];
GenesisRewardState usdx_reward_state = 2 [
(gogoproto.customname) = "USDXRewardState",
(gogoproto.nullable) = false
];
GenesisRewardState hard_supply_reward_state = 3 [(gogoproto.nullable) = false];
GenesisRewardState hard_borrow_reward_state = 4 [(gogoproto.nullable) = false];
GenesisRewardState delegator_reward_state = 5 [(gogoproto.nullable) = false];
GenesisRewardState swap_reward_state = 6 [(gogoproto.nullable) = false];
repeated USDXMintingClaim usdx_minting_claims = 7 [
(gogoproto.customname) = "USDXMintingClaims",
(gogoproto.castrepeated) = "USDXMintingClaims",
(gogoproto.nullable) = false
];
repeated HardLiquidityProviderClaim hard_liquidity_provider_claims = 8 [
(gogoproto.castrepeated) = "HardLiquidityProviderClaims",
(gogoproto.nullable) = false
];
repeated DelegatorClaim delegator_claims = 9 [
(gogoproto.castrepeated) = "DelegatorClaims",
(gogoproto.nullable) = false
];
repeated SwapClaim swap_claims = 10 [
(gogoproto.castrepeated) = "SwapClaims",
(gogoproto.nullable) = false
];
GenesisRewardState savings_reward_state = 11 [(gogoproto.nullable) = false];
repeated SavingsClaim savings_claims = 12 [
(gogoproto.castrepeated) = "SavingsClaims",
(gogoproto.nullable) = false
];
GenesisRewardState earn_reward_state = 13 [(gogoproto.nullable) = false];
repeated EarnClaim earn_claims = 14 [
(gogoproto.castrepeated) = "EarnClaims",
(gogoproto.nullable) = false
];
}

View File

@ -1,121 +0,0 @@
syntax = "proto3";
package kava.incentive.v1beta1;
import "cosmos/base/v1beta1/coin.proto";
import "gogoproto/gogo.proto";
import "google/protobuf/timestamp.proto";
option go_package = "github.com/0glabs/0g-chain/x/incentive/types";
option (gogoproto.goproto_getters_all) = false;
// RewardPeriod stores the state of an ongoing reward
message RewardPeriod {
bool active = 1;
string collateral_type = 2;
google.protobuf.Timestamp start = 3 [
(gogoproto.nullable) = false,
(gogoproto.stdtime) = true
];
google.protobuf.Timestamp end = 4 [
(gogoproto.nullable) = false,
(gogoproto.stdtime) = true
];
cosmos.base.v1beta1.Coin rewards_per_second = 5 [(gogoproto.nullable) = false];
}
// MultiRewardPeriod supports multiple reward types
message MultiRewardPeriod {
bool active = 1;
string collateral_type = 2;
google.protobuf.Timestamp start = 3 [
(gogoproto.nullable) = false,
(gogoproto.stdtime) = true
];
google.protobuf.Timestamp end = 4 [
(gogoproto.nullable) = false,
(gogoproto.stdtime) = true
];
repeated cosmos.base.v1beta1.Coin rewards_per_second = 5 [
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins",
(gogoproto.nullable) = false
];
}
// Multiplier amount the claim rewards get increased by, along with how long the claim rewards are locked
message Multiplier {
string name = 1;
int64 months_lockup = 2;
bytes factor = 3 [
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.nullable) = false
];
}
// MultipliersPerDenom is a map of denoms to a set of multipliers
message MultipliersPerDenom {
string denom = 1;
repeated Multiplier multipliers = 2 [
(gogoproto.castrepeated) = "Multipliers",
(gogoproto.nullable) = false
];
}
// Params
message Params {
repeated RewardPeriod usdx_minting_reward_periods = 1 [
(gogoproto.customname) = "USDXMintingRewardPeriods",
(gogoproto.castrepeated) = "RewardPeriods",
(gogoproto.nullable) = false
];
repeated MultiRewardPeriod hard_supply_reward_periods = 2 [
(gogoproto.castrepeated) = "MultiRewardPeriods",
(gogoproto.nullable) = false
];
repeated MultiRewardPeriod hard_borrow_reward_periods = 3 [
(gogoproto.castrepeated) = "MultiRewardPeriods",
(gogoproto.nullable) = false
];
repeated MultiRewardPeriod delegator_reward_periods = 4 [
(gogoproto.castrepeated) = "MultiRewardPeriods",
(gogoproto.nullable) = false
];
repeated MultiRewardPeriod swap_reward_periods = 5 [
(gogoproto.castrepeated) = "MultiRewardPeriods",
(gogoproto.nullable) = false
];
repeated MultipliersPerDenom claim_multipliers = 6 [
(gogoproto.castrepeated) = "MultipliersPerDenoms",
(gogoproto.nullable) = false
];
google.protobuf.Timestamp claim_end = 7 [
(gogoproto.nullable) = false,
(gogoproto.stdtime) = true
];
repeated MultiRewardPeriod savings_reward_periods = 8 [
(gogoproto.castrepeated) = "MultiRewardPeriods",
(gogoproto.nullable) = false
];
repeated MultiRewardPeriod earn_reward_periods = 9 [
(gogoproto.castrepeated) = "MultiRewardPeriods",
(gogoproto.nullable) = false
];
}

View File

@ -1,130 +0,0 @@
syntax = "proto3";
package kava.incentive.v1beta1;
import "gogoproto/gogo.proto";
import "google/api/annotations.proto";
import "kava/incentive/v1beta1/apy.proto";
import "kava/incentive/v1beta1/claims.proto";
import "kava/incentive/v1beta1/params.proto";
option go_package = "github.com/0glabs/0g-chain/x/incentive/types";
// Query defines the gRPC querier service for incentive module.
service Query {
// Params queries module params.
rpc Params(QueryParamsRequest) returns (QueryParamsResponse) {
option (google.api.http).get = "/kava/incentive/v1beta1/params";
}
// Rewards queries reward information for a given user.
rpc Rewards(QueryRewardsRequest) returns (QueryRewardsResponse) {
option (google.api.http).get = "/kava/incentive/v1beta1/rewards";
}
// Rewards queries the reward factors.
rpc RewardFactors(QueryRewardFactorsRequest) returns (QueryRewardFactorsResponse) {
option (google.api.http).get = "/kava/incentive/v1beta1/reward_factors";
}
// Apy queries incentive reward apy for a reward.
rpc Apy(QueryApyRequest) returns (QueryApyResponse) {
option (google.api.http).get = "/kava/incentive/v1beta1/apy";
}
}
// QueryParamsRequest is the request type for the Query/Params RPC method.
message QueryParamsRequest {}
// QueryParamsResponse is the response type for the Query/Params RPC method.
message QueryParamsResponse {
Params params = 1 [(gogoproto.nullable) = false];
}
// QueryRewardsRequest is the request type for the Query/Rewards RPC method.
message QueryRewardsRequest {
// owner is the address of the user to query rewards for.
string owner = 1;
// reward_type is the type of reward to query rewards for, e.g. hard, earn,
// swap.
string reward_type = 2;
// unsynchronized is a flag to query rewards that are not simulated for reward
// synchronized for the current block.
bool unsynchronized = 3;
}
// QueryRewardsResponse is the response type for the Query/Rewards RPC method.
message QueryRewardsResponse {
repeated USDXMintingClaim usdx_minting_claims = 1 [
(gogoproto.customname) = "USDXMintingClaims",
(gogoproto.castrepeated) = "USDXMintingClaims",
(gogoproto.nullable) = false
];
repeated HardLiquidityProviderClaim hard_liquidity_provider_claims = 2 [
(gogoproto.castrepeated) = "HardLiquidityProviderClaims",
(gogoproto.nullable) = false
];
repeated DelegatorClaim delegator_claims = 3 [
(gogoproto.castrepeated) = "DelegatorClaims",
(gogoproto.nullable) = false
];
repeated SwapClaim swap_claims = 4 [
(gogoproto.castrepeated) = "SwapClaims",
(gogoproto.nullable) = false
];
repeated SavingsClaim savings_claims = 5 [
(gogoproto.castrepeated) = "SavingsClaims",
(gogoproto.nullable) = false
];
repeated EarnClaim earn_claims = 6 [
(gogoproto.castrepeated) = "EarnClaims",
(gogoproto.nullable) = false
];
}
// QueryRewardFactorsRequest is the request type for the Query/RewardFactors RPC method.
message QueryRewardFactorsRequest {}
// QueryRewardFactorsResponse is the response type for the Query/RewardFactors RPC method.
message QueryRewardFactorsResponse {
repeated RewardIndex usdx_minting_reward_factors = 1 [
(gogoproto.castrepeated) = "RewardIndexes",
(gogoproto.nullable) = false
];
repeated MultiRewardIndex hard_supply_reward_factors = 2 [
(gogoproto.castrepeated) = "MultiRewardIndexes",
(gogoproto.nullable) = false
];
repeated MultiRewardIndex hard_borrow_reward_factors = 3 [
(gogoproto.castrepeated) = "MultiRewardIndexes",
(gogoproto.nullable) = false
];
repeated MultiRewardIndex delegator_reward_factors = 4 [
(gogoproto.castrepeated) = "MultiRewardIndexes",
(gogoproto.nullable) = false
];
repeated MultiRewardIndex swap_reward_factors = 5 [
(gogoproto.castrepeated) = "MultiRewardIndexes",
(gogoproto.nullable) = false
];
repeated MultiRewardIndex savings_reward_factors = 6 [
(gogoproto.castrepeated) = "MultiRewardIndexes",
(gogoproto.nullable) = false
];
repeated MultiRewardIndex earn_reward_factors = 7 [
(gogoproto.castrepeated) = "MultiRewardIndexes",
(gogoproto.nullable) = false
];
}
// QueryApysRequest is the request type for the Query/Apys RPC method.
message QueryApyRequest {}
// QueryApysResponse is the response type for the Query/Apys RPC method.
message QueryApyResponse {
repeated Apy earn = 1 [(gogoproto.nullable) = false];
}

View File

@ -1,124 +0,0 @@
syntax = "proto3";
package kava.incentive.v1beta1;
import "gogoproto/gogo.proto";
option go_package = "github.com/0glabs/0g-chain/x/incentive/types";
// Msg defines the incentive Msg service.
service Msg {
// ClaimUSDXMintingReward is a message type used to claim USDX minting rewards
rpc ClaimUSDXMintingReward(MsgClaimUSDXMintingReward) returns (MsgClaimUSDXMintingRewardResponse);
// ClaimHardReward is a message type used to claim Hard liquidity provider rewards
rpc ClaimHardReward(MsgClaimHardReward) returns (MsgClaimHardRewardResponse);
// ClaimDelegatorReward is a message type used to claim delegator rewards
rpc ClaimDelegatorReward(MsgClaimDelegatorReward) returns (MsgClaimDelegatorRewardResponse);
// ClaimSwapReward is a message type used to claim swap rewards
rpc ClaimSwapReward(MsgClaimSwapReward) returns (MsgClaimSwapRewardResponse);
// ClaimSavingsReward is a message type used to claim savings rewards
rpc ClaimSavingsReward(MsgClaimSavingsReward) returns (MsgClaimSavingsRewardResponse);
// ClaimEarnReward is a message type used to claim earn rewards
rpc ClaimEarnReward(MsgClaimEarnReward) returns (MsgClaimEarnRewardResponse);
}
// Selection is a pair of denom and multiplier name. It holds the choice of multiplier a user makes when they claim a
// denom.
message Selection {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;
string denom = 1;
string multiplier_name = 2;
}
// MsgClaimUSDXMintingReward message type used to claim USDX minting rewards
message MsgClaimUSDXMintingReward {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;
string sender = 1;
string multiplier_name = 2;
}
// MsgClaimUSDXMintingRewardResponse defines the Msg/ClaimUSDXMintingReward response type.
message MsgClaimUSDXMintingRewardResponse {}
// MsgClaimHardReward message type used to claim Hard liquidity provider rewards
message MsgClaimHardReward {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;
string sender = 1;
repeated Selection denoms_to_claim = 2 [
(gogoproto.castrepeated) = "Selections",
(gogoproto.nullable) = false
];
}
// MsgClaimHardRewardResponse defines the Msg/ClaimHardReward response type.
message MsgClaimHardRewardResponse {}
// MsgClaimDelegatorReward message type used to claim delegator rewards
message MsgClaimDelegatorReward {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;
string sender = 1;
repeated Selection denoms_to_claim = 2 [
(gogoproto.castrepeated) = "Selections",
(gogoproto.nullable) = false
];
}
// MsgClaimDelegatorRewardResponse defines the Msg/ClaimDelegatorReward response type.
message MsgClaimDelegatorRewardResponse {}
// MsgClaimSwapReward message type used to claim delegator rewards
message MsgClaimSwapReward {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;
string sender = 1;
repeated Selection denoms_to_claim = 2 [
(gogoproto.castrepeated) = "Selections",
(gogoproto.nullable) = false
];
}
// MsgClaimSwapRewardResponse defines the Msg/ClaimSwapReward response type.
message MsgClaimSwapRewardResponse {}
// MsgClaimSavingsReward message type used to claim savings rewards
message MsgClaimSavingsReward {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;
string sender = 1;
repeated Selection denoms_to_claim = 2 [
(gogoproto.castrepeated) = "Selections",
(gogoproto.nullable) = false
];
}
// MsgClaimSavingsRewardResponse defines the Msg/ClaimSavingsReward response type.
message MsgClaimSavingsRewardResponse {}
// MsgClaimEarnReward message type used to claim earn rewards
message MsgClaimEarnReward {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;
string sender = 1;
repeated Selection denoms_to_claim = 2 [
(gogoproto.castrepeated) = "Selections",
(gogoproto.nullable) = false
];
}
// MsgClaimEarnRewardResponse defines the Msg/ClaimEarnReward response type.
message MsgClaimEarnRewardResponse {}

View File

@ -1,18 +0,0 @@
syntax = "proto3";
package kava.kavadist.v1beta1;
import "gogoproto/gogo.proto";
import "google/protobuf/timestamp.proto";
import "kava/kavadist/v1beta1/params.proto";
option go_package = "github.com/0glabs/0g-chain/x/kavadist/types";
// GenesisState defines the kavadist module's genesis state.
message GenesisState {
Params params = 1 [(gogoproto.nullable) = false];
google.protobuf.Timestamp previous_block_time = 2 [
(gogoproto.stdtime) = true,
(gogoproto.nullable) = false
];
}

View File

@ -1,83 +0,0 @@
syntax = "proto3";
package kava.kavadist.v1beta1;
import "cosmos/base/v1beta1/coin.proto";
import "cosmos_proto/cosmos.proto";
import "gogoproto/gogo.proto";
import "google/protobuf/timestamp.proto";
option go_package = "github.com/0glabs/0g-chain/x/kavadist/types";
option (gogoproto.goproto_getters_all) = false;
option (gogoproto.goproto_stringer_all) = false;
// Params governance parameters for kavadist module
message Params {
bool active = 1;
repeated Period periods = 3 [(gogoproto.nullable) = false];
InfrastructureParams infrastructure_params = 4 [(gogoproto.nullable) = false];
}
// InfrastructureParams define the parameters for infrastructure rewards.
message InfrastructureParams {
repeated Period infrastructure_periods = 1 [
(gogoproto.castrepeated) = "Periods",
(gogoproto.nullable) = false
];
repeated CoreReward core_rewards = 2 [
(gogoproto.castrepeated) = "CoreRewards",
(gogoproto.nullable) = false
];
repeated PartnerReward partner_rewards = 3 [
(gogoproto.castrepeated) = "PartnerRewards",
(gogoproto.nullable) = false
];
option (gogoproto.goproto_stringer) = true;
}
// CoreReward defines the reward weights for core infrastructure providers.
message CoreReward {
bytes address = 1 [
(cosmos_proto.scalar) = "cosmos.AddressBytes",
(gogoproto.casttype) = "github.com/cosmos/cosmos-sdk/types.AccAddress"
];
string weight = 2 [
(cosmos_proto.scalar) = "cosmos.Dec",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.nullable) = false
];
option (gogoproto.goproto_stringer) = true;
}
// PartnerRewards defines the reward schedule for partner infrastructure providers.
message PartnerReward {
bytes address = 1 [
(cosmos_proto.scalar) = "cosmos.AddressBytes",
(gogoproto.casttype) = "github.com/cosmos/cosmos-sdk/types.AccAddress"
];
cosmos.base.v1beta1.Coin rewards_per_second = 2 [(gogoproto.nullable) = false];
option (gogoproto.goproto_stringer) = true;
}
// Period stores the specified start and end dates, and the inflation, expressed as a decimal
// representing the yearly APR of KAVA tokens that will be minted during that period
message Period {
option (gogoproto.equal) = true;
// example "2020-03-01T15:20:00Z"
google.protobuf.Timestamp start = 1 [
(gogoproto.stdtime) = true,
(gogoproto.nullable) = false
];
// example "2020-06-01T15:20:00Z"
google.protobuf.Timestamp end = 2 [
(gogoproto.stdtime) = true,
(gogoproto.nullable) = false
];
// example "1.000000003022265980" - 10% inflation
bytes inflation = 3 [
(gogoproto.nullable) = false,
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec"
];
}

View File

@ -1,44 +0,0 @@
syntax = "proto3";
package kava.kavadist.v1beta1;
import "cosmos/base/v1beta1/coin.proto";
import "gogoproto/gogo.proto";
option go_package = "github.com/0glabs/0g-chain/x/kavadist/types";
// CommunityPoolMultiSpendProposal spends from the community pool by sending to one or more
// addresses
message CommunityPoolMultiSpendProposal {
option (gogoproto.goproto_stringer) = false;
option (gogoproto.goproto_getters) = false;
string title = 1;
string description = 2;
repeated MultiSpendRecipient recipient_list = 3 [(gogoproto.nullable) = false];
}
// CommunityPoolMultiSpendProposalJSON defines a CommunityPoolMultiSpendProposal with a deposit
message CommunityPoolMultiSpendProposalJSON {
option (gogoproto.goproto_stringer) = true;
option (gogoproto.goproto_getters) = false;
string title = 1;
string description = 2;
repeated MultiSpendRecipient recipient_list = 3 [(gogoproto.nullable) = false];
repeated cosmos.base.v1beta1.Coin deposit = 4 [
(gogoproto.nullable) = false,
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"
];
}
// MultiSpendRecipient defines a recipient and the amount of coins they are receiving
message MultiSpendRecipient {
option (gogoproto.goproto_stringer) = false;
option (gogoproto.goproto_getters) = false;
string address = 1;
repeated cosmos.base.v1beta1.Coin amount = 2 [
(gogoproto.nullable) = false,
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"
];
}

View File

@ -1,41 +0,0 @@
syntax = "proto3";
package kava.kavadist.v1beta1;
import "cosmos/base/v1beta1/coin.proto";
import "gogoproto/gogo.proto";
import "google/api/annotations.proto";
import "kava/kavadist/v1beta1/params.proto";
option go_package = "github.com/0glabs/0g-chain/x/kavadist/types";
// Query defines the gRPC querier service.
service Query {
// Params queries the parameters of x/kavadist module.
rpc Params(QueryParamsRequest) returns (QueryParamsResponse) {
option (google.api.http).get = "/kava/kavadist/v1beta1/parameters";
}
// Balance queries the balance of all coins of x/kavadist module.
rpc Balance(QueryBalanceRequest) returns (QueryBalanceResponse) {
option (google.api.http).get = "/kava/kavadist/v1beta1/balance";
}
}
// QueryParamsRequest defines the request type for querying x/kavadist parameters.
message QueryParamsRequest {}
// QueryParamsResponse defines the response type for querying x/kavadist parameters.
message QueryParamsResponse {
Params params = 1 [(gogoproto.nullable) = false];
}
// QueryBalanceRequest defines the request type for querying x/kavadist balance.
message QueryBalanceRequest {}
// QueryBalanceResponse defines the response type for querying x/kavadist balance.
message QueryBalanceResponse {
repeated cosmos.base.v1beta1.Coin coins = 1 [
(gogoproto.nullable) = false,
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"
];
}

View File

@ -1,52 +0,0 @@
syntax = "proto3";
package kava.liquid.v1beta1;
import "cosmos/base/v1beta1/coin.proto";
import "cosmos_proto/cosmos.proto";
import "gogoproto/gogo.proto";
import "google/api/annotations.proto";
option go_package = "github.com/0glabs/0g-chain/x/liquid/types";
option (gogoproto.goproto_getters_all) = false;
// Query defines the gRPC querier service for liquid module
service Query {
// DelegatedBalance returns an account's vesting and vested coins currently delegated to validators.
// It ignores coins in unbonding delegations.
rpc DelegatedBalance(QueryDelegatedBalanceRequest) returns (QueryDelegatedBalanceResponse) {
option (google.api.http).get = "/kava/liquid/v1beta1/delegated_balance/{delegator}";
}
// TotalSupply returns the total sum of all coins currently locked into the liquid module.
rpc TotalSupply(QueryTotalSupplyRequest) returns (QueryTotalSupplyResponse) {
option (google.api.http).get = "/kava/liquid/v1beta1/total_supply";
}
}
// QueryDelegatedBalanceRequest defines the request type for Query/DelegatedBalance method.
message QueryDelegatedBalanceRequest {
// delegator is the address of the account to query
string delegator = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];
}
// DelegatedBalanceResponse defines the response type for the Query/DelegatedBalance method.
message QueryDelegatedBalanceResponse {
// vested is the amount of all delegated coins that have vested (ie not locked)
cosmos.base.v1beta1.Coin vested = 1 [(gogoproto.nullable) = false];
// vesting is the amount of all delegated coins that are still vesting (ie locked)
cosmos.base.v1beta1.Coin vesting = 2 [(gogoproto.nullable) = false];
}
// QueryTotalSupplyRequest defines the request type for Query/TotalSupply method.
message QueryTotalSupplyRequest {}
// TotalSupplyResponse defines the response type for the Query/TotalSupply method.
message QueryTotalSupplyResponse {
// Height is the block height at which these totals apply
int64 height = 1;
// Result is a list of coins supplied to liquid
repeated cosmos.base.v1beta1.Coin result = 2 [
(gogoproto.nullable) = false,
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"
];
}

View File

@ -1,53 +0,0 @@
syntax = "proto3";
package kava.liquid.v1beta1;
import "cosmos/base/v1beta1/coin.proto";
import "cosmos_proto/cosmos.proto";
import "gogoproto/gogo.proto";
option go_package = "github.com/0glabs/0g-chain/x/liquid/types";
// Msg defines the liquid Msg service.
service Msg {
// MintDerivative defines a method for converting a delegation into staking deriviatives.
rpc MintDerivative(MsgMintDerivative) returns (MsgMintDerivativeResponse);
// BurnDerivative defines a method for converting staking deriviatives into a delegation.
rpc BurnDerivative(MsgBurnDerivative) returns (MsgBurnDerivativeResponse);
}
// MsgMintDerivative defines the Msg/MintDerivative request type.
message MsgMintDerivative {
// sender is the owner of the delegation to be converted
string sender = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];
// validator is the validator of the delegation to be converted
string validator = 2;
// amount is the quantity of staked assets to be converted
cosmos.base.v1beta1.Coin amount = 3 [(gogoproto.nullable) = false];
}
// MsgMintDerivativeResponse defines the Msg/MintDerivative response type.
message MsgMintDerivativeResponse {
// received is the amount of staking derivative minted and sent to the sender
cosmos.base.v1beta1.Coin received = 1 [(gogoproto.nullable) = false];
}
// MsgBurnDerivative defines the Msg/BurnDerivative request type.
message MsgBurnDerivative {
// sender is the owner of the derivatives to be converted
string sender = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];
// validator is the validator of the derivatives to be converted
string validator = 2;
// amount is the quantity of derivatives to be converted
cosmos.base.v1beta1.Coin amount = 3 [(gogoproto.nullable) = false];
}
// MsgBurnDerivativeResponse defines the Msg/BurnDerivative response type.
message MsgBurnDerivativeResponse {
// received is the number of delegation shares sent to the sender
string received = 1 [
(cosmos_proto.scalar) = "cosmos.Dec",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.nullable) = false
];
}

View File

@ -1,80 +0,0 @@
syntax = "proto3";
package kava.router.v1beta1;
import "cosmos/base/v1beta1/coin.proto";
import "cosmos_proto/cosmos.proto";
import "gogoproto/gogo.proto";
option go_package = "github.com/0glabs/0g-chain/x/router/types";
option (gogoproto.goproto_getters_all) = false;
// Msg defines the router Msg service.
service Msg {
// MintDeposit converts a delegation into staking derivatives and deposits it all into an earn vault.
rpc MintDeposit(MsgMintDeposit) returns (MsgMintDepositResponse);
// DelegateMintDeposit delegates tokens to a validator, then converts them into staking derivatives,
// then deposits to an earn vault.
rpc DelegateMintDeposit(MsgDelegateMintDeposit) returns (MsgDelegateMintDepositResponse);
// WithdrawBurn removes staking derivatives from an earn vault and converts them back to a staking delegation.
rpc WithdrawBurn(MsgWithdrawBurn) returns (MsgWithdrawBurnResponse);
// WithdrawBurnUndelegate removes staking derivatives from an earn vault, converts them to a staking delegation,
// then undelegates them from their validator.
rpc WithdrawBurnUndelegate(MsgWithdrawBurnUndelegate) returns (MsgWithdrawBurnUndelegateResponse);
}
// MsgMintDeposit converts a delegation into staking derivatives and deposits it all into an earn vault.
message MsgMintDeposit {
// depositor represents the owner of the delegation to convert
string depositor = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];
// validator is the validator for the depositor's delegation
string validator = 2;
// amount is the delegation balance to convert
cosmos.base.v1beta1.Coin amount = 3 [(gogoproto.nullable) = false];
}
// MsgMintDepositResponse defines the Msg/MsgMintDeposit response type.
message MsgMintDepositResponse {}
// MsgDelegateMintDeposit delegates tokens to a validator, then converts them into staking derivatives,
// then deposits to an earn vault.
message MsgDelegateMintDeposit {
// depositor represents the owner of the tokens to delegate
string depositor = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];
// validator is the address of the validator to delegate to
string validator = 2;
// amount is the tokens to delegate
cosmos.base.v1beta1.Coin amount = 3 [(gogoproto.nullable) = false];
}
// MsgDelegateMintDepositResponse defines the Msg/MsgDelegateMintDeposit response type.
message MsgDelegateMintDepositResponse {}
// MsgWithdrawBurn removes staking derivatives from an earn vault and converts them back to a staking delegation.
message MsgWithdrawBurn {
// from is the owner of the earn vault to withdraw from
string from = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];
// validator is the address to select the derivative denom to withdraw
string validator = 2;
// amount is the staked token equivalent to withdraw
cosmos.base.v1beta1.Coin amount = 3 [(gogoproto.nullable) = false];
}
// MsgWithdrawBurnResponse defines the Msg/MsgWithdrawBurn response type.
message MsgWithdrawBurnResponse {}
// MsgWithdrawBurnUndelegate removes staking derivatives from an earn vault, converts them to a staking delegation,
// then undelegates them from their validator.
message MsgWithdrawBurnUndelegate {
// from is the owner of the earn vault to withdraw from
string from = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];
// validator is the address to select the derivative denom to withdraw
string validator = 2;
// amount is the staked token equivalent to withdraw
cosmos.base.v1beta1.Coin amount = 3 [(gogoproto.nullable) = false];
}
// MsgWithdrawBurnUndelegateResponse defines the Msg/MsgWithdrawBurnUndelegate response type.
message MsgWithdrawBurnUndelegateResponse {}

View File

@ -1,18 +0,0 @@
syntax = "proto3";
package kava.savings.v1beta1;
import "gogoproto/gogo.proto";
import "kava/savings/v1beta1/store.proto";
option go_package = "github.com/0glabs/0g-chain/x/savings/types";
// GenesisState defines the savings module's genesis state.
message GenesisState {
// params defines all the parameters of the module.
Params params = 1 [(gogoproto.nullable) = false];
repeated Deposit deposits = 2 [
(gogoproto.castrepeated) = "Deposits",
(gogoproto.nullable) = false
];
}

View File

@ -1,75 +0,0 @@
syntax = "proto3";
package kava.savings.v1beta1;
import "cosmos/base/query/v1beta1/pagination.proto";
import "cosmos/base/v1beta1/coin.proto";
import "cosmos_proto/cosmos.proto";
import "gogoproto/gogo.proto";
import "google/api/annotations.proto";
import "kava/savings/v1beta1/store.proto";
option go_package = "github.com/0glabs/0g-chain/x/savings/types";
// Query defines the gRPC querier service for savings module
service Query {
// Params queries all parameters of the savings module.
rpc Params(QueryParamsRequest) returns (QueryParamsResponse) {
option (google.api.http).get = "/kava/savings/v1beta1/params";
}
// Deposits queries savings deposits.
rpc Deposits(QueryDepositsRequest) returns (QueryDepositsResponse) {
option (google.api.http).get = "/kava/savings/v1beta1/deposits";
}
// TotalSupply returns the total sum of all coins currently locked into the savings module.
rpc TotalSupply(QueryTotalSupplyRequest) returns (QueryTotalSupplyResponse) {
option (google.api.http).get = "/kava/savings/v1beta1/total_supply";
}
}
// QueryParamsRequest defines the request type for querying x/savings
// parameters.
message QueryParamsRequest {}
// QueryParamsResponse defines the response type for querying x/savings
// parameters.
message QueryParamsResponse {
option (gogoproto.goproto_getters) = false;
Params params = 1 [(gogoproto.nullable) = false];
}
// QueryDepositsRequest defines the request type for querying x/savings
// deposits.
message QueryDepositsRequest {
string denom = 1;
string owner = 2 [(cosmos_proto.scalar) = "cosmos.AddressString"];
cosmos.base.query.v1beta1.PageRequest pagination = 3;
}
// QueryDepositsResponse defines the response type for querying x/savings
// deposits.
message QueryDepositsResponse {
repeated Deposit deposits = 1 [
(gogoproto.castrepeated) = "Deposits",
(gogoproto.nullable) = false
];
cosmos.base.query.v1beta1.PageResponse pagination = 2;
}
// QueryTotalSupplyRequest defines the request type for Query/TotalSupply method.
message QueryTotalSupplyRequest {}
// TotalSupplyResponse defines the response type for the Query/TotalSupply method.
message QueryTotalSupplyResponse {
// Height is the block height at which these totals apply
int64 height = 1;
// Result is a list of coins supplied to savings
repeated cosmos.base.v1beta1.Coin result = 2 [
(gogoproto.nullable) = false,
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"
];
}

View File

@ -1,27 +0,0 @@
syntax = "proto3";
package kava.savings.v1beta1;
import "cosmos/base/v1beta1/coin.proto";
import "cosmos_proto/cosmos.proto";
import "gogoproto/gogo.proto";
option go_package = "github.com/0glabs/0g-chain/x/savings/types";
option (gogoproto.goproto_getters_all) = false;
// Params defines the parameters for the savings module.
message Params {
repeated string supported_denoms = 1;
}
// Deposit defines an amount of coins deposited into a savings module account.
message Deposit {
string depositor = 1 [
(cosmos_proto.scalar) = "cosmos.AddressBytes",
(gogoproto.casttype) = "github.com/cosmos/cosmos-sdk/types.AccAddress"
];
repeated cosmos.base.v1beta1.Coin amount = 2 [
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins",
(gogoproto.nullable) = false
];
}

View File

@ -1,41 +0,0 @@
syntax = "proto3";
package kava.savings.v1beta1;
import "cosmos/base/v1beta1/coin.proto";
import "cosmos_proto/cosmos.proto";
import "gogoproto/gogo.proto";
option go_package = "github.com/0glabs/0g-chain/x/savings/types";
// Msg defines the savings Msg service.
service Msg {
// Deposit defines a method for depositing funds to the savings module account
rpc Deposit(MsgDeposit) returns (MsgDepositResponse);
// Withdraw defines a method for withdrawing funds to the savings module account
rpc Withdraw(MsgWithdraw) returns (MsgWithdrawResponse);
}
// MsgDeposit defines the Msg/Deposit request type.
message MsgDeposit {
string depositor = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];
repeated cosmos.base.v1beta1.Coin amount = 2 [
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins",
(gogoproto.nullable) = false
];
}
// MsgDepositResponse defines the Msg/Deposit response type.
message MsgDepositResponse {}
// MsgWithdraw defines the Msg/Withdraw request type.
message MsgWithdraw {
string depositor = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];
repeated cosmos.base.v1beta1.Coin amount = 2 [
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins",
(gogoproto.nullable) = false
];
}
// MsgWithdrawResponse defines the Msg/Withdraw response type.
message MsgWithdrawResponse {}

View File

@ -1,23 +0,0 @@
syntax = "proto3";
package kava.swap.v1beta1;
import "gogoproto/gogo.proto";
import "kava/swap/v1beta1/swap.proto";
option go_package = "github.com/0glabs/0g-chain/x/swap/types";
// GenesisState defines the swap module's genesis state.
message GenesisState {
// params defines all the parameters related to swap
Params params = 1 [(gogoproto.nullable) = false];
// pool_records defines the available pools
repeated PoolRecord pool_records = 2 [
(gogoproto.castrepeated) = "PoolRecords",
(gogoproto.nullable) = false
];
// share_records defines the owned shares of each pool
repeated ShareRecord share_records = 3 [
(gogoproto.castrepeated) = "ShareRecords",
(gogoproto.nullable) = false
];
}

View File

@ -1,118 +0,0 @@
syntax = "proto3";
package kava.swap.v1beta1;
import "cosmos/base/query/v1beta1/pagination.proto";
import "cosmos/base/v1beta1/coin.proto";
import "cosmos_proto/cosmos.proto";
import "gogoproto/gogo.proto";
import "google/api/annotations.proto";
import "kava/swap/v1beta1/swap.proto";
option go_package = "github.com/0glabs/0g-chain/x/swap/types";
// Query defines the gRPC querier service for swap module
service Query {
// Params queries all parameters of the swap module.
rpc Params(QueryParamsRequest) returns (QueryParamsResponse) {
option (google.api.http).get = "/kava/swap/v1beta1/params";
}
// Pools queries pools based on pool ID
rpc Pools(QueryPoolsRequest) returns (QueryPoolsResponse) {
option (google.api.http).get = "/kava/swap/v1beta1/pools";
}
// Deposits queries deposit details based on owner address and pool
rpc Deposits(QueryDepositsRequest) returns (QueryDepositsResponse) {
option (google.api.http).get = "/kava/swap/v1beta1/deposits";
}
}
// QueryParamsRequest defines the request type for querying x/swap parameters.
message QueryParamsRequest {
option (gogoproto.goproto_getters) = false;
}
// QueryParamsResponse defines the response type for querying x/swap parameters.
message QueryParamsResponse {
option (gogoproto.goproto_getters) = false;
// params represents the swap module parameters
Params params = 1 [(gogoproto.nullable) = false];
}
// QueryPoolsRequest is the request type for the Query/Pools RPC method.
message QueryPoolsRequest {
// pool_id filters pools by id
string pool_id = 1;
// pagination defines an optional pagination for the request.
cosmos.base.query.v1beta1.PageRequest pagination = 2;
}
// QueryPoolsResponse is the response type for the Query/Pools RPC method.
message QueryPoolsResponse {
// pools represents returned pools
repeated PoolResponse pools = 1 [(gogoproto.nullable) = false];
// pagination defines the pagination in the response.
cosmos.base.query.v1beta1.PageResponse pagination = 2;
}
// Pool represents the state of a single pool
message PoolResponse {
option (gogoproto.goproto_getters) = false;
// name represents the name of the pool
string name = 1;
// coins represents the total reserves of the pool
repeated cosmos.base.v1beta1.Coin coins = 2 [
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins",
(gogoproto.nullable) = false
];
// total_shares represents the total shares of the pool
string total_shares = 3 [
(cosmos_proto.scalar) = "cosmos.Int",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
(gogoproto.nullable) = false
];
}
// QueryDepositsRequest is the request type for the Query/Deposits RPC method.
message QueryDepositsRequest {
option (gogoproto.goproto_getters) = false;
// owner optionally filters deposits by owner
string owner = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];
// pool_id optionally fitlers deposits by pool id
string pool_id = 2;
// pagination defines an optional pagination for the request.
cosmos.base.query.v1beta1.PageRequest pagination = 3;
}
// QueryDepositsResponse is the response type for the Query/Deposits RPC method.
message QueryDepositsResponse {
option (gogoproto.goproto_getters) = false;
// deposits returns the deposits matching the requested parameters
repeated DepositResponse deposits = 1 [(gogoproto.nullable) = false];
// pagination defines the pagination in the response.
cosmos.base.query.v1beta1.PageResponse pagination = 2;
}
// DepositResponse defines a single deposit query response type.
message DepositResponse {
option (gogoproto.goproto_getters) = false;
// depositor represents the owner of the deposit
string depositor = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];
// pool_id represents the pool the deposit is for
string pool_id = 2;
// shares_owned presents the shares owned by the depositor for the pool
string shares_owned = 3 [
(cosmos_proto.scalar) = "cosmos.AddressString",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
(gogoproto.nullable) = false
];
// shares_value represents the coin value of the shares_owned
repeated cosmos.base.v1beta1.Coin shares_value = 4 [
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins",
(gogoproto.nullable) = false
];
}

View File

@ -1,69 +0,0 @@
syntax = "proto3";
package kava.swap.v1beta1;
import "cosmos/base/v1beta1/coin.proto";
import "cosmos_proto/cosmos.proto";
import "gogoproto/gogo.proto";
option go_package = "github.com/0glabs/0g-chain/x/swap/types";
// Params defines the parameters for the swap module.
message Params {
option (gogoproto.goproto_stringer) = false; // false here because we define Stringer method in params.go
// allowed_pools defines that pools that are allowed to be created
repeated AllowedPool allowed_pools = 1 [
(gogoproto.castrepeated) = "AllowedPools",
(gogoproto.nullable) = false
];
// swap_fee defines the swap fee for all pools
string swap_fee = 2 [
(cosmos_proto.scalar) = "cosmos.Dec",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.nullable) = false
];
}
// AllowedPool defines a pool that is allowed to be created
message AllowedPool {
option (gogoproto.goproto_stringer) = false; // false here because we define Stringer method in params.go
// token_a represents the a token allowed
string token_a = 1;
// token_b represents the b token allowed
string token_b = 2;
}
// PoolRecord represents the state of a liquidity pool
// and is used to store the state of a denominated pool
message PoolRecord {
// pool_id represents the unique id of the pool
string pool_id = 1 [(gogoproto.customname) = "PoolID"];
// reserves_a is the a token coin reserves
cosmos.base.v1beta1.Coin reserves_a = 2 [(gogoproto.nullable) = false];
// reserves_b is the a token coin reserves
cosmos.base.v1beta1.Coin reserves_b = 3 [(gogoproto.nullable) = false];
// total_shares is the total distrubuted shares of the pool
string total_shares = 4 [
(cosmos_proto.scalar) = "cosmos.Int",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
(gogoproto.nullable) = false
];
}
// ShareRecord stores the shares owned for a depositor and pool
message ShareRecord {
// depositor represents the owner of the shares
bytes depositor = 1 [
(cosmos_proto.scalar) = "cosmos.AddressBytes",
(gogoproto.casttype) = "github.com/cosmos/cosmos-sdk/types.AccAddress"
];
// pool_id represents the pool the shares belong to
string pool_id = 2 [(gogoproto.customname) = "PoolID"];
// shares_owned represents the number of shares owned by depsoitor for the pool_id
string shares_owned = 3 [
(cosmos_proto.scalar) = "cosmos.Int",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
(gogoproto.nullable) = false
];
}

View File

@ -1,114 +0,0 @@
syntax = "proto3";
package kava.swap.v1beta1;
import "cosmos/base/v1beta1/coin.proto";
import "cosmos_proto/cosmos.proto";
import "gogoproto/gogo.proto";
option go_package = "github.com/0glabs/0g-chain/x/swap/types";
// Msg defines the swap Msg service.
service Msg {
// Deposit defines a method for depositing liquidity into a pool
rpc Deposit(MsgDeposit) returns (MsgDepositResponse);
// Withdraw defines a method for withdrawing liquidity into a pool
rpc Withdraw(MsgWithdraw) returns (MsgWithdrawResponse);
// SwapExactForTokens represents a message for trading exact coinA for coinB
rpc SwapExactForTokens(MsgSwapExactForTokens) returns (MsgSwapExactForTokensResponse);
// SwapForExactTokens represents a message for trading coinA for an exact coinB
rpc SwapForExactTokens(MsgSwapForExactTokens) returns (MsgSwapForExactTokensResponse);
}
// MsgDeposit represents a message for depositing liquidity into a pool
message MsgDeposit {
option (gogoproto.goproto_getters) = false;
// depositor represents the address to deposit funds from
string depositor = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];
// token_a represents one token of deposit pair
cosmos.base.v1beta1.Coin token_a = 2 [(gogoproto.nullable) = false];
// token_b represents one token of deposit pair
cosmos.base.v1beta1.Coin token_b = 3 [(gogoproto.nullable) = false];
// slippage represents the max decimal percentage price change
string slippage = 4 [
(cosmos_proto.scalar) = "cosmos.Dec",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.nullable) = false
];
// deadline represents the unix timestamp to complete the deposit by
int64 deadline = 5;
}
// MsgDepositResponse defines the Msg/Deposit response type.
message MsgDepositResponse {}
// MsgWithdraw represents a message for withdrawing liquidity from a pool
message MsgWithdraw {
option (gogoproto.goproto_getters) = false;
// from represents the address we are withdrawing for
string from = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];
// shares represents the amount of shares to withdraw
string shares = 2 [
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
(gogoproto.nullable) = false
];
// min_token_a represents the minimum a token to withdraw
cosmos.base.v1beta1.Coin min_token_a = 3 [(gogoproto.nullable) = false];
// min_token_a represents the minimum a token to withdraw
cosmos.base.v1beta1.Coin min_token_b = 4 [(gogoproto.nullable) = false];
// deadline represents the unix timestamp to complete the withdraw by
int64 deadline = 5;
}
// MsgWithdrawResponse defines the Msg/Withdraw response type.
message MsgWithdrawResponse {}
// MsgSwapExactForTokens represents a message for trading exact coinA for coinB
message MsgSwapExactForTokens {
option (gogoproto.goproto_getters) = false;
// represents the address swaping the tokens
string requester = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];
// exact_token_a represents the exact amount to swap for token_b
cosmos.base.v1beta1.Coin exact_token_a = 2 [(gogoproto.nullable) = false];
// token_b represents the desired token_b to swap for
cosmos.base.v1beta1.Coin token_b = 3 [(gogoproto.nullable) = false];
// slippage represents the maximum change in token_b allowed
string slippage = 4 [
(cosmos_proto.scalar) = "cosmos.Dec",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.nullable) = false
];
// deadline represents the unix timestamp to complete the swap by
int64 deadline = 5;
}
// MsgSwapExactForTokensResponse defines the Msg/SwapExactForTokens response
// type.
message MsgSwapExactForTokensResponse {}
// MsgSwapForExactTokens represents a message for trading coinA for an exact
// coinB
message MsgSwapForExactTokens {
option (gogoproto.goproto_getters) = false;
// represents the address swaping the tokens
string requester = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];
// token_a represents the desired token_a to swap for
cosmos.base.v1beta1.Coin token_a = 2 [(gogoproto.nullable) = false];
// exact_token_b represents the exact token b amount to swap for token a
cosmos.base.v1beta1.Coin exact_token_b = 3 [(gogoproto.nullable) = false];
// slippage represents the maximum change in token_a allowed
string slippage = 4 [
(cosmos_proto.scalar) = "cosmos.Dec",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.nullable) = false
];
// deadline represents the unix timestamp to complete the swap by
int64 deadline = 5;
}
// MsgSwapForExactTokensResponse defines the Msg/SwapForExactTokensResponse
// response type.
message MsgSwapForExactTokensResponse {}

View File

@ -1,187 +1,12 @@
package e2e_test
import (
"context"
"encoding/hex"
"time"
sdkmath "cosmossdk.io/math"
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
govv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1"
"github.com/0glabs/0g-chain/tests/e2e/testutil"
"github.com/0glabs/0g-chain/tests/util"
communitytypes "github.com/0glabs/0g-chain/x/community/types"
)
func (suite *IntegrationTestSuite) TestCommunityUpdateParams_NonAuthority() {
// ARRANGE
// setup kava account
funds := ukava(1e5) // .1 KAVA
kavaAcc := suite.Kava.NewFundedAccount("community-non-authority", sdk.NewCoins(funds))
gasLimit := int64(2e5)
fee := ukava(200)
msg := communitytypes.NewMsgUpdateParams(
kavaAcc.SdkAddress,
communitytypes.DefaultParams(),
)
// ACT
req := util.KavaMsgRequest{
Msgs: []sdk.Msg{&msg},
GasLimit: uint64(gasLimit),
FeeAmount: sdk.NewCoins(fee),
Memo: "this is a failure!",
}
res := kavaAcc.SignAndBroadcastKavaTx(req)
// ASSERT
_, err := util.WaitForSdkTxCommit(suite.Kava.Grpc.Query.Tx, res.Result.TxHash, 6*time.Second)
suite.Require().Error(err)
suite.Require().ErrorContains(
err,
govtypes.ErrInvalidSigner.Error(),
"should return with authority check error",
)
}
func (suite *IntegrationTestSuite) TestCommunityUpdateParams_Authority() {
// ARRANGE
govParamsRes, err := suite.Kava.Grpc.Query.Gov.Params(context.Background(), &govv1.QueryParamsRequest{
ParamsType: govv1.ParamDeposit,
})
suite.NoError(err)
// Check initial params
communityParamsResInitial, err := suite.Kava.Grpc.Query.Community.Params(
context.Background(),
&communitytypes.QueryParamsRequest{},
)
suite.Require().NoError(err)
// setup kava account
// .1 KAVA + min deposit amount for proposal
funds := sdk.NewCoins(ukava(1e5)).Add(govParamsRes.DepositParams.MinDeposit...)
kavaAcc := suite.Kava.NewFundedAccount("community-update-params", funds)
gasLimit := int64(2e5)
fee := ukava(200)
// Wait until switchover actually happens - When testing without the upgrade
// handler that sets a relative switchover time, the switchover time in
// genesis should be set in the past so it runs immediately.
suite.Require().Eventually(
func() bool {
params, err := suite.Kava.Grpc.Query.Community.Params(
context.Background(),
&communitytypes.QueryParamsRequest{},
)
suite.Require().NoError(err)
return params.Params.UpgradeTimeDisableInflation.Equal(time.Time{})
},
20*time.Second,
1*time.Second,
"switchover should happen",
)
// Add 1 to the staking rewards per second
newStakingRewardsPerSecond := communityParamsResInitial.Params.
StakingRewardsPerSecond.
Add(sdkmath.LegacyNewDec(1))
// 1. Proposal
// Only modify stakingRewardsPerSecond, as to not re-run the switchover and
// to not influence other tests
updateParamsMsg := communitytypes.NewMsgUpdateParams(
authtypes.NewModuleAddress(govtypes.ModuleName), // authority
communitytypes.NewParams(
time.Time{}, // after switchover, is empty
newStakingRewardsPerSecond, // only modify stakingRewardsPerSecond
communityParamsResInitial.Params.UpgradeTimeSetStakingRewardsPerSecond,
),
)
// Make sure we're actually changing the params
suite.NotEqual(
updateParamsMsg.Params,
communityParamsResInitial.Params,
"new params should be different from existing",
)
proposalMsg, err := govv1.NewMsgSubmitProposal(
[]sdk.Msg{&updateParamsMsg},
govParamsRes.Params.MinDeposit,
kavaAcc.SdkAddress.String(),
"community-update-params",
"title",
"summary",
)
suite.NoError(err)
req := util.KavaMsgRequest{
Msgs: []sdk.Msg{proposalMsg},
GasLimit: uint64(gasLimit),
FeeAmount: sdk.NewCoins(fee),
Memo: "this is a proposal please accept me",
}
res := kavaAcc.SignAndBroadcastKavaTx(req)
suite.Require().NoError(res.Err)
// Wait for proposal to be submitted
txRes, err := util.WaitForSdkTxCommit(suite.Kava.Grpc.Query.Tx, res.Result.TxHash, 6*time.Second)
suite.Require().NoError(err)
// Parse tx response to get proposal id
var govRes govv1.MsgSubmitProposalResponse
suite.decodeTxMsgResponse(txRes, &govRes)
// 2. Vote for proposal from whale account
whale := suite.Kava.GetAccount(testutil.FundedAccountName)
voteMsg := govv1.NewMsgVote(
whale.SdkAddress,
govRes.ProposalId,
govv1.OptionYes,
"",
)
voteReq := util.KavaMsgRequest{
Msgs: []sdk.Msg{voteMsg},
GasLimit: uint64(gasLimit),
FeeAmount: sdk.NewCoins(fee),
Memo: "voting",
}
voteRes := whale.SignAndBroadcastKavaTx(voteReq)
suite.Require().NoError(voteRes.Err)
_, err = util.WaitForSdkTxCommit(suite.Kava.Grpc.Query.Tx, voteRes.Result.TxHash, 6*time.Second)
suite.Require().NoError(err)
// 3. Wait until proposal passes
suite.Require().Eventually(func() bool {
proposalRes, err := suite.Kava.Grpc.Query.Gov.Proposal(context.Background(), &govv1.QueryProposalRequest{
ProposalId: govRes.ProposalId,
})
suite.NoError(err)
return proposalRes.Proposal.Status == govv1.StatusPassed
}, 60*time.Second, 1*time.Second)
// Check parameters are updated
communityParamsRes, err := suite.Kava.Grpc.Query.Community.Params(
context.Background(),
&communitytypes.QueryParamsRequest{},
)
suite.Require().NoError(err)
suite.Equal(updateParamsMsg.Params, communityParamsRes.Params)
}
func (suite *IntegrationTestSuite) decodeTxMsgResponse(txRes *sdk.TxResponse, ptr codec.ProtoMarshaler) {
// convert txRes.Data hex string to bytes
txResBytes, err := hex.DecodeString(txRes.Data)

View File

@ -11,7 +11,6 @@ import (
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
"github.com/0glabs/0g-chain/app"
cdptypes "github.com/0glabs/0g-chain/x/cdp/types"
evmutiltypes "github.com/0glabs/0g-chain/x/evmutil/types"
"github.com/0glabs/0g-chain/tests/e2e/contracts/greeter"
@ -111,7 +110,7 @@ func (suite *IntegrationTestSuite) TestEip712BasicMessageAuthorization() {
func (suite *IntegrationTestSuite) TestEip712ConvertToCoinAndDepositToLend() {
// cdp requires minimum of $11 collateral
amount := sdk.NewInt(11e6) // 11 USDT
principal := sdk.NewCoin("usdx", sdk.NewInt(10e6))
sdkDenom := suite.DeployedErc20.CosmosDenom
// create new funded account
@ -127,17 +126,9 @@ func (suite *IntegrationTestSuite) TestEip712ConvertToCoinAndDepositToLend() {
evmutiltypes.NewInternalEVMAddress(suite.DeployedErc20.Address),
amount,
)
depositMsg := cdptypes.NewMsgCreateCDP(
depositor.SdkAddress,
sdk.NewCoin(sdkDenom, amount),
principal,
suite.DeployedErc20.CdpCollateralType,
)
msgs := []sdk.Msg{
// convert to coin
&convertMsg,
// deposit into cdp (Mint), take out USDX
&depositMsg,
}
// create tx
@ -168,28 +159,15 @@ func (suite *IntegrationTestSuite) TestEip712ConvertToCoinAndDepositToLend() {
balance := suite.Kava.GetErc20Balance(suite.DeployedErc20.Address, depositor.EvmAddress)
suite.BigIntsEqual(big.NewInt(0), balance, "expected no erc20 balance")
// check that account has cdp
cdpRes, err := suite.Kava.Grpc.Query.Cdp.Cdp(context.Background(), &cdptypes.QueryCdpRequest{
CollateralType: suite.DeployedErc20.CdpCollateralType,
Owner: depositor.SdkAddress.String(),
})
suite.NoError(err)
suite.True(cdpRes.Cdp.Collateral.Amount.Equal(amount))
suite.True(cdpRes.Cdp.Principal.Equal(principal))
// withdraw deposit & convert back to erc20 (this allows refund to recover erc20s used in test)
withdraw := cdptypes.NewMsgRepayDebt(
depositor.SdkAddress,
suite.DeployedErc20.CdpCollateralType,
principal,
)
convertBack := evmutiltypes.NewMsgConvertCoinToERC20(
depositor.SdkAddress.String(),
depositor.EvmAddress.Hex(),
sdk.NewCoin(sdkDenom, amount),
)
withdrawAndConvertBack := util.KavaMsgRequest{
Msgs: []sdk.Msg{&withdraw, &convertBack},
Msgs: []sdk.Msg{&convertBack},
GasLimit: 1e6,
FeeAmount: sdk.NewCoins(ukava(1000)),
Data: "withdrawing from mint & converting back to erc20",

View File

@ -1,256 +1,241 @@
package e2e_test
import (
"context"
"fmt"
"time"
// func (suite *IntegrationTestSuite) TestUpgradeCommunityParams() {
// suite.SkipIfUpgradeDisabled()
sdk "github.com/cosmos/cosmos-sdk/types"
distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types"
minttypes "github.com/cosmos/cosmos-sdk/x/mint/types"
// beforeUpgradeCtx := util.CtxAtHeight(suite.UpgradeHeight - 1)
// afterUpgradeCtx := util.CtxAtHeight(suite.UpgradeHeight)
"github.com/0glabs/0g-chain/app"
"github.com/0glabs/0g-chain/tests/util"
communitytypes "github.com/0glabs/0g-chain/x/community/types"
kavadisttypes "github.com/0glabs/0g-chain/x/kavadist/types"
)
// // Before params
// kavaDistParamsBefore, err := suite.Kava.Kavadist.Params(beforeUpgradeCtx, &kavadisttypes.QueryParamsRequest{})
// suite.NoError(err)
// mintParamsBefore, err := suite.Kava.Mint.Params(beforeUpgradeCtx, &minttypes.QueryParamsRequest{})
// suite.NoError(err)
func (suite *IntegrationTestSuite) TestUpgradeCommunityParams() {
suite.SkipIfUpgradeDisabled()
// // Before parameters
// suite.Run("x/community and x/kavadist parameters before upgrade", func() {
// _, err = suite.Kava.Community.Params(beforeUpgradeCtx, &communitytypes.QueryParamsRequest{})
// suite.Error(err, "x/community should not have params before upgrade")
beforeUpgradeCtx := util.CtxAtHeight(suite.UpgradeHeight - 1)
afterUpgradeCtx := util.CtxAtHeight(suite.UpgradeHeight)
// suite.Require().True(
// kavaDistParamsBefore.Params.Active,
// "x/kavadist should be active before upgrade",
// )
// Before params
kavaDistParamsBefore, err := suite.Kava.Kavadist.Params(beforeUpgradeCtx, &kavadisttypes.QueryParamsRequest{})
suite.NoError(err)
mintParamsBefore, err := suite.Kava.Mint.Params(beforeUpgradeCtx, &minttypes.QueryParamsRequest{})
suite.NoError(err)
// suite.Require().True(
// mintParamsBefore.Params.InflationMax.IsPositive(),
// "x/mint inflation max should be positive before upgrade",
// )
// suite.Require().True(
// mintParamsBefore.Params.InflationMin.IsPositive(),
// "x/mint inflation min should be positive before upgrade",
// )
// })
// Before parameters
suite.Run("x/community and x/kavadist parameters before upgrade", func() {
_, err = suite.Kava.Community.Params(beforeUpgradeCtx, &communitytypes.QueryParamsRequest{})
suite.Error(err, "x/community should not have params before upgrade")
// // After upgrade, Before switchover - parameters
// suite.Run("x/kavadist, x/mint, x/community parameters after upgrade, before switchover", func() {
// kavaDistParamsAfter, err := suite.Kava.Kavadist.Params(afterUpgradeCtx, &kavadisttypes.QueryParamsRequest{})
// suite.NoError(err)
// mintParamsAfter, err := suite.Kava.Mint.Params(afterUpgradeCtx, &minttypes.QueryParamsRequest{})
// suite.NoError(err)
// communityParamsAfter, err := suite.Kava.Community.Params(afterUpgradeCtx, &communitytypes.QueryParamsRequest{})
// suite.NoError(err)
suite.Require().True(
kavaDistParamsBefore.Params.Active,
"x/kavadist should be active before upgrade",
)
// suite.Equal(
// kavaDistParamsBefore.Params,
// kavaDistParamsAfter.Params,
// "x/kavadist should be unaffected after upgrade",
// )
suite.Require().True(
mintParamsBefore.Params.InflationMax.IsPositive(),
"x/mint inflation max should be positive before upgrade",
)
suite.Require().True(
mintParamsBefore.Params.InflationMin.IsPositive(),
"x/mint inflation min should be positive before upgrade",
)
})
// suite.Equal(
// mintParamsBefore.Params,
// mintParamsAfter.Params,
// "x/mint params should be unaffected after upgrade",
// )
// After upgrade, Before switchover - parameters
suite.Run("x/kavadist, x/mint, x/community parameters after upgrade, before switchover", func() {
kavaDistParamsAfter, err := suite.Kava.Kavadist.Params(afterUpgradeCtx, &kavadisttypes.QueryParamsRequest{})
suite.NoError(err)
mintParamsAfter, err := suite.Kava.Mint.Params(afterUpgradeCtx, &minttypes.QueryParamsRequest{})
suite.NoError(err)
communityParamsAfter, err := suite.Kava.Community.Params(afterUpgradeCtx, &communitytypes.QueryParamsRequest{})
suite.NoError(err)
// expectedParams := app.CommunityParams_E2E
// // Make UpgradeTimeDisableInflation match so that we ignore it, because
// // referencing app.CommunityParams_E2E in this test files is different
// // from the one set in the upgrade handler. At least check that it is
// // set to a non-zero value in the assertion below
// expectedParams.UpgradeTimeDisableInflation = communityParamsAfter.Params.UpgradeTimeDisableInflation
suite.Equal(
kavaDistParamsBefore.Params,
kavaDistParamsAfter.Params,
"x/kavadist should be unaffected after upgrade",
)
// suite.False(
// communityParamsAfter.Params.UpgradeTimeDisableInflation.IsZero(),
// "x/community switchover time should be set after upgrade",
// )
// suite.Equal(
// expectedParams,
// communityParamsAfter.Params,
// "x/community params should be set to E2E params after upgrade",
// )
// })
suite.Equal(
mintParamsBefore.Params,
mintParamsAfter.Params,
"x/mint params should be unaffected after upgrade",
)
// suite.Require().Eventually(
// func() bool {
// // Get x/community for switchover time
// params, err := suite.Kava.Community.Params(
// context.Background(),
// &communitytypes.QueryParamsRequest{},
// )
// suite.Require().NoError(err)
expectedParams := app.CommunityParams_E2E
// Make UpgradeTimeDisableInflation match so that we ignore it, because
// referencing app.CommunityParams_E2E in this test files is different
// from the one set in the upgrade handler. At least check that it is
// set to a non-zero value in the assertion below
expectedParams.UpgradeTimeDisableInflation = communityParamsAfter.Params.UpgradeTimeDisableInflation
// // Check that switchover time is set to zero, e.g. switchover happened
// return params.Params.UpgradeTimeDisableInflation.Equal(time.Time{})
// },
// 20*time.Second, 1*time.Second,
// "switchover should happen and x/community params should be updated",
// )
suite.False(
communityParamsAfter.Params.UpgradeTimeDisableInflation.IsZero(),
"x/community switchover time should be set after upgrade",
)
suite.Equal(
expectedParams,
communityParamsAfter.Params,
"x/community params should be set to E2E params after upgrade",
)
})
// // Fetch exact block when inflation stop event emitted
// _, switchoverHeight, err := suite.Kava.GetBeginBlockEventsFromQuery(
// context.Background(),
// fmt.Sprintf(
// "%s.%s EXISTS",
// communitytypes.EventTypeInflationStop,
// communitytypes.AttributeKeyInflationDisableTime,
// ),
// )
// suite.Require().NoError(err)
// suite.Require().NotZero(switchoverHeight)
suite.Require().Eventually(
func() bool {
// Get x/community for switchover time
params, err := suite.Kava.Community.Params(
context.Background(),
&communitytypes.QueryParamsRequest{},
)
suite.Require().NoError(err)
// beforeSwitchoverCtx := util.CtxAtHeight(switchoverHeight - 1)
// afterSwitchoverCtx := util.CtxAtHeight(switchoverHeight)
// Check that switchover time is set to zero, e.g. switchover happened
return params.Params.UpgradeTimeDisableInflation.Equal(time.Time{})
},
20*time.Second, 1*time.Second,
"switchover should happen and x/community params should be updated",
)
// suite.Run("x/kavadist, x/mint, x/community parameters after upgrade, after switchover", func() {
// kavaDistParamsAfter, err := suite.Kava.Kavadist.Params(
// afterSwitchoverCtx,
// &kavadisttypes.QueryParamsRequest{},
// )
// suite.NoError(err)
// mintParamsAfter, err := suite.Kava.Mint.Params(
// afterSwitchoverCtx,
// &minttypes.QueryParamsRequest{},
// )
// suite.NoError(err)
// communityParamsAfter, err := suite.Kava.Community.Params(
// afterSwitchoverCtx,
// &communitytypes.QueryParamsRequest{},
// )
// suite.NoError(err)
// Fetch exact block when inflation stop event emitted
_, switchoverHeight, err := suite.Kava.GetBeginBlockEventsFromQuery(
context.Background(),
fmt.Sprintf(
"%s.%s EXISTS",
communitytypes.EventTypeInflationStop,
communitytypes.AttributeKeyInflationDisableTime,
),
)
suite.Require().NoError(err)
suite.Require().NotZero(switchoverHeight)
// suite.False(
// kavaDistParamsAfter.Params.Active,
// "x/kavadist should be disabled after upgrade",
// )
beforeSwitchoverCtx := util.CtxAtHeight(switchoverHeight - 1)
afterSwitchoverCtx := util.CtxAtHeight(switchoverHeight)
// suite.True(
// mintParamsAfter.Params.InflationMax.IsZero(),
// "x/mint inflation max should be zero after switchover",
// )
// suite.True(
// mintParamsAfter.Params.InflationMin.IsZero(),
// "x/mint inflation min should be zero after switchover",
// )
suite.Run("x/kavadist, x/mint, x/community parameters after upgrade, after switchover", func() {
kavaDistParamsAfter, err := suite.Kava.Kavadist.Params(
afterSwitchoverCtx,
&kavadisttypes.QueryParamsRequest{},
)
suite.NoError(err)
mintParamsAfter, err := suite.Kava.Mint.Params(
afterSwitchoverCtx,
&minttypes.QueryParamsRequest{},
)
suite.NoError(err)
communityParamsAfter, err := suite.Kava.Community.Params(
afterSwitchoverCtx,
&communitytypes.QueryParamsRequest{},
)
suite.NoError(err)
// suite.Equal(
// time.Time{},
// communityParamsAfter.Params.UpgradeTimeDisableInflation,
// "x/community switchover time should be reset",
// )
suite.False(
kavaDistParamsAfter.Params.Active,
"x/kavadist should be disabled after upgrade",
)
// suite.Equal(
// communityParamsAfter.Params.UpgradeTimeSetStakingRewardsPerSecond,
// communityParamsAfter.Params.StakingRewardsPerSecond,
// "x/community staking rewards per second should match upgrade time staking rewards per second",
// )
// })
suite.True(
mintParamsAfter.Params.InflationMax.IsZero(),
"x/mint inflation max should be zero after switchover",
)
suite.True(
mintParamsAfter.Params.InflationMin.IsZero(),
"x/mint inflation min should be zero after switchover",
)
// suite.Run("x/kavadist, x/distribution, x/community balances after switchover", func() {
// // Before balances - community pool fund consolidation
// kavaDistBalBefore, err := suite.Kava.Kavadist.Balance(
// beforeSwitchoverCtx,
// &kavadisttypes.QueryBalanceRequest{},
// )
// suite.NoError(err)
// distrBalBefore, err := suite.Kava.Distribution.CommunityPool(
// beforeSwitchoverCtx,
// &distrtypes.QueryCommunityPoolRequest{},
// )
// suite.NoError(err)
// distrBalCoinsBefore, distrDustBefore := distrBalBefore.Pool.TruncateDecimal()
// beforeCommPoolBalance, err := suite.Kava.Community.Balance(
// beforeSwitchoverCtx,
// &communitytypes.QueryBalanceRequest{},
// )
// suite.NoError(err)
suite.Equal(
time.Time{},
communityParamsAfter.Params.UpgradeTimeDisableInflation,
"x/community switchover time should be reset",
)
// // After balances
// kavaDistBalAfter, err := suite.Kava.Kavadist.Balance(
// afterSwitchoverCtx,
// &kavadisttypes.QueryBalanceRequest{},
// )
// suite.NoError(err)
// distrBalAfter, err := suite.Kava.Distribution.CommunityPool(
// afterSwitchoverCtx,
// &distrtypes.QueryCommunityPoolRequest{},
// )
// suite.NoError(err)
// afterCommPoolBalance, err := suite.Kava.Community.Balance(
// afterSwitchoverCtx,
// &communitytypes.QueryBalanceRequest{},
// )
// suite.NoError(err)
suite.Equal(
communityParamsAfter.Params.UpgradeTimeSetStakingRewardsPerSecond,
communityParamsAfter.Params.StakingRewardsPerSecond,
"x/community staking rewards per second should match upgrade time staking rewards per second",
)
})
// expectedKavadistBal := sdk.NewCoins(sdk.NewCoin(
// "ukava",
// kavaDistBalBefore.Coins.AmountOf("ukava"),
// ))
// suite.Equal(
// expectedKavadistBal,
// kavaDistBalAfter.Coins,
// "x/kavadist balance should persist the ukava amount and move all other funds",
// )
// expectedKavadistTransferred := kavaDistBalBefore.Coins.Sub(expectedKavadistBal...)
suite.Run("x/kavadist, x/distribution, x/community balances after switchover", func() {
// Before balances - community pool fund consolidation
kavaDistBalBefore, err := suite.Kava.Kavadist.Balance(
beforeSwitchoverCtx,
&kavadisttypes.QueryBalanceRequest{},
)
suite.NoError(err)
distrBalBefore, err := suite.Kava.Distribution.CommunityPool(
beforeSwitchoverCtx,
&distrtypes.QueryCommunityPoolRequest{},
)
suite.NoError(err)
distrBalCoinsBefore, distrDustBefore := distrBalBefore.Pool.TruncateDecimal()
beforeCommPoolBalance, err := suite.Kava.Community.Balance(
beforeSwitchoverCtx,
&communitytypes.QueryBalanceRequest{},
)
suite.NoError(err)
// // very low ukava balance after (ignoring dust in x/distribution)
// // a small amount of tx fees can still end up here.
// // dust should stay in x/distribution, but may not be the same so it's unchecked
// distrCoinsAfter, distrDustAfter := distrBalAfter.Pool.TruncateDecimal()
// suite.Empty(distrCoinsAfter, "expected no coins in x/distribution community pool")
// After balances
kavaDistBalAfter, err := suite.Kava.Kavadist.Balance(
afterSwitchoverCtx,
&kavadisttypes.QueryBalanceRequest{},
)
suite.NoError(err)
distrBalAfter, err := suite.Kava.Distribution.CommunityPool(
afterSwitchoverCtx,
&distrtypes.QueryCommunityPoolRequest{},
)
suite.NoError(err)
afterCommPoolBalance, err := suite.Kava.Community.Balance(
afterSwitchoverCtx,
&communitytypes.QueryBalanceRequest{},
)
suite.NoError(err)
// // Fetch block results for paid staking rewards in the block
// blockRes, err := suite.Kava.TmSignClient.BlockResults(
// context.Background(),
// &switchoverHeight,
// )
// suite.Require().NoError(err)
expectedKavadistBal := sdk.NewCoins(sdk.NewCoin(
"ukava",
kavaDistBalBefore.Coins.AmountOf("ukava"),
))
suite.Equal(
expectedKavadistBal,
kavaDistBalAfter.Coins,
"x/kavadist balance should persist the ukava amount and move all other funds",
)
expectedKavadistTransferred := kavaDistBalBefore.Coins.Sub(expectedKavadistBal...)
// stakingRewardPaidEvents := util.FilterEventsByType(
// blockRes.BeginBlockEvents,
// communitytypes.EventTypeStakingRewardsPaid,
// )
// suite.Require().Len(stakingRewardPaidEvents, 1, "there should be only 1 staking reward paid event")
// stakingRewardAmount := sdk.NewCoins()
// for _, attr := range stakingRewardPaidEvents[0].Attributes {
// if string(attr.Key) == communitytypes.AttributeKeyStakingRewardAmount {
// stakingRewardAmount, err = sdk.ParseCoinsNormalized(string(attr.Value))
// suite.Require().NoError(err)
// very low ukava balance after (ignoring dust in x/distribution)
// a small amount of tx fees can still end up here.
// dust should stay in x/distribution, but may not be the same so it's unchecked
distrCoinsAfter, distrDustAfter := distrBalAfter.Pool.TruncateDecimal()
suite.Empty(distrCoinsAfter, "expected no coins in x/distribution community pool")
// break
// }
// }
// Fetch block results for paid staking rewards in the block
blockRes, err := suite.Kava.TmSignClient.BlockResults(
context.Background(),
&switchoverHeight,
)
suite.Require().NoError(err)
// expectedCommunityBal := beforeCommPoolBalance.Coins.
// Add(distrBalCoinsBefore...).
// Add(expectedKavadistTransferred...).
// Sub(stakingRewardAmount...) // Remove staking rewards paid in the block
stakingRewardPaidEvents := util.FilterEventsByType(
blockRes.BeginBlockEvents,
communitytypes.EventTypeStakingRewardsPaid,
)
suite.Require().Len(stakingRewardPaidEvents, 1, "there should be only 1 staking reward paid event")
stakingRewardAmount := sdk.NewCoins()
for _, attr := range stakingRewardPaidEvents[0].Attributes {
if string(attr.Key) == communitytypes.AttributeKeyStakingRewardAmount {
stakingRewardAmount, err = sdk.ParseCoinsNormalized(string(attr.Value))
suite.Require().NoError(err)
// // x/kavadist and x/distribution community pools should be moved to x/community
// suite.Equal(
// expectedCommunityBal,
// afterCommPoolBalance.Coins,
// )
break
}
}
expectedCommunityBal := beforeCommPoolBalance.Coins.
Add(distrBalCoinsBefore...).
Add(expectedKavadistTransferred...).
Sub(stakingRewardAmount...) // Remove staking rewards paid in the block
// x/kavadist and x/distribution community pools should be moved to x/community
suite.Equal(
expectedCommunityBal,
afterCommPoolBalance.Coins,
)
suite.Equal(
distrDustBefore,
distrDustAfter,
"x/distribution community pool dust should be unchanged",
)
})
}
// suite.Equal(
// distrDustBefore,
// distrDustAfter,
// "x/distribution community pool dust should be unchanged",
// )
// })
// }

View File

@ -1,65 +1,57 @@
package e2e_test
import (
sdkmath "cosmossdk.io/math"
sdk "github.com/cosmos/cosmos-sdk/types"
// func (suite *IntegrationTestSuite) TestUpgradeIncentiveParams() {
// suite.SkipIfUpgradeDisabled()
"github.com/0glabs/0g-chain/tests/util"
incentivetypes "github.com/0glabs/0g-chain/x/incentive/types"
)
// beforeUpgradeCtx := util.CtxAtHeight(suite.UpgradeHeight - 1)
// afterUpgradeCtx := util.CtxAtHeight(suite.UpgradeHeight)
func (suite *IntegrationTestSuite) TestUpgradeIncentiveParams() {
suite.SkipIfUpgradeDisabled()
// // Before params
// incentiveParamsBefore, err := suite.Kava.Incentive.Params(
// beforeUpgradeCtx,
// &incentivetypes.QueryParamsRequest{},
// )
// suite.NoError(err)
beforeUpgradeCtx := util.CtxAtHeight(suite.UpgradeHeight - 1)
afterUpgradeCtx := util.CtxAtHeight(suite.UpgradeHeight)
// incentiveParamsAfter, err := suite.Kava.Incentive.Params(
// afterUpgradeCtx,
// &incentivetypes.QueryParamsRequest{},
// )
// suite.NoError(err)
// Before params
incentiveParamsBefore, err := suite.Kava.Incentive.Params(
beforeUpgradeCtx,
&incentivetypes.QueryParamsRequest{},
)
suite.NoError(err)
// suite.Run("x/incentive parameters before upgrade", func() {
// suite.Require().Len(
// incentiveParamsBefore.Params.EarnRewardPeriods,
// 1,
// "x/incentive should have 1 earn reward period before upgrade",
// )
incentiveParamsAfter, err := suite.Kava.Incentive.Params(
afterUpgradeCtx,
&incentivetypes.QueryParamsRequest{},
)
suite.NoError(err)
// suite.Require().Equal(
// sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(159_459))),
// incentiveParamsBefore.Params.EarnRewardPeriods[0].RewardsPerSecond,
// )
// })
suite.Run("x/incentive parameters before upgrade", func() {
suite.Require().Len(
incentiveParamsBefore.Params.EarnRewardPeriods,
1,
"x/incentive should have 1 earn reward period before upgrade",
)
// suite.Run("x/incentive parameters after upgrade", func() {
// suite.Require().Len(
// incentiveParamsAfter.Params.EarnRewardPeriods,
// 1,
// "x/incentive should have 1 earn reward period before upgrade",
// )
suite.Require().Equal(
sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(159_459))),
incentiveParamsBefore.Params.EarnRewardPeriods[0].RewardsPerSecond,
)
})
// suite.Require().Equal(
// // Manual calculation of
// // 600,000 * 1000,000 / (365 * 24 * 60 * 60)
// sdk.NewCoins(sdk.NewCoin("ukava", sdkmath.NewInt(19025))),
// incentiveParamsAfter.Params.EarnRewardPeriods[0].RewardsPerSecond,
// )
suite.Run("x/incentive parameters after upgrade", func() {
suite.Require().Len(
incentiveParamsAfter.Params.EarnRewardPeriods,
1,
"x/incentive should have 1 earn reward period before upgrade",
)
suite.Require().Equal(
// Manual calculation of
// 600,000 * 1000,000 / (365 * 24 * 60 * 60)
sdk.NewCoins(sdk.NewCoin("ukava", sdkmath.NewInt(19025))),
incentiveParamsAfter.Params.EarnRewardPeriods[0].RewardsPerSecond,
)
// No other changes
incentiveParamsAfter.Params.EarnRewardPeriods[0].RewardsPerSecond = incentiveParamsBefore.Params.EarnRewardPeriods[0].RewardsPerSecond
suite.Require().Equal(
incentiveParamsBefore,
incentiveParamsAfter,
"other param values should not be changed",
)
})
}
// // No other changes
// incentiveParamsAfter.Params.EarnRewardPeriods[0].RewardsPerSecond = incentiveParamsBefore.Params.EarnRewardPeriods[0].RewardsPerSecond
// suite.Require().Equal(
// incentiveParamsBefore,
// incentiveParamsAfter,
// "other param values should not be changed",
// )
// })
// }

View File

@ -1,470 +1,453 @@
package e2e_test
import (
"context"
"fmt"
"strconv"
"time"
sdkmath "cosmossdk.io/math"
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/bank/types"
distributiontypes "github.com/cosmos/cosmos-sdk/x/distribution/types"
minttypes "github.com/cosmos/cosmos-sdk/x/mint/types"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
abci "github.com/tendermint/tendermint/abci/types"
coretypes "github.com/tendermint/tendermint/rpc/core/types"
"github.com/0glabs/0g-chain/tests/util"
communitytypes "github.com/0glabs/0g-chain/x/community/types"
kavadisttypes "github.com/0glabs/0g-chain/x/kavadist/types"
)
func (suite *IntegrationTestSuite) TestUpgradeInflation_Disable() {
suite.SkipIfUpgradeDisabled()
afterUpgradeCtx := util.CtxAtHeight(suite.UpgradeHeight)
// Get x/community for switchover time
params, err := suite.Kava.Community.Params(afterUpgradeCtx, &communitytypes.QueryParamsRequest{})
suite.Require().NoError(err)
// Sleep until switchover time + 6 seconds for extra block
sleepDuration := time.Until(params.Params.UpgradeTimeDisableInflation.Add(6 * time.Second))
time.Sleep(sleepDuration)
suite.Require().Eventually(func() bool {
communityParams, err := suite.Kava.Community.Params(afterUpgradeCtx, &communitytypes.QueryParamsRequest{})
suite.Require().NoError(err)
// After params are set in x/community -- non-zero switchover time
return !communityParams.Params.UpgradeTimeDisableInflation.Equal(time.Time{})
}, 20*time.Second, 3*time.Second)
// Fetch exact block when inflation stop event emitted
// This is run after the switchover, so we don't need to poll
_, switchoverHeight, err := suite.Kava.GetBeginBlockEventsFromQuery(
context.Background(),
fmt.Sprintf(
"%s.%s EXISTS",
communitytypes.EventTypeInflationStop,
communitytypes.AttributeKeyInflationDisableTime,
),
)
suite.Require().NoError(err)
suite.Require().NotZero(switchoverHeight)
// 1 block before switchover
beforeSwitchoverCtx := util.CtxAtHeight(switchoverHeight - 1)
afterSwitchoverCtx := util.CtxAtHeight(switchoverHeight)
suite.Run("x/mint, x/kavadist inflation before switchover", func() {
mintParams, err := suite.Kava.Mint.Params(
beforeSwitchoverCtx,
&minttypes.QueryParamsRequest{},
)
suite.NoError(err)
kavaDistParams, err := suite.Kava.Kavadist.Params(
beforeSwitchoverCtx,
&kavadisttypes.QueryParamsRequest{},
)
suite.NoError(err)
// Use .String() to compare Decs since x/mint uses the deprecated one,
// mismatch of types but same value.
suite.Equal(
sdkmath.LegacyMustNewDecFromStr("0.595000000000000000").String(),
mintParams.Params.InflationMin.String(),
"x/mint inflation min should be 59.5%% before switchover",
)
suite.Equal(
sdkmath.LegacyMustNewDecFromStr("0.595000000000000000").String(),
mintParams.Params.InflationMax.String(),
"x/mint inflation max should be 59.5%% before switchover",
)
suite.True(
kavaDistParams.Params.Active,
"x/kavadist should be active before switchover",
)
})
suite.Run("x/distribution community tax before switchover", func() {
distrParams, err := suite.Kava.Distribution.Params(
beforeSwitchoverCtx,
&distributiontypes.QueryParamsRequest{},
)
suite.NoError(err)
suite.Equal(
sdkmath.LegacyMustNewDecFromStr("0.949500000000000000").String(),
distrParams.Params.CommunityTax.String(),
"x/distribution community tax should be 94.95%% before switchover",
)
})
suite.Run("x/mint, x/kavadist inflation after switchover", func() {
mintParams, err := suite.Kava.Mint.Params(
afterSwitchoverCtx,
&minttypes.QueryParamsRequest{},
)
suite.NoError(err)
kavaDistParams, err := suite.Kava.Kavadist.Params(
afterSwitchoverCtx,
&kavadisttypes.QueryParamsRequest{},
)
suite.NoError(err)
suite.Equal(
sdkmath.LegacyZeroDec().String(),
mintParams.Params.InflationMin.String(),
"x/mint inflation min should be 0% after switchover",
)
suite.Equal(
sdkmath.LegacyZeroDec().String(),
mintParams.Params.InflationMax.String(),
"x/mint inflation max should be 0% after switchover",
)
suite.False(
kavaDistParams.Params.Active,
"x/kavadist should be inactive after switchover",
)
})
suite.Run("x/distribution community tax after switchover", func() {
distrParams, err := suite.Kava.Distribution.Params(
afterSwitchoverCtx,
&distributiontypes.QueryParamsRequest{},
)
suite.NoError(err)
suite.Equal(
sdkmath.LegacyZeroDec().String(),
distrParams.Params.CommunityTax.String(),
"x/distribution community tax should be 0%% before switchover",
)
})
// Ensure inflation was still active before switchover
suite.Run("positive mint events before switchover", func() {
// 1 block before switchover
queryHeight := switchoverHeight - 1
block, err := suite.Kava.TmSignClient.BlockResults(
context.Background(),
&queryHeight,
)
suite.Require().NoError(err)
// Mint events should only occur in begin block
mintEvents := util.FilterEventsByType(block.BeginBlockEvents, minttypes.EventTypeMint)
suite.Require().NotEmpty(mintEvents, "mint events should be emitted")
// Ensure mint amounts are non-zero
found := false
for _, event := range mintEvents {
for _, attribute := range event.Attributes {
// Bonded ratio and annual provisions unchecked
if string(attribute.Key) == minttypes.AttributeKeyInflation {
suite.Equal(
sdkmath.LegacyMustNewDecFromStr("0.595000000000000000").String(),
string(attribute.Value),
"inflation should be 59.5%% before switchover",
)
}
if string(attribute.Key) == sdk.AttributeKeyAmount {
found = true
// Parse as native go int, not necessary to use sdk.Int
value, err := strconv.Atoi(string(attribute.Value))
suite.Require().NoError(err)
suite.NotZero(value, "mint amount should be non-zero")
suite.Positive(value, "mint amount should be positive")
}
}
}
suite.True(found, "mint amount should be found")
})
suite.Run("staking denom supply increases before switchover", func() {
queryHeight := switchoverHeight - 2
supply1, err := suite.Kava.Bank.SupplyOf(
util.CtxAtHeight(queryHeight),
&types.QuerySupplyOfRequest{
Denom: suite.Kava.StakingDenom,
},
)
suite.Require().NoError(err)
suite.NotZero(supply1.Amount, "ukava supply should be non-zero")
// Next block
queryHeight += 1
supply2, err := suite.Kava.Bank.SupplyOf(
util.CtxAtHeight(queryHeight),
&types.QuerySupplyOfRequest{
Denom: suite.Kava.StakingDenom,
},
)
suite.Require().NoError(err)
suite.NotZero(supply2.Amount, "ukava supply should be non-zero")
suite.Truef(
supply2.Amount.Amount.GT(supply1.Amount.Amount),
"ukava supply before switchover should increase between blocks, %s > %s",
supply2.Amount.Amount.String(),
)
})
// Check if inflation is ACTUALLY disabled... check if any coins are being
// minted in the blocks after switchover
suite.Run("no minting after switchover", func() {
kavaSupply := sdk.NewCoin(suite.Kava.StakingDenom, sdkmath.ZeroInt())
// Next 5 blocks after switchover, ensure there's actually no more inflation
for i := 0; i < 5; i++ {
queryHeight := switchoverHeight + int64(i)
suite.Run(
fmt.Sprintf("x/mint events with 0 amount @ height=%d", queryHeight),
func() {
var block *coretypes.ResultBlockResults
suite.Require().Eventually(func() bool {
// Check begin block events
block, err = suite.Kava.TmSignClient.BlockResults(
context.Background(),
&queryHeight,
)
return err == nil
}, 20*time.Second, 3*time.Second)
var mintEvents []abci.Event
// Mint events should only occur in begin block, but we just include
// everything else just in case anything changes in x/mint
mintEventsBegin := util.FilterEventsByType(block.BeginBlockEvents, minttypes.EventTypeMint)
mintEventsEnd := util.FilterEventsByType(block.EndBlockEvents, minttypes.EventTypeMint)
mintEventsTx := util.FilterTxEventsByType(block.TxsResults, minttypes.EventTypeMint)
mintEvents = append(mintEvents, mintEventsBegin...)
mintEvents = append(mintEvents, mintEventsEnd...)
mintEvents = append(mintEvents, mintEventsTx...)
suite.Require().NotEmpty(mintEvents, "mint events should still be emitted")
// Ensure mint amounts are 0
found := false
for _, event := range mintEvents {
for _, attribute := range event.Attributes {
// Bonded ratio and annual provisions unchecked
if string(attribute.Key) == minttypes.AttributeKeyInflation {
suite.Equal(sdkmath.LegacyZeroDec().String(), string(attribute.Value))
}
if string(attribute.Key) == sdk.AttributeKeyAmount {
found = true
suite.Equal(sdkmath.ZeroInt().String(), string(attribute.Value))
}
}
}
suite.True(found, "mint amount should be found")
},
)
// Run this after the events check, since that one waits for the
// new block if necessary
suite.Run(
fmt.Sprintf("total staking denom supply should not change @ height=%d", queryHeight),
func() {
supplyRes, err := suite.Kava.Bank.SupplyOf(
util.CtxAtHeight(queryHeight),
&types.QuerySupplyOfRequest{
Denom: suite.Kava.StakingDenom,
},
)
suite.Require().NoError(err)
if kavaSupply.IsZero() {
// First iteration, set supply
kavaSupply = supplyRes.Amount
} else {
suite.Require().Equal(
kavaSupply,
supplyRes.Amount,
"ukava supply should not change",
)
}
},
)
}
})
suite.Run("no staking rewards from x/community before switchover", func() {
// 1 block before switchover
queryHeight := switchoverHeight - 1
block, err := suite.Kava.TmSignClient.BlockResults(
context.Background(),
&queryHeight,
)
suite.Require().NoError(err)
// Events are not emitted if amount is 0
stakingRewardEvents := util.FilterEventsByType(block.BeginBlockEvents, communitytypes.EventTypeStakingRewardsPaid)
suite.Require().Empty(stakingRewardEvents, "staking reward events should not be emitted")
})
suite.Run("staking rewards pay out from x/community after switchover", func() {
for i := 0; i < 5; i++ {
// after switchover
queryHeight := switchoverHeight + int64(i)
block, err := suite.Kava.TmSignClient.BlockResults(
context.Background(),
&queryHeight,
)
suite.Require().NoError(err)
stakingRewardEvents := util.FilterEventsByType(
block.BeginBlockEvents,
communitytypes.EventTypeStakingRewardsPaid,
)
suite.Require().NotEmptyf(
stakingRewardEvents,
"staking reward events should be emitted at height=%d",
queryHeight,
)
// Ensure amounts are non-zero
found := false
for _, attr := range stakingRewardEvents[0].Attributes {
if string(attr.Key) == communitytypes.AttributeKeyStakingRewardAmount {
coins, err := sdk.ParseCoinNormalized(string(attr.Value))
suite.Require().NoError(err, "staking reward amount should be parsable coins")
suite.Truef(
coins.Amount.IsPositive(),
"staking reward amount should be a positive amount at height=%d",
queryHeight,
)
found = true
}
}
suite.Truef(
found,
"staking reward amount should be found in events at height=%d",
queryHeight,
)
}
})
// Staking rewards can still be claimed
suite.Run("staking rewards claimable after switchover", func() {
suite.SkipIfKvtoolDisabled()
// Get the delegator of the only validator
validators, err := suite.Kava.Staking.Validators(
context.Background(),
&stakingtypes.QueryValidatorsRequest{},
)
suite.Require().NoError(err)
suite.Require().Positive(len(validators.Validators), "should only be at least 1 validator")
valAddr, err := sdk.ValAddressFromBech32(validators.Validators[0].OperatorAddress)
suite.Require().NoError(err)
accAddr := sdk.AccAddress(valAddr.Bytes())
balBefore, err := suite.Kava.Bank.Balance(
context.Background(),
&types.QueryBalanceRequest{
Address: accAddr.String(),
Denom: suite.Kava.StakingDenom,
},
)
suite.Require().NoError(err)
suite.Require().False(balBefore.Balance.IsZero(), "val staking denom balance should be non-zero")
delegationRewards, err := suite.Kava.Distribution.DelegationRewards(
context.Background(),
&distributiontypes.QueryDelegationRewardsRequest{
ValidatorAddress: valAddr.String(),
DelegatorAddress: accAddr.String(),
},
)
suite.Require().NoError(err)
suite.False(delegationRewards.Rewards.Empty())
suite.True(delegationRewards.Rewards.IsAllPositive(), "queried rewards should be positive")
withdrawRewardsMsg := distributiontypes.NewMsgWithdrawDelegatorReward(
accAddr,
valAddr,
)
// Get the validator private key from kava keyring
key, err := suite.Kava.Keyring.(unsafeExporter).ExportPrivateKeyObject(
"validator",
)
suite.Require().NoError(err)
acc := suite.Kava.AddNewSigningAccountFromPrivKey(
"validator",
key,
"",
suite.Kava.ChainID,
)
gasLimit := int64(2e5)
fee := ukava(200)
req := util.KavaMsgRequest{
Msgs: []sdk.Msg{withdrawRewardsMsg},
GasLimit: uint64(gasLimit),
FeeAmount: sdk.NewCoins(fee),
Memo: "give me my money",
}
res := acc.SignAndBroadcastKavaTx(req)
_, err = util.WaitForSdkTxCommit(suite.Kava.Tx, res.Result.TxHash, 6*time.Second)
suite.Require().NoError(err)
balAfter, err := suite.Kava.Bank.Balance(
context.Background(),
&types.QueryBalanceRequest{
Address: accAddr.String(),
Denom: suite.Kava.StakingDenom,
},
)
suite.Require().NoError(err)
suite.Require().False(balAfter.Balance.IsZero(), "val staking denom balance should be non-zero")
balIncrease := balAfter.Balance.
Sub(*balBefore.Balance).
Add(res.Tx.GetFee()[0]) // Add the fee back to balance to compare actual balances
queriedRewardsCoins, _ := delegationRewards.Rewards.TruncateDecimal()
suite.Require().Truef(
queriedRewardsCoins.AmountOf(suite.Kava.StakingDenom).
LTE(balIncrease.Amount),
"claimed rewards should be >= queried delegation rewards, got claimed %s vs queried %s",
balIncrease.Amount.String(),
queriedRewardsCoins.AmountOf(suite.Kava.StakingDenom).String(),
)
})
}
// func (suite *IntegrationTestSuite) TestUpgradeInflation_Disable() {
// suite.SkipIfUpgradeDisabled()
// afterUpgradeCtx := util.CtxAtHeight(suite.UpgradeHeight)
// // Get x/community for switchover time
// params, err := suite.Kava.Community.Params(afterUpgradeCtx, &communitytypes.QueryParamsRequest{})
// suite.Require().NoError(err)
// // Sleep until switchover time + 6 seconds for extra block
// sleepDuration := time.Until(params.Params.UpgradeTimeDisableInflation.Add(6 * time.Second))
// time.Sleep(sleepDuration)
// suite.Require().Eventually(func() bool {
// communityParams, err := suite.Kava.Community.Params(afterUpgradeCtx, &communitytypes.QueryParamsRequest{})
// suite.Require().NoError(err)
// // After params are set in x/community -- non-zero switchover time
// return !communityParams.Params.UpgradeTimeDisableInflation.Equal(time.Time{})
// }, 20*time.Second, 3*time.Second)
// // Fetch exact block when inflation stop event emitted
// // This is run after the switchover, so we don't need to poll
// _, switchoverHeight, err := suite.Kava.GetBeginBlockEventsFromQuery(
// context.Background(),
// fmt.Sprintf(
// "%s.%s EXISTS",
// communitytypes.EventTypeInflationStop,
// communitytypes.AttributeKeyInflationDisableTime,
// ),
// )
// suite.Require().NoError(err)
// suite.Require().NotZero(switchoverHeight)
// // 1 block before switchover
// beforeSwitchoverCtx := util.CtxAtHeight(switchoverHeight - 1)
// afterSwitchoverCtx := util.CtxAtHeight(switchoverHeight)
// suite.Run("x/mint, x/kavadist inflation before switchover", func() {
// mintParams, err := suite.Kava.Mint.Params(
// beforeSwitchoverCtx,
// &minttypes.QueryParamsRequest{},
// )
// suite.NoError(err)
// kavaDistParams, err := suite.Kava.Kavadist.Params(
// beforeSwitchoverCtx,
// &kavadisttypes.QueryParamsRequest{},
// )
// suite.NoError(err)
// // Use .String() to compare Decs since x/mint uses the deprecated one,
// // mismatch of types but same value.
// suite.Equal(
// sdkmath.LegacyMustNewDecFromStr("0.595000000000000000").String(),
// mintParams.Params.InflationMin.String(),
// "x/mint inflation min should be 59.5%% before switchover",
// )
// suite.Equal(
// sdkmath.LegacyMustNewDecFromStr("0.595000000000000000").String(),
// mintParams.Params.InflationMax.String(),
// "x/mint inflation max should be 59.5%% before switchover",
// )
// suite.True(
// kavaDistParams.Params.Active,
// "x/kavadist should be active before switchover",
// )
// })
// suite.Run("x/distribution community tax before switchover", func() {
// distrParams, err := suite.Kava.Distribution.Params(
// beforeSwitchoverCtx,
// &distributiontypes.QueryParamsRequest{},
// )
// suite.NoError(err)
// suite.Equal(
// sdkmath.LegacyMustNewDecFromStr("0.949500000000000000").String(),
// distrParams.Params.CommunityTax.String(),
// "x/distribution community tax should be 94.95%% before switchover",
// )
// })
// suite.Run("x/mint, x/kavadist inflation after switchover", func() {
// mintParams, err := suite.Kava.Mint.Params(
// afterSwitchoverCtx,
// &minttypes.QueryParamsRequest{},
// )
// suite.NoError(err)
// kavaDistParams, err := suite.Kava.Kavadist.Params(
// afterSwitchoverCtx,
// &kavadisttypes.QueryParamsRequest{},
// )
// suite.NoError(err)
// suite.Equal(
// sdkmath.LegacyZeroDec().String(),
// mintParams.Params.InflationMin.String(),
// "x/mint inflation min should be 0% after switchover",
// )
// suite.Equal(
// sdkmath.LegacyZeroDec().String(),
// mintParams.Params.InflationMax.String(),
// "x/mint inflation max should be 0% after switchover",
// )
// suite.False(
// kavaDistParams.Params.Active,
// "x/kavadist should be inactive after switchover",
// )
// })
// suite.Run("x/distribution community tax after switchover", func() {
// distrParams, err := suite.Kava.Distribution.Params(
// afterSwitchoverCtx,
// &distributiontypes.QueryParamsRequest{},
// )
// suite.NoError(err)
// suite.Equal(
// sdkmath.LegacyZeroDec().String(),
// distrParams.Params.CommunityTax.String(),
// "x/distribution community tax should be 0%% before switchover",
// )
// })
// // Ensure inflation was still active before switchover
// suite.Run("positive mint events before switchover", func() {
// // 1 block before switchover
// queryHeight := switchoverHeight - 1
// block, err := suite.Kava.TmSignClient.BlockResults(
// context.Background(),
// &queryHeight,
// )
// suite.Require().NoError(err)
// // Mint events should only occur in begin block
// mintEvents := util.FilterEventsByType(block.BeginBlockEvents, minttypes.EventTypeMint)
// suite.Require().NotEmpty(mintEvents, "mint events should be emitted")
// // Ensure mint amounts are non-zero
// found := false
// for _, event := range mintEvents {
// for _, attribute := range event.Attributes {
// // Bonded ratio and annual provisions unchecked
// if string(attribute.Key) == minttypes.AttributeKeyInflation {
// suite.Equal(
// sdkmath.LegacyMustNewDecFromStr("0.595000000000000000").String(),
// string(attribute.Value),
// "inflation should be 59.5%% before switchover",
// )
// }
// if string(attribute.Key) == sdk.AttributeKeyAmount {
// found = true
// // Parse as native go int, not necessary to use sdk.Int
// value, err := strconv.Atoi(string(attribute.Value))
// suite.Require().NoError(err)
// suite.NotZero(value, "mint amount should be non-zero")
// suite.Positive(value, "mint amount should be positive")
// }
// }
// }
// suite.True(found, "mint amount should be found")
// })
// suite.Run("staking denom supply increases before switchover", func() {
// queryHeight := switchoverHeight - 2
// supply1, err := suite.Kava.Bank.SupplyOf(
// util.CtxAtHeight(queryHeight),
// &types.QuerySupplyOfRequest{
// Denom: suite.Kava.StakingDenom,
// },
// )
// suite.Require().NoError(err)
// suite.NotZero(supply1.Amount, "ukava supply should be non-zero")
// // Next block
// queryHeight += 1
// supply2, err := suite.Kava.Bank.SupplyOf(
// util.CtxAtHeight(queryHeight),
// &types.QuerySupplyOfRequest{
// Denom: suite.Kava.StakingDenom,
// },
// )
// suite.Require().NoError(err)
// suite.NotZero(supply2.Amount, "ukava supply should be non-zero")
// suite.Truef(
// supply2.Amount.Amount.GT(supply1.Amount.Amount),
// "ukava supply before switchover should increase between blocks, %s > %s",
// supply2.Amount.Amount.String(),
// )
// })
// // Check if inflation is ACTUALLY disabled... check if any coins are being
// // minted in the blocks after switchover
// suite.Run("no minting after switchover", func() {
// kavaSupply := sdk.NewCoin(suite.Kava.StakingDenom, sdkmath.ZeroInt())
// // Next 5 blocks after switchover, ensure there's actually no more inflation
// for i := 0; i < 5; i++ {
// queryHeight := switchoverHeight + int64(i)
// suite.Run(
// fmt.Sprintf("x/mint events with 0 amount @ height=%d", queryHeight),
// func() {
// var block *coretypes.ResultBlockResults
// suite.Require().Eventually(func() bool {
// // Check begin block events
// block, err = suite.Kava.TmSignClient.BlockResults(
// context.Background(),
// &queryHeight,
// )
// return err == nil
// }, 20*time.Second, 3*time.Second)
// var mintEvents []abci.Event
// // Mint events should only occur in begin block, but we just include
// // everything else just in case anything changes in x/mint
// mintEventsBegin := util.FilterEventsByType(block.BeginBlockEvents, minttypes.EventTypeMint)
// mintEventsEnd := util.FilterEventsByType(block.EndBlockEvents, minttypes.EventTypeMint)
// mintEventsTx := util.FilterTxEventsByType(block.TxsResults, minttypes.EventTypeMint)
// mintEvents = append(mintEvents, mintEventsBegin...)
// mintEvents = append(mintEvents, mintEventsEnd...)
// mintEvents = append(mintEvents, mintEventsTx...)
// suite.Require().NotEmpty(mintEvents, "mint events should still be emitted")
// // Ensure mint amounts are 0
// found := false
// for _, event := range mintEvents {
// for _, attribute := range event.Attributes {
// // Bonded ratio and annual provisions unchecked
// if string(attribute.Key) == minttypes.AttributeKeyInflation {
// suite.Equal(sdkmath.LegacyZeroDec().String(), string(attribute.Value))
// }
// if string(attribute.Key) == sdk.AttributeKeyAmount {
// found = true
// suite.Equal(sdkmath.ZeroInt().String(), string(attribute.Value))
// }
// }
// }
// suite.True(found, "mint amount should be found")
// },
// )
// // Run this after the events check, since that one waits for the
// // new block if necessary
// suite.Run(
// fmt.Sprintf("total staking denom supply should not change @ height=%d", queryHeight),
// func() {
// supplyRes, err := suite.Kava.Bank.SupplyOf(
// util.CtxAtHeight(queryHeight),
// &types.QuerySupplyOfRequest{
// Denom: suite.Kava.StakingDenom,
// },
// )
// suite.Require().NoError(err)
// if kavaSupply.IsZero() {
// // First iteration, set supply
// kavaSupply = supplyRes.Amount
// } else {
// suite.Require().Equal(
// kavaSupply,
// supplyRes.Amount,
// "ukava supply should not change",
// )
// }
// },
// )
// }
// })
// suite.Run("no staking rewards from x/community before switchover", func() {
// // 1 block before switchover
// queryHeight := switchoverHeight - 1
// block, err := suite.Kava.TmSignClient.BlockResults(
// context.Background(),
// &queryHeight,
// )
// suite.Require().NoError(err)
// // Events are not emitted if amount is 0
// stakingRewardEvents := util.FilterEventsByType(block.BeginBlockEvents, communitytypes.EventTypeStakingRewardsPaid)
// suite.Require().Empty(stakingRewardEvents, "staking reward events should not be emitted")
// })
// suite.Run("staking rewards pay out from x/community after switchover", func() {
// for i := 0; i < 5; i++ {
// // after switchover
// queryHeight := switchoverHeight + int64(i)
// block, err := suite.Kava.TmSignClient.BlockResults(
// context.Background(),
// &queryHeight,
// )
// suite.Require().NoError(err)
// stakingRewardEvents := util.FilterEventsByType(
// block.BeginBlockEvents,
// communitytypes.EventTypeStakingRewardsPaid,
// )
// suite.Require().NotEmptyf(
// stakingRewardEvents,
// "staking reward events should be emitted at height=%d",
// queryHeight,
// )
// // Ensure amounts are non-zero
// found := false
// for _, attr := range stakingRewardEvents[0].Attributes {
// if string(attr.Key) == communitytypes.AttributeKeyStakingRewardAmount {
// coins, err := sdk.ParseCoinNormalized(string(attr.Value))
// suite.Require().NoError(err, "staking reward amount should be parsable coins")
// suite.Truef(
// coins.Amount.IsPositive(),
// "staking reward amount should be a positive amount at height=%d",
// queryHeight,
// )
// found = true
// }
// }
// suite.Truef(
// found,
// "staking reward amount should be found in events at height=%d",
// queryHeight,
// )
// }
// })
// // Staking rewards can still be claimed
// suite.Run("staking rewards claimable after switchover", func() {
// suite.SkipIfKvtoolDisabled()
// // Get the delegator of the only validator
// validators, err := suite.Kava.Staking.Validators(
// context.Background(),
// &stakingtypes.QueryValidatorsRequest{},
// )
// suite.Require().NoError(err)
// suite.Require().Positive(len(validators.Validators), "should only be at least 1 validator")
// valAddr, err := sdk.ValAddressFromBech32(validators.Validators[0].OperatorAddress)
// suite.Require().NoError(err)
// accAddr := sdk.AccAddress(valAddr.Bytes())
// balBefore, err := suite.Kava.Bank.Balance(
// context.Background(),
// &types.QueryBalanceRequest{
// Address: accAddr.String(),
// Denom: suite.Kava.StakingDenom,
// },
// )
// suite.Require().NoError(err)
// suite.Require().False(balBefore.Balance.IsZero(), "val staking denom balance should be non-zero")
// delegationRewards, err := suite.Kava.Distribution.DelegationRewards(
// context.Background(),
// &distributiontypes.QueryDelegationRewardsRequest{
// ValidatorAddress: valAddr.String(),
// DelegatorAddress: accAddr.String(),
// },
// )
// suite.Require().NoError(err)
// suite.False(delegationRewards.Rewards.Empty())
// suite.True(delegationRewards.Rewards.IsAllPositive(), "queried rewards should be positive")
// withdrawRewardsMsg := distributiontypes.NewMsgWithdrawDelegatorReward(
// accAddr,
// valAddr,
// )
// // Get the validator private key from kava keyring
// key, err := suite.Kava.Keyring.(unsafeExporter).ExportPrivateKeyObject(
// "validator",
// )
// suite.Require().NoError(err)
// acc := suite.Kava.AddNewSigningAccountFromPrivKey(
// "validator",
// key,
// "",
// suite.Kava.ChainID,
// )
// gasLimit := int64(2e5)
// fee := ukava(200)
// req := util.KavaMsgRequest{
// Msgs: []sdk.Msg{withdrawRewardsMsg},
// GasLimit: uint64(gasLimit),
// FeeAmount: sdk.NewCoins(fee),
// Memo: "give me my money",
// }
// res := acc.SignAndBroadcastKavaTx(req)
// _, err = util.WaitForSdkTxCommit(suite.Kava.Tx, res.Result.TxHash, 6*time.Second)
// suite.Require().NoError(err)
// balAfter, err := suite.Kava.Bank.Balance(
// context.Background(),
// &types.QueryBalanceRequest{
// Address: accAddr.String(),
// Denom: suite.Kava.StakingDenom,
// },
// )
// suite.Require().NoError(err)
// suite.Require().False(balAfter.Balance.IsZero(), "val staking denom balance should be non-zero")
// balIncrease := balAfter.Balance.
// Sub(*balBefore.Balance).
// Add(res.Tx.GetFee()[0]) // Add the fee back to balance to compare actual balances
// queriedRewardsCoins, _ := delegationRewards.Rewards.TruncateDecimal()
// suite.Require().Truef(
// queriedRewardsCoins.AmountOf(suite.Kava.StakingDenom).
// LTE(balIncrease.Amount),
// "claimed rewards should be >= queried delegation rewards, got claimed %s vs queried %s",
// balIncrease.Amount.String(),
// queriedRewardsCoins.AmountOf(suite.Kava.StakingDenom).String(),
// )
// })
// }
// unsafeExporter is implemented by key stores that support unsafe export
// of private keys' material.

View File

@ -28,13 +28,8 @@ import (
kavaparams "github.com/0glabs/0g-chain/app/params"
"github.com/0glabs/0g-chain/tests/e2e/runner"
"github.com/0glabs/0g-chain/tests/util"
cdptypes "github.com/0glabs/0g-chain/x/cdp/types"
committeetypes "github.com/0glabs/0g-chain/x/committee/types"
communitytypes "github.com/0glabs/0g-chain/x/community/types"
earntypes "github.com/0glabs/0g-chain/x/earn/types"
evmutiltypes "github.com/0glabs/0g-chain/x/evmutil/types"
incentivetypes "github.com/0glabs/0g-chain/x/incentive/types"
kavadisttypes "github.com/0glabs/0g-chain/x/kavadist/types"
)
// Chain wraps query clients & accounts for a network
@ -55,13 +50,8 @@ type Chain struct {
Auth authtypes.QueryClient
Authz authz.QueryClient
Bank banktypes.QueryClient
Cdp cdptypes.QueryClient
Committee committeetypes.QueryClient
Community communitytypes.QueryClient
Distribution distrtypes.QueryClient
Incentive incentivetypes.QueryClient
Kavadist kavadisttypes.QueryClient
Earn earntypes.QueryClient
Evm evmtypes.QueryClient
Evmutil evmutiltypes.QueryClient
Gov govv1types.QueryClient
@ -122,13 +112,9 @@ func NewChain(t *testing.T, details *runner.ChainDetails, fundedAccountMnemonic
chain.Auth = authtypes.NewQueryClient(grpcConn)
chain.Authz = authz.NewQueryClient(grpcConn)
chain.Bank = banktypes.NewQueryClient(grpcConn)
chain.Cdp = cdptypes.NewQueryClient(grpcConn)
chain.Committee = committeetypes.NewQueryClient(grpcConn)
chain.Community = communitytypes.NewQueryClient(grpcConn)
chain.Distribution = distrtypes.NewQueryClient(grpcConn)
chain.Incentive = incentivetypes.NewQueryClient(grpcConn)
chain.Kavadist = kavadisttypes.NewQueryClient(grpcConn)
chain.Earn = earntypes.NewQueryClient(grpcConn)
chain.Evm = evmtypes.NewQueryClient(grpcConn)
chain.Evmutil = evmutiltypes.NewQueryClient(grpcConn)
chain.Gov = govv1types.NewQueryClient(grpcConn)

View File

@ -8,7 +8,6 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/0glabs/0g-chain/tests/e2e/contracts/greeter"
"github.com/0glabs/0g-chain/x/cdp/types"
evmutiltypes "github.com/0glabs/0g-chain/x/evmutil/types"
)
@ -45,23 +44,6 @@ func (suite *E2eTestSuite) InitKavaEvmData() {
}
suite.Kava.RegisterErc20(suite.DeployedErc20.Address)
// expect the erc20's cosmos denom to be a supported cdp collateral type
cdpParams, err := suite.Kava.Grpc.Query.Cdp.Params(context.Background(), &types.QueryParamsRequest{})
suite.Require().NoError(err)
found = false
for _, cp := range cdpParams.Params.CollateralParams {
if cp.Denom == suite.DeployedErc20.CosmosDenom {
found = true
suite.DeployedErc20.CdpCollateralType = cp.Type
}
}
if !found {
panic(fmt.Sprintf(
"erc20's cosmos denom %s must be valid cdp collateral type",
suite.DeployedErc20.CosmosDenom),
)
}
// deploy an example contract
greeterAddr, _, _, err := greeter.DeployGreeter(
whale.evmSigner.Auth,

View File

@ -1,23 +0,0 @@
package auction
import (
"errors"
"time"
"github.com/cosmos/cosmos-sdk/telemetry"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/0glabs/0g-chain/x/auction/keeper"
"github.com/0glabs/0g-chain/x/auction/types"
)
// BeginBlocker closes all expired auctions at the end of each block. It panics if
// there's an error other than ErrAuctionNotFound.
func BeginBlocker(ctx sdk.Context, k keeper.Keeper) {
defer telemetry.ModuleMeasureSince(types.ModuleName, time.Now(), telemetry.MetricKeyBeginBlocker)
err := k.CloseExpiredAuctions(ctx)
if err != nil && !errors.Is(err, types.ErrAuctionNotFound) {
panic(err)
}
}

View File

@ -1,58 +0,0 @@
package auction_test
import (
"testing"
"github.com/stretchr/testify/suite"
sdkmath "cosmossdk.io/math"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/0glabs/0g-chain/x/auction"
"github.com/0glabs/0g-chain/x/auction/testutil"
types "github.com/0glabs/0g-chain/x/auction/types"
)
type abciTestSuite struct {
testutil.Suite
}
func (suite *abciTestSuite) SetupTest() {
suite.Suite.SetupTest(4)
}
func TestABCITestSuite(t *testing.T) {
suite.Run(t, new(abciTestSuite))
}
func (suite *abciTestSuite) TestKeeper_BeginBlocker() {
buyer := suite.Addrs[0]
returnAddrs := []sdk.AccAddress{suite.Addrs[1]}
returnWeights := []sdkmath.Int{sdkmath.NewInt(1)}
suite.AddCoinsToNamedModule(suite.ModAcc.Name, cs(c("token1", 100), c("token2", 100), c("debt", 100)))
// Start an auction and place a bid
auctionID, err := suite.Keeper.StartCollateralAuction(suite.Ctx, suite.ModAcc.Name, c("token1", 20), c("token2", 50), returnAddrs, returnWeights, c("debt", 40))
suite.Require().NoError(err)
suite.Require().NoError(suite.Keeper.PlaceBid(suite.Ctx, auctionID, buyer, c("token2", 30)))
// Run the beginblocker, simulating a block time 1ns before auction expiry
preExpiryTime := suite.Ctx.BlockTime().Add(types.DefaultForwardBidDuration - 1)
auction.BeginBlocker(suite.Ctx.WithBlockTime(preExpiryTime), suite.Keeper)
// Check auction has not been closed yet
_, found := suite.Keeper.GetAuction(suite.Ctx, auctionID)
suite.True(found)
// Run the endblocker, simulating a block time equal to auction expiry
expiryTime := suite.Ctx.BlockTime().Add(types.DefaultForwardBidDuration)
auction.BeginBlocker(suite.Ctx.WithBlockTime(expiryTime), suite.Keeper)
// Check auction has been closed
_, found = suite.Keeper.GetAuction(suite.Ctx, auctionID)
suite.False(found)
}
func c(denom string, amount int64) sdk.Coin { return sdk.NewInt64Coin(denom, amount) }
func cs(coins ...sdk.Coin) sdk.Coins { return sdk.NewCoins(coins...) }

View File

@ -1,212 +0,0 @@
package cli
import (
"context"
"fmt"
"strconv"
"strings"
"github.com/spf13/cobra"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/version"
"github.com/0glabs/0g-chain/x/auction/types"
)
// GetQueryCmd returns the cli query commands for the auction module
func GetQueryCmd() *cobra.Command {
auctionQueryCmd := &cobra.Command{
Use: types.ModuleName,
Short: fmt.Sprintf("Querying commands for the %s module", types.ModuleName),
}
cmds := []*cobra.Command{
GetCmdQueryParams(),
GetCmdQueryAuction(),
GetCmdQueryAuctions(),
}
for _, cmd := range cmds {
flags.AddQueryFlagsToCmd(cmd)
}
auctionQueryCmd.AddCommand(cmds...)
return auctionQueryCmd
}
// GetCmdQueryParams queries the issuance module parameters
func GetCmdQueryParams() *cobra.Command {
return &cobra.Command{
Use: "params",
Short: fmt.Sprintf("get the %s module parameters", types.ModuleName),
Long: "Get the current auction module parameters.",
Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientQueryContext(cmd)
if err != nil {
return err
}
queryClient := types.NewQueryClient(clientCtx)
res, err := queryClient.Params(context.Background(), &types.QueryParamsRequest{})
if err != nil {
return err
}
return clientCtx.PrintProto(&res.Params)
},
}
}
// GetCmdQueryAuction queries one auction in the store
func GetCmdQueryAuction() *cobra.Command {
return &cobra.Command{
Use: "auction [auction-id]",
Short: "get info about an auction",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientQueryContext(cmd)
if err != nil {
return err
}
queryClient := types.NewQueryClient(clientCtx)
auctionID, err := strconv.Atoi(args[0])
if err != nil {
return err
}
params := types.QueryAuctionRequest{
AuctionId: uint64(auctionID),
}
res, err := queryClient.Auction(context.Background(), &params)
if err != nil {
return err
}
return clientCtx.PrintProto(res)
},
}
}
// Query auction flags
const (
flagType = "type"
flagDenom = "denom"
flagPhase = "phase"
flagOwner = "owner"
)
// GetCmdQueryAuctions queries the auctions in the store
func GetCmdQueryAuctions() *cobra.Command {
cmd := &cobra.Command{
Use: "auctions",
Short: "query auctions with optional filters",
Long: "Query for all paginated auctions that match optional filters.",
Example: strings.Join([]string{
fmt.Sprintf(" $ %s q %s auctions --type=(collateral|surplus|debt)", version.AppName, types.ModuleName),
fmt.Sprintf(" $ %s q %s auctions --owner=kava1hatdq32u5x4wnxrtv5wzjzmq49sxgjgsj0mffm", version.AppName, types.ModuleName),
fmt.Sprintf(" $ %s q %s auctions --denom=bnb", version.AppName, types.ModuleName),
fmt.Sprintf(" $ %s q %s auctions --phase=(forward|reverse)", version.AppName, types.ModuleName),
fmt.Sprintf(" $ %s q %s auctions --page=2 --limit=100", version.AppName, types.ModuleName),
}, "\n"),
RunE: func(cmd *cobra.Command, args []string) error {
auctionType, err := cmd.Flags().GetString(flagType)
if err != nil {
return err
}
owner, err := cmd.Flags().GetString(flagOwner)
if err != nil {
return err
}
denom, err := cmd.Flags().GetString(flagDenom)
if err != nil {
return err
}
phase, err := cmd.Flags().GetString(flagPhase)
if err != nil {
return err
}
pageReq, err := client.ReadPageRequest(cmd.Flags())
if err != nil {
return err
}
if len(auctionType) != 0 {
auctionType = strings.ToLower(auctionType)
if auctionType != types.CollateralAuctionType &&
auctionType != types.SurplusAuctionType &&
auctionType != types.DebtAuctionType {
return fmt.Errorf("invalid auction type %s", auctionType)
}
}
if len(owner) != 0 {
if auctionType != types.CollateralAuctionType {
return fmt.Errorf("cannot apply owner flag to non-collateral auction type")
}
_, err := sdk.AccAddressFromBech32(owner)
if err != nil {
return fmt.Errorf("cannot parse address from auction owner %s", owner)
}
}
if len(denom) != 0 {
err := sdk.ValidateDenom(denom)
if err != nil {
return err
}
}
if len(phase) != 0 {
phase = strings.ToLower(phase)
if len(auctionType) > 0 && auctionType != types.CollateralAuctionType {
return fmt.Errorf("cannot apply phase flag to non-collateral auction type")
}
if phase != types.ForwardAuctionPhase && phase != types.ReverseAuctionPhase {
return fmt.Errorf("invalid auction phase %s", phase)
}
}
clientCtx, err := client.GetClientQueryContext(cmd)
if err != nil {
return err
}
queryClient := types.NewQueryClient(clientCtx)
request := types.QueryAuctionsRequest{
Type: auctionType,
Owner: owner,
Denom: denom,
Phase: phase,
Pagination: pageReq,
}
res, err := queryClient.Auctions(context.Background(), &request)
if err != nil {
return err
}
return clientCtx.PrintProto(res)
},
}
flags.AddPaginationFlagsToCmd(cmd, "auctions")
cmd.Flags().String(flagType, "", "(optional) filter by auction type, type: collateral, debt, surplus")
cmd.Flags().String(flagOwner, "", "(optional) filter by collateral auction owner")
cmd.Flags().String(flagDenom, "", "(optional) filter by auction denom")
cmd.Flags().String(flagPhase, "", "(optional) filter by collateral auction phase, phase: forward/reverse")
return cmd
}

View File

@ -1,70 +0,0 @@
package cli
import (
"fmt"
"strconv"
"github.com/spf13/cobra"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/client/tx"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/version"
"github.com/0glabs/0g-chain/x/auction/types"
)
// GetTxCmd returns the transaction cli commands for this module
func GetTxCmd() *cobra.Command {
txCmd := &cobra.Command{
Use: types.ModuleName,
Short: "transaction commands for the auction module",
}
cmds := []*cobra.Command{
GetCmdPlaceBid(),
}
for _, cmd := range cmds {
flags.AddTxFlagsToCmd(cmd)
}
txCmd.AddCommand(cmds...)
return txCmd
}
// GetCmdPlaceBid cli command for placing bids on auctions
func GetCmdPlaceBid() *cobra.Command {
return &cobra.Command{
Use: "bid [auction-id] [amount]",
Short: "place a bid on an auction",
Long: "Place a bid on any type of auction, updating the latest bid amount to [amount]. Collateral auctions must be bid up to their maxbid before entering reverse phase.",
Example: fmt.Sprintf(" $ %s tx %s bid 34 1000usdx --from myKeyName", version.AppName, types.ModuleName),
Args: cobra.ExactArgs(2),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientTxContext(cmd)
if err != nil {
return err
}
id, err := strconv.ParseUint(args[0], 10, 64)
if err != nil {
return fmt.Errorf("auction-id '%s' not a valid uint", args[0])
}
amt, err := sdk.ParseCoinNormalized(args[1])
if err != nil {
return err
}
msg := types.NewMsgPlaceBid(id, clientCtx.GetFromAddress().String(), amt)
err = msg.ValidateBasic()
if err != nil {
return err
}
return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), &msg)
},
}
}

View File

@ -1,74 +0,0 @@
package auction
import (
"fmt"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/0glabs/0g-chain/x/auction/keeper"
"github.com/0glabs/0g-chain/x/auction/types"
)
// InitGenesis initializes the store state from a genesis state.
func InitGenesis(ctx sdk.Context, keeper keeper.Keeper, bankKeeper types.BankKeeper, accountKeeper types.AccountKeeper, gs *types.GenesisState) {
if err := gs.Validate(); err != nil {
panic(fmt.Sprintf("failed to validate %s genesis state: %s", types.ModuleName, err))
}
keeper.SetNextAuctionID(ctx, gs.NextAuctionId)
keeper.SetParams(ctx, gs.Params)
totalAuctionCoins := sdk.NewCoins()
auctions, err := types.UnpackGenesisAuctions(gs.Auctions)
if err != nil {
panic(fmt.Sprintf("failed to unpack genesis auctions: %s", err))
}
for _, a := range auctions {
keeper.SetAuction(ctx, a)
// find the total coins that should be present in the module account
totalAuctionCoins = totalAuctionCoins.Add(a.GetModuleAccountCoins()...)
}
// check if the module account exists
moduleAcc := accountKeeper.GetModuleAccount(ctx, types.ModuleName)
if moduleAcc == nil {
panic(fmt.Sprintf("%s module account has not been set", types.ModuleName))
}
maccCoins := bankKeeper.GetAllBalances(ctx, moduleAcc.GetAddress())
// check module coins match auction coins
// Note: Other sdk modules do not check this, instead just using the existing module account coins, or if zero, setting them.
if !maccCoins.IsEqual(totalAuctionCoins) {
panic(fmt.Sprintf("total auction coins (%s) do not equal (%s) module account (%s) ", maccCoins, types.ModuleName, totalAuctionCoins))
}
}
// ExportGenesis returns a GenesisState for a given context and keeper.
func ExportGenesis(ctx sdk.Context, keeper keeper.Keeper) *types.GenesisState {
nextAuctionID, err := keeper.GetNextAuctionID(ctx)
if err != nil {
panic(err)
}
params := keeper.GetParams(ctx)
genAuctions := []types.GenesisAuction{} // return empty list instead of nil if no auctions
keeper.IterateAuctions(ctx, func(a types.Auction) bool {
ga, ok := a.(types.GenesisAuction)
if !ok {
panic("could not convert stored auction to GenesisAuction type")
}
genAuctions = append(genAuctions, ga)
return false
})
gs, err := types.NewGenesisState(nextAuctionID, params, genAuctions)
if err != nil {
panic(err)
}
return gs
}

View File

@ -1,159 +0,0 @@
package auction_test
import (
"sort"
"testing"
"time"
"github.com/stretchr/testify/require"
sdkmath "cosmossdk.io/math"
tmproto "github.com/cometbft/cometbft/proto/tendermint/types"
sdk "github.com/cosmos/cosmos-sdk/types"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
"github.com/0glabs/0g-chain/app"
"github.com/0glabs/0g-chain/x/auction"
"github.com/0glabs/0g-chain/x/auction/types"
)
var (
_, testAddrs = app.GeneratePrivKeyAddressPairs(2)
testTime = time.Date(1998, 1, 1, 0, 0, 0, 0, time.UTC)
testAuction = types.NewCollateralAuction(
"seller",
c("lotdenom", 10),
testTime,
c("biddenom", 1000),
types.WeightedAddresses{Addresses: testAddrs, Weights: []sdkmath.Int{sdk.OneInt(), sdk.OneInt()}},
c("debt", 1000),
).WithID(3).(types.GenesisAuction)
)
func TestInitGenesis(t *testing.T) {
t.Run("valid", func(t *testing.T) {
// setup keepers
tApp := app.NewTestApp()
ctx := tApp.NewContext(true, tmproto.Header{Height: 1})
// setup module account
modBaseAcc := authtypes.NewBaseAccount(authtypes.NewModuleAddress(types.ModuleName), nil, 0, 0)
modAcc := authtypes.NewModuleAccount(modBaseAcc, types.ModuleName, []string{authtypes.Minter, authtypes.Burner}...)
tApp.GetAccountKeeper().SetModuleAccount(ctx, modAcc)
tApp.GetBankKeeper().MintCoins(ctx, types.ModuleName, testAuction.GetModuleAccountCoins())
// set up auction genesis state with module account
auctionGS, err := types.NewGenesisState(
10,
types.DefaultParams(),
[]types.GenesisAuction{testAuction},
)
require.NoError(t, err)
// run init
keeper := tApp.GetAuctionKeeper()
require.NotPanics(t, func() {
auction.InitGenesis(ctx, keeper, tApp.GetBankKeeper(), tApp.GetAccountKeeper(), auctionGS)
})
// check state is as expected
actualID, err := keeper.GetNextAuctionID(ctx)
require.NoError(t, err)
require.Equal(t, auctionGS.NextAuctionId, actualID)
require.Equal(t, auctionGS.Params, keeper.GetParams(ctx))
genesisAuctions, err := types.UnpackGenesisAuctions(auctionGS.Auctions)
if err != nil {
panic(err)
}
sort.Slice(genesisAuctions, func(i, j int) bool {
return genesisAuctions[i].GetID() > genesisAuctions[j].GetID()
})
i := 0
keeper.IterateAuctions(ctx, func(a types.Auction) bool {
require.Equal(t, genesisAuctions[i], a)
i++
return false
})
})
t.Run("invalid (invalid nextAuctionID)", func(t *testing.T) {
// setup keepers
tApp := app.NewTestApp()
ctx := tApp.NewContext(true, tmproto.Header{Height: 1})
// setup module account
modBaseAcc := authtypes.NewBaseAccount(authtypes.NewModuleAddress(types.ModuleName), nil, 0, 0)
modAcc := authtypes.NewModuleAccount(modBaseAcc, types.ModuleName, []string{authtypes.Minter, authtypes.Burner}...)
tApp.GetAccountKeeper().SetModuleAccount(ctx, modAcc)
tApp.GetBankKeeper().MintCoins(ctx, types.ModuleName, testAuction.GetModuleAccountCoins())
// create invalid genesis
auctionGS, err := types.NewGenesisState(
0, // next id < testAuction ID
types.DefaultParams(),
[]types.GenesisAuction{testAuction},
)
require.NoError(t, err)
// check init fails
require.Panics(t, func() {
auction.InitGenesis(ctx, tApp.GetAuctionKeeper(), tApp.GetBankKeeper(), tApp.GetAccountKeeper(), auctionGS)
})
})
t.Run("invalid (missing mod account coins)", func(t *testing.T) {
// setup keepers
tApp := app.NewTestApp()
ctx := tApp.NewContext(true, tmproto.Header{Height: 1})
// invalid as there is no module account setup
// create invalid genesis
auctionGS, err := types.NewGenesisState(
10,
types.DefaultParams(),
[]types.GenesisAuction{testAuction},
)
require.NoError(t, err)
// check init fails
require.Panics(t, func() {
auction.InitGenesis(ctx, tApp.GetAuctionKeeper(), tApp.GetBankKeeper(), tApp.GetAccountKeeper(), auctionGS)
})
})
}
func TestExportGenesis(t *testing.T) {
t.Run("default", func(t *testing.T) {
// setup state
tApp := app.NewTestApp()
ctx := tApp.NewContext(true, tmproto.Header{Height: 1})
tApp.InitializeFromGenesisStates()
// export
gs := auction.ExportGenesis(ctx, tApp.GetAuctionKeeper())
// check state matches
defaultGS := types.DefaultGenesisState()
require.Equal(t, defaultGS, gs)
})
t.Run("one auction", func(t *testing.T) {
// setup state
tApp := app.NewTestApp()
ctx := tApp.NewContext(true, tmproto.Header{Height: 1})
tApp.InitializeFromGenesisStates()
tApp.GetAuctionKeeper().SetAuction(ctx, testAuction)
// export
gs := auction.ExportGenesis(ctx, tApp.GetAuctionKeeper())
// check state matches
expectedGenesisState := types.DefaultGenesisState()
packedGenesisAuctions, err := types.PackGenesisAuctions([]types.GenesisAuction{testAuction})
require.NoError(t, err)
expectedGenesisState.Auctions = append(expectedGenesisState.Auctions, packedGenesisAuctions...)
require.Equal(t, expectedGenesisState, gs)
})
}

View File

@ -1,583 +0,0 @@
package keeper
import (
"errors"
"fmt"
"time"
errorsmod "cosmossdk.io/errors"
sdkmath "cosmossdk.io/math"
sdk "github.com/cosmos/cosmos-sdk/types"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
"github.com/0glabs/0g-chain/x/auction/types"
)
// StartSurplusAuction starts a new surplus (forward) auction.
func (k Keeper) StartSurplusAuction(ctx sdk.Context, seller string, lot sdk.Coin, bidDenom string) (uint64, error) {
auction := types.NewSurplusAuction(
seller,
lot,
bidDenom,
types.DistantFuture,
)
// NOTE: for the duration of the auction the auction module account holds the lot
err := k.bankKeeper.SendCoinsFromModuleToModule(ctx, seller, types.ModuleName, sdk.NewCoins(lot))
if err != nil {
return 0, err
}
auctionID, err := k.StoreNewAuction(ctx, &auction)
if err != nil {
return 0, err
}
ctx.EventManager().EmitEvent(
sdk.NewEvent(
types.EventTypeAuctionStart,
sdk.NewAttribute(types.AttributeKeyAuctionID, fmt.Sprintf("%d", auctionID)),
sdk.NewAttribute(types.AttributeKeyAuctionType, auction.GetType()),
sdk.NewAttribute(types.AttributeKeyBid, auction.Bid.String()),
sdk.NewAttribute(types.AttributeKeyLot, auction.Lot.String()),
),
)
return auctionID, nil
}
// StartDebtAuction starts a new debt (reverse) auction.
func (k Keeper) StartDebtAuction(ctx sdk.Context, buyer string, bid sdk.Coin, initialLot sdk.Coin, debt sdk.Coin) (uint64, error) {
auction := types.NewDebtAuction(
buyer,
bid,
initialLot,
types.DistantFuture,
debt,
)
// This auction type mints coins at close. Need to check module account has minting privileges to avoid potential err in endblocker.
macc := k.accountKeeper.GetModuleAccount(ctx, buyer)
if !macc.HasPermission(authtypes.Minter) {
panic(fmt.Errorf("module '%s' does not have '%s' permission", buyer, authtypes.Minter))
}
// NOTE: for the duration of the auction the auction module account holds the debt
err := k.bankKeeper.SendCoinsFromModuleToModule(ctx, buyer, types.ModuleName, sdk.NewCoins(debt))
if err != nil {
return 0, err
}
auctionID, err := k.StoreNewAuction(ctx, &auction)
if err != nil {
return 0, err
}
ctx.EventManager().EmitEvent(
sdk.NewEvent(
types.EventTypeAuctionStart,
sdk.NewAttribute(types.AttributeKeyAuctionID, fmt.Sprintf("%d", auctionID)),
sdk.NewAttribute(types.AttributeKeyAuctionType, auction.GetType()),
sdk.NewAttribute(types.AttributeKeyBid, auction.Bid.String()),
sdk.NewAttribute(types.AttributeKeyLot, auction.Lot.String()),
),
)
return auctionID, nil
}
// StartCollateralAuction starts a new collateral (2-phase) auction.
func (k Keeper) StartCollateralAuction(
ctx sdk.Context, seller string, lot, maxBid sdk.Coin,
lotReturnAddrs []sdk.AccAddress, lotReturnWeights []sdkmath.Int, debt sdk.Coin,
) (uint64, error) {
weightedAddresses, err := types.NewWeightedAddresses(lotReturnAddrs, lotReturnWeights)
if err != nil {
return 0, err
}
auction := types.NewCollateralAuction(
seller,
lot,
types.DistantFuture,
maxBid,
weightedAddresses,
debt,
)
// NOTE: for the duration of the auction the auction module account holds the debt and the lot
err = k.bankKeeper.SendCoinsFromModuleToModule(ctx, seller, types.ModuleName, sdk.NewCoins(lot))
if err != nil {
return 0, err
}
err = k.bankKeeper.SendCoinsFromModuleToModule(ctx, seller, types.ModuleName, sdk.NewCoins(debt))
if err != nil {
return 0, err
}
auctionID, err := k.StoreNewAuction(ctx, &auction)
if err != nil {
return 0, err
}
ctx.EventManager().EmitEvent(
sdk.NewEvent(
types.EventTypeAuctionStart,
sdk.NewAttribute(types.AttributeKeyAuctionID, fmt.Sprintf("%d", auctionID)),
sdk.NewAttribute(types.AttributeKeyAuctionType, auction.GetType()),
sdk.NewAttribute(types.AttributeKeyBid, auction.Bid.String()),
sdk.NewAttribute(types.AttributeKeyLot, auction.Lot.String()),
sdk.NewAttribute(types.AttributeKeyMaxBid, auction.MaxBid.String()),
),
)
return auctionID, nil
}
// PlaceBid places a bid on any auction.
func (k Keeper) PlaceBid(ctx sdk.Context, auctionID uint64, bidder sdk.AccAddress, newAmount sdk.Coin) error {
auction, found := k.GetAuction(ctx, auctionID)
if !found {
return errorsmod.Wrapf(types.ErrAuctionNotFound, "%d", auctionID)
}
// validation common to all auctions
if ctx.BlockTime().After(auction.GetEndTime()) {
return errorsmod.Wrapf(types.ErrAuctionHasExpired, "%d", auctionID)
}
// move coins and return updated auction
var (
err error
updatedAuction types.Auction
)
switch auctionType := auction.(type) {
case *types.SurplusAuction:
updatedAuction, err = k.PlaceBidSurplus(ctx, auctionType, bidder, newAmount)
case *types.DebtAuction:
updatedAuction, err = k.PlaceBidDebt(ctx, auctionType, bidder, newAmount)
case *types.CollateralAuction:
if !auctionType.IsReversePhase() {
updatedAuction, err = k.PlaceForwardBidCollateral(ctx, auctionType, bidder, newAmount)
} else {
updatedAuction, err = k.PlaceReverseBidCollateral(ctx, auctionType, bidder, newAmount)
}
default:
err = errorsmod.Wrap(types.ErrUnrecognizedAuctionType, auction.GetType())
}
if err != nil {
return err
}
k.SetAuction(ctx, updatedAuction)
return nil
}
// PlaceBidSurplus places a forward bid on a surplus auction, moving coins and returning the updated auction.
func (k Keeper) PlaceBidSurplus(ctx sdk.Context, auction *types.SurplusAuction, bidder sdk.AccAddress, bid sdk.Coin) (*types.SurplusAuction, error) {
// Validate new bid
if bid.Denom != auction.Bid.Denom {
return auction, errorsmod.Wrapf(types.ErrInvalidBidDenom, "%s ≠ %s", bid.Denom, auction.Bid.Denom)
}
minNewBidAmt := auction.Bid.Amount.Add( // new bids must be some % greater than old bid, and at least 1 larger to avoid replacing an old bid at no cost
sdk.MaxInt(
sdkmath.NewInt(1),
sdk.NewDecFromInt(auction.Bid.Amount).Mul(k.GetParams(ctx).IncrementSurplus).RoundInt(),
),
)
if bid.Amount.LT(minNewBidAmt) {
return auction, errorsmod.Wrapf(types.ErrBidTooSmall, "%s < %s%s", bid, minNewBidAmt, auction.Bid.Denom)
}
// New bidder pays back old bidder
// Catch edge cases of a bidder replacing their own bid, or the amount being zero (sending zero coins produces meaningless send events).
if !bidder.Equals(auction.Bidder) && !auction.Bid.IsZero() { // bidder isn't same as before AND previous auction bid must exist
err := k.bankKeeper.SendCoinsFromAccountToModule(ctx, bidder, types.ModuleName, sdk.NewCoins(auction.Bid))
if err != nil {
return auction, err
}
err = k.bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, auction.Bidder, sdk.NewCoins(auction.Bid))
if err != nil {
return auction, err
}
}
err := k.bankKeeper.SendCoinsFromAccountToModule(ctx, bidder, auction.Initiator, sdk.NewCoins(bid.Sub(auction.Bid)))
if err != nil {
return auction, err
}
// Received bid amount is burned from the module account
err = k.bankKeeper.BurnCoins(ctx, auction.Initiator, sdk.NewCoins(bid.Sub(auction.Bid)))
if err != nil {
return auction, err
}
// Update Auction
auction.Bidder = bidder
auction.Bid = bid
if !auction.HasReceivedBids {
auction.MaxEndTime = ctx.BlockTime().Add(k.GetParams(ctx).MaxAuctionDuration) // set maximum ending time on receipt of first bid
auction.HasReceivedBids = true
}
auction.EndTime = earliestTime(ctx.BlockTime().Add(k.GetParams(ctx).ForwardBidDuration), auction.MaxEndTime) // increment timeout, up to MaxEndTime
ctx.EventManager().EmitEvent(
sdk.NewEvent(
types.EventTypeAuctionBid,
sdk.NewAttribute(types.AttributeKeyAuctionID, fmt.Sprintf("%d", auction.ID)),
sdk.NewAttribute(types.AttributeKeyBidder, auction.Bidder.String()),
sdk.NewAttribute(types.AttributeKeyBid, auction.Bid.String()),
sdk.NewAttribute(types.AttributeKeyEndTime, fmt.Sprintf("%d", auction.EndTime.Unix())),
),
)
return auction, nil
}
// PlaceForwardBidCollateral places a forward bid on a collateral auction, moving coins and returning the updated auction.
func (k Keeper) PlaceForwardBidCollateral(ctx sdk.Context, auction *types.CollateralAuction, bidder sdk.AccAddress, bid sdk.Coin) (*types.CollateralAuction, error) {
// Validate new bid
if bid.Denom != auction.Bid.Denom {
return auction, errorsmod.Wrapf(types.ErrInvalidBidDenom, "%s ≠ %s", bid.Denom, auction.Bid.Denom)
}
if auction.IsReversePhase() {
panic("cannot place reverse bid on auction in forward phase")
}
minNewBidAmt := auction.Bid.Amount.Add( // new bids must be some % greater than old bid, and at least 1 larger to avoid replacing an old bid at no cost
sdk.MaxInt(
sdkmath.NewInt(1),
sdk.NewDecFromInt(auction.Bid.Amount).Mul(k.GetParams(ctx).IncrementCollateral).RoundInt(),
),
)
minNewBidAmt = sdk.MinInt(minNewBidAmt, auction.MaxBid.Amount) // allow new bids to hit MaxBid even though it may be less than the increment %
if bid.Amount.LT(minNewBidAmt) {
return auction, errorsmod.Wrapf(types.ErrBidTooSmall, "%s < %s%s", bid, minNewBidAmt, auction.Bid.Denom)
}
if auction.MaxBid.IsLT(bid) {
return auction, errorsmod.Wrapf(types.ErrBidTooLarge, "%s > %s", bid, auction.MaxBid)
}
// New bidder pays back old bidder
// Catch edge cases of a bidder replacing their own bid, and the amount being zero (sending zero coins produces meaningless send events).
if !bidder.Equals(auction.Bidder) && !auction.Bid.IsZero() {
err := k.bankKeeper.SendCoinsFromAccountToModule(ctx, bidder, types.ModuleName, sdk.NewCoins(auction.Bid))
if err != nil {
return auction, err
}
err = k.bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, auction.Bidder, sdk.NewCoins(auction.Bid))
if err != nil {
return auction, err
}
}
// Increase in bid sent to auction initiator
bidIncrement := bid.Sub(auction.Bid)
err := k.bankKeeper.SendCoinsFromAccountToModule(ctx, bidder, auction.Initiator, sdk.NewCoins(bidIncrement))
if err != nil {
return auction, err
}
// Debt coins are sent to liquidator (until there is no CorrespondingDebt left). Amount sent is equal to bidIncrement (or whatever is left if < bidIncrement).
if auction.CorrespondingDebt.IsPositive() {
debtAmountToReturn := sdk.MinInt(bidIncrement.Amount, auction.CorrespondingDebt.Amount)
debtToReturn := sdk.NewCoin(auction.CorrespondingDebt.Denom, debtAmountToReturn)
err = k.bankKeeper.SendCoinsFromModuleToModule(ctx, types.ModuleName, auction.Initiator, sdk.NewCoins(debtToReturn))
if err != nil {
return auction, err
}
auction.CorrespondingDebt = auction.CorrespondingDebt.Sub(debtToReturn) // debtToReturn will always be ≤ auction.CorrespondingDebt from the MinInt above
}
// Update Auction
auction.Bidder = bidder
auction.Bid = bid
if !auction.HasReceivedBids {
auction.MaxEndTime = ctx.BlockTime().Add(k.GetParams(ctx).MaxAuctionDuration) // set maximum ending time on receipt of first bid
auction.HasReceivedBids = true
}
// If this forward bid converts this to a reverse, increase timeout with ReverseBidDuration
if auction.IsReversePhase() {
auction.EndTime = earliestTime(ctx.BlockTime().Add(k.GetParams(ctx).ReverseBidDuration), auction.MaxEndTime) // increment timeout, up to MaxEndTime
} else {
auction.EndTime = earliestTime(ctx.BlockTime().Add(k.GetParams(ctx).ForwardBidDuration), auction.MaxEndTime) // increment timeout, up to MaxEndTime
}
ctx.EventManager().EmitEvent(
sdk.NewEvent(
types.EventTypeAuctionBid,
sdk.NewAttribute(types.AttributeKeyAuctionID, fmt.Sprintf("%d", auction.ID)),
sdk.NewAttribute(types.AttributeKeyBidder, auction.Bidder.String()),
sdk.NewAttribute(types.AttributeKeyBid, auction.Bid.String()),
sdk.NewAttribute(types.AttributeKeyEndTime, fmt.Sprintf("%d", auction.EndTime.Unix())),
),
)
return auction, nil
}
// PlaceReverseBidCollateral places a reverse bid on a collateral auction, moving coins and returning the updated auction.
func (k Keeper) PlaceReverseBidCollateral(ctx sdk.Context, auction *types.CollateralAuction, bidder sdk.AccAddress, lot sdk.Coin) (*types.CollateralAuction, error) {
// Validate new bid
if lot.Denom != auction.Lot.Denom {
return auction, errorsmod.Wrapf(types.ErrInvalidLotDenom, "%s ≠ %s", lot.Denom, auction.Lot.Denom)
}
if !auction.IsReversePhase() {
panic("cannot place forward bid on auction in reverse phase")
}
maxNewLotAmt := auction.Lot.Amount.Sub( // new lot must be some % less than old lot, and at least 1 smaller to avoid replacing an old bid at no cost
sdk.MaxInt(
sdkmath.NewInt(1),
sdk.NewDecFromInt(auction.Lot.Amount).Mul(k.GetParams(ctx).IncrementCollateral).RoundInt(),
),
)
if lot.Amount.GT(maxNewLotAmt) {
return auction, errorsmod.Wrapf(types.ErrLotTooLarge, "%s > %s%s", lot, maxNewLotAmt, auction.Lot.Denom)
}
if lot.IsNegative() {
return auction, errorsmod.Wrapf(types.ErrLotTooSmall, "%s < 0%s", lot, auction.Lot.Denom)
}
// New bidder pays back old bidder
// Catch edge cases of a bidder replacing their own bid
if !bidder.Equals(auction.Bidder) {
err := k.bankKeeper.SendCoinsFromAccountToModule(ctx, bidder, types.ModuleName, sdk.NewCoins(auction.Bid))
if err != nil {
return auction, err
}
err = k.bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, auction.Bidder, sdk.NewCoins(auction.Bid))
if err != nil {
return auction, err
}
}
// Decrease in lot is sent to weighted addresses (normally the CDP depositors)
// Note: splitting an integer amount across weighted buckets results in small errors.
lotPayouts, err := splitCoinIntoWeightedBuckets(auction.Lot.Sub(lot), auction.LotReturns.Weights)
if err != nil {
return auction, err
}
for i, payout := range lotPayouts {
// if the payout amount is 0, don't send 0 coins
if !payout.IsPositive() {
continue
}
err = k.bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, auction.LotReturns.Addresses[i], sdk.NewCoins(payout))
if err != nil {
return auction, err
}
}
// Update Auction
auction.Bidder = bidder
auction.Lot = lot
if !auction.HasReceivedBids {
auction.MaxEndTime = ctx.BlockTime().Add(k.GetParams(ctx).MaxAuctionDuration) // set maximum ending time on receipt of first bid
auction.HasReceivedBids = true
}
auction.EndTime = earliestTime(ctx.BlockTime().Add(k.GetParams(ctx).ReverseBidDuration), auction.MaxEndTime) // increment timeout, up to MaxEndTime
ctx.EventManager().EmitEvent(
sdk.NewEvent(
types.EventTypeAuctionBid,
sdk.NewAttribute(types.AttributeKeyAuctionID, fmt.Sprintf("%d", auction.ID)),
sdk.NewAttribute(types.AttributeKeyBidder, auction.Bidder.String()),
sdk.NewAttribute(types.AttributeKeyLot, auction.Lot.String()),
sdk.NewAttribute(types.AttributeKeyEndTime, fmt.Sprintf("%d", auction.EndTime.Unix())),
),
)
return auction, nil
}
// PlaceBidDebt places a reverse bid on a debt auction, moving coins and returning the updated auction.
func (k Keeper) PlaceBidDebt(ctx sdk.Context, auction *types.DebtAuction, bidder sdk.AccAddress, lot sdk.Coin) (*types.DebtAuction, error) {
// Validate new bid
if lot.Denom != auction.Lot.Denom {
return auction, errorsmod.Wrapf(types.ErrInvalidLotDenom, "%s ≠ %s", lot.Denom, auction.Lot.Denom)
}
maxNewLotAmt := auction.Lot.Amount.Sub( // new lot must be some % less than old lot, and at least 1 smaller to avoid replacing an old bid at no cost
sdk.MaxInt(
sdkmath.NewInt(1),
sdk.NewDecFromInt(auction.Lot.Amount).Mul(k.GetParams(ctx).IncrementDebt).RoundInt(),
),
)
if lot.Amount.GT(maxNewLotAmt) {
return auction, errorsmod.Wrapf(types.ErrLotTooLarge, "%s > %s%s", lot, maxNewLotAmt, auction.Lot.Denom)
}
if lot.IsNegative() {
return auction, errorsmod.Wrapf(types.ErrLotTooSmall, "%s ≤ %s%s", lot, sdk.ZeroInt(), auction.Lot.Denom)
}
// New bidder pays back old bidder
// Catch edge cases of a bidder replacing their own bid
if !bidder.Equals(auction.Bidder) {
// Bidder sends coins to module
err := k.bankKeeper.SendCoinsFromAccountToModule(ctx, bidder, types.ModuleName, sdk.NewCoins(auction.Bid))
if err != nil {
return auction, err
}
// Coins are sent from module to old bidder
oldBidder := auction.Bidder
if oldBidder.Equals(authtypes.NewModuleAddress(auction.Initiator)) { // First bid on auction (where there is no previous bidder)
err = k.bankKeeper.SendCoinsFromModuleToModule(ctx, types.ModuleName, auction.Initiator, sdk.NewCoins(auction.Bid))
} else { // Second and later bids on auction (where previous bidder is a user account)
err = k.bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, oldBidder, sdk.NewCoins(auction.Bid))
}
if err != nil {
return auction, err
}
}
// Debt coins are sent to liquidator the first time a bid is placed. Amount sent is equal to min of Bid and amount of debt.
if auction.Bidder.Equals(authtypes.NewModuleAddress(auction.Initiator)) {
// Handle debt coins for first bid
debtAmountToReturn := sdk.MinInt(auction.Bid.Amount, auction.CorrespondingDebt.Amount)
debtToReturn := sdk.NewCoin(auction.CorrespondingDebt.Denom, debtAmountToReturn)
err := k.bankKeeper.SendCoinsFromModuleToModule(ctx, types.ModuleName, auction.Initiator, sdk.NewCoins(debtToReturn))
if err != nil {
return auction, err
}
auction.CorrespondingDebt = auction.CorrespondingDebt.Sub(debtToReturn) // debtToReturn will always be ≤ auction.CorrespondingDebt from the MinInt above
}
// Update Auction
auction.Bidder = bidder
auction.Lot = lot
if !auction.HasReceivedBids {
auction.MaxEndTime = ctx.BlockTime().Add(k.GetParams(ctx).MaxAuctionDuration) // set maximum ending time on receipt of first bid
auction.HasReceivedBids = true
}
auction.EndTime = earliestTime(ctx.BlockTime().Add(k.GetParams(ctx).ForwardBidDuration), auction.MaxEndTime) // increment timeout, up to MaxEndTime
ctx.EventManager().EmitEvent(
sdk.NewEvent(
types.EventTypeAuctionBid,
sdk.NewAttribute(types.AttributeKeyAuctionID, fmt.Sprintf("%d", auction.ID)),
sdk.NewAttribute(types.AttributeKeyBidder, auction.Bidder.String()),
sdk.NewAttribute(types.AttributeKeyLot, auction.Lot.String()),
sdk.NewAttribute(types.AttributeKeyEndTime, fmt.Sprintf("%d", auction.EndTime.Unix())),
),
)
return auction, nil
}
// CloseAuction closes an auction and distributes funds to the highest bidder.
func (k Keeper) CloseAuction(ctx sdk.Context, auctionID uint64) error {
auction, found := k.GetAuction(ctx, auctionID)
if !found {
return errorsmod.Wrapf(types.ErrAuctionNotFound, "%d", auctionID)
}
if ctx.BlockTime().Before(auction.GetEndTime()) {
return errorsmod.Wrapf(types.ErrAuctionHasNotExpired, "block time %s, auction end time %s", ctx.BlockTime().UTC(), auction.GetEndTime().UTC())
}
// payout to the last bidder
var err error
switch auc := auction.(type) {
case *types.SurplusAuction:
err = k.PayoutSurplusAuction(ctx, auc)
case *types.DebtAuction:
err = k.PayoutDebtAuction(ctx, auc)
case *types.CollateralAuction:
err = k.PayoutCollateralAuction(ctx, auc)
default:
err = errorsmod.Wrap(types.ErrUnrecognizedAuctionType, auc.GetType())
}
if err != nil {
return err
}
k.DeleteAuction(ctx, auctionID)
ctx.EventManager().EmitEvent(
sdk.NewEvent(
types.EventTypeAuctionClose,
sdk.NewAttribute(types.AttributeKeyAuctionID, fmt.Sprintf("%d", auctionID)),
sdk.NewAttribute(types.AttributeKeyCloseBlock, fmt.Sprintf("%d", ctx.BlockHeight())),
),
)
return nil
}
// PayoutDebtAuction pays out the proceeds for a debt auction, first minting the coins.
func (k Keeper) PayoutDebtAuction(ctx sdk.Context, auction *types.DebtAuction) error {
// create the coins that are needed to pay off the debt
err := k.bankKeeper.MintCoins(ctx, auction.Initiator, sdk.NewCoins(auction.Lot))
if err != nil {
panic(fmt.Errorf("could not mint coins: %w", err))
}
// send the new coins from the initiator module to the bidder
err = k.bankKeeper.SendCoinsFromModuleToAccount(ctx, auction.Initiator, auction.Bidder, sdk.NewCoins(auction.Lot))
if err != nil {
return err
}
// if there is remaining debt, return it to the calling module to manage
if !auction.CorrespondingDebt.IsPositive() {
return nil
}
return k.bankKeeper.SendCoinsFromModuleToModule(ctx, types.ModuleName, auction.Initiator, sdk.NewCoins(auction.CorrespondingDebt))
}
// PayoutSurplusAuction pays out the proceeds for a surplus auction.
func (k Keeper) PayoutSurplusAuction(ctx sdk.Context, auction *types.SurplusAuction) error {
// Send the tokens from the auction module account where they are being managed to the bidder who won the auction
return k.bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, auction.Bidder, sdk.NewCoins(auction.Lot))
}
// PayoutCollateralAuction pays out the proceeds for a collateral auction.
func (k Keeper) PayoutCollateralAuction(ctx sdk.Context, auction *types.CollateralAuction) error {
// Send the tokens from the auction module account where they are being managed to the bidder who won the auction
err := k.bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, auction.Bidder, sdk.NewCoins(auction.Lot))
if err != nil {
return err
}
// if there is remaining debt after the auction, send it back to the initiating module for management
if !auction.CorrespondingDebt.IsPositive() {
return nil
}
return k.bankKeeper.SendCoinsFromModuleToModule(ctx, types.ModuleName, auction.Initiator, sdk.NewCoins(auction.CorrespondingDebt))
}
// CloseExpiredAuctions iterates over all the auctions stored by until the current
// block timestamp and that are past (or at) their ending times and closes them,
// paying out to the highest bidder.
func (k Keeper) CloseExpiredAuctions(ctx sdk.Context) error {
var err error
k.IterateAuctionsByTime(ctx, ctx.BlockTime(), func(id uint64) (stop bool) {
err = k.CloseAuction(ctx, id)
if err != nil && !errors.Is(err, types.ErrAuctionNotFound) {
// stop iteration
return true
}
// reset error in case the last element had an ErrAuctionNotFound
err = nil
return false
})
return err
}
// earliestTime returns the earliest of two times.
func earliestTime(t1, t2 time.Time) time.Time {
if t1.Before(t2) {
return t1
}
return t2 // also returned if times are equal
}
// splitCoinIntoWeightedBuckets divides up some amount of coins according to some weights.
func splitCoinIntoWeightedBuckets(coin sdk.Coin, buckets []sdkmath.Int) ([]sdk.Coin, error) {
amounts := splitIntIntoWeightedBuckets(coin.Amount, buckets)
result := make([]sdk.Coin, len(amounts))
for i, a := range amounts {
result[i] = sdk.NewCoin(coin.Denom, a)
}
return result, nil
}

View File

@ -1,319 +0,0 @@
package keeper_test
import (
"testing"
"time"
"github.com/stretchr/testify/suite"
sdk "github.com/cosmos/cosmos-sdk/types"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
"github.com/0glabs/0g-chain/x/auction/testutil"
"github.com/0glabs/0g-chain/x/auction/types"
)
type auctionTestSuite struct {
testutil.Suite
}
func (suite *auctionTestSuite) SetupTest() {
suite.Suite.SetupTest(4)
}
func TestAuctionTestSuite(t *testing.T) {
suite.Run(t, new(auctionTestSuite))
}
func (suite *auctionTestSuite) TestSurplusAuctionBasic() {
buyer := suite.Addrs[0]
// TODO: use cdp.LiquidatorMacc once CDP module is available
// sellerModName := cdp.LiquidatorMacc
sellerAddr := authtypes.NewModuleAddress(suite.ModAcc.Name)
suite.AddCoinsToNamedModule(suite.ModAcc.Name, cs(c("token1", 100), c("token2", 100)))
// Create an auction (lot: 20 token1, initialBid: 0 token2)
auctionID, err := suite.Keeper.StartSurplusAuction(suite.Ctx, suite.ModAcc.Name, c("token1", 20), "token2") // lobid denom
suite.NoError(err)
// Check seller's coins have decreased
suite.CheckAccountBalanceEqual(sellerAddr, cs(c("token1", 80), c("token2", 100)))
// PlaceBid (bid: 10 token, lot: same as starting)
suite.NoError(suite.Keeper.PlaceBid(suite.Ctx, auctionID, buyer, c("token2", 10)))
// Check buyer's coins have decreased
suite.CheckAccountBalanceEqual(buyer, cs(c("token1", 100), c("token2", 90)))
// Check seller's coins have not increased (because proceeds are burned)
suite.CheckAccountBalanceEqual(sellerAddr, cs(c("token1", 80), c("token2", 100)))
// increment bid same bidder
err = suite.Keeper.PlaceBid(suite.Ctx, auctionID, buyer, c("token2", 20))
suite.NoError(err)
// Close auction just at auction expiry time
suite.Ctx = suite.Ctx.WithBlockTime(suite.Ctx.BlockTime().Add(types.DefaultForwardBidDuration))
suite.NoError(suite.Keeper.CloseAuction(suite.Ctx, auctionID))
// Check buyer's coins increased
suite.CheckAccountBalanceEqual(buyer, cs(c("token1", 120), c("token2", 80)))
}
func (suite *auctionTestSuite) TestDebtAuctionBasic() {
// Setup
seller := suite.Addrs[0]
suite.AddCoinsToNamedModule(suite.ModAcc.Name, cs(c("debt", 100)))
// Start auction
auctionID, err := suite.Keeper.StartDebtAuction(suite.Ctx, suite.ModAcc.Name, c("token1", 20), c("token2", 99999), c("debt", 20))
suite.NoError(err)
// Check buyer's coins have not decreased (except for debt), as lot is minted at the end
suite.CheckAccountBalanceEqual(suite.ModAcc.GetAddress(), cs(c("debt", 80)))
// Place a bid
suite.NoError(suite.Keeper.PlaceBid(suite.Ctx, auctionID, seller, c("token2", 10)))
// Check seller's coins have decreased
suite.CheckAccountBalanceEqual(seller, cs(c("token1", 80), c("token2", 100)))
// Check buyer's coins have increased
suite.CheckAccountBalanceEqual(suite.ModAcc.GetAddress(), cs(c("token1", 20), c("debt", 100)))
// Close auction at just after auction expiry
ctx := suite.Ctx.WithBlockTime(suite.Ctx.BlockTime().Add(types.DefaultForwardBidDuration))
suite.NoError(suite.Keeper.CloseAuction(ctx, auctionID))
// Check seller's coins increased
suite.CheckAccountBalanceEqual(seller, cs(c("token1", 80), c("token2", 110)))
}
func (suite *auctionTestSuite) TestDebtAuctionDebtRemaining() {
seller := suite.Addrs[0]
buyerAddr := authtypes.NewModuleAddress(suite.ModAcc.Name)
suite.AddCoinsToNamedModule(suite.ModAcc.Name, cs(c("debt", 100)))
// Start auction
auctionID, err := suite.Keeper.StartDebtAuction(suite.Ctx, suite.ModAcc.Name, c("token1", 10), c("token2", 99999), c("debt", 20))
suite.NoError(err)
// Check buyer's coins have not decreased (except for debt), as lot is minted at the end
suite.CheckAccountBalanceEqual(buyerAddr, cs(c("debt", 80)))
// Place a bid
suite.NoError(suite.Keeper.PlaceBid(suite.Ctx, auctionID, seller, c("token2", 10)))
// Check seller's coins have decreased
suite.CheckAccountBalanceEqual(seller, cs(c("token1", 90), c("token2", 100)))
// Check buyer's coins have increased
suite.CheckAccountBalanceEqual(buyerAddr, cs(c("token1", 10), c("debt", 90)))
// Close auction at just after auction expiry
ctx := suite.Ctx.WithBlockTime(suite.Ctx.BlockTime().Add(types.DefaultForwardBidDuration))
suite.NoError(suite.Keeper.CloseAuction(ctx, auctionID))
// Check seller's coins increased
suite.CheckAccountBalanceEqual(seller, cs(c("token1", 90), c("token2", 110)))
// check that debt has increased due to corresponding debt being greater than bid
suite.CheckAccountBalanceEqual(buyerAddr, cs(c("token1", 10), c("debt", 100)))
}
func (suite *auctionTestSuite) TestCollateralAuctionBasic() {
// Setup
buyer := suite.Addrs[0]
returnAddrs := suite.Addrs[1:]
returnWeights := is(30, 20, 10)
sellerModName := suite.ModAcc.Name
sellerAddr := suite.ModAcc.GetAddress()
suite.AddCoinsToNamedModule(sellerModName, cs(c("token1", 100), c("token2", 100), c("debt", 100)))
// Start auction
auctionID, err := suite.Keeper.StartCollateralAuction(suite.Ctx, sellerModName, c("token1", 20), c("token2", 50), returnAddrs, returnWeights, c("debt", 40))
suite.NoError(err)
// Check seller's coins have decreased
suite.CheckAccountBalanceEqual(sellerAddr, cs(c("token1", 80), c("token2", 100), c("debt", 60)))
// Place a forward bid
suite.NoError(suite.Keeper.PlaceBid(suite.Ctx, auctionID, buyer, c("token2", 10)))
// Check bidder's coins have decreased
suite.CheckAccountBalanceEqual(buyer, cs(c("token1", 100), c("token2", 90)))
// Check seller's coins have increased
suite.CheckAccountBalanceEqual(sellerAddr, cs(c("token1", 80), c("token2", 110), c("debt", 70)))
// Check return addresses have not received coins
for _, ra := range suite.Addrs[1:] {
suite.CheckAccountBalanceEqual(ra, cs(c("token1", 100), c("token2", 100)))
}
// Place a reverse bid
suite.NoError(suite.Keeper.PlaceBid(suite.Ctx, auctionID, buyer, c("token2", 50))) // first bid up to max bid to switch phases
suite.NoError(suite.Keeper.PlaceBid(suite.Ctx, auctionID, buyer, c("token1", 15)))
// Check bidder's coins have decreased
suite.CheckAccountBalanceEqual(buyer, cs(c("token1", 100), c("token2", 50)))
// Check seller's coins have increased
suite.CheckAccountBalanceEqual(sellerAddr, cs(c("token1", 80), c("token2", 150), c("debt", 100)))
// Check return addresses have received coins
suite.CheckAccountBalanceEqual(suite.Addrs[1], cs(c("token1", 102), c("token2", 100)))
suite.CheckAccountBalanceEqual(suite.Addrs[2], cs(c("token1", 102), c("token2", 100)))
suite.CheckAccountBalanceEqual(suite.Addrs[3], cs(c("token1", 101), c("token2", 100)))
// Close auction at just after auction expiry
ctx := suite.Ctx.WithBlockTime(suite.Ctx.BlockTime().Add(types.DefaultReverseBidDuration))
suite.NoError(suite.Keeper.CloseAuction(ctx, auctionID))
// Check buyer's coins increased
suite.CheckAccountBalanceEqual(buyer, cs(c("token1", 115), c("token2", 50)))
}
func (suite *auctionTestSuite) TestCollateralAuctionDebtRemaining() {
// Setup
buyer := suite.Addrs[0]
returnAddrs := suite.Addrs[1:]
returnWeights := is(30, 20, 10)
sellerModName := suite.ModAcc.Name
sellerAddr := suite.ModAcc.GetAddress()
suite.AddCoinsToNamedModule(sellerModName, cs(c("token1", 100), c("token2", 100), c("debt", 100)))
// Start auction
auctionID, err := suite.Keeper.StartCollateralAuction(suite.Ctx, sellerModName, c("token1", 20), c("token2", 50), returnAddrs, returnWeights, c("debt", 40))
suite.NoError(err)
// Check seller's coins have decreased
suite.CheckAccountBalanceEqual(sellerAddr, cs(c("token1", 80), c("token2", 100), c("debt", 60)))
// Place a forward bid
suite.NoError(suite.Keeper.PlaceBid(suite.Ctx, auctionID, buyer, c("token2", 10)))
// Check bidder's coins have decreased
suite.CheckAccountBalanceEqual(buyer, cs(c("token1", 100), c("token2", 90)))
// Check seller's coins have increased
suite.CheckAccountBalanceEqual(sellerAddr, cs(c("token1", 80), c("token2", 110), c("debt", 70)))
// Check return addresses have not received coins
for _, ra := range suite.Addrs[1:] {
suite.CheckAccountBalanceEqual(ra, cs(c("token1", 100), c("token2", 100)))
}
ctx := suite.Ctx.WithBlockTime(suite.Ctx.BlockTime().Add(types.DefaultForwardBidDuration))
suite.NoError(suite.Keeper.CloseAuction(ctx, auctionID))
// check that buyers coins have increased
suite.CheckAccountBalanceEqual(buyer, cs(c("token1", 120), c("token2", 90)))
// Check return addresses have not received coins
for _, ra := range suite.Addrs[1:] {
suite.CheckAccountBalanceEqual(ra, cs(c("token1", 100), c("token2", 100)))
}
// check that token2 has increased by 10, debt by 40, for a net debt increase of 30 debt
suite.CheckAccountBalanceEqual(sellerAddr, cs(c("token1", 80), c("token2", 110), c("debt", 100)))
}
func (suite *auctionTestSuite) TestStartSurplusAuction() {
someTime := time.Date(1998, time.January, 1, 0, 0, 0, 0, time.UTC)
type args struct {
seller string
lot sdk.Coin
bidDenom string
}
testCases := []struct {
name string
blockTime time.Time
args args
expectPass bool
expPanic bool
}{
{
"normal",
someTime,
args{suite.ModAcc.Name, c("stable", 10), "gov"},
true, false,
},
{
"no module account",
someTime,
args{"nonExistentModule", c("stable", 10), "gov"},
false, true,
},
{
"not enough coins",
someTime,
args{suite.ModAcc.Name, c("stable", 101), "gov"},
false, false,
},
{
"incorrect denom",
someTime,
args{suite.ModAcc.Name, c("notacoin", 10), "gov"},
false, false,
},
}
for _, tc := range testCases {
suite.Run(tc.name, func() {
suite.SetupTest()
// setup
initialLiquidatorCoins := cs(c("stable", 100))
suite.AddCoinsToNamedModule(suite.ModAcc.Name, initialLiquidatorCoins)
// run function under test
var (
id uint64
err error
)
if tc.expPanic {
suite.Panics(func() {
_, _ = suite.Keeper.StartSurplusAuction(suite.Ctx, tc.args.seller, tc.args.lot, tc.args.bidDenom)
}, tc.name)
} else {
id, err = suite.Keeper.StartSurplusAuction(suite.Ctx, tc.args.seller, tc.args.lot, tc.args.bidDenom)
}
// check
liquidatorCoins := suite.BankKeeper.GetAllBalances(suite.Ctx, suite.ModAcc.GetAddress())
actualAuc, found := suite.Keeper.GetAuction(suite.Ctx, id)
if tc.expectPass {
suite.NoError(err, tc.name)
// check coins moved
suite.Equal(initialLiquidatorCoins.Sub(tc.args.lot), liquidatorCoins, tc.name)
// check auction in store and is correct
suite.True(found, tc.name)
surplusAuction := types.SurplusAuction{BaseAuction: types.BaseAuction{
ID: id,
Initiator: tc.args.seller,
Lot: tc.args.lot,
Bidder: nil,
Bid: c(tc.args.bidDenom, 0),
HasReceivedBids: false,
EndTime: types.DistantFuture,
MaxEndTime: types.DistantFuture,
}}
suite.Equal(&surplusAuction, actualAuc, tc.name)
} else if !tc.expPanic && !tc.expectPass {
suite.Error(err, tc.name)
// check coins not moved
suite.Equal(initialLiquidatorCoins, liquidatorCoins, tc.name)
// check auction not in store
suite.False(found, tc.name)
}
})
}
}
func (suite *auctionTestSuite) TestCloseAuction() {
suite.AddCoinsToNamedModule(suite.ModAcc.Name, cs(c("token1", 100), c("token2", 100)))
// Create an auction (lot: 20 token1, initialBid: 0 token2)
id, err := suite.Keeper.StartSurplusAuction(suite.Ctx, suite.ModAcc.Name, c("token1", 20), "token2") // lot, bid denom
suite.NoError(err)
// Attempt to close the auction before EndTime
suite.Error(suite.Keeper.CloseAuction(suite.Ctx, id))
// Attempt to close auction that does not exist
suite.Error(suite.Keeper.CloseAuction(suite.Ctx, 999))
}
func (suite *auctionTestSuite) TestCloseExpiredAuctions() {
suite.AddCoinsToNamedModule(suite.ModAcc.Name, cs(c("token1", 100), c("token2", 100)))
// Start auction 1
_, err := suite.Keeper.StartSurplusAuction(suite.Ctx, suite.ModAcc.Name, c("token1", 20), "token2") // lot, bid denom
suite.NoError(err)
// Start auction 2
_, err = suite.Keeper.StartSurplusAuction(suite.Ctx, suite.ModAcc.Name, c("token1", 20), "token2") // lot, bid denom
suite.NoError(err)
// Fast forward the block time
ctx := suite.Ctx.WithBlockTime(suite.Ctx.BlockTime().Add(types.DefaultMaxAuctionDuration).Add(1))
// Close expired auctions
err = suite.Keeper.CloseExpiredAuctions(ctx)
suite.NoError(err)
}

View File

@ -1,591 +0,0 @@
package keeper_test
import (
"strings"
"testing"
"time"
"github.com/stretchr/testify/require"
sdkmath "cosmossdk.io/math"
tmproto "github.com/cometbft/cometbft/proto/tendermint/types"
sdk "github.com/cosmos/cosmos-sdk/types"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
"github.com/0glabs/0g-chain/app"
"github.com/0glabs/0g-chain/x/auction/types"
)
type AuctionType int
const (
Invalid AuctionType = 0
Surplus AuctionType = 1
Debt AuctionType = 2
Collateral AuctionType = 3
)
func TestAuctionBidding(t *testing.T) {
config := sdk.GetConfig()
app.SetBech32AddressPrefixes(config)
someTime := time.Date(0o001, time.January, 1, 0, 0, 0, 0, time.UTC)
_, addrs := app.GeneratePrivKeyAddressPairs(5)
buyer := addrs[0]
secondBuyer := addrs[1]
modName := "liquidator"
collateralAddrs := addrs[2:]
collateralWeights := is(30, 20, 10)
initialBalance := cs(c("token1", 1000), c("token2", 1000))
type auctionArgs struct {
auctionType AuctionType
seller string
lot sdk.Coin
bid sdk.Coin
debt sdk.Coin
addresses []sdk.AccAddress
weights []sdkmath.Int
}
type bidArgs struct {
bidder sdk.AccAddress
amount sdk.Coin
}
tests := []struct {
name string
auctionArgs auctionArgs
setupBids []bidArgs
bidArgs bidArgs
expectedError error
expectedEndTime time.Time
expectedBidder sdk.AccAddress
expectedBid sdk.Coin
expectPass bool
expectPanic bool
}{
{
"basic: auction doesn't exist",
auctionArgs{Surplus, "", c("token1", 1), c("token2", 1), sdk.Coin{}, []sdk.AccAddress{}, []sdkmath.Int{}},
nil,
bidArgs{buyer, c("token2", 10)},
types.ErrAuctionNotFound,
someTime.Add(types.DefaultForwardBidDuration),
buyer,
c("token2", 10),
false,
true,
},
{
"basic: closed auction",
auctionArgs{Surplus, modName, c("token1", 100), c("token2", 10), sdk.Coin{}, []sdk.AccAddress{}, []sdkmath.Int{}},
nil,
bidArgs{buyer, c("token2", 10)},
types.ErrAuctionHasExpired,
types.DistantFuture,
nil,
c("token2", 0),
false,
false,
},
{
// This is the first bid on an auction with NO bids
"surplus: normal",
auctionArgs{Surplus, modName, c("token1", 100), c("token2", 10), sdk.Coin{}, []sdk.AccAddress{}, []sdkmath.Int{}},
nil,
bidArgs{buyer, c("token2", 10)},
nil,
someTime.Add(types.DefaultForwardBidDuration),
buyer,
c("token2", 10),
true,
false,
},
{
"surplus: second bidder",
auctionArgs{Surplus, modName, c("token1", 100), c("token2", 10), sdk.Coin{}, []sdk.AccAddress{}, []sdkmath.Int{}},
[]bidArgs{{buyer, c("token2", 10)}},
bidArgs{secondBuyer, c("token2", 11)},
nil,
someTime.Add(types.DefaultForwardBidDuration),
secondBuyer,
c("token2", 11),
true,
false,
},
{
"surplus: invalid bid denom",
auctionArgs{Surplus, modName, c("token1", 100), c("token2", 10), sdk.Coin{}, []sdk.AccAddress{}, []sdkmath.Int{}},
nil,
bidArgs{buyer, c("badtoken", 10)},
types.ErrInvalidBidDenom,
types.DistantFuture,
nil, // surplus auctions are created with initial bidder as a nil address
c("token2", 0),
false,
false,
},
{
"surplus: invalid bid (less than)",
auctionArgs{Surplus, modName, c("token1", 100), c("token2", 0), sdk.Coin{}, []sdk.AccAddress{}, []sdkmath.Int{}},
[]bidArgs{{buyer, c("token2", 100)}},
bidArgs{buyer, c("token2", 99)},
types.ErrBidTooSmall,
someTime.Add(types.DefaultForwardBidDuration),
buyer,
c("token2", 100),
false,
false,
},
{
"surplus: invalid bid (equal)",
auctionArgs{Surplus, modName, c("token1", 100), c("token2", 0), sdk.Coin{}, []sdk.AccAddress{}, []sdkmath.Int{}},
nil,
bidArgs{buyer, c("token2", 0)}, // min bid is technically 0 at default 5%, but it's capped at 1
types.ErrBidTooSmall,
types.DistantFuture,
nil, // surplus auctions are created with initial bidder as a nil address
c("token2", 0),
false,
false,
},
{
"surplus: invalid bid (less than min increment)",
auctionArgs{Surplus, modName, c("token1", 100), c("token2", 0), sdk.Coin{}, []sdk.AccAddress{}, []sdkmath.Int{}},
[]bidArgs{{buyer, c("token2", 100)}},
bidArgs{buyer, c("token2", 104)}, // min bid is 105 at default 5%
types.ErrBidTooSmall,
someTime.Add(types.DefaultForwardBidDuration),
buyer,
c("token2", 100),
false,
false,
},
{
"debt: normal",
auctionArgs{Debt, modName, c("token1", 20), c("token2", 100), c("debt", 100), []sdk.AccAddress{}, []sdkmath.Int{}}, // initial bid, lot
nil,
bidArgs{buyer, c("token1", 10)},
nil,
someTime.Add(types.DefaultForwardBidDuration),
buyer,
c("token2", 100),
true,
false,
},
{
"debt: second bidder",
auctionArgs{Debt, modName, c("token1", 20), c("token2", 100), c("debt", 100), []sdk.AccAddress{}, []sdkmath.Int{}}, // initial bid, lot
[]bidArgs{{buyer, c("token1", 10)}},
bidArgs{secondBuyer, c("token1", 9)},
nil,
someTime.Add(types.DefaultForwardBidDuration),
secondBuyer,
c("token2", 100),
true,
false,
},
{
"debt: invalid lot denom",
auctionArgs{Debt, modName, c("token1", 20), c("token2", 100), c("debt", 100), []sdk.AccAddress{}, []sdkmath.Int{}}, // initial bid, lot
nil,
bidArgs{buyer, c("badtoken", 10)},
types.ErrInvalidLotDenom,
types.DistantFuture,
authtypes.NewModuleAddress(modName),
c("token2", 100),
false,
false,
},
{
"debt: invalid lot size (larger)",
auctionArgs{Debt, modName, c("token1", 20), c("token2", 100), c("debt", 100), []sdk.AccAddress{}, []sdkmath.Int{}},
nil,
bidArgs{buyer, c("token1", 21)},
types.ErrLotTooLarge,
types.DistantFuture,
authtypes.NewModuleAddress(modName),
c("token2", 100),
false,
false,
},
{
"debt: invalid lot size (equal)",
auctionArgs{Debt, modName, c("token1", 20), c("token2", 100), c("debt", 100), []sdk.AccAddress{}, []sdkmath.Int{}},
nil,
bidArgs{buyer, c("token1", 20)},
types.ErrLotTooLarge,
types.DistantFuture,
authtypes.NewModuleAddress(modName),
c("token2", 100),
false,
false,
},
{
"debt: invalid lot size (larger than min increment)",
auctionArgs{Debt, modName, c("token1", 60), c("token2", 100), c("debt", 100), []sdk.AccAddress{}, []sdkmath.Int{}},
nil,
bidArgs{buyer, c("token1", 58)}, // max lot at default 5% is 57
types.ErrLotTooLarge,
types.DistantFuture,
authtypes.NewModuleAddress(modName),
c("token2", 100),
false, false,
},
{
"collateral [forward]: normal",
auctionArgs{Collateral, modName, c("token1", 20), c("token2", 100), c("debt", 50), collateralAddrs, collateralWeights}, // lot, max bid
nil,
bidArgs{buyer, c("token2", 10)},
nil,
someTime.Add(types.DefaultForwardBidDuration),
buyer,
c("token2", 10),
true,
false,
},
{
"collateral [forward]: second bidder",
auctionArgs{Collateral, modName, c("token1", 20), c("token2", 100), c("debt", 50), collateralAddrs, collateralWeights}, // lot, max bid
[]bidArgs{{buyer, c("token2", 10)}},
bidArgs{secondBuyer, c("token2", 11)},
nil,
someTime.Add(types.DefaultForwardBidDuration),
secondBuyer,
c("token2", 11),
true,
false,
},
{
"collateral [forward]: convert to reverse (reach maxBid)",
auctionArgs{Collateral, modName, c("token1", 20), c("token2", 100), c("debt", 50), collateralAddrs, collateralWeights}, // lot, max bid
[]bidArgs{{buyer, c("token2", 10)}},
bidArgs{secondBuyer, c("token2", 100)},
nil,
someTime.Add(types.DefaultReverseBidDuration),
secondBuyer,
c("token2", 100),
true,
false,
},
{
"collateral [forward]: invalid bid denom",
auctionArgs{Collateral, modName, c("token1", 20), c("token2", 100), c("debt", 50), collateralAddrs, collateralWeights}, // lot, max bid
nil,
bidArgs{buyer, c("badtoken", 10)},
types.ErrInvalidBidDenom,
types.DistantFuture,
nil,
c("token2", 0),
false,
false,
},
{
"collateral [forward]: invalid bid size (smaller)",
auctionArgs{Collateral, modName, c("token1", 20), c("token2", 100), c("debt", 50), collateralAddrs, collateralWeights}, // lot, max bid
[]bidArgs{{buyer, c("token2", 10)}},
bidArgs{buyer, c("token2", 9)},
types.ErrBidTooSmall,
someTime.Add(types.DefaultForwardBidDuration),
buyer,
c("token2", 10),
false,
false,
},
{
"collateral [forward]: invalid bid size (equal)",
auctionArgs{Collateral, modName, c("token1", 20), c("token2", 100), c("debt", 50), collateralAddrs, collateralWeights}, // lot, max bid
nil,
bidArgs{buyer, c("token2", 0)},
types.ErrBidTooSmall,
types.DistantFuture,
nil,
c("token2", 0),
false,
false,
},
{
"collateral [forward]: invalid bid size (less than min increment)",
auctionArgs{Collateral, modName, c("token1", 20), c("token2", 100), c("debt", 50), collateralAddrs, collateralWeights}, // lot, max bid
[]bidArgs{{buyer, c("token2", 50)}},
bidArgs{buyer, c("token2", 51)},
types.ErrBidTooSmall,
someTime.Add(types.DefaultForwardBidDuration),
buyer,
c("token2", 50),
false,
false,
},
{
"collateral [forward]: less than min increment but equal to maxBid",
auctionArgs{Collateral, modName, c("token1", 20), c("token2", 100), c("debt", 50), collateralAddrs, collateralWeights}, // lot, max bid
[]bidArgs{{buyer, c("token2", 99)}},
bidArgs{buyer, c("token2", 100)}, // min bid at default 5% is 104
nil,
someTime.Add(types.DefaultReverseBidDuration), // Converts to a reverse bid when max reached
buyer,
c("token2", 100),
true,
false,
},
{
"collateral [forward]: invalid bid size (greater than max)",
auctionArgs{Collateral, modName, c("token1", 20), c("token2", 100), c("debt", 50), collateralAddrs, collateralWeights}, // lot, max bid
nil,
bidArgs{buyer, c("token2", 101)},
types.ErrBidTooLarge,
types.DistantFuture,
nil,
c("token2", 0),
false,
false,
},
{
"collateral [forward]: bidder replaces previous bid with only funds for difference",
auctionArgs{Collateral, modName, c("token1", 1000), c("token2", 2000), c("debt", 50), collateralAddrs, collateralWeights}, // lot, max bid
[]bidArgs{{buyer, c("token2", 900)}},
bidArgs{buyer, c("token2", 1000)}, // buyer only has enough to cover the increase from previous bid
nil,
someTime.Add(types.DefaultForwardBidDuration),
buyer,
c("token2", 1000),
true,
false,
},
{
"collateral [reverse]: normal",
auctionArgs{Collateral, modName, c("token1", 20), c("token2", 50), c("debt", 50), collateralAddrs, collateralWeights}, // lot, max bid
[]bidArgs{{buyer, c("token2", 50)}}, // put auction into reverse phase
bidArgs{buyer, c("token1", 15)},
nil,
someTime.Add(types.DefaultReverseBidDuration),
buyer,
c("token2", 50),
true,
false,
},
{
"collateral [reverse]: second bidder",
auctionArgs{Collateral, modName, c("token1", 20), c("token2", 50), c("debt", 50), collateralAddrs, collateralWeights}, // lot, max bid
[]bidArgs{{buyer, c("token2", 50)}, {buyer, c("token1", 15)}}, // put auction into reverse phase, and add a reverse phase bid
bidArgs{secondBuyer, c("token1", 14)},
nil,
someTime.Add(types.DefaultReverseBidDuration),
secondBuyer,
c("token2", 50),
true,
false,
},
{
"collateral [reverse]: invalid lot denom",
auctionArgs{Collateral, modName, c("token1", 20), c("token2", 50), c("debt", 50), collateralAddrs, collateralWeights}, // lot, max bid
[]bidArgs{{buyer, c("token2", 50)}}, // put auction into reverse phase
bidArgs{buyer, c("badtoken", 15)},
types.ErrInvalidLotDenom,
someTime.Add(types.DefaultReverseBidDuration),
buyer,
c("token2", 50),
false,
false,
},
{
"collateral [reverse]: invalid lot size (greater)",
auctionArgs{Collateral, modName, c("token1", 20), c("token2", 50), c("debt", 50), collateralAddrs, collateralWeights}, // lot, max bid
[]bidArgs{{buyer, c("token2", 50)}}, // put auction into reverse phase
bidArgs{buyer, c("token1", 21)},
types.ErrLotTooLarge,
someTime.Add(types.DefaultReverseBidDuration),
buyer,
c("token2", 50),
false,
false,
},
{
"collateral [reverse]: invalid lot size (equal)",
auctionArgs{Collateral, modName, c("token1", 20), c("token2", 50), c("debt", 50), collateralAddrs, collateralWeights}, // lot, max bid
[]bidArgs{{buyer, c("token2", 50)}}, // put auction into reverse phase
bidArgs{buyer, c("token1", 20)},
types.ErrLotTooLarge,
someTime.Add(types.DefaultReverseBidDuration),
buyer,
c("token2", 50),
false,
false,
},
{
"collateral [reverse]: invalid lot size (larger than min increment)",
auctionArgs{Collateral, modName, c("token1", 60), c("token2", 50), c("debt", 50), collateralAddrs, collateralWeights}, // lot, max bid
[]bidArgs{{buyer, c("token2", 50)}}, // put auction into reverse phase
bidArgs{buyer, c("token1", 58)}, // max lot at default 5% is 57
types.ErrLotTooLarge,
someTime.Add(types.DefaultReverseBidDuration),
buyer,
c("token2", 50),
false,
false,
},
{
"collateral [reverse]: bidder replaces previous bid without funds",
auctionArgs{Collateral, modName, c("token1", 1000), c("token2", 1000), c("debt", 50), collateralAddrs, collateralWeights}, // lot, max bid
[]bidArgs{{buyer, c("token2", 1000)}},
bidArgs{buyer, c("token1", 100)}, // buyer has already bid all of their token2
nil,
someTime.Add(types.DefaultReverseBidDuration),
buyer,
c("token2", 1000),
true,
false,
},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
// Setup test
tApp := app.NewTestApp()
// Set up module account
modName := "liquidator"
modBaseAcc := authtypes.NewBaseAccount(authtypes.NewModuleAddress(modName), nil, 0, 0)
modAcc := authtypes.NewModuleAccount(modBaseAcc, modName, []string{authtypes.Minter, authtypes.Burner}...)
// Set up normal accounts
addrs := []sdk.AccAddress{buyer, secondBuyer, collateralAddrs[0], collateralAddrs[1], collateralAddrs[2]}
// Initialize app
authGS := app.NewFundedGenStateWithSameCoinsWithModuleAccount(tApp.AppCodec(), initialBalance, addrs, modAcc)
params := types.NewParams(
types.DefaultMaxAuctionDuration,
types.DefaultForwardBidDuration,
types.DefaultReverseBidDuration,
types.DefaultIncrement,
types.DefaultIncrement,
types.DefaultIncrement,
)
auctionGs, err := types.NewGenesisState(types.DefaultNextAuctionID, params, []types.GenesisAuction{})
require.NoError(t, err)
moduleGs := tApp.AppCodec().MustMarshalJSON(auctionGs)
gs := app.GenesisState{types.ModuleName: moduleGs}
tApp.InitializeFromGenesisStates(authGS, gs)
ctx := tApp.NewContext(true, tmproto.Header{Height: 1, Time: someTime})
keeper := tApp.GetAuctionKeeper()
bank := tApp.GetBankKeeper()
err = tApp.FundModuleAccount(ctx, modName, cs(c("token1", 1000), c("token2", 1000), c("debt", 1000)))
require.NoError(t, err)
// Start Auction
var id uint64
switch tc.auctionArgs.auctionType {
case Surplus:
if tc.expectPanic {
require.Panics(t, func() {
id, err = keeper.StartSurplusAuction(ctx, tc.auctionArgs.seller, tc.auctionArgs.lot, tc.auctionArgs.bid.Denom)
})
} else {
id, err = keeper.StartSurplusAuction(ctx, tc.auctionArgs.seller, tc.auctionArgs.lot, tc.auctionArgs.bid.Denom)
}
case Debt:
id, err = keeper.StartDebtAuction(ctx, tc.auctionArgs.seller, tc.auctionArgs.bid, tc.auctionArgs.lot, tc.auctionArgs.debt)
case Collateral:
id, err = keeper.StartCollateralAuction(ctx, tc.auctionArgs.seller, tc.auctionArgs.lot, tc.auctionArgs.bid, tc.auctionArgs.addresses, tc.auctionArgs.weights, tc.auctionArgs.debt) // seller, lot, maxBid, otherPerson
default:
t.Fail()
}
require.NoError(t, err)
// Place setup bids
for _, b := range tc.setupBids {
require.NoError(t, keeper.PlaceBid(ctx, id, b.bidder, b.amount))
}
// Close the auction early to test late bidding (if applicable)
if strings.Contains(tc.name, "closed") {
ctx = ctx.WithBlockTime(types.DistantFuture.Add(1))
}
// Store some state for use in checks
var oldBidder sdk.AccAddress
var oldBidderOldCoins sdk.Coins
oldAuction, found := keeper.GetAuction(ctx, id)
if found {
oldBidder = oldAuction.GetBidder()
}
if !oldBidder.Empty() {
oldBidderOldCoins = bank.GetAllBalances(ctx, oldBidder)
}
newBidderOldCoins := bank.GetAllBalances(ctx, tc.bidArgs.bidder)
// Place bid on auction
err = keeper.PlaceBid(ctx, id, tc.bidArgs.bidder, tc.bidArgs.amount)
// Check success/failure
if tc.expectPass {
require.NoError(t, err)
// Check auction was found
newAuction, found := keeper.GetAuction(ctx, id)
require.True(t, found)
// Check auction values
require.Equal(t, modName, newAuction.GetInitiator())
require.Equal(t, tc.expectedBidder, newAuction.GetBidder())
require.Equal(t, tc.expectedBid, newAuction.GetBid())
require.Equal(t, tc.expectedEndTime, newAuction.GetEndTime())
// Check coins have moved between bidder and previous bidder
bidAmt := tc.bidArgs.amount
switch tc.auctionArgs.auctionType {
case Debt:
bidAmt = oldAuction.GetBid()
case Collateral:
collatAuction, ok := oldAuction.(*types.CollateralAuction)
require.True(t, ok, tc.name)
if collatAuction.IsReversePhase() {
bidAmt = oldAuction.GetBid()
}
}
if oldBidder.Equals(tc.bidArgs.bidder) { // same bidder
require.Equal(t, newBidderOldCoins.Sub(bidAmt.Sub(oldAuction.GetBid())), bank.GetAllBalances(ctx, tc.bidArgs.bidder))
} else { // different bidder
require.Equal(t, newBidderOldCoins.Sub(bidAmt), bank.GetAllBalances(ctx, tc.bidArgs.bidder)) // wrapping in cs() to avoid comparing nil and empty coins
// handle checking debt coins for case debt auction has had no bids placed yet TODO make this less confusing
if oldBidder.Equals(authtypes.NewModuleAddress(oldAuction.GetInitiator())) {
require.Equal(t, oldBidderOldCoins.Add(oldAuction.GetBid()).Add(c("debt", oldAuction.GetBid().Amount.Int64())), bank.GetAllBalances(ctx, oldBidder))
} else if oldBidder.Empty() {
require.Equal(t, oldBidderOldCoins.Add(oldAuction.GetBid()).Add(c("debt", oldAuction.GetBid().Amount.Int64())).Empty(), oldBidderOldCoins.Empty())
} else {
require.Equal(t, cs(oldBidderOldCoins.Add(oldAuction.GetBid())...), bank.GetAllBalances(ctx, oldBidder))
}
}
} else {
// Check expected error code type
require.Error(t, err, "PlaceBid did not return an error")
require.ErrorIs(t, err, tc.expectedError)
// Check auction values
newAuction, found := keeper.GetAuction(ctx, id)
if found {
require.Equal(t, modName, newAuction.GetInitiator())
require.Equal(t, tc.expectedBidder, newAuction.GetBidder())
require.Equal(t, tc.expectedBid, newAuction.GetBid())
require.Equal(t, tc.expectedEndTime, newAuction.GetEndTime())
}
// Check coins have not moved
require.Equal(t, newBidderOldCoins, bank.GetAllBalances(ctx, tc.bidArgs.bidder))
if !oldBidder.Empty() {
require.Equal(t, oldBidderOldCoins, bank.GetAllBalances(ctx, oldBidder))
}
}
})
}
}

View File

@ -1,145 +0,0 @@
package keeper
import (
"context"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
"github.com/cosmos/cosmos-sdk/store/prefix"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/query"
proto "github.com/cosmos/gogoproto/proto"
"github.com/0glabs/0g-chain/x/auction/types"
)
type queryServer struct {
keeper Keeper
}
// NewQueryServerImpl creates a new server for handling gRPC queries.
func NewQueryServerImpl(k Keeper) types.QueryServer {
return &queryServer{keeper: k}
}
var _ types.QueryServer = queryServer{}
// Params implements the gRPC service handler for querying x/auction parameters.
func (s queryServer) Params(ctx context.Context, req *types.QueryParamsRequest) (*types.QueryParamsResponse, error) {
if req == nil {
return nil, status.Errorf(codes.InvalidArgument, "empty request")
}
sdkCtx := sdk.UnwrapSDKContext(ctx)
params := s.keeper.GetParams(sdkCtx)
return &types.QueryParamsResponse{Params: params}, nil
}
// Auction implements the Query/Auction gRPC method
func (s queryServer) Auction(c context.Context, req *types.QueryAuctionRequest) (*types.QueryAuctionResponse, error) {
if req == nil {
return nil, status.Errorf(codes.InvalidArgument, "empty request")
}
ctx := sdk.UnwrapSDKContext(c)
auction, found := s.keeper.GetAuction(ctx, req.AuctionId)
if !found {
return &types.QueryAuctionResponse{}, nil
}
msg, ok := auction.(proto.Message)
if !ok {
return nil, status.Errorf(codes.Internal, "can't protomarshal %T", msg)
}
auctionAny, err := codectypes.NewAnyWithValue(msg)
if err != nil {
return nil, status.Errorf(codes.Internal, err.Error())
}
return &types.QueryAuctionResponse{
Auction: auctionAny,
}, nil
}
// Auctions implements the Query/Auctions gRPC method
func (s queryServer) Auctions(c context.Context, req *types.QueryAuctionsRequest) (*types.QueryAuctionsResponse, error) {
if req == nil {
return nil, status.Errorf(codes.InvalidArgument, "empty request")
}
ctx := sdk.UnwrapSDKContext(c)
var auctions []*codectypes.Any
auctionStore := prefix.NewStore(ctx.KVStore(s.keeper.storeKey), types.AuctionKeyPrefix)
pageRes, err := query.FilteredPaginate(auctionStore, req.Pagination, func(key []byte, value []byte, accumulate bool) (bool, error) {
result, err := s.keeper.UnmarshalAuction(value)
if err != nil {
return false, err
}
// True if empty owner, otherwise check if auction contains owner
ownerIsMatch := req.Owner == ""
if req.Owner != "" {
if cAuc, ok := result.(*types.CollateralAuction); ok {
for _, addr := range cAuc.GetLotReturns().Addresses {
if addr.String() == req.Owner {
ownerIsMatch = true
break
}
}
}
}
phaseIsMatch := req.Phase == "" || req.Phase == result.GetPhase()
typeIsMatch := req.Type == "" || req.Type == result.GetType()
denomIsMatch := req.Denom == "" || req.Denom == result.GetBid().Denom || req.Denom == result.GetLot().Denom
if ownerIsMatch && phaseIsMatch && typeIsMatch && denomIsMatch {
if accumulate {
msg, ok := result.(proto.Message)
if !ok {
return false, status.Errorf(codes.Internal, "can't protomarshal %T", msg)
}
auctionAny, err := codectypes.NewAnyWithValue(msg)
if err != nil {
return false, err
}
auctions = append(auctions, auctionAny)
}
return true, nil
}
return false, nil
})
if err != nil {
return &types.QueryAuctionsResponse{}, err
}
return &types.QueryAuctionsResponse{
Auctions: auctions,
Pagination: pageRes,
}, nil
}
// NextAuctionID implements the gRPC service handler for querying x/auction next auction ID.
func (s queryServer) NextAuctionID(ctx context.Context, req *types.QueryNextAuctionIDRequest) (*types.QueryNextAuctionIDResponse, error) {
if req == nil {
return nil, status.Errorf(codes.InvalidArgument, "empty request")
}
sdkCtx := sdk.UnwrapSDKContext(ctx)
nextAuctionID, err := s.keeper.GetNextAuctionID(sdkCtx)
if err != nil {
return &types.QueryNextAuctionIDResponse{}, err
}
return &types.QueryNextAuctionIDResponse{Id: nextAuctionID}, nil
}

View File

@ -1,137 +0,0 @@
package keeper_test
import (
"testing"
"time"
sdkmath "cosmossdk.io/math"
tmproto "github.com/cometbft/cometbft/proto/tendermint/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/0glabs/0g-chain/app"
"github.com/0glabs/0g-chain/x/auction/keeper"
"github.com/0glabs/0g-chain/x/auction/types"
"github.com/stretchr/testify/require"
)
func TestGrpcAuctionsFilter(t *testing.T) {
// setup
tApp := app.NewTestApp()
tApp.InitializeFromGenesisStates()
auctionsKeeper := tApp.GetAuctionKeeper()
ctx := tApp.NewContext(true, tmproto.Header{Height: 1})
_, addrs := app.GeneratePrivKeyAddressPairs(2)
auctions := []types.Auction{
types.NewSurplusAuction(
"sellerMod",
c("swp", 12345678),
"usdx",
time.Date(1998, time.January, 1, 0, 0, 0, 0, time.UTC),
).WithID(0),
types.NewDebtAuction(
"buyerMod",
c("hard", 12345678),
c("usdx", 12345678),
time.Date(1998, time.January, 1, 0, 0, 0, 0, time.UTC),
c("debt", 12345678),
).WithID(1),
types.NewCollateralAuction(
"sellerMod",
c("ukava", 12345678),
time.Date(1998, time.January, 1, 0, 0, 0, 0, time.UTC),
c("usdx", 12345678),
types.WeightedAddresses{
Addresses: addrs,
Weights: []sdkmath.Int{sdkmath.NewInt(100)},
},
c("debt", 12345678),
).WithID(2),
types.NewCollateralAuction(
"sellerMod",
c("hard", 12345678),
time.Date(1998, time.January, 1, 0, 0, 0, 0, time.UTC),
c("usdx", 12345678),
types.WeightedAddresses{
Addresses: addrs,
Weights: []sdkmath.Int{sdkmath.NewInt(100)},
},
c("debt", 12345678),
).WithID(3),
}
for _, a := range auctions {
auctionsKeeper.SetAuction(ctx, a)
}
qs := keeper.NewQueryServerImpl(auctionsKeeper)
tests := []struct {
giveName string
giveRequest types.QueryAuctionsRequest
wantResponse []types.Auction
}{
{
"empty request",
types.QueryAuctionsRequest{},
auctions,
},
{
"denom query swp",
types.QueryAuctionsRequest{
Denom: "swp",
},
auctions[0:1],
},
{
"denom query usdx all",
types.QueryAuctionsRequest{
Denom: "usdx",
},
auctions,
},
{
"owner",
types.QueryAuctionsRequest{
Owner: addrs[0].String(),
},
auctions[2:4],
},
{
"owner and denom",
types.QueryAuctionsRequest{
Owner: addrs[0].String(),
Denom: "hard",
},
auctions[3:4],
},
{
"owner, denom, type, phase",
types.QueryAuctionsRequest{
Owner: addrs[0].String(),
Denom: "hard",
Type: types.CollateralAuctionType,
Phase: types.ForwardAuctionPhase,
},
auctions[3:4],
},
}
for _, tc := range tests {
t.Run(tc.giveName, func(t *testing.T) {
res, err := qs.Auctions(sdk.WrapSDKContext(ctx), &tc.giveRequest)
require.NoError(t, err)
var unpackedAuctions []types.Auction
for _, anyAuction := range res.Auctions {
var auction types.Auction
err := tApp.AppCodec().UnpackAny(anyAuction, &auction)
require.NoError(t, err)
unpackedAuctions = append(unpackedAuctions, auction)
}
require.Equal(t, tc.wantResponse, unpackedAuctions)
})
}
}

View File

@ -1,15 +0,0 @@
package keeper_test
import (
sdkmath "cosmossdk.io/math"
sdk "github.com/cosmos/cosmos-sdk/types"
)
func c(denom string, amount int64) sdk.Coin { return sdk.NewInt64Coin(denom, amount) }
func cs(coins ...sdk.Coin) sdk.Coins { return sdk.NewCoins(coins...) }
func is(ns ...int64) (is []sdkmath.Int) {
for _, n := range ns {
is = append(is, sdkmath.NewInt(n))
}
return
}

View File

@ -1,132 +0,0 @@
package keeper
import (
"fmt"
"github.com/cosmos/cosmos-sdk/store/prefix"
sdk "github.com/cosmos/cosmos-sdk/types"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
"github.com/0glabs/0g-chain/x/auction/types"
)
// RegisterInvariants registers all staking invariants
func RegisterInvariants(ir sdk.InvariantRegistry, k Keeper) {
ir.RegisterRoute(types.ModuleName, "module-account",
ModuleAccountInvariants(k))
ir.RegisterRoute(types.ModuleName, "valid-auctions",
ValidAuctionInvariant(k))
ir.RegisterRoute(types.ModuleName, "valid-index",
ValidIndexInvariant(k))
}
// ModuleAccountInvariants checks that the module account's coins matches those stored in auctions
func ModuleAccountInvariants(k Keeper) sdk.Invariant {
return func(ctx sdk.Context) (string, bool) {
totalAuctionCoins := sdk.NewCoins()
k.IterateAuctions(ctx, func(auction types.Auction) bool {
a, ok := auction.(types.GenesisAuction)
if !ok {
panic("stored auction type does not fulfill GenesisAuction interface")
}
totalAuctionCoins = totalAuctionCoins.Add(a.GetModuleAccountCoins()...)
return false
})
moduleAccCoins := k.bankKeeper.GetAllBalances(ctx, authtypes.NewModuleAddress(types.ModuleName))
broken := !moduleAccCoins.IsEqual(totalAuctionCoins)
invariantMessage := sdk.FormatInvariant(
types.ModuleName,
"module account",
fmt.Sprintf(
"\texpected ModuleAccount coins: %s\n"+
"\tactual ModuleAccount coins: %s\n",
totalAuctionCoins, moduleAccCoins),
)
return invariantMessage, broken
}
}
// ValidAuctionInvariant verifies that all auctions in the store are independently valid
func ValidAuctionInvariant(k Keeper) sdk.Invariant {
return func(ctx sdk.Context) (string, bool) {
var validationErr error
var invalidAuction types.Auction
k.IterateAuctions(ctx, func(auction types.Auction) bool {
a, ok := auction.(types.GenesisAuction)
if !ok {
panic("stored auction type does not fulfill GenesisAuction interface")
}
if err := a.Validate(); err != nil {
validationErr = err
invalidAuction = a
return true
}
return false
})
broken := validationErr != nil
invariantMessage := sdk.FormatInvariant(
types.ModuleName,
"valid auctions",
fmt.Sprintf(
"\tfound invalid auction, reason: %s\n"+
"\tauction:\n\t%s\n",
validationErr, invalidAuction),
)
return invariantMessage, broken
}
}
// ValidIndexInvariant checks that all auctions in the store are also in the index and vice versa.
func ValidIndexInvariant(k Keeper) sdk.Invariant {
return func(ctx sdk.Context) (string, bool) {
/* Method:
- check all the auction IDs in the index have a corresponding auction in the store
- index is now valid but there could be extra auction in the store
- check for these extra auctions by checking num items in the store equals that of index (store keys are always unique)
- doesn't check the IDs in the auction structs match the IDs in the keys
*/
// Check all auction IDs in the index are in the auction store
store := prefix.NewStore(ctx.KVStore(k.storeKey), types.AuctionKeyPrefix)
indexIterator := sdk.KVStorePrefixIterator(ctx.KVStore(k.storeKey), types.AuctionByTimeKeyPrefix)
defer indexIterator.Close()
var indexLength int
for ; indexIterator.Valid(); indexIterator.Next() {
indexLength++
idBytes := indexIterator.Value()
auctionBytes := store.Get(idBytes)
if auctionBytes == nil {
invariantMessage := sdk.FormatInvariant(
types.ModuleName,
"valid index",
fmt.Sprintf("\tauction with ID '%d' found in index but not in store", types.Uint64FromBytes(idBytes)))
return invariantMessage, true
}
}
// Check length of auction store matches the length of the index
storeIterator := sdk.KVStorePrefixIterator(ctx.KVStore(k.storeKey), types.AuctionKeyPrefix)
defer storeIterator.Close()
var storeLength int
for ; storeIterator.Valid(); storeIterator.Next() {
storeLength++
}
if storeLength != indexLength {
invariantMessage := sdk.FormatInvariant(
types.ModuleName,
"valid index",
fmt.Sprintf("\tmismatched number of items in auction store (%d) and index (%d)", storeLength, indexLength))
return invariantMessage, true
}
return "", false
}
}

View File

@ -1,217 +0,0 @@
package keeper
import (
"fmt"
"time"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/store/prefix"
storetypes "github.com/cosmos/cosmos-sdk/store/types"
sdk "github.com/cosmos/cosmos-sdk/types"
paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
"github.com/cometbft/cometbft/libs/log"
"github.com/0glabs/0g-chain/x/auction/types"
)
type Keeper struct {
storeKey storetypes.StoreKey
cdc codec.Codec
paramSubspace paramtypes.Subspace
bankKeeper types.BankKeeper
accountKeeper types.AccountKeeper
}
// NewKeeper returns a new auction keeper.
func NewKeeper(cdc codec.Codec, storeKey storetypes.StoreKey, paramstore paramtypes.Subspace,
bankKeeper types.BankKeeper, accountKeeper types.AccountKeeper,
) Keeper {
if !paramstore.HasKeyTable() {
paramstore = paramstore.WithKeyTable(types.ParamKeyTable())
}
return Keeper{
storeKey: storeKey,
cdc: cdc,
paramSubspace: paramstore,
accountKeeper: accountKeeper,
bankKeeper: bankKeeper,
}
}
// MustUnmarshalAuction attempts to decode and return an Auction object from
// raw encoded bytes. It panics on error.
func (k Keeper) MustUnmarshalAuction(bz []byte) types.Auction {
auction, err := k.UnmarshalAuction(bz)
if err != nil {
panic(fmt.Errorf("failed to decode auction: %w", err))
}
return auction
}
// MustMarshalAuction attempts to encode an Auction object and returns the
// raw encoded bytes. It panics on error.
func (k Keeper) MustMarshalAuction(auction types.Auction) []byte {
bz, err := k.MarshalAuction(auction)
if err != nil {
panic(fmt.Errorf("failed to encode auction: %w", err))
}
return bz
}
// MarshalAuction protobuf serializes an Auction interface
func (k Keeper) MarshalAuction(auctionI types.Auction) ([]byte, error) {
return k.cdc.MarshalInterface(auctionI)
}
// UnmarshalAuction returns an Auction interface from raw encoded auction
// bytes of a Proto-based Auction type
func (k Keeper) UnmarshalAuction(bz []byte) (types.Auction, error) {
var evi types.Auction
return evi, k.cdc.UnmarshalInterface(bz, &evi)
}
// Logger returns a module-specific logger.
func (k Keeper) Logger(ctx sdk.Context) log.Logger {
return ctx.Logger().With("module", fmt.Sprintf("x/%s", types.ModuleName))
}
// SetNextAuctionID stores an ID to be used for the next created auction
func (k Keeper) SetNextAuctionID(ctx sdk.Context, id uint64) {
store := prefix.NewStore(ctx.KVStore(k.storeKey), types.NextAuctionIDKey)
store.Set(types.NextAuctionIDKey, types.Uint64ToBytes(id))
}
// GetNextAuctionID reads the next available global ID from store
func (k Keeper) GetNextAuctionID(ctx sdk.Context) (uint64, error) {
store := prefix.NewStore(ctx.KVStore(k.storeKey), types.NextAuctionIDKey)
bz := store.Get(types.NextAuctionIDKey)
if bz == nil {
return 0, types.ErrInvalidInitialAuctionID
}
return types.Uint64FromBytes(bz), nil
}
// IncrementNextAuctionID increments the next auction ID in the store by 1.
func (k Keeper) IncrementNextAuctionID(ctx sdk.Context) error {
id, err := k.GetNextAuctionID(ctx)
if err != nil {
return err
}
k.SetNextAuctionID(ctx, id+1)
return nil
}
// StoreNewAuction stores an auction, adding a new ID
func (k Keeper) StoreNewAuction(ctx sdk.Context, auction types.Auction) (uint64, error) {
newAuctionID, err := k.GetNextAuctionID(ctx)
if err != nil {
return 0, err
}
auction = auction.WithID(newAuctionID)
k.SetAuction(ctx, auction)
err = k.IncrementNextAuctionID(ctx)
if err != nil {
return 0, err
}
return newAuctionID, nil
}
// SetAuction puts the auction into the store, and updates any indexes.
func (k Keeper) SetAuction(ctx sdk.Context, auction types.Auction) {
// remove the auction from the byTime index if it is already in there
existingAuction, found := k.GetAuction(ctx, auction.GetID())
if found {
k.removeFromByTimeIndex(ctx, existingAuction.GetEndTime(), existingAuction.GetID())
}
store := prefix.NewStore(ctx.KVStore(k.storeKey), types.AuctionKeyPrefix)
store.Set(types.GetAuctionKey(auction.GetID()), k.MustMarshalAuction(auction))
k.InsertIntoByTimeIndex(ctx, auction.GetEndTime(), auction.GetID())
}
// GetAuction gets an auction from the store.
func (k Keeper) GetAuction(ctx sdk.Context, auctionID uint64) (types.Auction, bool) {
var auction types.Auction
store := prefix.NewStore(ctx.KVStore(k.storeKey), types.AuctionKeyPrefix)
bz := store.Get(types.GetAuctionKey(auctionID))
if bz == nil {
return auction, false
}
return k.MustUnmarshalAuction(bz), true
}
// DeleteAuction removes an auction from the store, and any indexes.
func (k Keeper) DeleteAuction(ctx sdk.Context, auctionID uint64) {
auction, found := k.GetAuction(ctx, auctionID)
if found {
k.removeFromByTimeIndex(ctx, auction.GetEndTime(), auctionID)
}
store := prefix.NewStore(ctx.KVStore(k.storeKey), types.AuctionKeyPrefix)
store.Delete(types.GetAuctionKey(auctionID))
}
// InsertIntoByTimeIndex adds an auction ID and end time into the byTime index.
func (k Keeper) InsertIntoByTimeIndex(ctx sdk.Context, endTime time.Time, auctionID uint64) {
store := prefix.NewStore(ctx.KVStore(k.storeKey), types.AuctionByTimeKeyPrefix)
store.Set(types.GetAuctionByTimeKey(endTime, auctionID), types.Uint64ToBytes(auctionID))
}
// removeFromByTimeIndex removes an auction ID and end time from the byTime index.
func (k Keeper) removeFromByTimeIndex(ctx sdk.Context, endTime time.Time, auctionID uint64) {
store := prefix.NewStore(ctx.KVStore(k.storeKey), types.AuctionByTimeKeyPrefix)
store.Delete(types.GetAuctionByTimeKey(endTime, auctionID))
}
// IterateAuctionByTime provides an iterator over auctions ordered by auction.EndTime.
// For each auction cb will be callled. If cb returns true the iterator will close and stop.
func (k Keeper) IterateAuctionsByTime(ctx sdk.Context, inclusiveCutoffTime time.Time, cb func(auctionID uint64) (stop bool)) {
store := prefix.NewStore(ctx.KVStore(k.storeKey), types.AuctionByTimeKeyPrefix)
iterator := store.Iterator(
nil, // start at the very start of the prefix store
sdk.PrefixEndBytes(sdk.FormatTimeBytes(inclusiveCutoffTime)), // include any keys with times equal to inclusiveCutoffTime
)
defer iterator.Close()
for ; iterator.Valid(); iterator.Next() {
auctionID := types.Uint64FromBytes(iterator.Value())
if cb(auctionID) {
break
}
}
}
// IterateAuctions provides an iterator over all stored auctions.
// For each auction, cb will be called. If cb returns true, the iterator will close and stop.
func (k Keeper) IterateAuctions(ctx sdk.Context, cb func(auction types.Auction) (stop bool)) {
iterator := sdk.KVStorePrefixIterator(ctx.KVStore(k.storeKey), types.AuctionKeyPrefix)
defer iterator.Close()
for ; iterator.Valid(); iterator.Next() {
auction := k.MustUnmarshalAuction(iterator.Value())
if cb(auction) {
break
}
}
}
// GetAllAuctions returns all auctions from the store
func (k Keeper) GetAllAuctions(ctx sdk.Context) (auctions []types.Auction) {
k.IterateAuctions(ctx, func(auction types.Auction) bool {
auctions = append(auctions, auction)
return false
})
return
}

View File

@ -1,135 +0,0 @@
package keeper_test
import (
"testing"
"time"
"github.com/stretchr/testify/require"
tmproto "github.com/cometbft/cometbft/proto/tendermint/types"
"github.com/0glabs/0g-chain/app"
"github.com/0glabs/0g-chain/x/auction/types"
)
func SetGetDeleteAuction(t *testing.T) {
// setup keeper, create auction
tApp := app.NewTestApp()
keeper := tApp.GetAuctionKeeper()
ctx := tApp.NewContext(true, tmproto.Header{Height: 1})
someTime := time.Date(43, time.January, 1, 0, 0, 0, 0, time.UTC) // need to specify UTC as tz info is lost on unmarshal
var id uint64 = 5
auction := types.NewSurplusAuction("some_module", c("usdx", 100), "kava", someTime).WithID(id)
// write and read from store
keeper.SetAuction(ctx, auction)
readAuction, found := keeper.GetAuction(ctx, id)
// check before and after match
require.True(t, found)
require.Equal(t, auction, readAuction)
// check auction is in the index
keeper.IterateAuctionsByTime(ctx, auction.GetEndTime(), func(readID uint64) bool {
require.Equal(t, auction.GetID(), readID)
return false
})
// delete auction
keeper.DeleteAuction(ctx, id)
// check auction does not exist
_, found = keeper.GetAuction(ctx, id)
require.False(t, found)
// check auction not in index
keeper.IterateAuctionsByTime(ctx, time.Unix(999999999, 0), func(readID uint64) bool {
require.Fail(t, "index should be empty", " found auction ID '%s", readID)
return false
})
}
func TestIncrementNextAuctionID(t *testing.T) {
// setup keeper
tApp := app.NewTestApp()
keeper := tApp.GetAuctionKeeper()
ctx := tApp.NewContext(true, tmproto.Header{Height: 1})
// store id
var id uint64 = 123456
keeper.SetNextAuctionID(ctx, id)
require.NoError(t, keeper.IncrementNextAuctionID(ctx))
// check id was incremented
readID, err := keeper.GetNextAuctionID(ctx)
require.NoError(t, err)
require.Equal(t, id+1, readID)
}
func TestIterateAuctions(t *testing.T) {
// setup
tApp := app.NewTestApp()
tApp.InitializeFromGenesisStates()
keeper := tApp.GetAuctionKeeper()
ctx := tApp.NewContext(true, tmproto.Header{Height: 1})
auctions := []types.Auction{
types.NewSurplusAuction("sellerMod", c("denom", 12345678), "anotherdenom", time.Date(1998, time.January, 1, 0, 0, 0, 0, time.UTC)).WithID(0),
types.NewDebtAuction("buyerMod", c("denom", 12345678), c("anotherdenom", 12345678), time.Date(1998, time.January, 1, 0, 0, 0, 0, time.UTC), c("debt", 12345678)).WithID(1),
types.NewCollateralAuction("sellerMod", c("denom", 12345678), time.Date(1998, time.January, 1, 0, 0, 0, 0, time.UTC), c("anotherdenom", 12345678), types.WeightedAddresses{}, c("debt", 12345678)).WithID(2),
}
for _, a := range auctions {
keeper.SetAuction(ctx, a)
}
// run
var readAuctions []types.Auction
keeper.IterateAuctions(ctx, func(a types.Auction) bool {
readAuctions = append(readAuctions, a)
return false
})
// check
require.Equal(t, auctions, readAuctions)
}
func TestIterateAuctionsByTime(t *testing.T) {
// setup keeper
tApp := app.NewTestApp()
keeper := tApp.GetAuctionKeeper()
ctx := tApp.NewContext(true, tmproto.Header{Height: 1})
// setup byTime index
byTimeIndex := []struct {
endTime time.Time
auctionID uint64
}{
{time.Date(0, time.January, 1, 0, 0, 0, 0, time.UTC), 9999}, // distant past
{time.Date(1998, time.January, 1, 11, 59, 59, 999999999, time.UTC), 1}, // just before cutoff
{time.Date(1998, time.January, 1, 11, 59, 59, 999999999, time.UTC), 2}, //
{time.Date(1998, time.January, 1, 12, 0, 0, 0, time.UTC), 3}, // equal to cutoff
{time.Date(1998, time.January, 1, 12, 0, 0, 0, time.UTC), 4}, //
{time.Date(1998, time.January, 1, 12, 0, 0, 1, time.UTC), 5}, // just after cutoff
{time.Date(1998, time.January, 1, 12, 0, 0, 1, time.UTC), 6}, //
{time.Date(9999, time.January, 1, 0, 0, 0, 0, time.UTC), 0}, // distant future
}
for _, v := range byTimeIndex {
keeper.InsertIntoByTimeIndex(ctx, v.endTime, v.auctionID)
}
// read out values from index up to a cutoff time and check they are as expected
cutoffTime := time.Date(1998, time.January, 1, 12, 0, 0, 0, time.UTC)
var expectedIndex []uint64
for _, v := range byTimeIndex {
if v.endTime.Before(cutoffTime) || v.endTime.Equal(cutoffTime) { // endTime ≤ cutoffTime
expectedIndex = append(expectedIndex, v.auctionID)
}
}
var readIndex []uint64
keeper.IterateAuctionsByTime(ctx, cutoffTime, func(id uint64) bool {
readIndex = append(readIndex, id)
return false
})
require.Equal(t, expectedIndex, readIndex)
}

View File

@ -1,81 +0,0 @@
package keeper
import (
"sort"
sdkmath "cosmossdk.io/math"
sdk "github.com/cosmos/cosmos-sdk/types"
)
// splitIntIntoWeightedBuckets divides an initial +ve integer among several buckets in proportion to the buckets' weights
// It uses the largest remainder method: https://en.wikipedia.org/wiki/Largest_remainder_method
// See also: https://stackoverflow.com/questions/13483430/how-to-make-rounded-percentages-add-up-to-100
func splitIntIntoWeightedBuckets(amount sdkmath.Int, buckets []sdkmath.Int) []sdkmath.Int {
// Limit input to +ve numbers as algorithm hasn't been scoped to work with -ve numbers.
if amount.IsNegative() {
panic("negative amount")
}
if len(buckets) < 1 {
panic("no buckets")
}
for _, bucket := range buckets {
if bucket.IsNegative() {
panic("negative bucket")
}
}
// 1) Split the amount by weights, recording whole number part and remainder
totalWeights := totalInts(buckets...)
if !totalWeights.IsPositive() {
panic("total weights must sum to > 0")
}
quotients := make([]quoRem, len(buckets))
for i := range buckets {
// amount * ( weight/total_weight )
q := amount.Mul(buckets[i]).Quo(totalWeights)
r := amount.Mul(buckets[i]).Mod(totalWeights)
quotients[i] = quoRem{index: i, quo: q, rem: r}
}
// 2) Calculate total left over from remainders, and apportion it to buckets with the highest remainder (to minimize error)
// sort by decreasing remainder order
sort.Slice(quotients, func(i, j int) bool {
return quotients[i].rem.GT(quotients[j].rem)
})
// calculate total left over from remainders
allocated := sdk.ZeroInt()
for _, qr := range quotients {
allocated = allocated.Add(qr.quo)
}
leftToAllocate := amount.Sub(allocated)
// apportion according to largest remainder
results := make([]sdkmath.Int, len(quotients))
for _, qr := range quotients {
results[qr.index] = qr.quo
if !leftToAllocate.IsZero() {
results[qr.index] = results[qr.index].Add(sdk.OneInt())
leftToAllocate = leftToAllocate.Sub(sdk.OneInt())
}
}
return results
}
type quoRem struct {
index int
quo sdkmath.Int
rem sdkmath.Int
}
// totalInts adds together sdk.Ints
func totalInts(is ...sdkmath.Int) sdkmath.Int {
total := sdk.ZeroInt()
for _, i := range is {
total = total.Add(i)
}
return total
}

View File

@ -1,115 +0,0 @@
package keeper
import (
"testing"
"github.com/stretchr/testify/require"
sdkmath "cosmossdk.io/math"
)
func TestSplitIntIntoWeightedBuckets(t *testing.T) {
testCases := []struct {
name string
amount sdkmath.Int
buckets []sdkmath.Int
want []sdkmath.Int
expectPanic bool
}{
{
name: "0split0",
amount: i(0),
buckets: is(0),
expectPanic: true,
},
{
name: "5splitnil",
amount: i(5),
buckets: is(),
expectPanic: true,
},
{
name: "-2split1,1",
amount: i(-2),
buckets: is(1, 1),
expectPanic: true,
},
{
name: "2split1,-1",
amount: i(2),
buckets: is(1, -1),
expectPanic: true,
},
{
name: "0split0,0,0,1",
amount: i(0),
buckets: is(0, 0, 0, 1),
want: is(0, 0, 0, 0),
},
{
name: "2split1,1",
amount: i(2),
buckets: is(1, 1),
want: is(1, 1),
},
{
name: "100split1,9",
amount: i(100),
buckets: is(1, 9),
want: is(10, 90),
},
{
name: "100split9,1",
amount: i(100),
buckets: is(9, 1),
want: is(90, 10),
},
{
name: "7split1,2",
amount: i(7),
buckets: is(1, 2),
want: is(2, 5),
},
{
name: "17split1,1,1",
amount: i(17),
buckets: is(1, 1, 1),
want: is(6, 6, 5),
},
{
name: "10split1000000,1",
amount: i(10),
buckets: is(1000000, 1),
want: is(10, 0),
},
{
name: "334733353split730777,31547",
amount: i(334733353),
buckets: is(730777, 31547),
want: is(320881194, 13852159),
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
var got []sdkmath.Int
run := func() {
got = splitIntIntoWeightedBuckets(tc.amount, tc.buckets)
}
if tc.expectPanic {
require.Panics(t, run)
} else {
require.NotPanics(t, run)
}
require.Equal(t, tc.want, got)
})
}
}
func i(n int64) sdkmath.Int { return sdkmath.NewInt(n) }
func is(ns ...int64) (is []sdkmath.Int) {
for _, n := range ns {
is = append(is, sdkmath.NewInt(n))
}
return
}

View File

@ -1,43 +0,0 @@
package keeper
import (
"context"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/0glabs/0g-chain/x/auction/types"
)
type msgServer struct {
keeper Keeper
}
// NewMsgServerImpl returns an implementation of the auction MsgServer interface
// for the provided Keeper.
func NewMsgServerImpl(keeper Keeper) types.MsgServer {
return &msgServer{keeper: keeper}
}
var _ types.MsgServer = msgServer{}
func (k msgServer) PlaceBid(goCtx context.Context, msg *types.MsgPlaceBid) (*types.MsgPlaceBidResponse, error) {
ctx := sdk.UnwrapSDKContext(goCtx)
bidder, err := sdk.AccAddressFromBech32(msg.Bidder)
if err != nil {
return nil, err
}
err = k.keeper.PlaceBid(ctx, msg.AuctionId, bidder, msg.Amount)
if err != nil {
return nil, err
}
ctx.EventManager().EmitEvent(
sdk.NewEvent(
sdk.EventTypeMessage,
sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
sdk.NewAttribute(sdk.AttributeKeySender, msg.Bidder),
),
)
return &types.MsgPlaceBidResponse{}, nil
}

View File

@ -1,16 +0,0 @@
package keeper
import (
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/0glabs/0g-chain/x/auction/types"
)
func (k Keeper) SetParams(ctx sdk.Context, params types.Params) {
k.paramSubspace.SetParamSet(ctx, &params)
}
func (k Keeper) GetParams(ctx sdk.Context) (params types.Params) {
k.paramSubspace.GetParamSet(ctx, &params)
return
}

View File

@ -1,16 +0,0 @@
package types
import (
v017auction "github.com/0glabs/0g-chain/x/auction/types"
types "github.com/cosmos/cosmos-sdk/codec/types"
)
func RegisterInterfaces(registry types.InterfaceRegistry) {
registry.RegisterInterface(
"kava.auction.v1beta1.GenesisAuction",
(*v017auction.GenesisAuction)(nil),
&v017auction.SurplusAuction{},
&v017auction.DebtAuction{},
&v017auction.CollateralAuction{},
)
}

View File

@ -1,761 +0,0 @@
// Code generated by protoc-gen-gogo. DO NOT EDIT.
// source: kava/auction/v1beta1/genesis.proto
package types
import (
fmt "fmt"
_ "github.com/cosmos/cosmos-proto"
types "github.com/cosmos/cosmos-sdk/codec/types"
github_com_cosmos_cosmos_sdk_types "github.com/cosmos/cosmos-sdk/types"
_ "github.com/gogo/protobuf/gogoproto"
proto "github.com/gogo/protobuf/proto"
github_com_gogo_protobuf_types "github.com/gogo/protobuf/types"
_ "google.golang.org/protobuf/types/known/durationpb"
io "io"
math "math"
math_bits "math/bits"
time "time"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
var _ = time.Kitchen
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
// GenesisState defines the auction module's genesis state.
type GenesisState struct {
NextAuctionId uint64 `protobuf:"varint,1,opt,name=next_auction_id,json=nextAuctionId,proto3" json:"next_auction_id,omitempty"`
Params Params `protobuf:"bytes,2,opt,name=params,proto3" json:"params"`
// Genesis auctions
Auctions []*types.Any `protobuf:"bytes,3,rep,name=auctions,proto3" json:"auctions,omitempty"`
}
func (m *GenesisState) Reset() { *m = GenesisState{} }
func (m *GenesisState) String() string { return proto.CompactTextString(m) }
func (*GenesisState) ProtoMessage() {}
func (*GenesisState) Descriptor() ([]byte, []int) {
return fileDescriptor_d0e5cb58293042f7, []int{0}
}
func (m *GenesisState) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *GenesisState) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_GenesisState.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
}
func (m *GenesisState) XXX_Merge(src proto.Message) {
xxx_messageInfo_GenesisState.Merge(m, src)
}
func (m *GenesisState) XXX_Size() int {
return m.Size()
}
func (m *GenesisState) XXX_DiscardUnknown() {
xxx_messageInfo_GenesisState.DiscardUnknown(m)
}
var xxx_messageInfo_GenesisState proto.InternalMessageInfo
// Params defines the parameters for the issuance module.
type Params struct {
MaxAuctionDuration time.Duration `protobuf:"bytes,1,opt,name=max_auction_duration,json=maxAuctionDuration,proto3,stdduration" json:"max_auction_duration"`
BidDuration time.Duration `protobuf:"bytes,2,opt,name=bid_duration,json=bidDuration,proto3,stdduration" json:"bid_duration"`
IncrementSurplus github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,3,opt,name=increment_surplus,json=incrementSurplus,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"increment_surplus"`
IncrementDebt github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,4,opt,name=increment_debt,json=incrementDebt,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"increment_debt"`
IncrementCollateral github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,5,opt,name=increment_collateral,json=incrementCollateral,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"increment_collateral"`
}
func (m *Params) Reset() { *m = Params{} }
func (m *Params) String() string { return proto.CompactTextString(m) }
func (*Params) ProtoMessage() {}
func (*Params) Descriptor() ([]byte, []int) {
return fileDescriptor_d0e5cb58293042f7, []int{1}
}
func (m *Params) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *Params) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_Params.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
}
func (m *Params) XXX_Merge(src proto.Message) {
xxx_messageInfo_Params.Merge(m, src)
}
func (m *Params) XXX_Size() int {
return m.Size()
}
func (m *Params) XXX_DiscardUnknown() {
xxx_messageInfo_Params.DiscardUnknown(m)
}
var xxx_messageInfo_Params proto.InternalMessageInfo
var fileDescriptor_d0e5cb58293042f7 = []byte{
// 466 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x93, 0x31, 0x6f, 0xd3, 0x40,
0x14, 0xc7, 0x7d, 0x4d, 0x88, 0xaa, 0x4b, 0x5a, 0xe0, 0xf0, 0xe0, 0x56, 0xc8, 0x89, 0x32, 0x54,
0x61, 0xc8, 0x59, 0x0d, 0x1b, 0x5b, 0x4d, 0x44, 0xc5, 0x86, 0x5c, 0x75, 0x81, 0x21, 0xba, 0xb3,
0x0f, 0x63, 0xd5, 0xf6, 0x45, 0xbe, 0x73, 0x95, 0x7c, 0x0b, 0x46, 0x3e, 0x08, 0x03, 0x13, 0x73,
0xc4, 0xd4, 0x11, 0x31, 0x14, 0x48, 0xbe, 0x08, 0xf2, 0xdd, 0xe5, 0x82, 0x80, 0x01, 0x75, 0xca,
0xdd, 0x7b, 0xff, 0xff, 0xef, 0xfd, 0x9f, 0x2e, 0x86, 0xc3, 0x2b, 0x72, 0x4d, 0x02, 0x52, 0xc7,
0x32, 0xe3, 0x65, 0x70, 0x7d, 0x4a, 0x99, 0x24, 0xa7, 0x41, 0xca, 0x4a, 0x26, 0x32, 0x81, 0xe7,
0x15, 0x97, 0x1c, 0xb9, 0x8d, 0x06, 0x1b, 0x0d, 0x36, 0x9a, 0x63, 0x37, 0xe5, 0x29, 0x57, 0x82,
0xa0, 0x39, 0x69, 0xed, 0xf1, 0x51, 0xca, 0x79, 0x9a, 0xb3, 0x40, 0xdd, 0x68, 0xfd, 0x36, 0x20,
0xe5, 0x72, 0xdb, 0x8a, 0xb9, 0x28, 0xb8, 0x98, 0x69, 0x8f, 0xbe, 0x98, 0x96, 0xff, 0xa7, 0x2b,
0xa9, 0x2b, 0xa2, 0xa6, 0xa9, 0xca, 0xf0, 0x13, 0x80, 0xbd, 0x73, 0x9d, 0xe9, 0x42, 0x12, 0xc9,
0xd0, 0x09, 0xbc, 0x5f, 0xb2, 0x85, 0x9c, 0x99, 0x50, 0xb3, 0x2c, 0xf1, 0xc0, 0x00, 0x8c, 0xda,
0xd1, 0x41, 0x53, 0x3e, 0xd3, 0xd5, 0x97, 0x09, 0x7a, 0x06, 0x3b, 0x73, 0x52, 0x91, 0x42, 0x78,
0x7b, 0x03, 0x30, 0xea, 0x4e, 0x1e, 0xe3, 0x7f, 0xed, 0x82, 0x5f, 0x29, 0x4d, 0xd8, 0x5e, 0xdd,
0xf6, 0x9d, 0xc8, 0x38, 0xd0, 0x14, 0xee, 0x1b, 0x9d, 0xf0, 0x5a, 0x83, 0xd6, 0xa8, 0x3b, 0x71,
0xb1, 0xce, 0x89, 0xb7, 0x39, 0xf1, 0x59, 0xb9, 0x0c, 0xd1, 0x97, 0x8f, 0xe3, 0x43, 0x93, 0xce,
0x4c, 0x8e, 0xac, 0x73, 0xf8, 0xb9, 0x05, 0x3b, 0x1a, 0x8f, 0x2e, 0xa1, 0x5b, 0x90, 0x85, 0xcd,
0xbc, 0xdd, 0x51, 0x25, 0xef, 0x4e, 0x8e, 0xfe, 0x82, 0x4f, 0x8d, 0x20, 0xdc, 0x6f, 0x72, 0x7d,
0xf8, 0xde, 0x07, 0x11, 0x2a, 0xc8, 0xc2, 0xcc, 0xd8, 0x76, 0xd1, 0x0b, 0xd8, 0xa3, 0x59, 0xb2,
0xc3, 0xed, 0xfd, 0x3f, 0xae, 0x4b, 0xb3, 0xc4, 0x72, 0xde, 0xc0, 0x87, 0x59, 0x19, 0x57, 0xac,
0x60, 0xa5, 0x9c, 0x89, 0xba, 0x9a, 0xe7, 0x75, 0xb3, 0x38, 0x18, 0xf5, 0x42, 0xdc, 0x38, 0xbe,
0xdd, 0xf6, 0x4f, 0xd2, 0x4c, 0xbe, 0xab, 0x29, 0x8e, 0x79, 0x61, 0x1e, 0xd0, 0xfc, 0x8c, 0x45,
0x72, 0x15, 0xc8, 0xe5, 0x9c, 0x09, 0x3c, 0x65, 0x71, 0xf4, 0xc0, 0x82, 0x2e, 0x34, 0x07, 0x5d,
0xc2, 0xc3, 0x1d, 0x3c, 0x61, 0x54, 0x7a, 0xed, 0x3b, 0x91, 0x0f, 0x2c, 0x65, 0xca, 0xa8, 0x44,
0x04, 0xba, 0x3b, 0x6c, 0xcc, 0xf3, 0x9c, 0x48, 0x56, 0x91, 0xdc, 0xbb, 0x77, 0x27, 0xf8, 0x23,
0xcb, 0x7a, 0x6e, 0x51, 0xe1, 0xf9, 0xea, 0xa7, 0xef, 0xac, 0xd6, 0x3e, 0xb8, 0x59, 0xfb, 0xe0,
0xc7, 0xda, 0x07, 0xef, 0x37, 0xbe, 0x73, 0xb3, 0xf1, 0x9d, 0xaf, 0x1b, 0xdf, 0x79, 0xfd, 0xe4,
0x37, 0x74, 0xf3, 0xd7, 0x1a, 0xe7, 0x84, 0x0a, 0x75, 0x0a, 0x16, 0xf6, 0xb3, 0x52, 0x13, 0x68,
0x47, 0xbd, 0xc4, 0xd3, 0x5f, 0x01, 0x00, 0x00, 0xff, 0xff, 0xa5, 0x20, 0xff, 0x87, 0x73, 0x03,
0x00, 0x00,
}
func (m *GenesisState) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *GenesisState) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if len(m.Auctions) > 0 {
for iNdEx := len(m.Auctions) - 1; iNdEx >= 0; iNdEx-- {
{
size, err := m.Auctions[iNdEx].MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintGenesis(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0x1a
}
}
{
size, err := m.Params.MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintGenesis(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0x12
if m.NextAuctionId != 0 {
i = encodeVarintGenesis(dAtA, i, uint64(m.NextAuctionId))
i--
dAtA[i] = 0x8
}
return len(dAtA) - i, nil
}
func (m *Params) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *Params) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
{
size := m.IncrementCollateral.Size()
i -= size
if _, err := m.IncrementCollateral.MarshalTo(dAtA[i:]); err != nil {
return 0, err
}
i = encodeVarintGenesis(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0x2a
{
size := m.IncrementDebt.Size()
i -= size
if _, err := m.IncrementDebt.MarshalTo(dAtA[i:]); err != nil {
return 0, err
}
i = encodeVarintGenesis(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0x22
{
size := m.IncrementSurplus.Size()
i -= size
if _, err := m.IncrementSurplus.MarshalTo(dAtA[i:]); err != nil {
return 0, err
}
i = encodeVarintGenesis(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0x1a
n2, err2 := github_com_gogo_protobuf_types.StdDurationMarshalTo(m.BidDuration, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdDuration(m.BidDuration):])
if err2 != nil {
return 0, err2
}
i -= n2
i = encodeVarintGenesis(dAtA, i, uint64(n2))
i--
dAtA[i] = 0x12
n3, err3 := github_com_gogo_protobuf_types.StdDurationMarshalTo(m.MaxAuctionDuration, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdDuration(m.MaxAuctionDuration):])
if err3 != nil {
return 0, err3
}
i -= n3
i = encodeVarintGenesis(dAtA, i, uint64(n3))
i--
dAtA[i] = 0xa
return len(dAtA) - i, nil
}
func encodeVarintGenesis(dAtA []byte, offset int, v uint64) int {
offset -= sovGenesis(v)
base := offset
for v >= 1<<7 {
dAtA[offset] = uint8(v&0x7f | 0x80)
v >>= 7
offset++
}
dAtA[offset] = uint8(v)
return base
}
func (m *GenesisState) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
if m.NextAuctionId != 0 {
n += 1 + sovGenesis(uint64(m.NextAuctionId))
}
l = m.Params.Size()
n += 1 + l + sovGenesis(uint64(l))
if len(m.Auctions) > 0 {
for _, e := range m.Auctions {
l = e.Size()
n += 1 + l + sovGenesis(uint64(l))
}
}
return n
}
func (m *Params) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
l = github_com_gogo_protobuf_types.SizeOfStdDuration(m.MaxAuctionDuration)
n += 1 + l + sovGenesis(uint64(l))
l = github_com_gogo_protobuf_types.SizeOfStdDuration(m.BidDuration)
n += 1 + l + sovGenesis(uint64(l))
l = m.IncrementSurplus.Size()
n += 1 + l + sovGenesis(uint64(l))
l = m.IncrementDebt.Size()
n += 1 + l + sovGenesis(uint64(l))
l = m.IncrementCollateral.Size()
n += 1 + l + sovGenesis(uint64(l))
return n
}
func sovGenesis(x uint64) (n int) {
return (math_bits.Len64(x|1) + 6) / 7
}
func sozGenesis(x uint64) (n int) {
return sovGenesis(uint64((x << 1) ^ uint64((int64(x) >> 63))))
}
func (m *GenesisState) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenesis
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: GenesisState: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: GenesisState: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field NextAuctionId", wireType)
}
m.NextAuctionId = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenesis
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.NextAuctionId |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Params", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenesis
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthGenesis
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthGenesis
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
if err := m.Params.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
case 3:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Auctions", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenesis
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthGenesis
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthGenesis
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Auctions = append(m.Auctions, &types.Any{})
if err := m.Auctions[len(m.Auctions)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipGenesis(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthGenesis
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *Params) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenesis
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: Params: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: Params: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field MaxAuctionDuration", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenesis
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthGenesis
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthGenesis
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
if err := github_com_gogo_protobuf_types.StdDurationUnmarshal(&m.MaxAuctionDuration, dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field BidDuration", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenesis
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthGenesis
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthGenesis
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
if err := github_com_gogo_protobuf_types.StdDurationUnmarshal(&m.BidDuration, dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
case 3:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field IncrementSurplus", wireType)
}
var byteLen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenesis
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
byteLen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if byteLen < 0 {
return ErrInvalidLengthGenesis
}
postIndex := iNdEx + byteLen
if postIndex < 0 {
return ErrInvalidLengthGenesis
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
if err := m.IncrementSurplus.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
case 4:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field IncrementDebt", wireType)
}
var byteLen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenesis
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
byteLen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if byteLen < 0 {
return ErrInvalidLengthGenesis
}
postIndex := iNdEx + byteLen
if postIndex < 0 {
return ErrInvalidLengthGenesis
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
if err := m.IncrementDebt.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
case 5:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field IncrementCollateral", wireType)
}
var byteLen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenesis
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
byteLen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if byteLen < 0 {
return ErrInvalidLengthGenesis
}
postIndex := iNdEx + byteLen
if postIndex < 0 {
return ErrInvalidLengthGenesis
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
if err := m.IncrementCollateral.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipGenesis(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthGenesis
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func skipGenesis(dAtA []byte) (n int, err error) {
l := len(dAtA)
iNdEx := 0
depth := 0
for iNdEx < l {
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowGenesis
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
wireType := int(wire & 0x7)
switch wireType {
case 0:
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowGenesis
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
iNdEx++
if dAtA[iNdEx-1] < 0x80 {
break
}
}
case 1:
iNdEx += 8
case 2:
var length int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowGenesis
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
length |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if length < 0 {
return 0, ErrInvalidLengthGenesis
}
iNdEx += length
case 3:
depth++
case 4:
if depth == 0 {
return 0, ErrUnexpectedEndOfGroupGenesis
}
depth--
case 5:
iNdEx += 4
default:
return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
}
if iNdEx < 0 {
return 0, ErrInvalidLengthGenesis
}
if depth == 0 {
return iNdEx, nil
}
}
return 0, io.ErrUnexpectedEOF
}
var (
ErrInvalidLengthGenesis = fmt.Errorf("proto: negative length found during unmarshaling")
ErrIntOverflowGenesis = fmt.Errorf("proto: integer overflow")
ErrUnexpectedEndOfGroupGenesis = fmt.Errorf("proto: unexpected end of group")
)

View File

@ -1,91 +0,0 @@
{
"auctions": [
{
"type": "auction/CollateralAuction",
"value": {
"base_auction": {
"bid": {
"amount": "0",
"denom": "bnb"
},
"bidder": "",
"end_time": "9000-01-01T00:00:00Z",
"has_received_bids": false,
"id": "3795",
"initiator": "hard",
"lot": {
"amount": "1",
"denom": "bnb"
},
"max_end_time": "9000-01-01T00:00:00Z"
},
"corresponding_debt": {
"amount": "0",
"denom": "debt"
},
"lot_returns": {
"addresses": ["kava1eevfnzkf2mt6feyttyzh6ektclauq7zlayefwf"],
"weights": ["100"]
},
"max_bid": {
"amount": "1",
"denom": "bnb"
}
}
},
{
"type": "auction/SurplusAuction",
"value": {
"base_auction": {
"bid": {
"amount": "0",
"denom": "bnb"
},
"bidder": "",
"end_time": "9000-01-01T00:00:00Z",
"has_received_bids": false,
"id": "3796",
"initiator": "hard",
"lot": {
"amount": "1",
"denom": "bnb"
},
"max_end_time": "9000-01-01T00:00:00Z"
}
}
},
{
"type": "auction/DebtAuction",
"value": {
"base_auction": {
"bid": {
"amount": "0",
"denom": "bnb"
},
"bidder": "",
"end_time": "9000-01-01T00:00:00Z",
"has_received_bids": false,
"id": "3895",
"initiator": "hard",
"lot": {
"amount": "1",
"denom": "bnb"
},
"max_end_time": "9000-01-01T00:00:00Z"
},
"corresponding_debt": {
"amount": "0",
"denom": "debt"
}
}
}
],
"next_auction_id": "12",
"params": {
"bid_duration": "600000000000",
"increment_collateral": "0.010000000000000000",
"increment_debt": "0.010000000000000000",
"increment_surplus": "0.010000000000000000",
"max_auction_duration": "172800000000000"
}
}

View File

@ -1,58 +0,0 @@
{
"next_auction_id": "12",
"params": {
"max_auction_duration": "172800s",
"bid_duration": "600s",
"increment_surplus": "0.010000000000000000",
"increment_debt": "0.010000000000000000",
"increment_collateral": "0.010000000000000000"
},
"auctions": [
{
"@type": "/kava.auction.v1beta1.CollateralAuction",
"base_auction": {
"id": "3795",
"initiator": "hard",
"lot": { "denom": "bnb", "amount": "1" },
"bidder": "",
"bid": { "denom": "bnb", "amount": "0" },
"has_received_bids": false,
"end_time": "9000-01-01T00:00:00Z",
"max_end_time": "9000-01-01T00:00:00Z"
},
"corresponding_debt": { "denom": "debt", "amount": "0" },
"max_bid": { "denom": "bnb", "amount": "1" },
"lot_returns": {
"addresses": ["kava1eevfnzkf2mt6feyttyzh6ektclauq7zlayefwf"],
"weights": ["100"]
}
},
{
"@type": "/kava.auction.v1beta1.SurplusAuction",
"base_auction": {
"id": "3796",
"initiator": "hard",
"lot": { "denom": "bnb", "amount": "1" },
"bidder": "",
"bid": { "denom": "bnb", "amount": "0" },
"has_received_bids": false,
"end_time": "9000-01-01T00:00:00Z",
"max_end_time": "9000-01-01T00:00:00Z"
}
},
{
"@type": "/kava.auction.v1beta1.DebtAuction",
"base_auction": {
"id": "3895",
"initiator": "hard",
"lot": { "denom": "bnb", "amount": "1" },
"bidder": "",
"bid": { "denom": "bnb", "amount": "0" },
"has_received_bids": false,
"end_time": "9000-01-01T00:00:00Z",
"max_end_time": "9000-01-01T00:00:00Z"
},
"corresponding_debt": { "denom": "debt", "amount": "0" }
}
]
}

View File

@ -1,25 +0,0 @@
package v0_17
import (
v016auction "github.com/0glabs/0g-chain/x/auction/legacy/v0_16"
v017auction "github.com/0glabs/0g-chain/x/auction/types"
)
func Migrate(oldState v016auction.GenesisState) *v017auction.GenesisState {
return &v017auction.GenesisState{
NextAuctionId: oldState.NextAuctionId,
Params: migrateParams(oldState.Params),
Auctions: oldState.Auctions,
}
}
func migrateParams(params v016auction.Params) v017auction.Params {
return v017auction.Params{
MaxAuctionDuration: params.MaxAuctionDuration,
ForwardBidDuration: v017auction.DefaultForwardBidDuration,
ReverseBidDuration: v017auction.DefaultReverseBidDuration,
IncrementSurplus: params.IncrementSurplus,
IncrementDebt: params.IncrementDebt,
IncrementCollateral: params.IncrementCollateral,
}
}

View File

@ -1,139 +0,0 @@
package auction
import (
"context"
"encoding/json"
"github.com/grpc-ecosystem/grpc-gateway/runtime"
"github.com/spf13/cobra"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/codec"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/module"
abci "github.com/cometbft/cometbft/abci/types"
"github.com/0glabs/0g-chain/x/auction/client/cli"
"github.com/0glabs/0g-chain/x/auction/keeper"
"github.com/0glabs/0g-chain/x/auction/types"
)
var (
_ module.AppModule = AppModule{}
_ module.AppModuleBasic = AppModuleBasic{}
)
// AppModuleBasic implements the sdk.AppModuleBasic interface.
type AppModuleBasic struct{}
// Name returns the module name.
func (AppModuleBasic) Name() string {
return types.ModuleName
}
// RegisterLegacyAminoCodec register module codec
func (AppModuleBasic) RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) {
types.RegisterLegacyAminoCodec(cdc)
}
// DefaultGenesis default genesis state
func (AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage {
return cdc.MustMarshalJSON(types.DefaultGenesisState())
}
// ValidateGenesis module validate genesis
func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, config client.TxEncodingConfig, bz json.RawMessage) error {
var gs types.GenesisState
err := cdc.UnmarshalJSON(bz, &gs)
if err != nil {
return err
}
return gs.Validate()
}
// RegisterInterfaces implements InterfaceModule.RegisterInterfaces
func (a AppModuleBasic) RegisterInterfaces(registry codectypes.InterfaceRegistry) {
types.RegisterInterfaces(registry)
}
// RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the gov module.
func (a AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux) {
types.RegisterQueryHandlerClient(context.Background(), mux, types.NewQueryClient(clientCtx))
}
// GetTxCmd returns the root tx command for the swap module.
func (AppModuleBasic) GetTxCmd() *cobra.Command {
return cli.GetTxCmd()
}
// GetQueryCmd returns no root query command for the swap module.
func (AppModuleBasic) GetQueryCmd() *cobra.Command {
return cli.GetQueryCmd()
}
//____________________________________________________________________________
// AppModule implements the sdk.AppModule interface.
type AppModule struct {
AppModuleBasic
keeper keeper.Keeper
accountKeeper types.AccountKeeper
bankKeeper types.BankKeeper
}
// NewAppModule creates a new AppModule object
func NewAppModule(keeper keeper.Keeper, accountKeeper types.AccountKeeper, bankKeeper types.BankKeeper) AppModule {
return AppModule{
AppModuleBasic: AppModuleBasic{},
keeper: keeper,
accountKeeper: accountKeeper,
bankKeeper: bankKeeper,
}
}
// Name module name
func (AppModule) Name() string {
return types.ModuleName
}
// RegisterInvariants register module invariants
func (AppModule) RegisterInvariants(_ sdk.InvariantRegistry) {}
// ConsensusVersion implements AppModule/ConsensusVersion.
func (AppModule) ConsensusVersion() uint64 {
return 1
}
// RegisterServices registers module services.
func (am AppModule) RegisterServices(cfg module.Configurator) {
types.RegisterMsgServer(cfg.MsgServer(), keeper.NewMsgServerImpl(am.keeper))
types.RegisterQueryServer(cfg.QueryServer(), keeper.NewQueryServerImpl(am.keeper))
}
// InitGenesis module init-genesis
func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, gs json.RawMessage) []abci.ValidatorUpdate {
var genState types.GenesisState
cdc.MustUnmarshalJSON(gs, &genState)
InitGenesis(ctx, am.keeper, am.bankKeeper, am.accountKeeper, &genState)
return []abci.ValidatorUpdate{}
}
// ExportGenesis module export genesis
func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.RawMessage {
gs := ExportGenesis(ctx, am.keeper)
return cdc.MustMarshalJSON(gs)
}
// BeginBlock module begin-block
func (am AppModule) BeginBlock(ctx sdk.Context, _ abci.RequestBeginBlock) {
BeginBlocker(ctx, am.keeper)
}
// EndBlock module end-block
func (am AppModule) EndBlock(_ sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate {
return []abci.ValidatorUpdate{}
}

View File

@ -1,13 +0,0 @@
<!--
order: 1
-->
# Concepts
Auctions are broken down into three distinct types, which correspond to three specific functionalities within the CDP system.
* **Surplus Auction:** An auction in which a fixed lot of coins (c1) is sold for increasing amounts of other coins (c2). Bidders increment the amount of c2 they are willing to pay for the lot of c1. After the completion of a surplus auction, the winning bid of c2 is burned, and the bidder receives the lot of c1. As a concrete example, surplus auction are used to sell a fixed amount of USDX stable coins in exchange for increasing bids of KAVA governance tokens. The governance tokens are then burned and the winner receives USDX.
* **Debt Auction:** An auction in which a fixed amount of coins (c1) is bid for a decreasing lot of other coins (c2). Bidders decrement the lot of c2 they are willing to receive for the fixed amount of c1. As a concrete example, debt auctions are used to raise a certain amount of USDX stable coins in exchange for decreasing lots of KAVA governance tokens. The USDX tokens are used to recapitalize the cdp system and the winner receives KAVA.
* **Surplus Reverse Auction:** Are two phase auction is which a fixed lot of coins (c1) is sold for increasing amounts of other coins (c2). Bidders increment the amount of c2 until a specific `maxBid` is reached. Once `maxBid` is reached, a fixed amount of c2 is bid for a decreasing lot of c1. In the second phase, bidders decrement the lot of c1 they are willing to receive for a fixed amount of c2. As a concrete example, collateral auctions are used to sell collateral (ATOM, for example) for up to a `maxBid` amount of USDX. The USDX tokens are used to recapitalize the cdp system and the winner receives the specified lot of ATOM. In the event that the winning lot is smaller than the total lot, the excess ATOM is ratably returned to the original owners of the liquidated CDPs that were collateralized with that ATOM.
Auctions are always initiated by another module, and not directly by users. Auctions start with an expiry, the time at which the auction is guaranteed to end, even if there have been no bidders. After each bid, the auction is extended by a specific amount of time, `BidDuration`. In the case that increasing the auction time by `BidDuration` would cause the auction to go past its expiry, the expiry is chosen as the ending time.

View File

@ -1,82 +0,0 @@
<!--
order: 2
-->
# State
## Parameters and genesis state
`parameters` define the rules according to which auctions are run. There is only one active parameter set at any given time. Updates to the parameter set can be made via on-chain parameter update proposals.
```go
// Params governance parameters for auction module
type Params struct {
MaxAuctionDuration time.Duration `json:"max_auction_duration" yaml:"max_auction_duration"` // max length of auction
MaxBidDuration time.Duration `json:"max_bid_duration" yaml:"max_bid_duration"` // additional time added to the auction end time after each bid, capped by the expiry.
IncrementSurplus sdk.Dec `json:"increment_surplus" yaml:"increment_surplus"` // percentage change (of auc.Bid) required for a new bid on a surplus auction
IncrementDebt sdk.Dec `json:"increment_debt" yaml:"increment_debt"` // percentage change (of auc.Lot) required for a new bid on a debt auction
IncrementCollateral sdk.Dec `json:"increment_collateral" yaml:"increment_collateral"` // percentage change (of auc.Bid or auc.Lot) required for a new bid on a collateral auction
}
```
`GenesisState` defines the state that must be persisted when the blockchain stops/restarts in order for normal function of the auction module to resume.
```go
// GenesisState - auction state that must be provided at genesis
type GenesisState struct {
NextAuctionID uint64 `json:"next_auction_id" yaml:"next_auction_id"` // auctionID that will be used for the next created auction
Params Params `json:"auction_params" yaml:"auction_params"` // auction params
Auctions Auctions `json:"genesis_auctions" yaml:"genesis_auctions"` // auctions currently in the store
}
```
## Base types
```go
// Auction is an interface to several types of auction.
type Auction interface {
GetID() uint64
WithID(uint64) Auction
GetEndTime() time.Time
}
// BaseAuction is a common type shared by all Auctions.
type BaseAuction struct {
ID uint64
Initiator string // Module name that starts the auction. Pays out Lot.
Lot sdk.Coin // Coins that will paid out by Initiator to the winning bidder.
Bidder sdk.AccAddress // Latest bidder. Receiver of Lot.
Bid sdk.Coin // Coins paid into the auction the bidder.
EndTime time.Time // Current auction closing time. Triggers at the end of the block with time ≥ EndTime.
MaxEndTime time.Time // Maximum closing time. Auctions can close before this but never after.
}
// SurplusAuction is a forward auction that burns what it receives from bids.
// It is normally used to sell off excess pegged asset acquired by the CDP system.
type SurplusAuction struct {
BaseAuction
}
// DebtAuction is a reverse auction that mints what it pays out.
// It is normally used to acquire pegged asset to cover the CDP system's debts that were not covered by selling collateral.
type DebtAuction struct {
BaseAuction
}
// WeightedAddresses is a type for storing some addresses and associated weights.
type WeightedAddresses struct {
Addresses []sdk.AccAddress
Weights []sdkmath.Int
}
// CollateralAuction is a two phase auction.
// Initially, in forward auction phase, bids can be placed up to a max bid.
// Then it switches to a reverse auction phase, where the initial amount up for auction is bid down.
// Unsold Lot is sent to LotReturns, being divided among the addresses by weight.
// Collateral auctions are normally used to sell off collateral seized from CDPs.
type CollateralAuction struct {
BaseAuction
MaxBid sdk.Coin
LotReturns WeightedAddresses
}
```

View File

@ -1,36 +0,0 @@
<!--
order: 3
-->
# Messages
## Bidding
Users can bid on auctions using the `MsgPlaceBid` message type. All auction types can be bid on using the same message type.
```go
// MsgPlaceBid is the message type used to place a bid on any type of auction.
type MsgPlaceBid struct {
AuctionID uint64
Bidder sdk.AccAddress
Amount sdk.Coin
}
```
**State Modifications:**
* Update bidder if different than previous bidder
* For Surplus auctions:
* Update Bid to msg.Amount
* Return bid coins to previous bidder
* Burn coins equal to the increment in the bid (CurrentBid - PreviousBid)
* For Debt auctions:
* Update Lot amount to msg.Amount
* Return bid coins to previous bidder
* For Collateral auctions:
* Return bid coins to previous bidder
* If in forward phase:
* Update Bid amount to msg.Amount
* If in reverse phase:
* Update Lot amount to msg.Amount
* Extend auction by `BidDuration`, up to `MaxEndTime`

View File

@ -1,38 +0,0 @@
<!--
order: 4
-->
# Events
The `x/auction` module emits the following events:
## Triggered By Other Modules
| Type | Attribute Key | Attribute Value |
|---------------|---------------|-------------------|
| auction_start | auction_id | `{auction ID}` |
| auction_start | auction_type | `{auction type}` |
| auction_start | lot | `{coin amount}` |
| auction_start | bid | `{coin amount}` |
| auction_start | max_bid | `{coin amount}` |
## Handlers
### MsgPlaceBid
| Type | Attribute Key | Attribute Value |
|-------------|---------------|----------------------|
| auction_bid | auction_id | `{auction ID}` |
| auction_bid | bidder | `{latest bidder}` |
| auction_bid | bid | `{coin amount}` |
| auction_bid | lot | `{coin amount}` |
| auction_bid | end_time | `{auction end time}` |
| message | module | auction |
| message | sender | `{sender address}` |
## BeginBlock
| Type | Attribute Key | Attribute Value |
|---------------|---------------|-------------------|
| auction_close | auction_id | `{auction ID}` |
| auction_close | close_block | `{block height}` |

View File

@ -1,15 +0,0 @@
<!--
order: 5
-->
# Parameters
The auction module contains the following parameters:
| Key | Type | Example | Description |
|---------------------|------------------------|------------------------|---------------------------------------------------------------------------------------|
| MaxAuctionDuration | string (time.Duration) | "48h0m0s" | |
| BidDuration | string (time.Duration) | "3h0m0s" | |
| IncrementSurplus | string (dec) | "0.050000000000000000" | percentage change in bid required for a new bid on a surplus auction |
| IncrementDebt | string (dec) | "0.050000000000000000" | percentage change in lot required for a new bid on a debt auction |
| IncrementCollateral | string (dec) | "0.050000000000000000" | percentage change in either bid or lot required for a new bid on a collateral auction |

View File

@ -1,22 +0,0 @@
<!--
order: 6
-->
# Begin Block
At the start of each block, auctions that have reached `EndTime` are closed. The logic to close auctions is as follows:
```go
var expiredAuctions []uint64
k.IterateAuctionsByTime(ctx, ctx.BlockTime(), func(id uint64) bool {
expiredAuctions = append(expiredAuctions, id)
return false
})
for _, id := range expiredAuctions {
err := k.CloseAuction(ctx, id)
if err != nil {
panic(err)
}
}
```

View File

@ -1,20 +0,0 @@
<!--
order: 0
title: "Auction Overview"
parent:
title: "auction"
-->
# `auction`
<!-- TOC -->
1. **[Concepts](01_concepts.md)**
2. **[State](02_state.md)**
3. **[Messages](03_messages.md)**
4. **[Events](04_events.md)**
5. **[Params](05_params.md)**
6. **[BeginBlock](06_begin_block.md)**
## Abstract
`x/auction` is an implementation of a Cosmos SDK Module that handles the creation, bidding, and payout of 3 distinct auction types. All auction types implement the `Auction` interface. Each auction type is used at different points during the normal functioning of the CDP system.

View File

@ -1,92 +0,0 @@
package testutil
import (
"github.com/stretchr/testify/suite"
sdkmath "cosmossdk.io/math"
sdk "github.com/cosmos/cosmos-sdk/types"
tmproto "github.com/cometbft/cometbft/proto/tendermint/types"
tmtime "github.com/cometbft/cometbft/types/time"
authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper"
"github.com/0glabs/0g-chain/app"
"github.com/0glabs/0g-chain/x/auction/keeper"
"github.com/0glabs/0g-chain/x/auction/types"
)
// Suite implements a test suite for the kavadist module integration tests
type Suite struct {
suite.Suite
Keeper keeper.Keeper
BankKeeper bankkeeper.Keeper
AccountKeeper authkeeper.AccountKeeper
App app.TestApp
Ctx sdk.Context
Addrs []sdk.AccAddress
ModAcc *authtypes.ModuleAccount
}
// SetupTest instantiates a new app, keepers, and sets suite state
func (suite *Suite) SetupTest(numAddrs int) {
config := sdk.GetConfig()
app.SetBech32AddressPrefixes(config)
tApp := app.NewTestApp()
_, addrs := app.GeneratePrivKeyAddressPairs(numAddrs)
// Fund liquidator module account
coins := sdk.NewCoins(
sdk.NewCoin("token1", sdkmath.NewInt(100)),
sdk.NewCoin("token2", sdkmath.NewInt(100)),
)
ctx := tApp.NewContext(true, tmproto.Header{Height: 1, Time: tmtime.Now()})
modName := "liquidator"
modBaseAcc := authtypes.NewBaseAccount(authtypes.NewModuleAddress(modName), nil, 0, 0)
modAcc := authtypes.NewModuleAccount(modBaseAcc, modName, []string{authtypes.Minter, authtypes.Burner}...)
suite.ModAcc = modAcc
authGS := app.NewFundedGenStateWithSameCoinsWithModuleAccount(tApp.AppCodec(), coins, addrs, modAcc)
params := types.NewParams(
types.DefaultMaxAuctionDuration,
types.DefaultForwardBidDuration,
types.DefaultReverseBidDuration,
types.DefaultIncrement,
types.DefaultIncrement,
types.DefaultIncrement,
)
auctionGs, err := types.NewGenesisState(types.DefaultNextAuctionID, params, []types.GenesisAuction{})
suite.Require().NoError(err)
moduleGs := tApp.AppCodec().MustMarshalJSON(auctionGs)
gs := app.GenesisState{types.ModuleName: moduleGs}
tApp.InitializeFromGenesisStates(authGS, gs)
suite.App = tApp
suite.Ctx = ctx
suite.Addrs = addrs
suite.Keeper = tApp.GetAuctionKeeper()
suite.BankKeeper = tApp.GetBankKeeper()
suite.AccountKeeper = tApp.GetAccountKeeper()
}
// AddCoinsToModule adds coins to a named module account
func (suite *Suite) AddCoinsToNamedModule(moduleName string, amount sdk.Coins) {
// Does not use suite.BankKeeper.MintCoins as module account would not have permission to mint
err := suite.App.FundModuleAccount(suite.Ctx, moduleName, amount)
suite.Require().NoError(err)
}
// CheckAccountBalanceEqual asserts that
func (suite *Suite) CheckAccountBalanceEqual(owner sdk.AccAddress, expectedCoins sdk.Coins) {
balances := suite.BankKeeper.GetAllBalances(suite.Ctx, owner)
suite.Equal(expectedCoins, balances)
}

File diff suppressed because it is too large Load Diff

View File

@ -1,291 +0,0 @@
package types
import (
"errors"
"fmt"
"strings"
"time"
sdkmath "cosmossdk.io/math"
sdk "github.com/cosmos/cosmos-sdk/types"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
"github.com/cosmos/gogoproto/proto"
)
const (
CollateralAuctionType = "collateral"
SurplusAuctionType = "surplus"
DebtAuctionType = "debt"
ForwardAuctionPhase = "forward"
ReverseAuctionPhase = "reverse"
)
// DistantFuture is a very large time value to use as initial the ending time for auctions.
// It is not set to the max time supported. This can cause problems with time comparisons, see https://stackoverflow.com/a/32620397.
// Also amino panics when encoding times ≥ the start of year 10000.
var DistantFuture = time.Date(9000, 1, 1, 0, 0, 0, 0, time.UTC)
var (
_ Auction = &SurplusAuction{}
_ GenesisAuction = &SurplusAuction{}
_ Auction = &DebtAuction{}
_ GenesisAuction = &DebtAuction{}
_ Auction = &CollateralAuction{}
_ GenesisAuction = &CollateralAuction{}
)
// --------------- Shared auction functionality ---------------
// Auction is an interface for handling common actions on auctions.
type Auction interface {
proto.Message
GetID() uint64
WithID(uint64) Auction
GetInitiator() string
GetLot() sdk.Coin
GetBidder() sdk.AccAddress
GetBid() sdk.Coin
GetEndTime() time.Time
GetMaxEndTime() time.Time
GetType() string
GetPhase() string
}
// --------------- BaseAuction ---------------
func (a BaseAuction) GetID() uint64 { return a.ID }
func (a BaseAuction) GetBid() sdk.Coin { return a.Bid }
func (a BaseAuction) GetLot() sdk.Coin { return a.Lot }
func (a BaseAuction) GetBidder() sdk.AccAddress { return a.Bidder }
func (a BaseAuction) GetInitiator() string { return a.Initiator }
func (a BaseAuction) GetEndTime() time.Time { return a.EndTime }
func (a BaseAuction) GetMaxEndTime() time.Time { return a.MaxEndTime }
// ValidateAuction verifies that the auction end time is before max end time
func ValidateAuction(a Auction) error {
// ID can be 0 for surplus, debt and collateral auctions
if strings.TrimSpace(a.GetInitiator()) == "" {
return errors.New("auction initiator cannot be blank")
}
if !a.GetLot().IsValid() {
return fmt.Errorf("invalid lot: %s", a.GetLot())
}
if !a.GetBid().IsValid() {
return fmt.Errorf("invalid bid: %s", a.GetBid())
}
if a.GetEndTime().Unix() <= 0 || a.GetMaxEndTime().Unix() <= 0 {
return errors.New("end time cannot be zero")
}
if a.GetEndTime().After(a.GetMaxEndTime()) {
return fmt.Errorf("MaxEndTime < EndTime (%s < %s)", a.GetMaxEndTime(), a.GetEndTime())
}
return nil
}
// --------------- SurplusAuction ---------------
// NewSurplusAuction returns a new surplus auction.
func NewSurplusAuction(seller string, lot sdk.Coin, bidDenom string, endTime time.Time) SurplusAuction {
auction := SurplusAuction{
BaseAuction: BaseAuction{
// No Id
Initiator: seller,
Lot: lot,
Bidder: nil,
Bid: sdk.NewInt64Coin(bidDenom, 0),
HasReceivedBids: false, // new auctions don't have any bids
EndTime: endTime,
MaxEndTime: endTime,
},
}
return auction
}
func (a SurplusAuction) WithID(id uint64) Auction {
a.ID = id
return Auction(&a)
}
// GetPhase returns the direction of a surplus auction, which never changes.
func (a SurplusAuction) GetPhase() string { return ForwardAuctionPhase }
// GetType returns the auction type. Used to identify auctions in event attributes.
func (a SurplusAuction) GetType() string { return SurplusAuctionType }
// GetModuleAccountCoins returns the total number of coins held in the module account for this auction.
// It is used in genesis initialize the module account correctly.
func (a SurplusAuction) GetModuleAccountCoins() sdk.Coins {
// a.Bid is paid out on bids, so is never stored in the module account
return sdk.NewCoins(a.Lot)
}
func (a SurplusAuction) Validate() error {
return ValidateAuction(&a)
}
// --------------- DebtAuction ---------------
// NewDebtAuction returns a new debt auction.
func NewDebtAuction(buyerModAccName string, bid sdk.Coin, initialLot sdk.Coin, endTime time.Time, debt sdk.Coin) DebtAuction {
// Note: Bidder is set to the initiator's module account address instead of module name. (when the first bid is placed, it is paid out to the initiator)
// Setting to the module account address bypasses calling supply.SendCoinsFromModuleToModule, instead calls SendCoinsFromModuleToAccount.
// This isn't a problem currently, but if additional logic/validation was added for sending to coins to Module Accounts, it would be bypassed.
auction := DebtAuction{
BaseAuction: BaseAuction{
// no ID
Initiator: buyerModAccName,
Lot: initialLot,
Bidder: authtypes.NewModuleAddress(buyerModAccName), // send proceeds from the first bid to the buyer.
Bid: bid, // amount that the buyer is buying - doesn't change over course of auction
HasReceivedBids: false, // new auctions don't have any bids
EndTime: endTime,
MaxEndTime: endTime,
},
CorrespondingDebt: debt,
}
return auction
}
func (a DebtAuction) WithID(id uint64) Auction {
a.ID = id
return Auction(&a)
}
// GetPhase returns the direction of a debt auction, which never changes.
func (a DebtAuction) GetPhase() string { return ReverseAuctionPhase }
// GetType returns the auction type. Used to identify auctions in event attributes.
func (a DebtAuction) GetType() string { return DebtAuctionType }
// GetModuleAccountCoins returns the total number of coins held in the module account for this auction.
// It is used in genesis initialize the module account correctly.
func (a DebtAuction) GetModuleAccountCoins() sdk.Coins {
// a.Lot is minted at auction close, so is never stored in the module account
// a.Bid is paid out on bids, so is never stored in the module account
return sdk.NewCoins(a.CorrespondingDebt)
}
// Validate validates the DebtAuction fields values.
func (a DebtAuction) Validate() error {
if !a.CorrespondingDebt.IsValid() {
return fmt.Errorf("invalid corresponding debt: %s", a.CorrespondingDebt)
}
return ValidateAuction(&a)
}
// --------------- CollateralAuction ---------------
// NewCollateralAuction returns a new collateral auction.
func NewCollateralAuction(seller string, lot sdk.Coin, endTime time.Time, maxBid sdk.Coin, lotReturns WeightedAddresses, debt sdk.Coin) CollateralAuction {
auction := CollateralAuction{
BaseAuction: BaseAuction{
// no ID
Initiator: seller,
Lot: lot,
Bidder: nil,
Bid: sdk.NewInt64Coin(maxBid.Denom, 0),
HasReceivedBids: false, // new auctions don't have any bids
EndTime: endTime,
MaxEndTime: endTime,
},
CorrespondingDebt: debt,
MaxBid: maxBid,
LotReturns: lotReturns,
}
return auction
}
func (a CollateralAuction) WithID(id uint64) Auction {
a.ID = id
return Auction(&a)
}
// GetType returns the auction type. Used to identify auctions in event attributes.
func (a CollateralAuction) GetType() string { return CollateralAuctionType }
// IsReversePhase returns whether the auction has switched over to reverse phase or not.
// CollateralAuctions initially start in forward phase.
func (a CollateralAuction) IsReversePhase() bool {
return a.Bid.IsEqual(a.MaxBid)
}
// GetPhase returns the direction of a collateral auction.
func (a CollateralAuction) GetPhase() string {
if a.IsReversePhase() {
return ReverseAuctionPhase
}
return ForwardAuctionPhase
}
// GetLotReturns returns the auction's lot returns as weighted addresses
func (a CollateralAuction) GetLotReturns() WeightedAddresses { return a.LotReturns }
// GetModuleAccountCoins returns the total number of coins held in the module account for this auction.
// It is used in genesis initialize the module account correctly.
func (a CollateralAuction) GetModuleAccountCoins() sdk.Coins {
// a.Bid is paid out on bids, so is never stored in the module account
return sdk.NewCoins(a.Lot).Add(sdk.NewCoins(a.CorrespondingDebt)...)
}
// Validate validates the CollateralAuction fields values.
func (a CollateralAuction) Validate() error {
if !a.CorrespondingDebt.IsValid() {
return fmt.Errorf("invalid corresponding debt: %s", a.CorrespondingDebt)
}
if !a.MaxBid.IsValid() {
return fmt.Errorf("invalid max bid: %s", a.MaxBid)
}
if err := a.LotReturns.Validate(); err != nil {
return fmt.Errorf("invalid lot returns: %w", err)
}
return ValidateAuction(&a)
}
// NewWeightedAddresses returns a new list addresses with weights.
func NewWeightedAddresses(addrs []sdk.AccAddress, weights []sdkmath.Int) (WeightedAddresses, error) {
wa := WeightedAddresses{
Addresses: addrs,
Weights: weights,
}
if err := wa.Validate(); err != nil {
return WeightedAddresses{}, err
}
return wa, nil
}
// Validate checks for that the weights are not negative, not all zero, and the lengths match.
func (wa WeightedAddresses) Validate() error {
if len(wa.Weights) < 1 {
return fmt.Errorf("must be at least 1 weighted address")
}
if len(wa.Addresses) != len(wa.Weights) {
return fmt.Errorf("number of addresses doesn't match number of weights, %d ≠ %d", len(wa.Addresses), len(wa.Weights))
}
totalWeight := sdk.ZeroInt()
for i := range wa.Addresses {
if wa.Addresses[i].Empty() {
return fmt.Errorf("address %d cannot be empty", i)
}
if wa.Weights[i].IsNegative() {
return fmt.Errorf("weight %d contains a negative amount: %s", i, wa.Weights[i])
}
totalWeight = totalWeight.Add(wa.Weights[i])
}
if !totalWeight.IsPositive() {
return fmt.Errorf("total weight must be positive")
}
return nil
}

View File

@ -1,356 +0,0 @@
package types
import (
"testing"
"time"
"github.com/stretchr/testify/require"
sdkmath "cosmossdk.io/math"
sdk "github.com/cosmos/cosmos-sdk/types"
)
const (
TestInitiatorModuleName = "liquidator"
TestLotDenom = "usdx"
TestLotAmount = 100
TestBidDenom = "kava"
TestBidAmount = 20
TestDebtDenom = "debt"
TestDebtAmount1 = 20
TestDebtAmount2 = 15
TestExtraEndTime = 10000
TestAuctionID = 9999123
testAccAddress1 = "kava1qcfdf69js922qrdr4yaww3ax7gjml6pd39p8lj"
testAccAddress2 = "kava1pdfav2cjhry9k79nu6r8kgknnjtq6a7rcr0qlr"
)
func init() {
sdk.GetConfig().SetBech32PrefixForAccount("kava", "kava"+sdk.PrefixPublic)
}
func d(amount string) sdk.Dec { return sdk.MustNewDecFromStr(amount) }
func c(denom string, amount int64) sdk.Coin { return sdk.NewInt64Coin(denom, amount) }
func i(n int64) sdkmath.Int { return sdkmath.NewInt(n) }
func is(ns ...int64) (is []sdkmath.Int) {
for _, n := range ns {
is = append(is, sdkmath.NewInt(n))
}
return
}
func TestNewWeightedAddresses(t *testing.T) {
addr1, err := sdk.AccAddressFromBech32(testAccAddress1)
require.NoError(t, err)
addr2, err := sdk.AccAddressFromBech32(testAccAddress2)
require.NoError(t, err)
tests := []struct {
name string
addresses []sdk.AccAddress
weights []sdkmath.Int
expPass bool
}{
{
"normal",
[]sdk.AccAddress{addr1, addr2},
[]sdkmath.Int{sdkmath.NewInt(6), sdkmath.NewInt(8)},
true,
},
{
"empty address",
[]sdk.AccAddress{nil, nil},
[]sdkmath.Int{sdkmath.NewInt(6), sdkmath.NewInt(8)},
false,
},
{
"mismatched",
[]sdk.AccAddress{addr1, addr2},
[]sdkmath.Int{sdkmath.NewInt(6)},
false,
},
{
"negative weight",
[]sdk.AccAddress{addr1, addr2},
is(6, -8),
false,
},
{
"zero weight",
[]sdk.AccAddress{addr1, addr2},
is(0, 0),
false,
},
}
// Run NewWeightedAdresses tests
for _, tc := range tests {
// Attempt to instantiate new WeightedAddresses
weightedAddresses, err := NewWeightedAddresses(tc.addresses, tc.weights)
if tc.expPass {
require.NoError(t, err)
require.Equal(t, tc.addresses, weightedAddresses.Addresses)
require.Equal(t, tc.weights, weightedAddresses.Weights)
} else {
require.Error(t, err)
}
}
}
func TestDebtAuctionValidate(t *testing.T) {
addr1, err := sdk.AccAddressFromBech32(testAccAddress1)
require.NoError(t, err)
now := time.Now()
tests := []struct {
msg string
auction DebtAuction
expPass bool
}{
{
"valid auction",
DebtAuction{
BaseAuction: BaseAuction{
ID: 1,
Initiator: testAccAddress1,
Lot: c("kava", 1),
Bidder: addr1,
Bid: c("kava", 1),
EndTime: now,
MaxEndTime: now,
HasReceivedBids: true,
},
CorrespondingDebt: c("kava", 1),
},
true,
},
{
"invalid corresponding debt",
DebtAuction{
BaseAuction: BaseAuction{
ID: 1,
Initiator: testAccAddress1,
Lot: c("kava", 1),
Bidder: addr1,
Bid: c("kava", 1),
EndTime: now,
MaxEndTime: now,
HasReceivedBids: true,
},
CorrespondingDebt: sdk.Coin{Denom: "", Amount: sdkmath.NewInt(1)},
},
false,
},
}
for _, tc := range tests {
err := tc.auction.Validate()
if tc.expPass {
require.NoError(t, err, tc.msg)
} else {
require.Error(t, err, tc.msg)
}
}
}
func TestCollateralAuctionValidate(t *testing.T) {
addr1, err := sdk.AccAddressFromBech32(testAccAddress1)
require.NoError(t, err)
now := time.Now()
tests := []struct {
msg string
auction CollateralAuction
expPass bool
}{
{
"valid auction",
CollateralAuction{
BaseAuction: BaseAuction{
ID: 1,
Initiator: testAccAddress1,
Lot: c("kava", 1),
Bidder: addr1,
Bid: c("kava", 1),
EndTime: now,
MaxEndTime: now,
HasReceivedBids: true,
},
CorrespondingDebt: c("kava", 1),
MaxBid: c("kava", 1),
LotReturns: WeightedAddresses{
Addresses: []sdk.AccAddress{addr1},
Weights: []sdkmath.Int{sdkmath.NewInt(1)},
},
},
true,
},
{
"invalid corresponding debt",
CollateralAuction{
BaseAuction: BaseAuction{
ID: 1,
Initiator: testAccAddress1,
Lot: c("kava", 1),
Bidder: addr1,
Bid: c("kava", 1),
EndTime: now,
MaxEndTime: now,
HasReceivedBids: true,
},
CorrespondingDebt: sdk.Coin{Denom: "DENOM", Amount: sdkmath.NewInt(1)},
},
false,
},
{
"invalid max bid",
CollateralAuction{
BaseAuction: BaseAuction{
ID: 1,
Initiator: testAccAddress1,
Lot: c("kava", 1),
Bidder: addr1,
Bid: c("kava", 1),
EndTime: now,
MaxEndTime: now,
HasReceivedBids: true,
},
CorrespondingDebt: c("kava", 1),
MaxBid: sdk.Coin{Denom: "DENOM", Amount: sdkmath.NewInt(1)},
},
false,
},
{
"invalid lot returns",
CollateralAuction{
BaseAuction: BaseAuction{
ID: 1,
Initiator: testAccAddress1,
Lot: c("kava", 1),
Bidder: addr1,
Bid: c("kava", 1),
EndTime: now,
MaxEndTime: now,
HasReceivedBids: true,
},
CorrespondingDebt: c("kava", 1),
MaxBid: c("kava", 1),
LotReturns: WeightedAddresses{
Addresses: []sdk.AccAddress{nil},
Weights: []sdkmath.Int{sdkmath.NewInt(1)},
},
},
false,
},
}
for _, tc := range tests {
err := tc.auction.Validate()
if tc.expPass {
require.NoError(t, err, tc.msg)
} else {
require.Error(t, err, tc.msg)
}
}
}
func TestBaseAuctionGetters(t *testing.T) {
endTime := time.Now().Add(TestExtraEndTime)
// Create a new BaseAuction (via SurplusAuction)
auction := NewSurplusAuction(
TestInitiatorModuleName,
c(TestLotDenom, TestLotAmount),
TestBidDenom, endTime,
)
auctionID := auction.GetID()
auctionBid := auction.GetBid()
auctionLot := auction.GetLot()
auctionEndTime := auction.GetEndTime()
require.Equal(t, auction.ID, auctionID)
require.Equal(t, auction.Bid, auctionBid)
require.Equal(t, auction.Lot, auctionLot)
require.Equal(t, auction.EndTime, auctionEndTime)
}
func TestNewSurplusAuction(t *testing.T) {
endTime := time.Now().Add(TestExtraEndTime)
// Create a new SurplusAuction
surplusAuction := NewSurplusAuction(
TestInitiatorModuleName,
c(TestLotDenom, TestLotAmount),
TestBidDenom, endTime,
)
require.Equal(t, surplusAuction.Initiator, TestInitiatorModuleName)
require.Equal(t, surplusAuction.Lot, c(TestLotDenom, TestLotAmount))
require.Equal(t, surplusAuction.Bid, c(TestBidDenom, 0))
require.Equal(t, surplusAuction.EndTime, endTime)
require.Equal(t, surplusAuction.MaxEndTime, endTime)
}
func TestNewDebtAuction(t *testing.T) {
endTime := time.Now().Add(TestExtraEndTime)
// Create a new DebtAuction
debtAuction := NewDebtAuction(
TestInitiatorModuleName,
c(TestBidDenom, TestBidAmount),
c(TestLotDenom, TestLotAmount),
endTime,
c(TestDebtDenom, TestDebtAmount1),
)
require.Equal(t, debtAuction.Initiator, TestInitiatorModuleName)
require.Equal(t, debtAuction.Lot, c(TestLotDenom, TestLotAmount))
require.Equal(t, debtAuction.Bid, c(TestBidDenom, TestBidAmount))
require.Equal(t, debtAuction.EndTime, endTime)
require.Equal(t, debtAuction.MaxEndTime, endTime)
require.Equal(t, debtAuction.CorrespondingDebt, c(TestDebtDenom, TestDebtAmount1))
}
func TestNewCollateralAuction(t *testing.T) {
// Set up WeightedAddresses
addresses := []sdk.AccAddress{
sdk.AccAddress([]byte(testAccAddress1)),
sdk.AccAddress([]byte(testAccAddress2)),
}
weights := []sdkmath.Int{
sdkmath.NewInt(6),
sdkmath.NewInt(8),
}
weightedAddresses, _ := NewWeightedAddresses(addresses, weights)
endTime := time.Now().Add(TestExtraEndTime)
collateralAuction := NewCollateralAuction(
TestInitiatorModuleName,
c(TestLotDenom, TestLotAmount),
endTime,
c(TestBidDenom, TestBidAmount),
weightedAddresses,
c(TestDebtDenom, TestDebtAmount2),
)
require.Equal(t, collateralAuction.Initiator, TestInitiatorModuleName)
require.Equal(t, collateralAuction.Lot, c(TestLotDenom, TestLotAmount))
require.Equal(t, collateralAuction.Bid, c(TestBidDenom, 0))
require.Equal(t, collateralAuction.EndTime, endTime)
require.Equal(t, collateralAuction.MaxEndTime, endTime)
require.Equal(t, collateralAuction.MaxBid, c(TestBidDenom, TestBidAmount))
require.Equal(t, collateralAuction.LotReturns, weightedAddresses)
require.Equal(t, collateralAuction.CorrespondingDebt, c(TestDebtDenom, TestDebtAmount2))
}

View File

@ -1,65 +0,0 @@
package types
import (
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/codec/types"
cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/msgservice"
authzcodec "github.com/cosmos/cosmos-sdk/x/authz/codec"
)
// RegisterLegacyAminoCodec registers all the necessary types and interfaces for the
// governance module.
func RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) {
cdc.RegisterConcrete(&MsgPlaceBid{}, "auction/MsgPlaceBid", nil)
cdc.RegisterInterface((*GenesisAuction)(nil), nil)
cdc.RegisterInterface((*Auction)(nil), nil)
cdc.RegisterConcrete(&SurplusAuction{}, "auction/SurplusAuction", nil)
cdc.RegisterConcrete(&DebtAuction{}, "auction/DebtAuction", nil)
cdc.RegisterConcrete(&CollateralAuction{}, "auction/CollateralAuction", nil)
}
func RegisterInterfaces(registry types.InterfaceRegistry) {
registry.RegisterImplementations((*sdk.Msg)(nil),
&MsgPlaceBid{},
)
registry.RegisterInterface(
"kava.auction.v1beta1.Auction",
(*Auction)(nil),
&SurplusAuction{},
&DebtAuction{},
&CollateralAuction{},
)
registry.RegisterInterface(
"kava.auction.v1beta1.GenesisAuction",
(*GenesisAuction)(nil),
&SurplusAuction{},
&DebtAuction{},
&CollateralAuction{},
)
msgservice.RegisterMsgServiceDesc(registry, &_Msg_serviceDesc)
}
var (
amino = codec.NewLegacyAmino()
// ModuleCdc is an amino codec instance with this module's types registered.
//
// Deprecated: The codec used for serialization should be provided to this module and
// defined at the application level.
ModuleCdc = codec.NewAminoCodec(amino)
)
func init() {
RegisterLegacyAminoCodec(amino)
cryptocodec.RegisterCrypto(amino)
// Register all Amino interfaces and concrete types on the authz Amino codec so that this can later be
// used to properly serialize MsgGrant and MsgExec instances
RegisterLegacyAminoCodec(authzcodec.Amino)
}

View File

@ -1,30 +0,0 @@
package types
import errorsmod "cosmossdk.io/errors"
// DONTCOVER
var (
// ErrInvalidInitialAuctionID error for when the initial auction ID hasn't been set
ErrInvalidInitialAuctionID = errorsmod.Register(ModuleName, 2, "initial auction ID hasn't been set")
// ErrUnrecognizedAuctionType error for unrecognized auction type
ErrUnrecognizedAuctionType = errorsmod.Register(ModuleName, 3, "unrecognized auction type")
// ErrAuctionNotFound error for when an auction is not found
ErrAuctionNotFound = errorsmod.Register(ModuleName, 4, "auction not found")
// ErrAuctionHasNotExpired error for attempting to close an auction that has not passed its end time
ErrAuctionHasNotExpired = errorsmod.Register(ModuleName, 5, "auction can't be closed as curent block time has not passed auction end time")
// ErrAuctionHasExpired error for when an auction is closed and unavailable for bidding
ErrAuctionHasExpired = errorsmod.Register(ModuleName, 6, "auction has closed")
// ErrInvalidBidDenom error for when bid denom doesn't match auction bid denom
ErrInvalidBidDenom = errorsmod.Register(ModuleName, 7, "bid denom doesn't match auction bid denom")
// ErrInvalidLotDenom error for when lot denom doesn't match auction lot denom
ErrInvalidLotDenom = errorsmod.Register(ModuleName, 8, "lot denom doesn't match auction lot denom")
// ErrBidTooSmall error for when bid is not greater than auction's min bid amount
ErrBidTooSmall = errorsmod.Register(ModuleName, 9, "bid is not greater than auction's min new bid amount")
// ErrBidTooLarge error for when bid is larger than auction's maximum allowed bid
ErrBidTooLarge = errorsmod.Register(ModuleName, 10, "bid is greater than auction's max bid")
// ErrLotTooSmall error for when lot is less than zero
ErrLotTooSmall = errorsmod.Register(ModuleName, 11, "lot is not greater than auction's min new lot amount")
// ErrLotTooLarge error for when lot is not smaller than auction's max new lot amount
ErrLotTooLarge = errorsmod.Register(ModuleName, 12, "lot is greater than auction's max new lot amount")
)

Some files were not shown because too many files have changed in this diff Show More