2020-08-21 22:56:20 +00:00
|
|
|
package keeper
|
|
|
|
|
|
|
|
import (
|
|
|
|
"time"
|
|
|
|
|
2023-04-05 23:21:59 +00:00
|
|
|
errorsmod "cosmossdk.io/errors"
|
2020-08-21 22:56:20 +00:00
|
|
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
|
|
|
2024-05-01 03:17:24 +00:00
|
|
|
"github.com/0glabs/0g-chain/x/issuance/types"
|
2020-08-21 22:56:20 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
// CreateNewAssetSupply creates a new AssetSupply in the store for the input denom
|
|
|
|
func (k Keeper) CreateNewAssetSupply(ctx sdk.Context, denom string) types.AssetSupply {
|
|
|
|
supply := types.NewAssetSupply(
|
|
|
|
sdk.NewCoin(denom, sdk.ZeroInt()), time.Duration(0))
|
|
|
|
k.SetAssetSupply(ctx, supply, denom)
|
|
|
|
return supply
|
|
|
|
}
|
|
|
|
|
|
|
|
// IncrementCurrentAssetSupply increments an asset's supply by the coin
|
|
|
|
func (k Keeper) IncrementCurrentAssetSupply(ctx sdk.Context, coin sdk.Coin) error {
|
|
|
|
supply, found := k.GetAssetSupply(ctx, coin.Denom)
|
|
|
|
if !found {
|
2023-04-05 23:21:59 +00:00
|
|
|
return errorsmod.Wrap(types.ErrAssetNotFound, coin.Denom)
|
2020-08-21 22:56:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
limit, err := k.GetRateLimit(ctx, coin.Denom)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
if limit.Active {
|
|
|
|
supplyLimit := sdk.NewCoin(coin.Denom, limit.Limit)
|
|
|
|
// Resulting current supply must be under asset's limit
|
|
|
|
if supplyLimit.IsLT(supply.CurrentSupply.Add(coin)) {
|
2023-04-05 23:21:59 +00:00
|
|
|
return errorsmod.Wrapf(types.ErrExceedsSupplyLimit, "increase %s, asset supply %s, limit %s", coin, supply.CurrentSupply, supplyLimit)
|
2020-08-21 22:56:20 +00:00
|
|
|
}
|
|
|
|
supply.CurrentSupply = supply.CurrentSupply.Add(coin)
|
|
|
|
k.SetAssetSupply(ctx, supply, coin.Denom)
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// UpdateTimeBasedSupplyLimits updates the time based supply for each asset, resetting it if the current time window has elapsed.
|
|
|
|
func (k Keeper) UpdateTimeBasedSupplyLimits(ctx sdk.Context) {
|
|
|
|
params := k.GetParams(ctx)
|
|
|
|
previousBlockTime, found := k.GetPreviousBlockTime(ctx)
|
|
|
|
if !found {
|
|
|
|
previousBlockTime = ctx.BlockTime()
|
|
|
|
k.SetPreviousBlockTime(ctx, previousBlockTime)
|
|
|
|
}
|
|
|
|
timeElapsed := ctx.BlockTime().Sub(previousBlockTime)
|
|
|
|
for _, asset := range params.Assets {
|
|
|
|
supply, found := k.GetAssetSupply(ctx, asset.Denom)
|
|
|
|
// if a new asset has been added by governance, create a new asset supply for it in the store
|
|
|
|
if !found {
|
|
|
|
supply = k.CreateNewAssetSupply(ctx, asset.Denom)
|
|
|
|
}
|
2021-02-04 18:35:24 +00:00
|
|
|
if !asset.RateLimit.Active {
|
|
|
|
// rate limiting is not active, reset supply
|
2020-08-21 22:56:20 +00:00
|
|
|
supply.CurrentSupply = sdk.NewCoin(asset.Denom, sdk.ZeroInt())
|
|
|
|
supply.TimeElapsed = time.Duration(0)
|
2021-02-04 18:35:24 +00:00
|
|
|
k.SetAssetSupply(ctx, supply, asset.Denom)
|
|
|
|
continue
|
2020-08-21 22:56:20 +00:00
|
|
|
}
|
2021-02-04 18:35:24 +00:00
|
|
|
if asset.RateLimit.TimePeriod > supply.TimeElapsed+timeElapsed {
|
|
|
|
// rate limiting is active, the rate-limiting period has not expired
|
|
|
|
supply.TimeElapsed = supply.TimeElapsed + timeElapsed
|
|
|
|
k.SetAssetSupply(ctx, supply, asset.Denom)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
// rate limiting is active, the rate-limiting period has expired, and is now reset
|
|
|
|
supply.TimeElapsed = time.Duration(0)
|
|
|
|
supply.CurrentSupply = sdk.NewCoin(asset.Denom, sdk.ZeroInt())
|
2020-08-21 22:56:20 +00:00
|
|
|
k.SetAssetSupply(ctx, supply, asset.Denom)
|
|
|
|
}
|
|
|
|
k.SetPreviousBlockTime(ctx, ctx.BlockTime())
|
|
|
|
}
|