Unverified Commit 1228659b authored by Dev Ojha's avatar Dev Ojha Committed by GitHub
Browse files

Move events out of stake.go (#963)

* Move events out of stake.go

* Rename SuperfluidDelegateMore -> IncreaseSuperfluidDelegation
parent 6795bb28
Showing with 60 additions and 64 deletions
+60 -64
......@@ -115,8 +115,6 @@ func (k Keeper) UpdateOsmoEquivalentMultipliers(ctx sdk.Context, asset types.Sup
}
twap := k.calculateOsmoBackingPerShare(pool, osmoPoolAsset)
// TODO: "newEpochNumber" is wrong in the edge-case where the chain is down for over a day.
// However, since we don't use this epoch number right now, we don't deal with it.
k.SetOsmoEquivalentMultiplier(ctx, newEpochNumber, asset.Denom, twap)
} else if asset.AssetType == types.SuperfluidAssetTypeNative {
// TODO: Consider deleting superfluid asset type native
......
package keeper
import (
"fmt"
"time"
sdk "github.com/cosmos/cosmos-sdk/types"
epochstypes "github.com/osmosis-labs/osmosis/v7/x/epochs/types"
"github.com/osmosis-labs/osmosis/v7/x/superfluid/types"
)
// Hooks wrapper struct for incentives keeper
......@@ -36,9 +38,15 @@ func (h Hooks) AfterAddTokensToLock(ctx sdk.Context, address sdk.AccAddress, loc
intermediaryAccAddr := h.k.GetLockIdIntermediaryAccountConnection(ctx, lockID)
if !intermediaryAccAddr.Empty() {
// superfluid delegate for additional amount
err := h.k.SuperfluidDelegateMore(ctx, lockID, amount)
err := h.k.IncreaseSuperfluidDelegation(ctx, lockID, amount)
if err != nil {
h.k.Logger(ctx).Error(err.Error())
} else {
ctx.EventManager().EmitEvent(sdk.NewEvent(
types.TypeEvtSuperfluidIncreaseDelegation,
sdk.NewAttribute(types.AttributeLockId, fmt.Sprintf("%d", lockID)),
sdk.NewAttribute(types.AttributeAmount, amount.String()),
))
}
}
}
......
......@@ -86,9 +86,10 @@ func (k Keeper) GetOrCreateIntermediaryAccount(ctx sdk.Context, denom, valAddr s
intermediaryAcct := types.NewSuperfluidIntermediaryAccount(denom, valAddr, gaugeID)
k.SetIntermediaryAccount(ctx, intermediaryAcct)
// TODO: @Dev added this hasAccount gating, think through if theres an edge case that makes it not right
// If the intermediary account's address doesn't already have an auth account associated with it,
// create a new account. We use base accounts, as this is whats done for cosmwasm smart contract accounts.
// and in the off-chance someone manages to find a bug that forces the account's creation.
if !k.ak.HasAccount(ctx, intermediaryAcct.GetAccAddress()) {
// TODO: Why is this a base account, not a module account?
k.ak.SetAccount(ctx, authtypes.NewBaseAccount(intermediaryAcct.GetAccAddress(), nil, 0, 0))
}
......
......@@ -2,6 +2,7 @@ package keeper
import (
"context"
"fmt"
sdk "github.com/cosmos/cosmos-sdk/types"
lockuptypes "github.com/osmosis-labs/osmosis/v7/x/lockup/types"
......@@ -25,6 +26,13 @@ func (server msgServer) SuperfluidDelegate(goCtx context.Context, msg *types.Msg
ctx := sdk.UnwrapSDKContext(goCtx)
err := server.keeper.SuperfluidDelegate(ctx, msg.Sender, msg.LockId, msg.ValAddr)
if err != nil {
ctx.EventManager().EmitEvent(sdk.NewEvent(
types.TypeEvtSuperfluidDelegate,
sdk.NewAttribute(types.AttributeLockId, fmt.Sprintf("%d", msg.LockId)),
sdk.NewAttribute(types.AttributeValidator, msg.ValAddr),
))
}
return &types.MsgSuperfluidDelegateResponse{}, err
}
......@@ -32,6 +40,12 @@ func (server msgServer) SuperfluidUndelegate(goCtx context.Context, msg *types.M
ctx := sdk.UnwrapSDKContext(goCtx)
err := server.keeper.SuperfluidUndelegate(ctx, msg.Sender, msg.LockId)
if err != nil {
ctx.EventManager().EmitEvent(sdk.NewEvent(
types.TypeEvtSuperfluidUndelegate,
sdk.NewAttribute(types.AttributeLockId, fmt.Sprintf("%d", msg.LockId)),
))
}
return &types.MsgSuperfluidUndelegateResponse{}, err
}
......@@ -47,6 +61,12 @@ func (server msgServer) SuperfluidUnbondLock(goCtx context.Context, msg *types.M
ctx := sdk.UnwrapSDKContext(goCtx)
err := server.keeper.SuperfluidUnbondLock(ctx, msg.LockId, msg.Sender)
if err != nil {
ctx.EventManager().EmitEvent(sdk.NewEvent(
types.TypeEvtSuperfluidUnbondLock,
sdk.NewAttribute(types.AttributeLockId, fmt.Sprintf("%d", msg.LockId)),
))
}
return &types.MsgSuperfluidUnbondLockResponse{}, err
}
......
......@@ -32,7 +32,6 @@ func (k Keeper) SlashLockupsForValidatorSlash(ctx sdk.Context, valAddr sdk.ValAd
// for every intermediary account, we first slash the live tokens comprosing delegated to it,
// and then all of its unbonding delegations.
// We do these slashes as burns.
// TODO: Make it go to community pool.
for _, acc := range accs {
locks := k.lk.GetLocksLongerThanDurationDenom(ctx, acc.Denom, time.Second)
for _, lock := range locks {
......@@ -42,7 +41,7 @@ func (k Keeper) SlashLockupsForValidatorSlash(ctx sdk.Context, valAddr sdk.ValAd
if err != nil {
synthLock, err = k.lk.GetSyntheticLockup(ctx, lock.ID, unstakingSyntheticDenom(acc.Denom, acc.ValAddr))
// synth lock doesn't exist for unbonding
// => no superlfuid staking on this lock ID, so continue
// => no superfluid staking on this lock ID, so continue
if err != nil {
continue
}
......
......@@ -49,8 +49,8 @@ func (k Keeper) RefreshIntermediaryDelegationAmounts(ctx sdk.Context) {
k.Logger(ctx).Info(fmt.Sprintf("Existing delegation not found for %s with %s during superfluid refresh."+
" It may have been previously bonded, but now unbonded.", mAddr.String(), acc.ValAddr))
} else {
// TODO: Be consistent withn TokensFromShares vs ValidateFromUnbondAmount
currentAmount = validator.TokensFromShares(delegation.Shares).RoundInt()
}
refreshedAmount := k.GetExpectedDelegationAmount(ctx, acc)
......@@ -60,7 +60,7 @@ func (k Keeper) RefreshIntermediaryDelegationAmounts(ctx sdk.Context) {
adjustment := refreshedAmount.Sub(currentAmount)
err = k.mintOsmoTokensAndDelegate(ctx, adjustment, acc)
if err != nil {
panic(err)
ctx.Logger().Error("Error in forceUndelegateAndBurnOsmoTokens, state update reverted", err)
}
} else if currentAmount.GT(refreshedAmount) {
// In this case, we want to change the IA's delegated balance to be refreshed Amount
......@@ -71,16 +71,17 @@ func (k Keeper) RefreshIntermediaryDelegationAmounts(ctx sdk.Context) {
err := k.forceUndelegateAndBurnOsmoTokens(ctx, adjustment, acc)
if err != nil {
// TODO: We can't panic here. We can err-wrap though.
panic(err)
ctx.Logger().Error("Error in forceUndelegateAndBurnOsmoTokens, state update reverted", err)
}
} else {
ctx.Logger().Info("Intermediary account already has correct delegation amount? sus. This whp implies the exact same spot price as the last epoch, and no delegation changes.")
ctx.Logger().Info("Intermediary account already has correct delegation amount?" +
" This with high probability implies the exact same spot price as the last epoch," +
"and no delegation changes.")
}
}
}
func (k Keeper) SuperfluidDelegateMore(ctx sdk.Context, lockID uint64, amount sdk.Coins) error {
func (k Keeper) IncreaseSuperfluidDelegation(ctx sdk.Context, lockID uint64, amount sdk.Coins) error {
acc, found := k.GetIntermediaryAccountFromLockId(ctx, lockID)
if !found {
return nil
......@@ -152,7 +153,7 @@ func (k Keeper) validateValAddrForDelegate(ctx sdk.Context, valAddr string) (sta
return validator, nil
}
// TODO: Merge a lot of logic with SuperfluidDelegateMore
// TODO: Merge a lot of logic with IncreaseSuperfluidDelegation
func (k Keeper) SuperfluidDelegate(ctx sdk.Context, sender string, lockID uint64, valAddr string) error {
lock, err := k.lk.GetLockByID(ctx, lockID)
if err != nil {
......@@ -191,18 +192,7 @@ func (k Keeper) SuperfluidDelegate(ctx sdk.Context, sender string, lockID uint64
return types.ErrOsmoEquivalentZeroNotAllowed
}
err = k.mintOsmoTokensAndDelegate(ctx, amount, acc)
if err != nil {
return err
}
ctx.EventManager().EmitEvent(sdk.NewEvent(
types.TypeEvtSuperfluidDelegate,
sdk.NewAttribute(types.AttributeLockId, fmt.Sprintf("%d", lockID)),
sdk.NewAttribute(types.AttributeValidator, valAddr),
))
return nil
return k.mintOsmoTokensAndDelegate(ctx, amount, acc)
}
func (k Keeper) SuperfluidUndelegate(ctx sdk.Context, sender string, lockID uint64) error {
......@@ -238,17 +228,7 @@ func (k Keeper) SuperfluidUndelegate(ctx sdk.Context, sender string, lockID uint
}
// Create a new synthetic lockup representing the unstaking side.
err = k.createSyntheticLockup(ctx, lockID, intermediaryAcc, unlockingStatus)
if err != nil {
return err
}
ctx.EventManager().EmitEvent(sdk.NewEvent(
types.TypeEvtSuperfluidUndelegate,
sdk.NewAttribute(types.AttributeLockId, fmt.Sprintf("%d", lockID)),
))
return nil
return k.createSyntheticLockup(ctx, lockID, intermediaryAcc, unlockingStatus)
}
func (k Keeper) SuperfluidUnbondLock(ctx sdk.Context, underlyingLockId uint64, sender string) error {
......@@ -267,17 +247,7 @@ func (k Keeper) SuperfluidUnbondLock(ctx sdk.Context, underlyingLockId uint64, s
if !synthLocks[0].IsUnlocking() {
return types.ErrBondingLockupNotSupported
}
err = k.lk.BeginForceUnlock(ctx, underlyingLockId, sdk.Coins{})
if err != nil {
return err
}
ctx.EventManager().EmitEvent(sdk.NewEvent(
types.TypeEvtSuperfluidUnbondLock,
sdk.NewAttribute(types.AttributeLockId, fmt.Sprintf("%d", underlyingLockId)),
))
return nil
return k.lk.BeginForceUnlock(ctx, underlyingLockId, sdk.Coins{})
}
func (k Keeper) alreadySuperfluidStaking(ctx sdk.Context, lockID uint64) bool {
......@@ -318,6 +288,7 @@ func (k Keeper) mintOsmoTokensAndDelegate(ctx sdk.Context, osmoAmount sdk.Int, i
// make delegation from module account to the validator
// TODO: What happens here if validator is jailed, tombstoned, or unbonding
// For now, we don't worry since worst case it errors, in which case we revert mint.
_, err = k.sk.Delegate(cacheCtx,
intermediaryAccount.GetAccAddress(),
osmoAmount, stakingtypes.Unbonded, validator, true)
......
......@@ -106,7 +106,7 @@ func (suite *KeeperTestSuite) SetupSuperfluidDelegate(delAddr sdk.AccAddress, va
// here we check if check `LockTokens` added to existing locks or created a new lock.
// if `LockTokens` created a new lock, we continue SuperfluidDelegate
// if lock has been existing before, we wouldn't have to call SuperfluidDelegate separately, as hooks on LockTokens would have automatically called SuperfluidDelegateMore
// if lock has been existing before, we wouldn't have to call SuperfluidDelegate separately, as hooks on LockTokens would have automatically called IncreaseSuperfluidDelegation
if lastLockID != lockID {
err = suite.app.SuperfluidKeeper.SuperfluidDelegate(suite.ctx, lock.Owner, lock.ID, valAddr.String())
suite.Require().NoError(err)
......
......@@ -20,8 +20,10 @@ func (k Keeper) BeginUnwindSuperfluidAsset(ctx sdk.Context, epochNum int64, asse
k.DeleteSuperfluidAsset(ctx, asset.Denom)
}
// Returns amount * (1 - k.RiskFactor(asset))
// Fow now, the risk factor is a global constant.
// It will move towards per pool functions.
func (k Keeper) GetRiskAdjustedOsmoValue(ctx sdk.Context, asset types.SuperfluidAsset, amount sdk.Int) sdk.Int {
// TODO: we need to figure out how to do this later.
minRiskFactor := k.GetParams(ctx).MinimumRiskFactor
return amount.Sub(amount.ToDec().Mul(minRiskFactor).RoundInt())
}
......
......@@ -5,7 +5,7 @@ order: 12
# Minting
Superfluid module has the ability to arbitrarily mint and burn Osmo through the `bank` module. This is potentially dangerous so we strictly constrain it's ability to do so.
This authority is mediated through the `mintOsmoTokensAndDelegate` and `forceUndelegateAndBurnOsmoTokens` keeper methods, which are in turn called by message handlers (`SuperfluidDelegate` and `SuperfluidUndelegate`) as well as by hooks on Epoch (`RefreshIntermediaryDelegationAmounts`) and Lockup (`SuperfluidDelegateMore`)
This authority is mediated through the `mintOsmoTokensAndDelegate` and `forceUndelegateAndBurnOsmoTokens` keeper methods, which are in turn called by message handlers (`SuperfluidDelegate` and `SuperfluidUndelegate`) as well as by hooks on Epoch (`RefreshIntermediaryDelegationAmounts`) and Lockup (`IncreaseSuperfluidDelegation`)
## Invariant
......@@ -30,7 +30,7 @@ When a user submits a transaction to unlock their asset the invariant is maintai
In the `RefreshIntermediaryDelegationAmounts` method, calls are made to `mintOsmoTokensAndDelegate` or `forceUndelegateAndBurnOsmoTokens` to adjust the real delegation up or down to match `GetExpectedDelegationAmount`.
### SuperfluidDelegateMore (AfterAddTokensToLock Hook)
### IncreaseSuperfluidDelegation (AfterAddTokensToLock Hook)
This is called as a result of a user adding more assets to a lock that has already been associated to an `IntermediaryAccount`. The invariant is maintained by using `mintOsmoTokenAndDelegate` to match the amount of new asset locked \* `GetOsmoEquivalentMultiplier` \* `GetRiskAdjustment` for the underlying asset.
......
......@@ -2,14 +2,16 @@ package types
// event types
const (
TypeEvtSetSuperfluidAsset = "set_superfluid_asset"
TypeEvtRemoveSuperfluidAsset = "remove_superfluid_asset"
TypeEvtSuperfluidDelegate = "superfluid_delegate"
TypeEvtSuperfluidUndelegate = "superfluid_undelegate"
TypeEvtSuperfluidUnbondLock = "superfluid_unbond_lock"
TypeEvtSetSuperfluidAsset = "set_superfluid_asset"
TypeEvtRemoveSuperfluidAsset = "remove_superfluid_asset"
TypeEvtSuperfluidDelegate = "superfluid_delegate"
TypeEvtSuperfluidIncreaseDelegation = "superfluid_increase_delegation"
TypeEvtSuperfluidUndelegate = "superfluid_undelegate"
TypeEvtSuperfluidUnbondLock = "superfluid_unbond_lock"
AttributeDenom = "denom"
AttributeSuperfluidAssetType = "superfluid_asset_type"
AttributeLockId = "lock_id"
AttributeValidator = "validator"
AttributeAmount = "amount"
)
......@@ -32,13 +32,8 @@ func (a SuperfluidIntermediaryAccount) GetAccAddress() sdk.AccAddress {
}
func GetSuperfluidIntermediaryAccountAddr(denom, valAddr string) sdk.AccAddress {
// TODO (pre-v7): Make this better namespaced.
// TODO: Make this better namespaced.
// if ValAddr's one day switch to potentially be 32 bytes, a malleability attack could be crafted.
// Options I (Dev) see:
// * length prefix ValAddr
// * add a special separator character (e.g. \x00) and assume neither denom or valAddr can contain it
// * assert right here that valAddr is length 20 and deal with a 32byte addr change later.
//
// (Dev) I prefer length prefix ValAddr
// We are launching with the address as is, so this will have to be done as a migration in the future.
return authtypes.NewModuleAddress(denom + valAddr)
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment