Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 16 additions & 14 deletions giga/deps/xbank/keeper/send.go
Original file line number Diff line number Diff line change
Expand Up @@ -204,9 +204,12 @@ func (k BaseSendKeeper) sendCoinsWithoutAccCreation(ctx sdk.Context, fromAddr sd
return nil
}

// SubUnlockedCoins removes the unlocked amt coins of the given account. An error is
// returned if the resulting balance is negative or the initial amount is invalid.
// A coin_spent event is emitted after.
// SubUnlockedCoins removes the unlocked amt coins of the given account. An error
// is returned if the resulting balance is negative or the initial amount is
// invalid. A coin_spent event is emitted after.
//
// When checkNeg is false the spendable-balance check is skipped and SubUnsafe
// is used; callers must ensure the operation is sound.
func (k BaseSendKeeper) SubUnlockedCoins(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coins, checkNeg bool) error {
if !amt.IsValid() {
return sdkerrors.Wrap(sdkerrors.ErrInvalidCoins, amt.String())
Expand All @@ -216,12 +219,11 @@ func (k BaseSendKeeper) SubUnlockedCoins(ctx sdk.Context, addr sdk.AccAddress, a

for _, coin := range amt {
balance := k.GetBalance(ctx, addr, coin.Denom)
if checkNeg {
locked := sdk.NewCoin(coin.Denom, lockedCoins.AmountOf(coin.Denom))
spendable := balance.Sub(locked)

_, hasNeg := sdk.Coins{spendable}.SafeSub(sdk.Coins{coin})
if hasNeg {
if checkNeg {
spendableAmt := sdk.MaxInt(balance.Amount.Sub(lockedCoins.AmountOf(coin.Denom)), sdk.ZeroInt())
if spendableAmt.LT(coin.Amount) {
spendable := sdk.NewCoin(coin.Denom, spendableAmt)
return sdkerrors.Wrapf(sdkerrors.ErrInsufficientFunds, "%s is smaller than %s", spendable, coin)
}
}
Expand All @@ -233,16 +235,12 @@ func (k BaseSendKeeper) SubUnlockedCoins(ctx sdk.Context, addr sdk.AccAddress, a
newBalance = balance.SubUnsafe(coin)
}

err := k.setBalance(ctx, addr, newBalance, checkNeg)
if err != nil {
if err := k.setBalance(ctx, addr, newBalance, checkNeg); err != nil {
return err
}
}

// emit coin spent event
ctx.EventManager().EmitEvent(
types.NewCoinSpentEvent(addr, amt),
)
ctx.EventManager().EmitEvent(types.NewCoinSpentEvent(addr, amt))
return nil
}

Expand Down Expand Up @@ -378,6 +376,10 @@ func (k BaseSendKeeper) SubWei(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Int
return sdkerrors.Wrapf(sdkerrors.ErrInsufficientFunds, "%swei is smaller than %swei", currentAggregatedBalance, amt)
}
useiBalance, weiBalance := SplitUseiWeiAmount(postAggregatedbalance)
lockedUsei := k.LockedCoins(ctx, addr).AmountOf(sdk.MustGetBaseDenom())
if useiBalance.LT(lockedUsei) {
return sdkerrors.Wrapf(sdkerrors.ErrInsufficientFunds, "%suei is smaller than locked %suei", useiBalance, lockedUsei)
}
if err := k.setBalance(ctx, addr, sdk.NewCoin(sdk.MustGetBaseDenom(), useiBalance), true); err != nil {
return err
}
Expand Down
18 changes: 13 additions & 5 deletions giga/deps/xevm/keeper/balance.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,19 @@ import (
sdk "github.com/sei-protocol/sei-chain/sei-cosmos/types"
)

// GetBalance returns addr's EVM-denominated balance in wei: spendable usei
// (scaled to wei) plus the wei remainder.
//
// Spendable usei is computed as (total − locked) rather than via
// BankKeeper.SpendableCoins, which iterates; LockedCoins does not.
func (k *Keeper) GetBalance(ctx sdk.Context, addr sdk.AccAddress) *big.Int {
bk := k.BankKeeper()
denom := k.GetBaseDenom(ctx)
allUsei := k.BankKeeper().GetBalance(ctx, addr, denom).Amount
lockedUsei := k.BankKeeper().LockedCoins(ctx, addr).AmountOf(denom) // LockedCoins doesn't use iterators
usei := allUsei.Sub(lockedUsei)
wei := k.BankKeeper().GetWeiBalance(ctx, addr)
return usei.Mul(state.SdkUseiToSweiMultiplier).Add(wei).BigInt()

total := bk.GetBalance(ctx, addr, denom).Amount
locked := bk.LockedCoins(ctx, addr).AmountOf(denom)
spendable := sdk.MaxInt(total.Sub(locked), sdk.ZeroInt())

wei := bk.GetWeiBalance(ctx, addr)
return spendable.Mul(state.SdkUseiToSweiMultiplier).Add(wei).BigInt()
}
6 changes: 3 additions & 3 deletions precompiles/bank/bank_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -193,9 +193,9 @@ func TestRun(t *testing.T) {
sdk.NewAttribute(banktypes.AttributeKeySender, senderAddr.String()),
),
// gas refund to the sender
banktypes.NewCoinReceivedEvent(senderAddr, sdk.NewCoins(sdk.NewCoin("usei", sdk.NewInt(132401)))),
banktypes.NewCoinReceivedEvent(senderAddr, sdk.NewCoins(sdk.NewCoin("usei", sdk.NewInt(131092)))),
// tip is paid to the validator
banktypes.NewCoinReceivedEvent(sdk.MustAccAddressFromBech32("sei1v4mx6hmrda5kucnpwdjsqqqqqqqqqqqqlve8dv"), sdk.NewCoins(sdk.NewCoin("usei", sdk.NewInt(67599)))),
banktypes.NewCoinReceivedEvent(sdk.MustAccAddressFromBech32("sei1v4mx6hmrda5kucnpwdjsqqqqqqqqqqqqlve8dv"), sdk.NewCoins(sdk.NewCoin("usei", sdk.NewInt(68908)))),
}
require.EqualValues(t, expectedEvts.ToABCIEvents(), evts)

Expand Down Expand Up @@ -244,7 +244,7 @@ func TestRun(t *testing.T) {
Denom: "ufoo",
}, bank.CoinBalance(parsedBalances[0]))
require.Equal(t, bank.CoinBalance{
Amount: big.NewInt(9932390),
Amount: big.NewInt(9931081),
Denom: "usei",
}, bank.CoinBalance(parsedBalances[1]))

Expand Down
41 changes: 25 additions & 16 deletions sei-cosmos/x/auth/vesting/types/msgs.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ import (
// TypeMsgCreateVestingAccount defines the type value for a MsgCreateVestingAccount.
const TypeMsgCreateVestingAccount = "msg_create_vesting_account"

// maxVestingCoinAmountBitLen bounds the magnitude of a single coin amount in
// MsgCreateVestingAccount. 2^200 is well above any realistic token supply.
const maxVestingCoinAmountBitLen = 200

var _ sdk.Msg = &MsgCreateVestingAccount{}

// NewMsgCreateVestingAccount returns a reference to a new MsgCreateVestingAccount.
Expand All @@ -30,34 +34,39 @@ func (msg MsgCreateVestingAccount) Type() string { return TypeMsgCreateVestingAc

// ValidateBasic Implements Msg.
func (msg MsgCreateVestingAccount) ValidateBasic() error {
from, err := sdk.AccAddressFromBech32(msg.FromAddress)
if err != nil {

if err := validateAddr(msg.FromAddress, "sender"); err != nil {
return err
}
to, err := sdk.AccAddressFromBech32(msg.ToAddress)
if err != nil {
if err := validateAddr(msg.ToAddress, "recipient"); err != nil {
return err
}
if err := sdk.VerifyAddressFormat(from); err != nil {
return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid sender address: %s", err)
}

if err := sdk.VerifyAddressFormat(to); err != nil {
return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid recipient address: %s", err)
}

if !msg.Amount.IsValid() {
return sdkerrors.Wrap(sdkerrors.ErrInvalidCoins, msg.Amount.String())
}

if !msg.Amount.IsAllPositive() {
if !msg.Amount.IsValid() || !msg.Amount.IsAllPositive() {
return sdkerrors.Wrap(sdkerrors.ErrInvalidCoins, msg.Amount.String())
}

if msg.EndTime <= 0 {
return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "invalid end time")
}

for _, c := range msg.Amount {
if c.Amount.BigInt().BitLen() > maxVestingCoinAmountBitLen {
return sdkerrors.Wrapf(sdkerrors.ErrInvalidCoins, "%s amount is out of range", c.Denom)
}
}

return nil
}

func validateAddr(bech32, label string) error {
addr, err := sdk.AccAddressFromBech32(bech32)
if err != nil {
return err
}
if err := sdk.VerifyAddressFormat(addr); err != nil {
return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid %s address: %s", label, err)
}
return nil
}

Expand Down
46 changes: 27 additions & 19 deletions sei-cosmos/x/auth/vesting/types/vesting_account.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package types
import (
"errors"
"fmt"
"math/big"
"time"

yaml "gopkg.in/yaml.v2"
Expand Down Expand Up @@ -226,25 +227,32 @@ func NewContinuousVestingAccount(baseAcc *authtypes.BaseAccount, originalVesting
// GetVestedCoins returns the total number of vested coins. If no coins are vested,
// nil is returned.
func (cva ContinuousVestingAccount) GetVestedCoins(blockTime time.Time) sdk.Coins {
var vestedCoins sdk.Coins

// We must handle the case where the start time for a vesting account has
// been set into the future or when the start of the chain is not exactly
// known.
if blockTime.Unix() <= cva.StartTime {
return vestedCoins
} else if blockTime.Unix() >= cva.EndTime {
// Handle the edges: start time set in the future (or genesis time not yet
// known), and the vesting period already fully elapsed.
now := blockTime.Unix()
if now <= cva.StartTime {
return nil
}
if now >= cva.EndTime {
return cva.OriginalVesting
}

// calculate the vesting scalar
x := blockTime.Unix() - cva.StartTime
y := cva.EndTime - cva.StartTime
s := sdk.NewDec(x).Quo(sdk.NewDec(y))
// vestedFraction = elapsed / duration, in (0, 1).
elapsed := now - cva.StartTime
duration := cva.EndTime - cva.StartTime
vestedFraction := sdk.NewDec(elapsed).Quo(sdk.NewDec(duration))

// Pull out the underlying big.Int once. It carries vestedFraction * 10^Precision,
// so multiplying a raw coin amount by it and then interpreting the product
// at the same precision yields amount * vestedFraction — equivalent to
// ovc.Amount.ToDec().Mul(vestedFraction).RoundInt(), without a per-coin Dec.
fractionScaled := vestedFraction.BigInt()

for _, ovc := range cva.OriginalVesting {
vestedAmt := ovc.Amount.ToDec().Mul(s).RoundInt()
vestedCoins = append(vestedCoins, sdk.NewCoin(ovc.Denom, vestedAmt))
vestedCoins := make(sdk.Coins, len(cva.OriginalVesting))
for i, ovc := range cva.OriginalVesting {
prod := new(big.Int).Mul(ovc.Amount.BigInt(), fractionScaled)
vestedAmt := sdk.NewDecFromBigIntWithPrec(prod, sdk.Precision).RoundInt()
vestedCoins[i] = sdk.NewCoin(ovc.Denom, vestedAmt)
}

return vestedCoins
Expand Down Expand Up @@ -278,7 +286,7 @@ func (cva ContinuousVestingAccount) GetStartTime() int64 {
// Validate checks for errors on the account fields
func (cva ContinuousVestingAccount) Validate() error {
if cva.GetStartTime() >= cva.GetEndTime() {
return errors.New("vesting start-time cannot be before end-time")
return errors.New("vesting start-time must be before end-time")
}

return cva.BaseVestingAccount.Validate()
Expand Down Expand Up @@ -363,8 +371,8 @@ func (pva PeriodicVestingAccount) GetVestedCoins(blockTime time.Time) sdk.Coins

// for each period, if the period is over, add those coins as vested and check the next period.
for _, period := range pva.VestingPeriods {
x := blockTime.Unix() - currentPeriodStartTime
if x < period.Length {
elapsed := blockTime.Unix() - currentPeriodStartTime
if elapsed < period.Length {
break
}

Expand Down Expand Up @@ -410,7 +418,7 @@ func (pva PeriodicVestingAccount) GetVestingPeriods() Periods {
// Validate checks for errors on the account fields
func (pva PeriodicVestingAccount) Validate() error {
if pva.GetStartTime() >= pva.GetEndTime() {
return errors.New("vesting start-time cannot be before end-time")
return errors.New("vesting start-time must be before end-time")
}
endTime := pva.StartTime
originalVesting := sdk.NewCoins()
Expand Down
Loading
Loading