mirror of
https://github.com/0glabs/0g-chain.git
synced 2024-11-10 10:05:18 +00:00
remove useless modules
This commit is contained in:
parent
4a55eb9259
commit
b8c8971119
@ -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"
|
||||
)
|
||||
|
||||
|
@ -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()
|
||||
|
140
app/app.go
140
app/app.go
@ -101,62 +101,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"
|
||||
@ -185,12 +152,7 @@ var (
|
||||
upgradeclient.LegacyCancelProposalHandler,
|
||||
ibcclientclient.UpdateClientProposalHandler,
|
||||
ibcclientclient.UpgradeProposalHandler,
|
||||
kavadistclient.ProposalHandler,
|
||||
committeeclient.ProposalHandler,
|
||||
earnclient.DepositProposalHandler,
|
||||
earnclient.WithdrawProposalHandler,
|
||||
communityclient.LendDepositProposalHandler,
|
||||
communityclient.LendWithdrawProposalHandler,
|
||||
}),
|
||||
params.AppModuleBasic{},
|
||||
crisis.AppModuleBasic{},
|
||||
@ -204,26 +166,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
|
||||
@ -238,20 +187,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,
|
||||
}
|
||||
)
|
||||
|
||||
@ -270,7 +208,6 @@ type Options struct {
|
||||
MempoolAuthAddresses []sdk.AccAddress
|
||||
EVMTrace string
|
||||
EVMMaxGasWanted uint64
|
||||
TelemetryOptions metricstypes.TelemetryOptions
|
||||
}
|
||||
|
||||
// DefaultOptions is a sensible default Options value.
|
||||
@ -377,7 +314,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,
|
||||
@ -415,8 +352,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)
|
||||
@ -430,7 +365,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
|
||||
@ -568,13 +502,6 @@ func NewApp(
|
||||
ibcRouter.AddRoute(ibctransfertypes.ModuleName, transferIBCModule)
|
||||
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],
|
||||
@ -710,7 +637,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.
|
||||
@ -732,12 +658,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()
|
||||
@ -746,9 +666,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()
|
||||
@ -794,22 +714,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),
|
||||
@ -818,7 +728,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.
|
||||
@ -828,7 +737,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
|
||||
@ -839,18 +747,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,
|
||||
@ -881,19 +784,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,
|
||||
@ -904,10 +801,6 @@ func NewApp(
|
||||
paramstypes.ModuleName,
|
||||
authz.ModuleName,
|
||||
evmutiltypes.ModuleName,
|
||||
savingstypes.ModuleName,
|
||||
liquidtypes.ModuleName,
|
||||
earntypes.ModuleName,
|
||||
routertypes.ModuleName,
|
||||
minttypes.ModuleName,
|
||||
communitytypes.ModuleName,
|
||||
metricstypes.ModuleName,
|
||||
@ -930,20 +823,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,
|
||||
@ -1159,16 +1043,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.
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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]
|
||||
|
155
app/upgrades.go
155
app/upgrades.go
@ -2,20 +2,13 @@ package app
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
sdkmath "cosmossdk.io/math"
|
||||
storetypes "github.com/cosmos/cosmos-sdk/store/types"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/module"
|
||||
"github.com/cosmos/cosmos-sdk/x/authz"
|
||||
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
|
||||
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
|
||||
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
|
||||
upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"
|
||||
|
||||
communitytypes "github.com/0glabs/0g-chain/x/community/types"
|
||||
kavadisttypes "github.com/0glabs/0g-chain/x/kavadist/types"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -30,33 +23,33 @@ var (
|
||||
secondsPerYear = sdk.NewInt(365 * 24 * 60 * 60)
|
||||
|
||||
// 10 Million KAVA per year in staking rewards, inflation disable time 2024-01-01T00:00:00 UTC
|
||||
CommunityParams_Mainnet = communitytypes.NewParams(
|
||||
time.Date(2024, 1, 1, 0, 0, 0, 0, time.UTC),
|
||||
// before switchover
|
||||
sdkmath.LegacyZeroDec(),
|
||||
// after switchover - 10M KAVA to ukava per year / seconds per year
|
||||
sdkmath.LegacyNewDec(10_000_000).
|
||||
MulInt(kavaConversionFactor).
|
||||
QuoInt(secondsPerYear),
|
||||
)
|
||||
// CommunityParams_Mainnet = communitytypes.NewParams(
|
||||
// time.Date(2024, 1, 1, 0, 0, 0, 0, time.UTC),
|
||||
// // before switchover
|
||||
// sdkmath.LegacyZeroDec(),
|
||||
// // after switchover - 10M KAVA to ukava per year / seconds per year
|
||||
// sdkmath.LegacyNewDec(10_000_000).
|
||||
// MulInt(kavaConversionFactor).
|
||||
// QuoInt(secondsPerYear),
|
||||
// )
|
||||
|
||||
// Testnet -- 15 Trillion KAVA per year in staking rewards, inflation disable time 2023-11-16T00:00:00 UTC
|
||||
CommunityParams_Testnet = communitytypes.NewParams(
|
||||
time.Date(2023, 11, 16, 0, 0, 0, 0, time.UTC),
|
||||
// before switchover
|
||||
sdkmath.LegacyZeroDec(),
|
||||
// after switchover
|
||||
sdkmath.LegacyNewDec(15_000_000).
|
||||
MulInt64(1_000_000). // 15M * 1M = 15T
|
||||
MulInt(kavaConversionFactor).
|
||||
QuoInt(secondsPerYear),
|
||||
)
|
||||
// CommunityParams_Testnet = communitytypes.NewParams(
|
||||
// time.Date(2023, 11, 16, 0, 0, 0, 0, time.UTC),
|
||||
// // before switchover
|
||||
// sdkmath.LegacyZeroDec(),
|
||||
// // after switchover
|
||||
// sdkmath.LegacyNewDec(15_000_000).
|
||||
// MulInt64(1_000_000). // 15M * 1M = 15T
|
||||
// MulInt(kavaConversionFactor).
|
||||
// QuoInt(secondsPerYear),
|
||||
// )
|
||||
|
||||
CommunityParams_E2E = communitytypes.NewParams(
|
||||
time.Now().Add(10*time.Second).UTC(), // relative time for testing
|
||||
sdkmath.LegacyNewDec(0), // stakingRewardsPerSecond
|
||||
sdkmath.LegacyNewDec(1000), // upgradeTimeSetstakingRewardsPerSecond
|
||||
)
|
||||
// CommunityParams_E2E = communitytypes.NewParams(
|
||||
// time.Now().Add(10*time.Second).UTC(), // relative time for testing
|
||||
// sdkmath.LegacyNewDec(0), // stakingRewardsPerSecond
|
||||
// sdkmath.LegacyNewDec(1000), // upgradeTimeSetstakingRewardsPerSecond
|
||||
// )
|
||||
|
||||
// ValidatorMinimumCommission is the new 5% minimum commission rate for validators
|
||||
ValidatorMinimumCommission = sdk.NewDecWithPrec(5, 2)
|
||||
@ -64,18 +57,18 @@ var (
|
||||
|
||||
// RegisterUpgradeHandlers registers the upgrade handlers for the app.
|
||||
func (app App) RegisterUpgradeHandlers() {
|
||||
app.upgradeKeeper.SetUpgradeHandler(
|
||||
UpgradeName_Mainnet,
|
||||
upgradeHandler(app, UpgradeName_Mainnet, CommunityParams_Mainnet),
|
||||
)
|
||||
app.upgradeKeeper.SetUpgradeHandler(
|
||||
UpgradeName_Testnet,
|
||||
upgradeHandler(app, UpgradeName_Testnet, CommunityParams_Testnet),
|
||||
)
|
||||
app.upgradeKeeper.SetUpgradeHandler(
|
||||
UpgradeName_E2ETest,
|
||||
upgradeHandler(app, UpgradeName_Testnet, CommunityParams_E2E),
|
||||
)
|
||||
// app.upgradeKeeper.SetUpgradeHandler(
|
||||
// UpgradeName_Mainnet,
|
||||
// upgradeHandler(app, UpgradeName_Mainnet, CommunityParams_Mainnet),
|
||||
// )
|
||||
// app.upgradeKeeper.SetUpgradeHandler(
|
||||
// UpgradeName_Testnet,
|
||||
// upgradeHandler(app, UpgradeName_Testnet, CommunityParams_Testnet),
|
||||
// )
|
||||
// app.upgradeKeeper.SetUpgradeHandler(
|
||||
// UpgradeName_E2ETest,
|
||||
// upgradeHandler(app, UpgradeName_Testnet, CommunityParams_E2E),
|
||||
// )
|
||||
|
||||
upgradeInfo, err := app.upgradeKeeper.ReadUpgradeInfoFromDisk()
|
||||
if err != nil {
|
||||
@ -90,7 +83,7 @@ func (app App) RegisterUpgradeHandlers() {
|
||||
storeUpgrades := storetypes.StoreUpgrades{
|
||||
Added: []string{
|
||||
// x/community added store
|
||||
communitytypes.ModuleName,
|
||||
// communitytypes.ModuleName,
|
||||
},
|
||||
}
|
||||
|
||||
@ -103,7 +96,7 @@ func (app App) RegisterUpgradeHandlers() {
|
||||
func upgradeHandler(
|
||||
app App,
|
||||
name string,
|
||||
communityParams communitytypes.Params,
|
||||
// communityParams communitytypes.Params,
|
||||
) upgradetypes.UpgradeHandler {
|
||||
return func(
|
||||
ctx sdk.Context,
|
||||
@ -125,31 +118,31 @@ func upgradeHandler(
|
||||
//
|
||||
// Community Params
|
||||
//
|
||||
app.communityKeeper.SetParams(ctx, communityParams)
|
||||
app.Logger().Info(
|
||||
"initialized x/community params",
|
||||
"UpgradeTimeDisableInflation", communityParams.UpgradeTimeDisableInflation,
|
||||
"StakingRewardsPerSecond", communityParams.StakingRewardsPerSecond,
|
||||
"UpgradeTimeSetStakingRewardsPerSecond", communityParams.UpgradeTimeSetStakingRewardsPerSecond,
|
||||
)
|
||||
// app.communityKeeper.SetParams(ctx, communityParams)
|
||||
// app.Logger().Info(
|
||||
// "initialized x/community params",
|
||||
// "UpgradeTimeDisableInflation", communityParams.UpgradeTimeDisableInflation,
|
||||
// "StakingRewardsPerSecond", communityParams.StakingRewardsPerSecond,
|
||||
// "UpgradeTimeSetStakingRewardsPerSecond", communityParams.UpgradeTimeSetStakingRewardsPerSecond,
|
||||
// )
|
||||
|
||||
//
|
||||
// Kavadist gov grant
|
||||
//
|
||||
msgGrant, err := authz.NewMsgGrant(
|
||||
app.accountKeeper.GetModuleAddress(kavadisttypes.ModuleName), // granter
|
||||
app.accountKeeper.GetModuleAddress(govtypes.ModuleName), // grantee
|
||||
authz.NewGenericAuthorization(sdk.MsgTypeURL(&banktypes.MsgSend{})), // authorization
|
||||
nil, // expiration
|
||||
)
|
||||
if err != nil {
|
||||
return toVM, err
|
||||
}
|
||||
_, err = app.authzKeeper.Grant(ctx, msgGrant)
|
||||
if err != nil {
|
||||
return toVM, err
|
||||
}
|
||||
app.Logger().Info("created gov grant for kavadist funds")
|
||||
// msgGrant, err := authz.NewMsgGrant(
|
||||
// app.accountKeeper.GetModuleAddress(kavadisttypes.ModuleName), // granter
|
||||
// app.accountKeeper.GetModuleAddress(govtypes.ModuleName), // grantee
|
||||
// authz.NewGenericAuthorization(sdk.MsgTypeURL(&banktypes.MsgSend{})), // authorization
|
||||
// nil, // expiration
|
||||
// )
|
||||
// if err != nil {
|
||||
// return toVM, err
|
||||
// }
|
||||
// _, err = app.authzKeeper.Grant(ctx, msgGrant)
|
||||
// if err != nil {
|
||||
// return toVM, err
|
||||
// }
|
||||
// app.Logger().Info("created gov grant for kavadist funds")
|
||||
|
||||
//
|
||||
// Gov Quorum
|
||||
@ -242,24 +235,24 @@ func UpdateIncentiveParams(
|
||||
ctx sdk.Context,
|
||||
app App,
|
||||
) {
|
||||
incentiveParams := app.incentiveKeeper.GetParams(ctx)
|
||||
// incentiveParams := app.incentiveKeeper.GetParams(ctx)
|
||||
|
||||
// bkava annualized rewards: 600K KAVA
|
||||
newAmount := sdkmath.LegacyNewDec(600_000).
|
||||
MulInt(kavaConversionFactor).
|
||||
QuoInt(secondsPerYear).
|
||||
TruncateInt()
|
||||
// newAmount := sdkmath.LegacyNewDec(600_000).
|
||||
// MulInt(kavaConversionFactor).
|
||||
// QuoInt(secondsPerYear).
|
||||
// TruncateInt()
|
||||
|
||||
for i := range incentiveParams.EarnRewardPeriods {
|
||||
if incentiveParams.EarnRewardPeriods[i].CollateralType != "bkava" {
|
||||
continue
|
||||
}
|
||||
// for i := range incentiveParams.EarnRewardPeriods {
|
||||
// if incentiveParams.EarnRewardPeriods[i].CollateralType != "bkava" {
|
||||
// continue
|
||||
// }
|
||||
|
||||
// Update rewards per second via index
|
||||
incentiveParams.EarnRewardPeriods[i].RewardsPerSecond = sdk.NewCoins(
|
||||
sdk.NewCoin("ukava", newAmount),
|
||||
)
|
||||
}
|
||||
// // Update rewards per second via index
|
||||
// incentiveParams.EarnRewardPeriods[i].RewardsPerSecond = sdk.NewCoins(
|
||||
// sdk.NewCoin("ukava", newAmount),
|
||||
// )
|
||||
// }
|
||||
|
||||
app.incentiveKeeper.SetParams(ctx, incentiveParams)
|
||||
// app.incentiveKeeper.SetParams(ctx, incentiveParams)
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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 (
|
||||
@ -112,7 +111,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
1
go.mod
@ -175,7 +175,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
|
||||
|
@ -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
|
||||
];
|
||||
}
|
@ -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
|
||||
];
|
||||
}
|
@ -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;
|
||||
}
|
@ -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 {}
|
@ -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"];
|
||||
}
|
@ -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 paramaters 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
|
||||
];
|
||||
}
|
@ -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;
|
||||
}
|
@ -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 {}
|
@ -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 paramaters 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];
|
||||
}
|
@ -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
|
||||
];
|
||||
}
|
@ -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];
|
||||
}
|
@ -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
|
||||
];
|
||||
}
|
@ -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
|
||||
];
|
||||
}
|
@ -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 {}
|
@ -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 paramaters 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
|
||||
];
|
||||
}
|
@ -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
|
||||
];
|
||||
}
|
@ -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"
|
||||
];
|
||||
}
|
@ -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"
|
||||
];
|
||||
}
|
@ -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;
|
||||
}
|
@ -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];
|
||||
}
|
@ -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
|
||||
];
|
||||
}
|
@ -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
|
||||
];
|
||||
}
|
@ -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
|
||||
];
|
||||
}
|
@ -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;
|
||||
}
|
@ -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 {}
|
@ -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
|
||||
];
|
||||
}
|
@ -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
|
||||
];
|
||||
}
|
@ -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
|
||||
];
|
||||
}
|
@ -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
|
||||
];
|
||||
}
|
@ -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];
|
||||
}
|
@ -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 {}
|
@ -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
|
||||
];
|
||||
}
|
@ -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"
|
||||
];
|
||||
}
|
@ -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"
|
||||
];
|
||||
}
|
@ -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"
|
||||
];
|
||||
}
|
@ -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"
|
||||
];
|
||||
}
|
@ -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
|
||||
];
|
||||
}
|
@ -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 {}
|
@ -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
|
||||
];
|
||||
}
|
@ -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"
|
||||
];
|
||||
}
|
@ -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
|
||||
];
|
||||
}
|
@ -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 {}
|
@ -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 paramaters 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
|
||||
];
|
||||
}
|
@ -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
|
||||
];
|
||||
}
|
@ -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
|
||||
];
|
||||
}
|
@ -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 {}
|
@ -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)
|
||||
|
@ -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",
|
||||
|
@ -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",
|
||||
// )
|
||||
// })
|
||||
// }
|
||||
|
@ -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",
|
||||
// )
|
||||
// })
|
||||
// }
|
||||
|
@ -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.
|
||||
|
@ -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)
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
@ -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...) }
|
@ -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(), ¶ms)
|
||||
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
|
||||
}
|
@ -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)
|
||||
},
|
||||
}
|
||||
}
|
@ -1,95 +0,0 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
errorsmod "cosmossdk.io/errors"
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
authtx "github.com/cosmos/cosmos-sdk/x/auth/tx"
|
||||
|
||||
"github.com/0glabs/0g-chain/x/auction/types"
|
||||
)
|
||||
|
||||
const (
|
||||
defaultPage = 1
|
||||
defaultLimit = 100
|
||||
)
|
||||
|
||||
// QueryAuctionByID returns an auction from state if present or falls back to searching old blocks
|
||||
func QueryAuctionByID(cliCtx client.Context, cdc *codec.Codec, queryRoute string, auctionID uint64) (types.Auction, int64, error) {
|
||||
bz, err := cliCtx.LegacyAmino.MarshalJSON(types.NewQueryAuctionParams(auctionID))
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
res, height, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryGetAuction), bz)
|
||||
|
||||
if err == nil {
|
||||
var auction types.Auction
|
||||
cliCtx.LegacyAmino.MustUnmarshalJSON(res, &auction)
|
||||
|
||||
return auction, height, nil
|
||||
}
|
||||
|
||||
if err != nil && !strings.Contains(err.Error(), "auction not found") {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
res, height, err = cliCtx.QueryWithData(fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryNextAuctionID), nil)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
var nextAuctionID uint64
|
||||
cliCtx.LegacyAmino.MustUnmarshalJSON(res, &nextAuctionID)
|
||||
|
||||
if auctionID >= nextAuctionID {
|
||||
return nil, 0, errorsmod.Wrapf(types.ErrAuctionNotFound, "%d", auctionID)
|
||||
}
|
||||
|
||||
events := []string{
|
||||
fmt.Sprintf("%s.%s='%s'", sdk.EventTypeMessage, sdk.AttributeKeyAction, "place_bid"),
|
||||
fmt.Sprintf("%s.%s='%s'", types.EventTypeAuctionBid, types.AttributeKeyAuctionID, []byte(fmt.Sprintf("%d", auctionID))),
|
||||
}
|
||||
|
||||
// if the auction is closed, query for previous bid transactions
|
||||
// note, will only fetch a maximum of 100 bids, so if an auction had more than that this
|
||||
// query may fail to retreive the final state of the auction
|
||||
searchResult, err := authtx.QueryTxsByEvents(cliCtx, events, defaultPage, defaultLimit, "")
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
maxHeight := int64(0)
|
||||
found := false
|
||||
|
||||
for _, info := range searchResult.Txs {
|
||||
for _, msg := range info.GetTx().GetMsgs() {
|
||||
_, ok := msg.(*types.MsgPlaceBid)
|
||||
if ok {
|
||||
found = true
|
||||
if info.Height > maxHeight {
|
||||
maxHeight = info.Height
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !found {
|
||||
return nil, 0, errorsmod.Wrapf(types.ErrAuctionNotFound, "%d", auctionID)
|
||||
}
|
||||
|
||||
queryCLIContext := cliCtx.WithHeight(maxHeight)
|
||||
res, height, err = queryCLIContext.QueryWithData(fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryGetAuction), bz)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
// Decode and print results
|
||||
var auction types.Auction
|
||||
cliCtx.LegacyAmino.MustUnmarshalJSON(res, &auction)
|
||||
return auction, height, nil
|
||||
}
|
@ -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
|
||||
}
|
@ -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)
|
||||
})
|
||||
}
|
@ -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
|
||||
}
|
@ -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)
|
||||
}
|
@ -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))
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
@ -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
|
||||
}
|
@ -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)
|
||||
})
|
||||
}
|
||||
}
|
@ -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
|
||||
}
|
@ -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
|
||||
}
|
||||
}
|
@ -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
|
||||
}
|
@ -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)
|
||||
}
|
@ -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
|
||||
}
|
@ -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
|
||||
}
|
@ -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
|
||||
}
|
@ -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, ¶ms)
|
||||
}
|
||||
|
||||
func (k Keeper) GetParams(ctx sdk.Context) (params types.Params) {
|
||||
k.paramSubspace.GetParamSet(ctx, ¶ms)
|
||||
return
|
||||
}
|
@ -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{},
|
||||
)
|
||||
}
|
@ -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")
|
||||
)
|
91
x/auction/legacy/v0_16/testdata/v15-auction.json
vendored
91
x/auction/legacy/v0_16/testdata/v15-auction.json
vendored
@ -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"
|
||||
}
|
||||
}
|
58
x/auction/legacy/v0_16/testdata/v16-auction.json
vendored
58
x/auction/legacy/v0_16/testdata/v16-auction.json
vendored
@ -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" }
|
||||
}
|
||||
]
|
||||
}
|
@ -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,
|
||||
}
|
||||
}
|
@ -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{}
|
||||
}
|
@ -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.
|
@ -1,82 +0,0 @@
|
||||
<!--
|
||||
order: 2
|
||||
-->
|
||||
|
||||
# State
|
||||
|
||||
## Parameters and genesis state
|
||||
|
||||
`Paramaters` 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
|
||||
}
|
||||
```
|
@ -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`
|
@ -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}` |
|
@ -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 |
|
@ -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)
|
||||
}
|
||||
}
|
||||
```
|
@ -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.
|
@ -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
@ -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
|
||||
}
|
@ -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))
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user