-
Notifications
You must be signed in to change notification settings - Fork 31
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
6afe633
commit fd4945a
Showing
7 changed files
with
402 additions
and
24 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package keeper | ||
|
||
import sdk "github.com/Finschia/finschia-sdk/types" | ||
|
||
type ( | ||
AccountKeeper interface { | ||
GetModuleAddress(name string) sdk.AccAddress | ||
} | ||
|
||
BankKeeper interface { | ||
HasBalance(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coin) bool | ||
GetBalance(ctx sdk.Context, addr sdk.AccAddress, denom string) sdk.Coin | ||
SendCoins(ctx sdk.Context, fromAddr, toAddr sdk.AccAddress, amt sdk.Coins) error | ||
MintCoins(ctx sdk.Context, moduleName string, amt sdk.Coins) error | ||
BurnCoins(ctx sdk.Context, moduleName string, amt sdk.Coins) error | ||
} | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,39 +1,161 @@ | ||
package keeper | ||
|
||
import ( | ||
"fmt" | ||
|
||
"github.com/tendermint/tendermint/libs/log" | ||
"errors" | ||
|
||
"github.com/Finschia/finschia-sdk/codec" | ||
storetypes "github.com/Finschia/finschia-sdk/store/types" | ||
sdk "github.com/Finschia/finschia-sdk/types" | ||
sdkerrors "github.com/Finschia/finschia-sdk/types/errors" | ||
"github.com/Finschia/finschia-sdk/x/fswap/types" | ||
) | ||
|
||
type ( | ||
Keeper struct { | ||
cdc codec.BinaryCodec | ||
accountKeeper types.AccountKeeper | ||
bankKeeper types.BankKeeper | ||
storeKey storetypes.StoreKey | ||
} | ||
// TODO: move const to proper place | ||
const ( | ||
OldDenom = "cony" | ||
NewDenom = "TBD" | ||
SwapMultiple = 123 | ||
) | ||
|
||
func NewKeeper( | ||
cdc codec.BinaryCodec, | ||
ak types.AccountKeeper, | ||
bk types.BankKeeper, | ||
storeKey storetypes.StoreKey, | ||
) Keeper { | ||
return Keeper{ | ||
cdc: cdc, | ||
accountKeeper: ak, | ||
bankKeeper: bk, | ||
storeKey: storeKey, | ||
type Keeper struct { | ||
cdc codec.BinaryCodec | ||
storeKey storetypes.StoreKey | ||
|
||
AccountKeeper | ||
BankKeeper | ||
} | ||
|
||
func NewKeeper(cdc codec.BinaryCodec, storeKey storetypes.StoreKey, ak AccountKeeper, bk BankKeeper) *Keeper { | ||
return &Keeper{ | ||
cdc, | ||
storeKey, | ||
ak, | ||
bk, | ||
} | ||
} | ||
|
||
func (k Keeper) Swap(ctx sdk.Context, addr sdk.AccAddress, amount sdk.Coin) error { | ||
// 1. Check Balance | ||
// 2. Check swapCap | ||
// 3. Send coin to module | ||
// 4. Burn & Mint TBD coins(with multiple) | ||
// 5. Send back coins to addr | ||
// 6. Update swapped state | ||
if ok := k.HasBalance(ctx, addr, amount); !ok { | ||
return sdkerrors.Wrapf(sdkerrors.ErrInsufficientFunds, "not enough amount: %s", amount) | ||
} | ||
|
||
multipleAmount := amount.Amount.Mul(sdk.NewInt(SwapMultiple)) | ||
newAmount := sdk.NewCoin(NewDenom, multipleAmount) | ||
if err := k.checkSwapCap(ctx, newAmount); err != nil { | ||
return err | ||
} | ||
|
||
moduleAddr := k.GetModuleAddress(types.ModuleName) | ||
if err := k.SendCoins(ctx, addr, moduleAddr, sdk.NewCoins(amount)); err != nil { | ||
return err | ||
} | ||
|
||
if err := k.BurnCoins(ctx, types.ModuleName, sdk.NewCoins(amount)); err != nil { | ||
return err | ||
} | ||
|
||
if err := k.MintCoins(ctx, types.ModuleName, sdk.NewCoins(newAmount)); err != nil { | ||
return err | ||
} | ||
|
||
if err := k.SendCoins(ctx, moduleAddr, addr, sdk.NewCoins(newAmount)); err != nil { | ||
return err | ||
} | ||
|
||
if err := k.updateSwapped(ctx, amount, newAmount); err != nil { | ||
return err | ||
} | ||
|
||
if err := ctx.EventManager().EmitTypedEvent(&types.EventSwapCoins{ | ||
Address: addr.String(), | ||
OldCoinAmount: amount, | ||
NewCoinAmount: newAmount, | ||
}); err != nil { | ||
panic(err) | ||
} | ||
return nil | ||
} | ||
|
||
func (k Keeper) SwapAll(ctx sdk.Context, addr sdk.AccAddress) error { | ||
balance := k.GetBalance(ctx, addr, OldDenom) | ||
if balance.IsZero() { | ||
return sdkerrors.Wrapf(sdkerrors.ErrInsufficientFunds, "zero balance for %s", OldDenom) | ||
} | ||
|
||
if err := k.Swap(ctx, addr, balance); err != nil { | ||
return err | ||
} | ||
return nil | ||
} | ||
|
||
func (k Keeper) updateSwapped(ctx sdk.Context, oldAmount sdk.Coin, newAmount sdk.Coin) error { | ||
prevSwapped, err := k.GetSwapped(ctx) | ||
if err != nil { | ||
return err | ||
} | ||
updatedSwapped := &types.Swapped{ | ||
OldCoinAmount: oldAmount.Add(prevSwapped.OldCoinAmount), | ||
NewCoinAmount: newAmount.Add(prevSwapped.NewCoinAmount), | ||
} | ||
|
||
store := ctx.KVStore(k.storeKey) | ||
key := swappedKey() | ||
bz, err := k.cdc.Marshal(updatedSwapped) | ||
if err != nil { | ||
return err | ||
} | ||
store.Set(key, bz) | ||
return nil | ||
} | ||
|
||
func (k Keeper) Logger(ctx sdk.Context) log.Logger { | ||
return ctx.Logger().With("module", fmt.Sprintf("x/%s", types.ModuleName)) | ||
func (k Keeper) GetSwapped(ctx sdk.Context) (types.Swapped, error) { | ||
store := ctx.KVStore(k.storeKey) | ||
key := swappedKey() | ||
bz := store.Get(key) | ||
swapped := types.Swapped{} | ||
if err := k.cdc.Unmarshal(bz, &swapped); err != nil { | ||
return types.Swapped{}, err | ||
} | ||
return swapped, nil | ||
} | ||
|
||
func (k Keeper) setSwapCap(ctx sdk.Context) error { | ||
// TODO(bjs): how to set it only once | ||
//store := ctx.KVStore(k.storeKey) | ||
return nil | ||
} | ||
|
||
func (k Keeper) getSwapCap(ctx sdk.Context) (sdk.Coin, error) { | ||
store := ctx.KVStore(k.storeKey) | ||
bz := store.Get(swapCapKey()) | ||
if bz == nil { | ||
return sdk.Coin{}, errors.New("swap cap not found") | ||
} | ||
|
||
swapCap := sdk.Coin{} | ||
if err := k.cdc.Unmarshal(bz, &swapCap); err != nil { | ||
return sdk.Coin{}, err | ||
} | ||
return swapCap, nil | ||
} | ||
|
||
func (k Keeper) checkSwapCap(ctx sdk.Context, amountNewCoin sdk.Coin) error { | ||
swapCap, err := k.getSwapCap(ctx) | ||
if err != nil { | ||
return err | ||
} | ||
swapped, err := k.GetSwapped(ctx) | ||
if err != nil { | ||
return err | ||
} | ||
if swapCap.IsLT(swapped.GetNewCoinAmount().Add(amountNewCoin)) { | ||
return errors.New("not enough swap coin amount") | ||
} | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package keeper | ||
|
||
import ( | ||
"testing" | ||
) | ||
|
||
func TestNewKeeper(t *testing.T) { | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package keeper | ||
|
||
import "cosmossdk.io/collections" | ||
|
||
var ( | ||
paramsKeyValue = collections.NewPrefix(0) | ||
swappedKeyValue = collections.NewPrefix(1) | ||
swapCapKeyValue = collections.NewPrefix(2) | ||
) | ||
|
||
func swappedKey() []byte { | ||
return swappedKeyValue.Bytes() | ||
} | ||
|
||
func swapCapKey() []byte { | ||
return swapCapKeyValue.Bytes() | ||
} |
Oops, something went wrong.