-
Notifications
You must be signed in to change notification settings - Fork 1
/
cosmos-originated.go
116 lines (100 loc) · 4.08 KB
/
cosmos-originated.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
package keeper
import (
"fmt"
"github.com/cosmos/cosmos-sdk/store/prefix"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
"github.com/onomyprotocol/near-aurora-bridge/module/x/nab/types"
)
func (k Keeper) GetCosmosOriginatedDenom(ctx sdk.Context, tokenContract string) (string, bool) {
store := ctx.KVStore(k.storeKey)
bz := store.Get(types.GetERC20ToDenomKey(tokenContract))
if bz != nil {
return string(bz), true
}
return "", false
}
func (k Keeper) GetCosmosOriginatedERC20(ctx sdk.Context, denom string) (string, bool) {
store := ctx.KVStore(k.storeKey)
bz := store.Get(types.GetDenomToERC20Key(denom))
if bz != nil {
return string(bz), true
}
return "", false
}
func (k Keeper) setCosmosOriginatedDenomToERC20(ctx sdk.Context, denom string, tokenContract string) {
store := ctx.KVStore(k.storeKey)
store.Set(types.GetDenomToERC20Key(denom), []byte(tokenContract))
store.Set(types.GetERC20ToDenomKey(tokenContract), []byte(denom))
}
// DenomToERC20 returns (bool isCosmosOriginated, string ERC20, err)
// Using this information, you can see if an asset is native to Cosmos or Ethereum,
// and get its corresponding ERC20 address.
// This will return an error if it cant parse the denom as a gravity denom, and then also can't find the denom
// in an index of ERC20 contracts deployed on Ethereum to serve as synthetic Cosmos assets.
func (k Keeper) DenomToERC20Lookup(ctx sdk.Context, denom string) (bool, string, error) {
// First try parsing the ERC20 out of the denom
tc1, err := types.GravityDenomToERC20(denom)
if err != nil {
// Look up ERC20 contract in index and error if it's not in there.
tc2, exists := k.GetCosmosOriginatedERC20(ctx, denom)
if !exists {
return false, "",
sdkerrors.Wrap(types.ErrInvalid, fmt.Sprintf("denom not a gravity voucher coin: %s, and also not in cosmos-originated ERC20 index", err))
}
// This is a cosmos-originated asset
return true, tc2, nil
}
// This is an ethereum-originated asset
return false, tc1, nil
}
// RewardToERC20Lookup is a specialized function wrapping DenomToERC20Lookup designed to validate
// the validator set reward any time we generate a validator set
func (k Keeper) RewardToERC20Lookup(ctx sdk.Context, coin sdk.Coin) (string, sdk.Int) {
if !coin.IsValid() || coin.IsZero() {
panic("Bad validator set relaying reward!")
} else {
// reward case, pass to DenomToERC20Lookup
_, addressStr, err := k.DenomToERC20Lookup(ctx, coin.Denom)
if err != nil {
// This can only ever happen if governance sets a value for the reward
// which is not a valid ERC20 that as been bridged before (either from or to Cosmos)
// We'll classify that as operator error and just panic
panic("Invalid Valset reward! Correct or remove the paramater value")
}
err = types.ValidateEthAddress(addressStr)
if err != nil {
panic("Invalid Valset reward! Correct or remove the paramater value")
}
return addressStr, coin.Amount
}
}
// ERC20ToDenom returns (bool isCosmosOriginated, string denom, err)
// Using this information, you can see if an ERC20 address representing an asset is native to Cosmos or Ethereum,
// and get its corresponding denom
func (k Keeper) ERC20ToDenomLookup(ctx sdk.Context, tokenContract string) (bool, string) {
// First try looking up tokenContract in index
dn1, exists := k.GetCosmosOriginatedDenom(ctx, tokenContract)
if exists {
// It is a cosmos originated asset
return true, dn1
}
// If it is not in there, it is not a cosmos originated token, turn the ERC20 into a gravity denom
return false, types.GravityDenom(tokenContract)
}
// IterateERC20ToDenom iterates over erc20 to denom relations
func (k Keeper) IterateERC20ToDenom(ctx sdk.Context, cb func([]byte, *types.ERC20ToDenom) bool) {
prefixStore := prefix.NewStore(ctx.KVStore(k.storeKey), types.ERC20ToDenomKey)
iter := prefixStore.Iterator(nil, nil)
defer iter.Close()
for ; iter.Valid(); iter.Next() {
erc20ToDenom := types.ERC20ToDenom{
Erc20: string(iter.Key()),
Denom: string(iter.Value()),
}
// cb returns true to stop early
if cb(iter.Key(), &erc20ToDenom) {
break
}
}
}