github.com/gravity-devs/liquidity@v1.5.3/x/liquidity/types/utils.go (about) 1 package types 2 3 import ( 4 "crypto/sha256" 5 "fmt" 6 "sort" 7 "strings" 8 9 sdk "github.com/cosmos/cosmos-sdk/types" 10 "github.com/cosmos/cosmos-sdk/types/address" 11 "github.com/tendermint/tendermint/crypto" 12 ) 13 14 // AlphabeticalDenomPair returns denom pairs that are alphabetically sorted. 15 func AlphabeticalDenomPair(denom1, denom2 string) (resDenom1, resDenom2 string) { 16 if denom1 > denom2 { 17 return denom2, denom1 18 } 19 return denom1, denom2 20 } 21 22 // SortDenoms sorts denoms in alphabetical order. 23 func SortDenoms(denoms []string) []string { 24 sort.Strings(denoms) 25 return denoms 26 } 27 28 // GetPoolReserveAcc returns the address of the pool's reserve account. 29 func GetPoolReserveAcc(poolName string, len32 bool) sdk.AccAddress { 30 if len32 { 31 // The rules are temporarily added for testing on 32-length bytes addresses of ADR-28 and are subject to change. 32 poolCoinDenom := GetPoolCoinDenom(poolName) 33 poolCoinDenom = strings.TrimPrefix(poolCoinDenom, PoolCoinDenomPrefix) 34 return sdk.AccAddress(address.Module(ModuleName, []byte(poolCoinDenom))) 35 } 36 return sdk.AccAddress(crypto.AddressHash([]byte(poolName))) 37 } 38 39 // GetPoolCoinDenom returns the denomination of the pool coin. 40 func GetPoolCoinDenom(poolName string) string { 41 // Originally pool coin denom has prefix with / splitter, but removed prefix for pass validation of ibc-transfer 42 return fmt.Sprintf("%s%X", PoolCoinDenomPrefix, sha256.Sum256([]byte(poolName))) 43 } 44 45 // GetReserveAcc extracts and returns reserve account from pool coin denom. 46 func GetReserveAcc(poolCoinDenom string, len32 bool) (sdk.AccAddress, error) { 47 if err := sdk.ValidateDenom(poolCoinDenom); err != nil { 48 return nil, err 49 } 50 if !strings.HasPrefix(poolCoinDenom, PoolCoinDenomPrefix) { 51 return nil, ErrInvalidDenom 52 } 53 poolCoinDenom = strings.TrimPrefix(poolCoinDenom, PoolCoinDenomPrefix) 54 if len(poolCoinDenom) != 64 { 55 return nil, ErrInvalidDenom 56 } 57 if len32 { 58 // The rules are temporarily added for testing on 32-length bytes addresses of ADR-28 and are subject to change. 59 return sdk.AccAddress(address.Module(ModuleName, []byte(poolCoinDenom))), nil 60 } 61 return sdk.AccAddressFromHex(poolCoinDenom[:40]) 62 } 63 64 // GetCoinsTotalAmount returns total amount of all coins in sdk.Coins. 65 func GetCoinsTotalAmount(coins sdk.Coins) sdk.Int { 66 totalAmount := sdk.ZeroInt() 67 for _, coin := range coins { 68 totalAmount = totalAmount.Add(coin.Amount) 69 } 70 return totalAmount 71 } 72 73 // ValidateReserveCoinLimit checks if total amounts of depositCoins exceed maxReserveCoinAmount. 74 func ValidateReserveCoinLimit(maxReserveCoinAmount sdk.Int, depositCoins sdk.Coins) error { 75 totalAmount := GetCoinsTotalAmount(depositCoins) 76 if maxReserveCoinAmount.IsZero() { 77 return nil 78 } else if totalAmount.GT(maxReserveCoinAmount) { 79 return ErrExceededReserveCoinLimit 80 } else { 81 return nil 82 } 83 } 84 85 func GetOfferCoinFee(offerCoin sdk.Coin, swapFeeRate sdk.Dec) sdk.Coin { 86 if swapFeeRate.IsZero() { 87 return sdk.NewCoin(offerCoin.Denom, sdk.ZeroInt()) 88 } 89 // apply half-ratio swap fee rate and ceiling 90 // see https://github.com/tendermint/liquidity/issues/41 for details 91 return sdk.NewCoin(offerCoin.Denom, offerCoin.Amount.ToDec().Mul(swapFeeRate.QuoInt64(2)).Ceil().TruncateInt()) // Ceil(offerCoin.Amount * (swapFeeRate/2)) 92 } 93 94 func MustParseCoinsNormalized(coinStr string) sdk.Coins { 95 coins, err := sdk.ParseCoinsNormalized(coinStr) 96 if err != nil { 97 panic(err) 98 } 99 return coins 100 } 101 102 func CheckOverflow(a, b sdk.Int) (err error) { 103 defer func() { 104 if r := recover(); r != nil { 105 err = ErrOverflowAmount 106 } 107 }() 108 a.Mul(b) 109 a.Quo(b) 110 b.Quo(a) 111 return nil 112 } 113 114 func CheckOverflowWithDec(a, b sdk.Dec) (err error) { 115 defer func() { 116 if r := recover(); r != nil { 117 err = ErrOverflowAmount 118 } 119 }() 120 a.Mul(b) 121 a.Quo(b) 122 b.Quo(a) 123 return nil 124 }