diff --git a/app/ante/vesting.go b/app/ante/vesting.go index 146a931..5c2d482 100644 --- a/app/ante/vesting.go +++ b/app/ante/vesting.go @@ -27,11 +27,11 @@ func NewEthVestingTransactionDecorator(ak evmtypes.AccountKeeper) EthVestingTran // vesting cliff and lockup period. // // This AnteHandler decorator will fail if: -// - the message is not a MsgEthereumTx -// - sender account cannot be found -// - sender account is not a ClawbackvestingAccount -// - blocktime is before surpassing vesting cliff end (with zero vested coins) AND -// - blocktime is before surpassing all lockup periods (with non-zero locked coins) +// - the message is not a MsgEthereumTx +// - sender account cannot be found +// - sender account is not a ClawbackvestingAccount +// - blocktime is before surpassing vesting cliff end (with zero vested coins) AND +// - blocktime is before surpassing all lockup periods (with non-zero locked coins) func (vtd EthVestingTransactionDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (newCtx sdk.Context, err error) { for _, msg := range tx.GetMsgs() { msgEthTx, ok := msg.(*evmtypes.MsgEthereumTx) @@ -132,9 +132,14 @@ func (vdd VestingDelegationDecorator) validateAuthz(ctx sdk.Context, execMsg *au // validateMsg checks that the only vested coins can be delegated func (vdd VestingDelegationDecorator) validateMsg(ctx sdk.Context, msg sdk.Msg) error { - delegateMsg, ok := msg.(*stakingtypes.MsgDelegate) + _, ok := msg.(*stakingtypes.MsgDelegate) + msgError := "Vesting account cannot delegate" if !ok { - return nil + _, isMsgCreateValidator := msg.(*stakingtypes.MsgCreateValidator) + if !isMsgCreateValidator { + return nil + } + msgError = "Vesting account cannot create validator" } for _, addr := range msg.GetSigners() { @@ -146,30 +151,13 @@ func (vdd VestingDelegationDecorator) validateMsg(ctx sdk.Context, msg sdk.Msg) ) } - clawbackAccount, isClawback := acc.(*vestingtypes.ClawbackVestingAccount) + _, isClawback := acc.(*vestingtypes.ClawbackVestingAccount) if !isClawback { // continue to next decorator as this logic only applies to vesting - return nil - } - - // error if bond amount is > vested coins - bondDenom := vdd.sk.BondDenom(ctx) - coins := clawbackAccount.GetVestedOnly(ctx.BlockTime()) - if coins == nil || coins.Empty() { - return sdkerrors.Wrap( - vestingtypes.ErrInsufficientVestedCoins, - "account has no vested coins", - ) + continue } - vested := coins.AmountOf(bondDenom) - if vested.LT(delegateMsg.Amount.Amount) { - return sdkerrors.Wrapf( - vestingtypes.ErrInsufficientVestedCoins, - "cannot delegate unvested coins. coins vested < delegation amount (%s < %s)", - vested, delegateMsg.Amount.Amount, - ) - } + return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, msgError) } return nil diff --git a/tests/vesting_test.go b/tests/vesting_test.go index b4e666a..7f70cf7 100644 --- a/tests/vesting_test.go +++ b/tests/vesting_test.go @@ -354,7 +354,7 @@ func (suite *KeeperTestSuite) TestCrawbackVestingAccounts() { suite.Require().Equal(expVested, vested) err := suite.delegate(clawbackAccount, 1) - suite.Require().NoError(err, "can delegate vested tokens") + suite.Require().Error(err, "cannot delegate vested tokens") err = suite.app.BankKeeper.SendCoins( suite.ctx, @@ -385,7 +385,7 @@ func (suite *KeeperTestSuite) TestCrawbackVestingAccounts() { suite.Require().Equal(expVested, vested) err := suite.delegate(clawbackAccount, 1) - suite.Require().NoError(err, "can delegate vested tokens") + suite.Require().Error(err, "cannot delegate vested tokens") err = suite.delegate(clawbackAccount, 30) suite.Require().Error(err, "cannot delegate unvested tokens") diff --git a/x/mint/spec/01_concepts.md b/x/mint/spec/01_concepts.md index a0c064c..667455b 100644 --- a/x/mint/spec/01_concepts.md +++ b/x/mint/spec/01_concepts.md @@ -32,14 +32,14 @@ the minting mechanism presented below, with an initial inflation set to 10%. At the genesis launch, there is a total of 1,200,000,000 ASAs distributed to Genesis Partners, Strategic Partners (Backers), Astra Foundation, Core Team, and the Community Pool. Here are the details: -| | % | #ASAs | Minted at genesis | Vesting schedule | -|:-----------------------|-----:|--------------:|------------------:|--------------------------------------------------------------------------------------------------:| -| **Genesis Partners** | 39% | 468,000,000 | 468,000,000 | 100% minted and unlocked at genesis | -| **Strategic Partners** | 36% | 432,000,000 | 432,000,000 | 100% minted and unlocked at genesis | -| **Astra Foundation** | 10% | 120,000,000 | 120,000,000 | 100% minted and unlocked at genesis | -| **Core Team** | 10% | 120,000,000 | 120,000,000 | 50% unlocked at genesis, 50% unlocked after 1 year | -| **Community Pool** | 5% | 60,000,000 | 60,000,000 | 100% minted & locked at genesis, unlocked with GOV rules | -| **Total** | 100% | 1,200,000,000 | 1,200,000,000 | | +| | % | #ASAs | Minted at genesis | Vesting schedule | +|:-----------------------|-----:|--------------:|------------------:|---------------------------------------------------------:| +| **Genesis Partners** | 39% | 468,000,000 | 468,000,000 | 100% minted and unlocked at genesis | +| **Strategic Partners** | 36% | 432,000,000 | 432,000,000 | 100% minted and unlocked at genesis | +| **Astra Foundation** | 10% | 120,000,000 | 120,000,000 | 100% minted and unlocked at genesis | +| **Core Team** | 10% | 120,000,000 | 120,000,000 | 100* minted and unlocked at genesis | +| **Community Pool** | 5% | 60,000,000 | 60,000,000 | 100% minted & locked at genesis, unlocked with GOV rules | +| **Total** | 100% | 1,200,000,000 | 1,200,000,000 | | ## The Minting Mechanism