Skip to content
Snippets Groups Projects

[feature] Circuit Breaker

Merged Son of Odin requested to merge circuit-breaker into develop
Compare and Show latest version
1 file
+ 27
28
Compare changes
  • Side-by-side
  • Inline
@@ -387,6 +387,32 @@ func (k KVStore) BurnFromModule(ctx cosmos.Context, module string, coin common.C
}
func (k KVStore) MintToModule(ctx cosmos.Context, module string, coin common.Coin) error {
version := k.GetVersion()
if version.GTE(semver.MustParse("1.109.0")) {
// circuit breaker
maxAmt, _ := k.GetMimir(ctx, "MaxRuneSupply")
if coin.Asset.IsRune() && maxAmt > 0 {
currentSupply := k.GetTotalSupply(ctx, common.RuneAsset())
surplus := common.SafeSub(currentSupply.Add(coin.Amount), cosmos.NewUint(uint64(maxAmt)))
if surplus.GT(cosmos.ZeroUint()) {
// Never mint an amount that would exceed MaxRuneSupply.
coin.Amount = common.SafeSub(coin.Amount, surplus)
reserveCoin := common.NewCoin(common.RuneAsset(), surplus)
if err := k.SendFromModuleToModule(ctx, ReserveName, module, common.NewCoins(reserveCoin)); err != nil {
// If unable to move the needed surplus coin from the Reserve, error out without any minting.
ctx.Logger().Error("fail to move coins during circuit breaker", "error", err)
return err
}
}
}
if coin.Amount.Equal(cosmos.ZeroUint()) {
// Don't proceed if the remaining amount to mint is zero.
return nil
}
}
coinToMint, err := coin.Native()
if err != nil {
return fmt.Errorf("fail to parse coins: %w", err)
@@ -397,34 +423,7 @@ func (k KVStore) MintToModule(ctx cosmos.Context, module string, coin common.Coi
return fmt.Errorf("fail to mint assets: %w", err)
}
version := k.GetVersion()
switch {
case version.GTE(semver.MustParse("1.109.0")):
// circuit breaker
coin := k.coinKeeper.GetSupply(ctx, common.RuneAsset().Native())
maxAmt, _ := k.GetMimir(ctx, "MaxRuneSupply")
if maxAmt > 0 && coin.Amount.GT(cosmos.NewInt(maxAmt)) {
diff := coin.Amount.SubRaw(maxAmt)
if diff.IsPositive() && diff.IsUint64() {
burn := common.NewCoin(common.RuneAsset(), cosmos.NewUint(diff.Uint64()))
if err := k.SendFromModuleToModule(ctx, ReserveName, ModuleName, common.NewCoins(burn)); err != nil {
ctx.Logger().Error("fail to move coins during circuit breaker", "error", err)
return err
}
err := k.BurnFromModule(ctx, ModuleName, burn)
if err != nil {
ctx.Logger().Error("fail to burn coins during circuit breaker", "error", err)
return err
}
burnEvt := NewEventMintBurn(BurnSupplyType, burn.Asset.Native(), burn.Amount, "circuit_breaker")
events, err := burnEvt.Events()
if err != nil {
return fmt.Errorf("fail to get events: %w", err)
}
ctx.EventManager().EmitEvents(events)
}
}
case version.GTE(semver.MustParse("1.95.0")):
if version.GTE(semver.MustParse("1.95.0")) {
// check if we've exceeded max rune supply cap. If we have, there could
// be an issue (infinite mint bug/exploit), or maybe runway rune
// hyperinflation. In any case, pause everything and allow the
Loading