mirror of
				https://github.com/0glabs/0g-chain.git
				synced 2025-11-04 00:07:51 +00:00 
			
		
		
		
	[R4R] BEP3 module spec and clean up (#450)
* bump SDK version to v0.38.2 * fix module.go and remove codespaces * fix coins Add() * fixes to handlers * migrate errors * more fixes * fixes fixes fixes * build * check for paramstore keytable * empty param validation function (TODO) * param validations * fix some tests * fix all tests * simulation fixes (WIP) * auction and bep3 sim refactor * fixes * bep3 sims fixes * auction and pricefeed fix * cdp sims fixes * fix tests * Update x/auction/keeper/auctions.go Co-Authored-By: Denali Marsh <denali@kava.io> * Update x/bep3/types/params.go Co-Authored-By: Denali Marsh <denali@kava.io> * Apply suggestions from code review Co-Authored-By: Denali Marsh <denali@kava.io> * Update x/bep3/keeper/swap.go Co-Authored-By: Denali Marsh <denali@kava.io> * address comments from review * address comments from review * fix: run sims * fix: implement marshal/unmarshal JSON for validator vesting account * fix: don't call set on sealed config * remove swap interface * add concepts spec * add state spec * add messages spec * update event names * implement swap expired event * add events spec * add params spec * add begin block spec * add module readme * update alias * revisions * aggregate expired swap ids for event emisison * markdown-link-check-disable for circleci * exclude api-endpoint links in Makefile Co-authored-by: Federico Kunze <federico.kunze94@gmail.com> Co-authored-by: Federico Kunze <31522760+fedekunze@users.noreply.github.com> Co-authored-by: Kevin Davis <kjydavis3@gmail.com>
This commit is contained in:
		
							parent
							
								
									cd6cb852ad
								
							
						
					
					
						commit
						a4c5a13822
					
				
							
								
								
									
										2
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								Makefile
									
									
									
									
									
								
							@ -101,7 +101,7 @@ clean:
 | 
			
		||||
# This tool checks local markdown links as well.
 | 
			
		||||
# Set to exclude riot links as they trigger false positives
 | 
			
		||||
link-check:
 | 
			
		||||
	@go run github.com/raviqqe/liche -r . --exclude "^http://127.*|^https://riot.im/app*"
 | 
			
		||||
	@go run github.com/raviqqe/liche -r . --exclude "^http://127.*|^https://riot.im/app*|^http://kava-testnet*|^https://testnet-dex*"
 | 
			
		||||
 | 
			
		||||
########################################
 | 
			
		||||
### Testing
 | 
			
		||||
 | 
			
		||||
@ -21,8 +21,8 @@ import (
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	errorNotEnoughCoins  = errors.New("account doesn't have enough coins")
 | 
			
		||||
	errorCantReceiveBids = errors.New("auction can't receive bids (lot = 0 in reverse auction)")
 | 
			
		||||
	noOpMsg             = simulation.NoOpMsg(types.ModuleName)
 | 
			
		||||
	ErrorNotEnoughCoins = errors.New("account doesn't have enough coins")
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Simulation operation weights constants
 | 
			
		||||
@ -72,11 +72,10 @@ func SimulateMsgPlaceBid(ak auth.AccountKeeper, keeper keeper.Keeper) simulation
 | 
			
		||||
 | 
			
		||||
		// search through auctions and an accounts to find a pair where a bid can be placed (ie account has enough coins to place bid on auction)
 | 
			
		||||
		blockTime := ctx.BlockHeader().Time
 | 
			
		||||
		params := keeper.GetParams(ctx)
 | 
			
		||||
		bidder, openAuction, found := findValidAccountAuctionPair(accs, openAuctions, func(acc simulation.Account, auc types.Auction) bool {
 | 
			
		||||
			account := ak.GetAccount(ctx, acc.Address)
 | 
			
		||||
			_, err := generateBidAmount(r, params, auc, account, blockTime)
 | 
			
		||||
			if err == errorNotEnoughCoins || err == errorCantReceiveBids {
 | 
			
		||||
			_, err := generateBidAmount(r, auc, account, blockTime)
 | 
			
		||||
			if err == ErrorNotEnoughCoins {
 | 
			
		||||
				return false // keep searching
 | 
			
		||||
			} else if err != nil {
 | 
			
		||||
				panic(err) // raise errors
 | 
			
		||||
@ -89,21 +88,27 @@ func SimulateMsgPlaceBid(ak auth.AccountKeeper, keeper keeper.Keeper) simulation
 | 
			
		||||
 | 
			
		||||
		bidderAcc := ak.GetAccount(ctx, bidder.Address)
 | 
			
		||||
		if bidderAcc == nil {
 | 
			
		||||
			return simulation.NoOpMsg(types.ModuleName), nil, fmt.Errorf("couldn't find account %s", bidder.Address)
 | 
			
		||||
			return simulation.NoOpMsg(types.ModuleName), nil, nil
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// pick a bid amount for the chosen auction and bidder
 | 
			
		||||
		amount, err := generateBidAmount(r, params, openAuction, bidderAcc, blockTime)
 | 
			
		||||
		if err != nil { // shouldn't happen given the checks above
 | 
			
		||||
		amount, err := generateBidAmount(r, openAuction, bidderAcc, blockTime)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return simulation.NoOpMsg(types.ModuleName), nil, err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// create and deliver a tx
 | 
			
		||||
		// create a msg
 | 
			
		||||
		msg := types.NewMsgPlaceBid(openAuction.GetID(), bidder.Address, amount)
 | 
			
		||||
 | 
			
		||||
		spendable := bidderAcc.SpendableCoins(ctx.BlockTime())
 | 
			
		||||
		fees, err := simulation.RandomFees(r, ctx, spendable)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return simulation.NoOpMsg(types.ModuleName), nil, err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		tx := helpers.GenTx(
 | 
			
		||||
			[]sdk.Msg{msg},
 | 
			
		||||
			sdk.NewCoins(), // TODO pick a random amount fees
 | 
			
		||||
			fees,
 | 
			
		||||
			helpers.DefaultGenTxGas,
 | 
			
		||||
			chainID,
 | 
			
		||||
			[]uint64{bidderAcc.GetAccountNumber()},
 | 
			
		||||
@ -113,103 +118,60 @@ func SimulateMsgPlaceBid(ak auth.AccountKeeper, keeper keeper.Keeper) simulation
 | 
			
		||||
 | 
			
		||||
		_, result, err := app.Deliver(tx)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			// to aid debugging, add the stack trace to the comment field of the returned opMsg
 | 
			
		||||
			return simulation.NewOperationMsg(msg, false, fmt.Sprintf("%+v", err)), nil, err
 | 
			
		||||
			return simulation.NoOpMsg(types.ModuleName), nil, err
 | 
			
		||||
		}
 | 
			
		||||
		// to aid debugging, add the result log to the comment field
 | 
			
		||||
 | 
			
		||||
		// Return an operationMsg indicating whether the msg was submitted successfully
 | 
			
		||||
		// Using result.Log as the comment field as it contains any error message emitted by the keeper
 | 
			
		||||
		return simulation.NewOperationMsg(msg, true, result.Log), nil, nil
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func generateBidAmount(
 | 
			
		||||
	r *rand.Rand, params types.Params, auc types.Auction,
 | 
			
		||||
	bidder authexported.Account, blockTime time.Time) (sdk.Coin, error) {
 | 
			
		||||
func generateBidAmount(r *rand.Rand, auc types.Auction, bidder authexported.Account, blockTime time.Time) (sdk.Coin, error) {
 | 
			
		||||
	bidderBalance := bidder.SpendableCoins(blockTime)
 | 
			
		||||
 | 
			
		||||
	switch a := auc.(type) {
 | 
			
		||||
 | 
			
		||||
	case types.DebtAuction:
 | 
			
		||||
		// Check bidder has enough (stable coin) to pay in
 | 
			
		||||
		if bidderBalance.AmountOf(a.Bid.Denom).LT(a.Bid.Amount) { // stable coin
 | 
			
		||||
			return sdk.Coin{}, errorNotEnoughCoins
 | 
			
		||||
			return sdk.Coin{}, ErrorNotEnoughCoins
 | 
			
		||||
		}
 | 
			
		||||
		// Check auction can still receive new bids
 | 
			
		||||
		if a.Lot.Amount.Equal(sdk.ZeroInt()) {
 | 
			
		||||
			return sdk.Coin{}, errorCantReceiveBids
 | 
			
		||||
		}
 | 
			
		||||
		// Generate a new lot amount (gov coin)
 | 
			
		||||
		maxNewLotAmt := a.Lot.Amount.Sub( // new lot must be some % less than old lot, and at least 1 smaller to avoid replacing an old bid at no cost
 | 
			
		||||
			sdk.MaxInt(
 | 
			
		||||
				sdk.NewInt(1),
 | 
			
		||||
				sdk.NewDecFromInt(a.Lot.Amount).Mul(params.IncrementDebt).RoundInt(),
 | 
			
		||||
			),
 | 
			
		||||
		)
 | 
			
		||||
		amt, err := RandIntInclusive(r, sdk.ZeroInt(), maxNewLotAmt) // maxNewLotAmt shouldn't be < 0 given the check above
 | 
			
		||||
		amt, err := RandIntInclusive(r, sdk.ZeroInt(), a.Lot.Amount) // pick amount less than current lot amount // TODO min bid increments
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			panic(err)
 | 
			
		||||
		}
 | 
			
		||||
		return sdk.NewCoin(a.Lot.Denom, amt), nil // gov coin
 | 
			
		||||
 | 
			
		||||
	case types.SurplusAuction:
 | 
			
		||||
		// Check the bidder has enough (gov coin) to pay in
 | 
			
		||||
		minNewBidAmt := a.Bid.Amount.Add( // new bids must be some % greater than old bid, and at least 1 larger to avoid replacing an old bid at no cost
 | 
			
		||||
			sdk.MaxInt(
 | 
			
		||||
				sdk.NewInt(1),
 | 
			
		||||
				sdk.NewDecFromInt(a.Bid.Amount).Mul(params.IncrementSurplus).RoundInt(),
 | 
			
		||||
			),
 | 
			
		||||
		)
 | 
			
		||||
		if bidderBalance.AmountOf(a.Bid.Denom).LT(minNewBidAmt) { // gov coin
 | 
			
		||||
			return sdk.Coin{}, errorNotEnoughCoins
 | 
			
		||||
		if bidderBalance.AmountOf(a.Bid.Denom).LT(a.Bid.Amount) { // gov coin // TODO account for bid increments
 | 
			
		||||
			return sdk.Coin{}, ErrorNotEnoughCoins
 | 
			
		||||
		}
 | 
			
		||||
		// Generate a new bid amount (gov coin)
 | 
			
		||||
		amt, err := RandIntInclusive(r, minNewBidAmt, bidderBalance.AmountOf(a.Bid.Denom))
 | 
			
		||||
		amt, err := RandIntInclusive(r, a.Bid.Amount, bidderBalance.AmountOf(a.Bid.Denom))
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			panic(err)
 | 
			
		||||
		}
 | 
			
		||||
		return sdk.NewCoin(a.Bid.Denom, amt), nil // gov coin
 | 
			
		||||
 | 
			
		||||
	case types.CollateralAuction:
 | 
			
		||||
		// Check the bidder has enough (stable coin) to pay in
 | 
			
		||||
		minNewBidAmt := a.Bid.Amount.Add( // new bids must be some % greater than old bid, and at least 1 larger to avoid replacing an old bid at no cost
 | 
			
		||||
			sdk.MaxInt(
 | 
			
		||||
				sdk.NewInt(1),
 | 
			
		||||
				sdk.NewDecFromInt(a.Bid.Amount).Mul(params.IncrementCollateral).RoundInt(),
 | 
			
		||||
			),
 | 
			
		||||
		)
 | 
			
		||||
		minNewBidAmt = sdk.MinInt(minNewBidAmt, a.MaxBid.Amount) // allow new bids to hit MaxBid even though it may be less than the increment %
 | 
			
		||||
		if bidderBalance.AmountOf(a.Bid.Denom).LT(minNewBidAmt) {
 | 
			
		||||
			return sdk.Coin{}, errorNotEnoughCoins
 | 
			
		||||
		if bidderBalance.AmountOf(a.Bid.Denom).LT(a.Bid.Amount) { // stable coin // TODO account for bid increments (in forward phase)
 | 
			
		||||
			return sdk.Coin{}, ErrorNotEnoughCoins
 | 
			
		||||
		}
 | 
			
		||||
		// Check auction can still receive new bids
 | 
			
		||||
		if a.IsReversePhase() && a.Lot.Amount.Equal(sdk.ZeroInt()) {
 | 
			
		||||
			return sdk.Coin{}, errorCantReceiveBids
 | 
			
		||||
		}
 | 
			
		||||
		// Generate a new bid amount (collateral coin in reverse phase)
 | 
			
		||||
		if a.IsReversePhase() {
 | 
			
		||||
			maxNewLotAmt := a.Lot.Amount.Sub( // new lot must be some % less than old lot, and at least 1 smaller to avoid replacing an old bid at no cost
 | 
			
		||||
				sdk.MaxInt(
 | 
			
		||||
					sdk.NewInt(1),
 | 
			
		||||
					sdk.NewDecFromInt(a.Lot.Amount).Mul(params.IncrementCollateral).RoundInt(),
 | 
			
		||||
				),
 | 
			
		||||
			)
 | 
			
		||||
			amt, err := RandIntInclusive(r, sdk.ZeroInt(), maxNewLotAmt) // maxNewLotAmt shouldn't be < 0 given the check above
 | 
			
		||||
			amt, err := RandIntInclusive(r, sdk.ZeroInt(), a.Lot.Amount) // pick amount less than current lot amount
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				panic(err)
 | 
			
		||||
			}
 | 
			
		||||
			return sdk.NewCoin(a.Lot.Denom, amt), nil // collateral coin
 | 
			
		||||
 | 
			
		||||
			// Generate a new bid amount (stable coin in forward phase)
 | 
			
		||||
		} else {
 | 
			
		||||
			amt, err := RandIntInclusive(r, minNewBidAmt, sdk.MinInt(bidderBalance.AmountOf(a.Bid.Denom), a.MaxBid.Amount))
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				panic(err)
 | 
			
		||||
			}
 | 
			
		||||
			// when the bidder has enough coins, pick the MaxBid amount more frequently to increase chance auctions phase get into reverse phase
 | 
			
		||||
			if r.Intn(2) == 0 && bidderBalance.AmountOf(a.Bid.Denom).GTE(a.MaxBid.Amount) { // 50%
 | 
			
		||||
				amt = a.MaxBid.Amount
 | 
			
		||||
			}
 | 
			
		||||
			return sdk.NewCoin(a.Bid.Denom, amt), nil // stable coin
 | 
			
		||||
		}
 | 
			
		||||
		amt, err := RandIntInclusive(r, a.Bid.Amount, sdk.MinInt(bidderBalance.AmountOf(a.Bid.Denom), a.MaxBid.Amount))
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			panic(err)
 | 
			
		||||
		}
 | 
			
		||||
		// pick the MaxBid amount more frequently to increase chance auctions phase get into reverse phase
 | 
			
		||||
		if r.Intn(10) == 0 { // 10%
 | 
			
		||||
			amt = a.MaxBid.Amount
 | 
			
		||||
		}
 | 
			
		||||
		return sdk.NewCoin(a.Bid.Denom, amt), nil // stable coin
 | 
			
		||||
 | 
			
		||||
	default:
 | 
			
		||||
		return sdk.Coin{}, fmt.Errorf("unknown auction type")
 | 
			
		||||
 | 
			
		||||
@ -10,6 +10,7 @@ const (
 | 
			
		||||
	AddrByteCount                  = types.AddrByteCount
 | 
			
		||||
	AttributeKeyAmount             = types.AttributeKeyAmount
 | 
			
		||||
	AttributeKeyAtomicSwapID       = types.AttributeKeyAtomicSwapID
 | 
			
		||||
	AttributeKeyAtomicSwapIDs      = types.AttributeKeyAtomicSwapIDs
 | 
			
		||||
	AttributeKeyClaimSender        = types.AttributeKeyClaimSender
 | 
			
		||||
	AttributeKeyDirection          = types.AttributeKeyDirection
 | 
			
		||||
	AttributeKeyExpectedIncome     = types.AttributeKeyExpectedIncome
 | 
			
		||||
@ -31,8 +32,8 @@ const (
 | 
			
		||||
	DepositAtomicSwap              = types.DepositAtomicSwap
 | 
			
		||||
	EventTypeClaimAtomicSwap       = types.EventTypeClaimAtomicSwap
 | 
			
		||||
	EventTypeCreateAtomicSwap      = types.EventTypeCreateAtomicSwap
 | 
			
		||||
	EventTypeDepositAtomicSwap     = types.EventTypeDepositAtomicSwap
 | 
			
		||||
	EventTypeRefundAtomicSwap      = types.EventTypeRefundAtomicSwap
 | 
			
		||||
	EventTypeSwapsExpired          = types.EventTypeSwapsExpired
 | 
			
		||||
	Expired                        = types.Expired
 | 
			
		||||
	INVALID                        = types.INVALID
 | 
			
		||||
	Incoming                       = types.Incoming
 | 
			
		||||
@ -135,7 +136,6 @@ type (
 | 
			
		||||
	QueryAtomicSwapByID = types.QueryAtomicSwapByID
 | 
			
		||||
	QueryAtomicSwaps    = types.QueryAtomicSwaps
 | 
			
		||||
	SupplyKeeper        = types.SupplyKeeper
 | 
			
		||||
	Swap                = types.Swap
 | 
			
		||||
	SwapDirection       = types.SwapDirection
 | 
			
		||||
	SwapStatus          = types.SwapStatus
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
@ -77,6 +77,9 @@ func (k Keeper) CreateAtomicSwap(ctx sdk.Context, randomNumberHash []byte, times
 | 
			
		||||
		timestamp, sender, recipient, senderOtherChain, recipientOtherChain, 0, types.Open,
 | 
			
		||||
		crossChain, direction)
 | 
			
		||||
 | 
			
		||||
	k.SetAtomicSwap(ctx, atomicSwap)
 | 
			
		||||
	k.InsertIntoByBlockIndex(ctx, atomicSwap)
 | 
			
		||||
 | 
			
		||||
	// Emit 'create_atomic_swap' event
 | 
			
		||||
	ctx.EventManager().EmitEvent(
 | 
			
		||||
		sdk.NewEvent(
 | 
			
		||||
@ -94,8 +97,6 @@ func (k Keeper) CreateAtomicSwap(ctx sdk.Context, randomNumberHash []byte, times
 | 
			
		||||
		),
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	k.SetAtomicSwap(ctx, atomicSwap)
 | 
			
		||||
	k.InsertIntoByBlockIndex(ctx, atomicSwap)
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -103,7 +104,7 @@ func (k Keeper) CreateAtomicSwap(ctx sdk.Context, randomNumberHash []byte, times
 | 
			
		||||
func (k Keeper) ClaimAtomicSwap(ctx sdk.Context, from sdk.AccAddress, swapID []byte, randomNumber []byte) error {
 | 
			
		||||
	atomicSwap, found := k.GetAtomicSwap(ctx, swapID)
 | 
			
		||||
	if !found {
 | 
			
		||||
		return sdkerrors.Wrapf(types.ErrAtomicSwapNotFound, "%d", swapID)
 | 
			
		||||
		return sdkerrors.Wrapf(types.ErrAtomicSwapNotFound, "%s", swapID)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Only open atomic swaps can be claimed
 | 
			
		||||
@ -148,6 +149,15 @@ func (k Keeper) ClaimAtomicSwap(ctx sdk.Context, from sdk.AccAddress, swapID []b
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Complete swap
 | 
			
		||||
	atomicSwap.Status = types.Completed
 | 
			
		||||
	atomicSwap.ClosedBlock = ctx.BlockHeight()
 | 
			
		||||
	k.SetAtomicSwap(ctx, atomicSwap)
 | 
			
		||||
 | 
			
		||||
	// Remove from byBlock index and transition to longterm storage
 | 
			
		||||
	k.RemoveFromByBlockIndex(ctx, atomicSwap)
 | 
			
		||||
	k.InsertIntoLongtermStorage(ctx, atomicSwap)
 | 
			
		||||
 | 
			
		||||
	// Emit 'claim_atomic_swap' event
 | 
			
		||||
	ctx.EventManager().EmitEvent(
 | 
			
		||||
		sdk.NewEvent(
 | 
			
		||||
@ -160,14 +170,6 @@ func (k Keeper) ClaimAtomicSwap(ctx sdk.Context, from sdk.AccAddress, swapID []b
 | 
			
		||||
		),
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	// Complete swap
 | 
			
		||||
	atomicSwap.Status = types.Completed
 | 
			
		||||
	atomicSwap.ClosedBlock = ctx.BlockHeight()
 | 
			
		||||
	k.SetAtomicSwap(ctx, atomicSwap)
 | 
			
		||||
 | 
			
		||||
	// Remove from byBlock index and transition to longterm storage
 | 
			
		||||
	k.RemoveFromByBlockIndex(ctx, atomicSwap)
 | 
			
		||||
	k.InsertIntoLongtermStorage(ctx, atomicSwap)
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -202,6 +204,14 @@ func (k Keeper) RefundAtomicSwap(ctx sdk.Context, from sdk.AccAddress, swapID []
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Complete swap
 | 
			
		||||
	atomicSwap.Status = types.Completed
 | 
			
		||||
	atomicSwap.ClosedBlock = ctx.BlockHeight()
 | 
			
		||||
	k.SetAtomicSwap(ctx, atomicSwap)
 | 
			
		||||
 | 
			
		||||
	// Transition to longterm storage
 | 
			
		||||
	k.InsertIntoLongtermStorage(ctx, atomicSwap)
 | 
			
		||||
 | 
			
		||||
	// Emit 'refund_atomic_swap' event
 | 
			
		||||
	ctx.EventManager().EmitEvent(
 | 
			
		||||
		sdk.NewEvent(
 | 
			
		||||
@ -213,13 +223,6 @@ func (k Keeper) RefundAtomicSwap(ctx sdk.Context, from sdk.AccAddress, swapID []
 | 
			
		||||
		),
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	// Complete swap
 | 
			
		||||
	atomicSwap.Status = types.Completed
 | 
			
		||||
	atomicSwap.ClosedBlock = ctx.BlockHeight()
 | 
			
		||||
	k.SetAtomicSwap(ctx, atomicSwap)
 | 
			
		||||
 | 
			
		||||
	// Transition to longterm storage
 | 
			
		||||
	k.InsertIntoLongtermStorage(ctx, atomicSwap)
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -232,12 +235,24 @@ func (k Keeper) UpdateExpiredAtomicSwaps(ctx sdk.Context) error {
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	// Expire incomplete swaps (claimed swaps have already been removed from byBlock index)
 | 
			
		||||
	var expiredSwapIDs []string
 | 
			
		||||
	for _, id := range expiredSwaps {
 | 
			
		||||
		swap, _ := k.GetAtomicSwap(ctx, id)
 | 
			
		||||
		swap.Status = types.Expired
 | 
			
		||||
		k.SetAtomicSwap(ctx, swap)
 | 
			
		||||
		k.RemoveFromByBlockIndex(ctx, swap)
 | 
			
		||||
		atomicSwap, _ := k.GetAtomicSwap(ctx, id)
 | 
			
		||||
		atomicSwap.Status = types.Expired
 | 
			
		||||
		k.SetAtomicSwap(ctx, atomicSwap)
 | 
			
		||||
		k.RemoveFromByBlockIndex(ctx, atomicSwap)
 | 
			
		||||
		expiredSwapIDs = append(expiredSwapIDs, hex.EncodeToString(atomicSwap.GetSwapID()))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Emit 'swaps_expired' event
 | 
			
		||||
		ctx.EventManager().EmitEvent(
 | 
			
		||||
			sdk.NewEvent(
 | 
			
		||||
				types.EventTypeSwapsExpired,
 | 
			
		||||
				sdk.NewAttribute(types.AttributeKeyAtomicSwapIDs, fmt.Sprintf("%s", expiredSwapIDs)),
 | 
			
		||||
				sdk.NewAttribute(types.AttributeExpirationBlock, fmt.Sprintf("%d", ctx.BlockHeight())),
 | 
			
		||||
			),
 | 
			
		||||
		)
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -337,7 +337,7 @@ func (suite *AtomicSwapTestSuite) TestCreateAtomicSwap() {
 | 
			
		||||
				suite.NotNil(actualSwap)
 | 
			
		||||
 | 
			
		||||
				// Confirm swap contents
 | 
			
		||||
				expectedSwap := types.Swap(
 | 
			
		||||
				expectedSwap :=
 | 
			
		||||
					types.AtomicSwap{
 | 
			
		||||
						Amount:              tc.args.coins,
 | 
			
		||||
						RandomNumberHash:    tc.args.randomNumberHash,
 | 
			
		||||
@ -351,7 +351,7 @@ func (suite *AtomicSwapTestSuite) TestCreateAtomicSwap() {
 | 
			
		||||
						Status:              types.Open,
 | 
			
		||||
						CrossChain:          tc.args.crossChain,
 | 
			
		||||
						Direction:           tc.args.direction,
 | 
			
		||||
					})
 | 
			
		||||
					}
 | 
			
		||||
				suite.Equal(expectedSwap, actualSwap)
 | 
			
		||||
			} else {
 | 
			
		||||
				suite.Error(err)
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										36
									
								
								x/bep3/spec/01_concepts.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								x/bep3/spec/01_concepts.md
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,36 @@
 | 
			
		||||
# Concepts
 | 
			
		||||
 | 
			
		||||
 The BEP3 module implements the [BEP3 protocol](https://github.com/binance-chain/BEPs/blob/master/BEP3.md) for secure cross-chain asset transfers between Kava and other BEP3 compatible chains, such as Binance Chain. Tranactions are witnessed and relayed between the two blockchains by Binance's BEP3 deputy process. The deputy maintains an address on both chains and is responsible for delivering tokens upon the successful completion of an Atomic Swap. Learn more about the BEP3 deputy process [here](https://github.com/binance-chain/bep3-deputy).
 | 
			
		||||
 | 
			
		||||
## Requirements
 | 
			
		||||
Kava
 | 
			
		||||
- The deputy’s Kava testnet-5000 address is **kava1aphsdnz5hu2t5ty2au6znprug5kx3zpy6zwq29**.
 | 
			
		||||
- We recommend using http://kava-testnet-5000.kava.io:1317 as Kava’s API endpoint.
 | 
			
		||||
 | 
			
		||||
Binance Chain
 | 
			
		||||
- The deputy’s Binance Chain testnet address is **tbnb1et8vmd0dgvswjnyaf73ez8ye0jehc8a7t7fljv**.
 | 
			
		||||
- We recommend using https://testnet-dex.binance.org/ as Binance Chain’s API endpoint.
 | 
			
		||||
 | 
			
		||||
Kava's [JavaScript SDK](https://github.com/Kava-Labs/javascript-sdk) and Binance Chain’s [JavaScript SDK](https://github.com/binance-chain/javascript-sdk) can be used to create, claim, and refund swaps.
 | 
			
		||||
 | 
			
		||||
## Binance Chain to Kava
 | 
			
		||||
 | 
			
		||||
When a user wants to transfer tokens from Binance Chain to Kava, the following steps are taken:
 | 
			
		||||
1. User’s tokens are locked on Binance Chain along with the hash of a secret only known to the user. If the secret is not revealed before the deadline, the tokens are refundable.
 | 
			
		||||
2. The deputy sends a message to Kava saying “a user has locked X tokens, if their secret is revealed before the deadline issue them an equivalent amount of pegged tokens”.
 | 
			
		||||
3. The user reveals the secret on Kava and receives the pegged tokens.
 | 
			
		||||
4. The deputy relays the secret to Binance Chain and the original tokens are locked permanently.   
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
## Kava to Binance Chain
 | 
			
		||||
1. When a user wants to transfer tokens from Kava to Binance Chain by redeeming pegged tokens, the following steps are taken:
 | 
			
		||||
User’s pegged tokens are locked on Kava along with the hash of a secret only known to the user. If the secret is not revealed before the deadline, the tokens are refundable.
 | 
			
		||||
2. The deputy sends a message to Binance Chain saying “a user has locked X pegged tokens, if their secret is revealed before the deadline issue them an equivalent amount of tokens”.
 | 
			
		||||
3. The user reveals the secret on Binance Chain and receives the tokens.
 | 
			
		||||
4. The deputy relays the secret to Kava and the pegged tokens are locked permanently.   
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
							
								
								
									
										82
									
								
								x/bep3/spec/02_state.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								x/bep3/spec/02_state.md
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,82 @@
 | 
			
		||||
# State
 | 
			
		||||
 | 
			
		||||
## Parameters and genesis state
 | 
			
		||||
 | 
			
		||||
`Paramaters` define the rules according to which swaps are executed. Parameter updates can be made via on-chain parameter update proposals.
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
// Params governance parameters for bep3 module
 | 
			
		||||
type Params struct {
 | 
			
		||||
	BnbDeputyAddress sdk.AccAddress `json:"bnb_deputy_address" yaml:"bnb_deputy_address"` // deputy's address on Kava
 | 
			
		||||
	MinBlockLock     int64          `json:"min_block_lock" yaml:"min_block_lock"` // minimum swap expire height
 | 
			
		||||
	MaxBlockLock     int64          `json:"max_block_lock" yaml:"max_block_lock"` // maximum swap expire height
 | 
			
		||||
	SupportedAssets  AssetParams    `json:"supported_assets" yaml:"supported_assets"` // array of supported asset
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AssetParam governance parameters for each asset within a supported chain
 | 
			
		||||
type AssetParam struct {
 | 
			
		||||
	Denom  string  `json:"denom" yaml:"denom"`     // name of the asset
 | 
			
		||||
	CoinID int     `json:"coin_id" yaml:"coin_id"` // internationally recognized coin ID
 | 
			
		||||
	Limit  sdk.Int `json:"limit" yaml:"limit"`     // asset supply limit
 | 
			
		||||
	Active bool    `json:"active" yaml:"active"`   // denotes if asset is active or paused
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
`GenesisState` defines the state that must be persisted when the blockchain stops/restarts in order for normal function of the bep3 module to resume.
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
// GenesisState - all bep3 state that must be provided at genesis
 | 
			
		||||
type GenesisState struct {
 | 
			
		||||
	Params        Params        `json:"params" yaml:"params"`
 | 
			
		||||
	AtomicSwaps   AtomicSwaps   `json:"atomic_swaps" yaml:"atomic_swaps"`
 | 
			
		||||
	AssetSupplies AssetSupplies `json:"assets_supplies" yaml:"assets_supplies"`
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Types
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
// AtomicSwap contains the information for an atomic swap
 | 
			
		||||
type AtomicSwap struct {
 | 
			
		||||
	Amount              sdk.Coins        `json:"amount"  yaml:"amount"`
 | 
			
		||||
	RandomNumberHash    tmbytes.HexBytes `json:"random_number_hash"  yaml:"random_number_hash"`
 | 
			
		||||
	ExpireHeight        int64            `json:"expire_height"  yaml:"expire_height"`
 | 
			
		||||
	Timestamp           int64            `json:"timestamp"  yaml:"timestamp"`
 | 
			
		||||
	Sender              sdk.AccAddress   `json:"sender"  yaml:"sender"`
 | 
			
		||||
	Recipient           sdk.AccAddress   `json:"recipient"  yaml:"recipient"`
 | 
			
		||||
	SenderOtherChain    string           `json:"sender_other_chain"  yaml:"sender_other_chain"`
 | 
			
		||||
	RecipientOtherChain string           `json:"recipient_other_chain"  yaml:"recipient_other_chain"`
 | 
			
		||||
	ClosedBlock         int64            `json:"closed_block"  yaml:"closed_block"`
 | 
			
		||||
	Status              SwapStatus       `json:"status"  yaml:"status"`
 | 
			
		||||
	CrossChain          bool             `json:"cross_chain"  yaml:"cross_chain"`
 | 
			
		||||
	Direction           SwapDirection    `json:"direction"  yaml:"direction"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SwapStatus is the status of an AtomicSwap
 | 
			
		||||
type SwapStatus byte
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	NULL      SwapStatus = 0x00
 | 
			
		||||
	Open      SwapStatus = 0x01
 | 
			
		||||
	Completed SwapStatus = 0x02
 | 
			
		||||
	Expired   SwapStatus = 0x03
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// SwapDirection is the direction of an AtomicSwap
 | 
			
		||||
type SwapDirection byte
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	INVALID  SwapDirection = 0x00
 | 
			
		||||
	Incoming SwapDirection = 0x01
 | 
			
		||||
	Outgoing SwapDirection = 0x02
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// AssetSupply contains information about an asset's supply
 | 
			
		||||
type AssetSupply struct {
 | 
			
		||||
	Denom          string   `json:"denom"  yaml:"denom"`
 | 
			
		||||
	IncomingSupply sdk.Coin `json:"incoming_supply"  yaml:"incoming_supply"`
 | 
			
		||||
	OutgoingSupply sdk.Coin `json:"outgoing_supply"  yaml:"outgoing_supply"`
 | 
			
		||||
	CurrentSupply  sdk.Coin `json:"current_supply"  yaml:"current_supply"`
 | 
			
		||||
	Limit          sdk.Coin `json:"limit"  yaml:"limit"`
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
							
								
								
									
										48
									
								
								x/bep3/spec/03_messages.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								x/bep3/spec/03_messages.md
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,48 @@
 | 
			
		||||
# Messages
 | 
			
		||||
 | 
			
		||||
## Create swap
 | 
			
		||||
 | 
			
		||||
Swaps are created using the `MsgCreateAtomicSwap` message type.
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
// MsgCreateAtomicSwap contains an AtomicSwap struct
 | 
			
		||||
type MsgCreateAtomicSwap struct {
 | 
			
		||||
	From                sdk.AccAddress   `json:"from"  yaml:"from"`
 | 
			
		||||
	To                  sdk.AccAddress   `json:"to"  yaml:"to"`
 | 
			
		||||
	RecipientOtherChain string           `json:"recipient_other_chain"  yaml:"recipient_other_chain"`
 | 
			
		||||
	SenderOtherChain    string           `json:"sender_other_chain"  yaml:"sender_other_chain"`
 | 
			
		||||
	RandomNumberHash    tmbytes.HexBytes `json:"random_number_hash"  yaml:"random_number_hash"`
 | 
			
		||||
	Timestamp           int64            `json:"timestamp"  yaml:"timestamp"`
 | 
			
		||||
	Amount              sdk.Coins        `json:"amount"  yaml:"amount"`
 | 
			
		||||
	ExpectedIncome      string           `json:"expected_income"  yaml:"expected_income"`
 | 
			
		||||
	HeightSpan          int64            `json:"height_span"  yaml:"height_span"`
 | 
			
		||||
	CrossChain          bool             `json:"cross_chain"  yaml:"cross_chain"`
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Claim swap
 | 
			
		||||
 | 
			
		||||
Active swaps are claimed using the `MsgClaimAtomicSwap` message type.
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
// MsgClaimAtomicSwap defines a AtomicSwap claim
 | 
			
		||||
type MsgClaimAtomicSwap struct {
 | 
			
		||||
	From         sdk.AccAddress   `json:"from"  yaml:"from"`
 | 
			
		||||
	SwapID       tmbytes.HexBytes `json:"swap_id"  yaml:"swap_id"`
 | 
			
		||||
	RandomNumber tmbytes.HexBytes `json:"random_number"  yaml:"random_number"`
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## Refund swap
 | 
			
		||||
 | 
			
		||||
Expired swaps are refunded using the `MsgRefundAtomicSwap` message type.
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
// MsgRefundAtomicSwap defines a refund msg
 | 
			
		||||
type MsgRefundAtomicSwap struct {
 | 
			
		||||
	From   sdk.AccAddress   `json:"from" yaml:"from"`
 | 
			
		||||
	SwapID tmbytes.HexBytes `json:"swap_id" yaml:"swap_id"`
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
							
								
								
									
										52
									
								
								x/bep3/spec/04_events.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								x/bep3/spec/04_events.md
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,52 @@
 | 
			
		||||
# Events
 | 
			
		||||
 | 
			
		||||
The `x/bep3` module emits the following events:
 | 
			
		||||
 | 
			
		||||
## Handlers
 | 
			
		||||
 | 
			
		||||
### MsgCreateAtomicSwap
 | 
			
		||||
 | 
			
		||||
| Type               | Attribute Key      | Attribute Value          |
 | 
			
		||||
|--------------------|--------------------|--------------------------|
 | 
			
		||||
| create_atomic_swap | sender             | {sender address}         |
 | 
			
		||||
| create_atomic_swap | recipient          | {recipient address}      |
 | 
			
		||||
| create_atomic_swap | atomic_swap_id     | {swap ID}                |
 | 
			
		||||
| create_atomic_swap | random_number_hash | {random number hash}     |
 | 
			
		||||
| create_atomic_swap | timestamp          | {timestamp}              |
 | 
			
		||||
| create_atomic_swap | sender_other_chain | {sender other chain}     |
 | 
			
		||||
| create_atomic_swap | expire_height      | {swap expiration block}  |
 | 
			
		||||
| create_atomic_swap | amount             | {coin amount}            |
 | 
			
		||||
| create_atomic_swap | expected_income    | {expected value received}|
 | 
			
		||||
| create_atomic_swap | direction          | {incoming or outgoing}   |
 | 
			
		||||
| message            | module             | bep3                     |
 | 
			
		||||
| message            | sender             | {sender address}         |
 | 
			
		||||
 | 
			
		||||
### MsgClaimAtomicSwap
 | 
			
		||||
 | 
			
		||||
| Type               | Attribute Key      | Attribute Value          |
 | 
			
		||||
|--------------------|--------------------|--------------------------|
 | 
			
		||||
| claim_atomic_swap  | claim_sender       | {sender address}         |
 | 
			
		||||
| claim_atomic_swap  | recipient          | {recipient address}      |
 | 
			
		||||
| claim_atomic_swap  | atomic_swap_id     | {swap ID}                |
 | 
			
		||||
| claim_atomic_swap  | random_number_hash | {random number hash}     |
 | 
			
		||||
| claim_atomic_swap  | random_number      | {secret random number}   |
 | 
			
		||||
| message            | module             | bep3                     |
 | 
			
		||||
| message            | sender             | {sender address}         |
 | 
			
		||||
 | 
			
		||||
## MsgRefundAtomicSwap
 | 
			
		||||
 | 
			
		||||
| Type               | Attribute Key      | Attribute Value          |
 | 
			
		||||
|--------------------|--------------------|--------------------------|
 | 
			
		||||
| refund_atomic_swap | refund_sender      | {sender address}         |
 | 
			
		||||
| refund_atomic_swap | sender             | {swap creator address}   |
 | 
			
		||||
| refund_atomic_swap | atomic_swap_id     | {swap ID}                |
 | 
			
		||||
| refund_atomic_swap | random_number_hash | {random number hash}     |
 | 
			
		||||
| message            | module             | bep3                     |
 | 
			
		||||
| message            | sender             | {sender address}         |
 | 
			
		||||
 | 
			
		||||
## BeginBlock
 | 
			
		||||
 | 
			
		||||
| Type          | Attribute Key    | Attribute Value              |
 | 
			
		||||
|---------------|------------------|------------------------------|
 | 
			
		||||
| swaps_expired | atomic_swap_ids  | {array of swap IDs}          |
 | 
			
		||||
| swaps_expired | expiration_block | {block height at expiration} |
 | 
			
		||||
							
								
								
									
										16
									
								
								x/bep3/spec/05_params.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								x/bep3/spec/05_params.md
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,16 @@
 | 
			
		||||
# Parameters
 | 
			
		||||
 | 
			
		||||
The bep3 module contains the following parameters:
 | 
			
		||||
 | 
			
		||||
| Key               | Type                    | Example                                       | Description                   |
 | 
			
		||||
|-------------------|-------------------------|-----------------------------------------------|-------------------------------|
 | 
			
		||||
| BnbDeputyAddress  | string (sdk.AccAddress) | "kava1xy7hrjy9r0algz9w3gzm8u6mrpq97kwta747gj" | deputy's Kava address         |
 | 
			
		||||
| MinBlockLock      | int64                   | 80                                            | minimum swap expire height    |
 | 
			
		||||
| MaxBlockLock      | int64                   | 600                                           | maximum swap expire height    |
 | 
			
		||||
| SupportedAssets   | AssetParams             | []AssetParam                                  | array of supported assets     |
 | 
			
		||||
|-------------------|-------------------------|-----------------------------------------------|-------------------------------|
 | 
			
		||||
| AssetParam        | AssetParam              | AssetParam{"bnb", 714, sdk.NewInt(100), true} | a supported asset             |
 | 
			
		||||
| AssetParam.Denom  | string                  | "bnb"                                         | asset's name                  |
 | 
			
		||||
| AssetParam.CoinID | int64                   | 714                                           | asset's international coin ID |
 | 
			
		||||
| AssetParam.Limit  | sdk.Int                 | sdk.NewInt(100)                               | asset's supply limit          |
 | 
			
		||||
| AssetParam.Active | boolean                 | true                                          | asset's state: live or paused |
 | 
			
		||||
							
								
								
									
										19
									
								
								x/bep3/spec/06_begin_block.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								x/bep3/spec/06_begin_block.md
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,19 @@
 | 
			
		||||
# Begin Block
 | 
			
		||||
 | 
			
		||||
At the start of each block, atomic swaps that have reached `ExpireHeight` are expired. The logic to expire atomic swaps is as follows:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
	var expiredSwaps [][]byte
 | 
			
		||||
	k.IterateAtomicSwapsByBlock(ctx, uint64(ctx.BlockHeight()), func(id []byte) bool {
 | 
			
		||||
		expiredSwaps = append(expiredSwaps, id)
 | 
			
		||||
		return false
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	// Expire incomplete swaps (claimed swaps have already been removed from byBlock index)
 | 
			
		||||
	for _, id := range expiredSwaps {
 | 
			
		||||
		atomicSwap, _ := k.GetAtomicSwap(ctx, id)
 | 
			
		||||
		atomicSwap.Status = types.Expired
 | 
			
		||||
		k.SetAtomicSwap(ctx, atomicSwap)
 | 
			
		||||
		k.RemoveFromByBlockIndex(ctx, atomicSwap)
 | 
			
		||||
	}
 | 
			
		||||
```
 | 
			
		||||
@ -1,17 +1,13 @@
 | 
			
		||||
# bep3 module specification
 | 
			
		||||
# `bep3` module specification
 | 
			
		||||
 | 
			
		||||
<!-- TOC -->
 | 
			
		||||
1. **[Concepts](01_concepts.md)**
 | 
			
		||||
2. **[State](02_state.md)**
 | 
			
		||||
3. **[Messages](03_messages.md)**
 | 
			
		||||
4. **[Events](04_events.md)**
 | 
			
		||||
5. **[Params](05_params.md)**
 | 
			
		||||
6. **[BeginBlock](06_begin_block.md)**
 | 
			
		||||
 | 
			
		||||
## Abstract
 | 
			
		||||
 | 
			
		||||
<!-- TODO: Create a abstract definition of what this module does, what functionality does it enable and how it can be used. -->
 | 
			
		||||
 | 
			
		||||
## Contents
 | 
			
		||||
 | 
			
		||||
// TODO: Create the below files if they are needed.
 | 
			
		||||
<!-- 1. **[Concepts](01_concepts.md)**
 | 
			
		||||
2. **[State](02_state.md)**
 | 
			
		||||
3. **[Messages](03_messages.md)**
 | 
			
		||||
4. **[Begin-Block](04_begin_block.md)**
 | 
			
		||||
5. **[End-Block](06_end_bloc.md)**
 | 
			
		||||
6. **[05_hooks](06_hooks.md)**
 | 
			
		||||
7. **[Events](07_events.md)**
 | 
			
		||||
8. **[Parameters](08_params.md)** -->
 | 
			
		||||
`x/bep3` is an implementation of a Cosmos SDK Module that handles cross-chain Atomic Swaps between Kava and blockchains that implement the BEP3 protocol. Atomic Swaps are created, then either claimed before their expiration block or refunded after they've expired.
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								x/bep3/spec/diagrams/BEP3_binance_chain_to_kava.jpg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								x/bep3/spec/diagrams/BEP3_binance_chain_to_kava.jpg
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 30 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								x/bep3/spec/diagrams/BEP3_kava_to_binance_chain.jpg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								x/bep3/spec/diagrams/BEP3_kava_to_binance_chain.jpg
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 30 KiB  | 
@ -12,8 +12,6 @@ func init() {
 | 
			
		||||
 | 
			
		||||
// RegisterCodec registers concrete types on amino
 | 
			
		||||
func RegisterCodec(cdc *codec.Codec) {
 | 
			
		||||
	cdc.RegisterInterface((*Swap)(nil), nil)
 | 
			
		||||
 | 
			
		||||
	cdc.RegisterConcrete(MsgCreateAtomicSwap{}, "bep3/MsgCreateAtomicSwap", nil)
 | 
			
		||||
	cdc.RegisterConcrete(MsgRefundAtomicSwap{}, "bep3/MsgRefundAtomicSwap", nil)
 | 
			
		||||
	cdc.RegisterConcrete(MsgClaimAtomicSwap{}, "bep3/MsgClaimAtomicSwap", nil)
 | 
			
		||||
 | 
			
		||||
@ -29,7 +29,7 @@ func atomicSwap(index int) types.AtomicSwap {
 | 
			
		||||
	randomNumberHash := types.CalculateRandomHash(randomNumber.Bytes(), timestamp)
 | 
			
		||||
 | 
			
		||||
	swap := types.NewAtomicSwap(cs(c("bnb", 50000)), randomNumberHash, expireOffset, timestamp, kavaAddrs[0],
 | 
			
		||||
	kavaAddrs[1], binanceAddrs[0].String(), binanceAddrs[1].String(), 0, types.Open, true, types.Incoming)
 | 
			
		||||
		kavaAddrs[1], binanceAddrs[0].String(), binanceAddrs[1].String(), 0, types.Open, true, types.Incoming)
 | 
			
		||||
 | 
			
		||||
	return swap
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,13 +1,13 @@
 | 
			
		||||
package types
 | 
			
		||||
 | 
			
		||||
// bep3 module event types
 | 
			
		||||
// Events for bep3 module
 | 
			
		||||
const (
 | 
			
		||||
	EventTypeCreateAtomicSwap  = "createAtomicSwap"
 | 
			
		||||
	EventTypeDepositAtomicSwap = "depositAtomicSwap"
 | 
			
		||||
	EventTypeClaimAtomicSwap   = "claimAtomicSwap"
 | 
			
		||||
	EventTypeRefundAtomicSwap  = "refundAtomicSwap"
 | 
			
		||||
	EventTypeCreateAtomicSwap = "create_atomic_swap"
 | 
			
		||||
	EventTypeClaimAtomicSwap  = "claim_atomic_swap"
 | 
			
		||||
	EventTypeRefundAtomicSwap = "refund_atomic_swap"
 | 
			
		||||
	EventTypeSwapsExpired     = "swaps_expired"
 | 
			
		||||
 | 
			
		||||
	// Common
 | 
			
		||||
	AttributeValueCategory       = ModuleName
 | 
			
		||||
	AttributeKeySender           = "sender"
 | 
			
		||||
	AttributeKeyRecipient        = "recipient"
 | 
			
		||||
	AttributeKeyAtomicSwapID     = "atomic_swap_id"
 | 
			
		||||
@ -18,13 +18,9 @@ const (
 | 
			
		||||
	AttributeKeyAmount           = "amount"
 | 
			
		||||
	AttributeKeyExpectedIncome   = "expected_income"
 | 
			
		||||
	AttributeKeyDirection        = "direction"
 | 
			
		||||
 | 
			
		||||
	// Claim
 | 
			
		||||
	AttributeKeyClaimSender  = "claim_sender"
 | 
			
		||||
	AttributeKeyRandomNumber = "random_number"
 | 
			
		||||
 | 
			
		||||
	// Refund
 | 
			
		||||
	AttributeKeyRefundSender = "refund_sender"
 | 
			
		||||
 | 
			
		||||
	AttributeValueCategory = ModuleName
 | 
			
		||||
	AttributeKeyClaimSender      = "claim_sender"
 | 
			
		||||
	AttributeKeyRandomNumber     = "random_number"
 | 
			
		||||
	AttributeKeyRefundSender     = "refund_sender"
 | 
			
		||||
	AttributeKeyAtomicSwapIDs    = "atomic_swap_ids"
 | 
			
		||||
	AttributeExpirationBlock     = "expiration_block"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
@ -10,16 +10,8 @@ import (
 | 
			
		||||
	sdk "github.com/cosmos/cosmos-sdk/types"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Swap is an interface for handling common actions
 | 
			
		||||
type Swap interface {
 | 
			
		||||
	GetSwapID() tmbytes.HexBytes
 | 
			
		||||
	GetModuleAccountCoins() sdk.Coins
 | 
			
		||||
	Validate() error
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AtomicSwap contains the information for an atomic swap
 | 
			
		||||
type AtomicSwap struct {
 | 
			
		||||
	Swap                `json:"swap" yaml:"swap"`
 | 
			
		||||
	Amount              sdk.Coins        `json:"amount"  yaml:"amount"`
 | 
			
		||||
	RandomNumberHash    tmbytes.HexBytes `json:"random_number_hash"  yaml:"random_number_hash"`
 | 
			
		||||
	ExpireHeight        int64            `json:"expire_height"  yaml:"expire_height"`
 | 
			
		||||
@ -59,8 +51,8 @@ func (a AtomicSwap) GetSwapID() tmbytes.HexBytes {
 | 
			
		||||
	return CalculateSwapID(a.RandomNumberHash, a.Sender, a.SenderOtherChain)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetModuleAccountCoins returns the swap's amount as sdk.Coins
 | 
			
		||||
func (a AtomicSwap) GetModuleAccountCoins() sdk.Coins {
 | 
			
		||||
// GetCoins returns the swap's amount as sdk.Coins
 | 
			
		||||
func (a AtomicSwap) GetCoins() sdk.Coins {
 | 
			
		||||
	return sdk.NewCoins(a.Amount...)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -128,7 +128,7 @@ func (suite *AtomicSwapTestSuite) TestNewAtomicSwap() {
 | 
			
		||||
 | 
			
		||||
		if tc.expectPass {
 | 
			
		||||
			suite.Nil(swap.Validate())
 | 
			
		||||
			suite.Equal(tc.args.amount, swap.GetModuleAccountCoins())
 | 
			
		||||
			suite.Equal(tc.args.amount, swap.GetCoins())
 | 
			
		||||
			expectedSwapID := types.CalculateSwapID(tc.args.randomNumberHash, tc.args.sender, tc.args.senderOtherChain)
 | 
			
		||||
			suite.Equal(tmbytes.HexBytes(expectedSwapID), swap.GetSwapID())
 | 
			
		||||
		} else {
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user