Skip to content

Commit

Permalink
Implement bep3 evm native conversion logic (#1848)
Browse files Browse the repository at this point in the history
* Implement bep3 evm native conversion logic

* Update changelog

* Fix indentation

* Add bep3 conversion keeper tests

* make DefaultBEP3ConversionDenoms private

* refactor bep3 conversion

* update bep3 tests to cover all bep3 assets

* minor refactor
  • Loading branch information
DracoLi authored Mar 25, 2024
1 parent 969614d commit 3afb656
Show file tree
Hide file tree
Showing 5 changed files with 501 additions and 10 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
- (validator-vesting) [#1832] Add grpc query service to replace removed legacy querier
- (incentive) [#1836] Update x/incentive cli to use grpc query client
- (ibc) [#1839] Add ibc packet forward middleware for ibc transfers
- (evmutil) [#1848] Update evm native conversion logic to handle bep3 assets

## [v0.25.0]

Expand Down Expand Up @@ -328,6 +329,7 @@ the [changelog](https://github.com/cosmos/cosmos-sdk/blob/v0.38.4/CHANGELOG.md).
large-scale simulations remotely using aws-batch

[#1846]: https://github.com/Kava-Labs/kava/pull/1846
[#1848]: https://github.com/Kava-Labs/kava/pull/1848
[#1839]: https://github.com/Kava-Labs/kava/pull/1839
[#1836]: https://github.com/Kava-Labs/kava/pull/1836
[#1832]: https://github.com/Kava-Labs/kava/pull/1832
Expand Down
24 changes: 21 additions & 3 deletions x/evmutil/keeper/conversion_evm_native.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,15 @@ func (k Keeper) ConvertCoinToERC20(
return err
}

if err := k.UnlockERC20Tokens(ctx, pair, coin.Amount.BigInt(), receiverAccount); err != nil {
// handle bep3 conversion pair (8 decimals sdk.Coin -> 18 decimals erc20)
// when converting bep3 bank coins to erc20, we will need to unlock the 18
// decimals erc20 equivalent of the 8 decimals bep3 sdk.Coins
amountToUnlock := coin.Amount.BigInt()
if isBep3Asset(pair.Denom) {
amountToUnlock = convertBep3CoinAmountToERC20Amount(coin.Amount.BigInt())
}

if err := k.UnlockERC20Tokens(ctx, pair, amountToUnlock, receiverAccount); err != nil {
return err
}

Expand Down Expand Up @@ -102,13 +110,23 @@ func (k Keeper) ConvertERC20ToCoin(
return err
}

amountToLock := amount.BigInt()
amountToMint := amount.BigInt()

if isBep3Asset(pair.Denom) {
amountToMint, amountToLock, err = bep3ERC20AmountToCoinMintAndERC20LockAmount(amount.BigInt())
if err != nil {
return err
}
}

// lock erc20 tokens
if err := k.LockERC20Tokens(ctx, pair, amount.BigInt(), initiator); err != nil {
if err := k.LockERC20Tokens(ctx, pair, amountToLock, initiator); err != nil {
return err
}

// mint conversion pair coin
coin, err := k.MintConversionPairCoin(ctx, pair, amount.BigInt(), receiver)
coin, err := k.MintConversionPairCoin(ctx, pair, amountToMint, receiver)
if err != nil {
return err
}
Expand Down
55 changes: 55 additions & 0 deletions x/evmutil/keeper/conversion_evm_native_bep3.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package keeper

import (
"math/big"

errorsmod "cosmossdk.io/errors"
"github.com/kava-labs/kava/x/evmutil/types"
)

var (
bep3Denoms = map[string]bool{
"bnb": true,
"busd": true,
"btcb": true,
"xrpb": true,
}

bep3ConversionFactor = new(big.Int).Exp(big.NewInt(10), big.NewInt(10), nil)
)

func isBep3Asset(denom string) bool {
return bep3Denoms[denom]
}

// convertBep3CoinAmountToERC20Amount converts a bep3 coin amount with 8 decimals
// to the equivalent ERC20 token with 18 decimals.
func convertBep3CoinAmountToERC20Amount(amount *big.Int) (erc20Amount *big.Int) {
return new(big.Int).Mul(amount, bep3ConversionFactor)
}

// convertBep3ERC20AmountToCoinAmount converts a bep3 ERC20 token with 18 decimals
// to the equivalent coin amount with 8 decimals, and dropping the remainder.
func convertBep3ERC20AmountToCoinAmount(amount *big.Int) (coinAmount *big.Int) {
return new(big.Int).Div(amount, bep3ConversionFactor)
}

// bep3ERC20AmountToCoinMintAndERC20LockAmount converts 18 decimals erc20 bep3
// amount to the equivalent 8 decimals coin amount to mint, and the
// 18 decimals erc20 bep3 amount to lock for the converted coin amount.
func bep3ERC20AmountToCoinMintAndERC20LockAmount(amount *big.Int) (
amountToMint *big.Int, amountToLock *big.Int, err error,
) {
amountToMint = convertBep3ERC20AmountToCoinAmount(amount)

// make sure we have at least 1 sdk.Coin to mint
if amountToMint.Cmp(big.NewInt(0)) == 0 {
err := errorsmod.Wrapf(
types.ErrInsufficientConversionAmount,
"unable to convert bep3 coin due converting less than 1 native unit",
)
return nil, nil, err
}
amountToLock = convertBep3CoinAmountToERC20Amount(amountToMint)
return amountToMint, amountToLock, nil
}
Loading

0 comments on commit 3afb656

Please sign in to comment.