Skip to content

Commit 76a6d67

Browse files
feat: ASI mobix staking replacement (#348)
1 parent 3e6b6a7 commit 76a6d67

File tree

1 file changed

+129
-4
lines changed

1 file changed

+129
-4
lines changed

cmd/fetchd/cmd/genesis-asi-upgrade.go

Lines changed: 129 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@ package cmd
33
import (
44
"bytes"
55
_ "embed"
6+
"encoding/base64"
7+
"encoding/binary"
68
"encoding/csv"
9+
"encoding/hex"
710
"encoding/json"
811
"fmt"
912
"github.com/btcsuite/btcutil/bech32"
@@ -29,6 +32,7 @@ const (
2932
Bech32Chars = "qpzry9x8gf2tvdw0s3jn54khce6mua7l"
3033
AddrDataLength = 32
3134
WasmAddrDataLength = 52
35+
MaxAddrDataLength = 100
3236
AddrChecksumLength = 6
3337

3438
AccAddressPrefix = ""
@@ -39,6 +43,12 @@ const (
3943
OldAddrPrefix = "fetch"
4044
)
4145

46+
var (
47+
stakesKey = prefixStringWithLength("stakes")
48+
unbondEntriesKey = prefixStringWithLength("unbond_entries")
49+
configKey = []byte("config")
50+
)
51+
4252
var ReconciliationTargetAddr = "fetch1rhrlzsx9z865dqen8t4v47r99dw6y4va4uph0x"
4353

4454
var networkInfos = map[string]NetworkConfig{
@@ -63,6 +73,9 @@ var networkInfos = map[string]NetworkConfig{
6373
AName: &AName{
6474
Addr: "fetch1479lwv5vy8skute5cycuz727e55spkhxut0valrcm38x9caa2x8q99ef0q", // mainnet DEVELOPMENT contract,
6575
},
76+
MobixStaking: &MobixStaking{
77+
Addr: "fetch1xr3rq8yvd7qplsw5yx90ftsr2zdhg4e9z60h5duusgxpv72hud3szdul6e", // TODO(JS): amend this
78+
},
6679
TokenBridge: &TokenBridge{
6780
Addr: "fetch1qxxlalvsdjd07p07y3rc5fu6ll8k4tmetpha8n",
6881
NewAdmin: "fetch15p3rl5aavw9rtu86tna5lgxfkz67zzr6ed4yhw",
@@ -90,6 +103,9 @@ var networkInfos = map[string]NetworkConfig{
90103
AName: &AName{
91104
Addr: "fetch1kewgfwxwtuxcnppr547wj6sd0e5fkckyp48dazsh89hll59epgpspmh0tn", // testnet DEVELOPMENT contract,
92105
},
106+
MobixStaking: &MobixStaking{
107+
Addr: "fetch1xr3rq8yvd7qplsw5yx90ftsr2zdhg4e9z60h5duusgxpv72hud3szdul6e",
108+
},
93109
TokenBridge: &TokenBridge{
94110
Addr: "fetch1kewgfwxwtuxcnppr547wj6sd0e5fkckyp48dazsh89hll59epgpspmh0tn",
95111
NewAdmin: "fetch15p3rl5aavw9rtu86tna5lgxfkz67zzr6ed4yhw",
@@ -146,11 +162,16 @@ func ASIGenesisUpgradeCmd(defaultNodeHome string) *cobra.Command {
146162
// replace chain-id
147163
ASIGenesisUpgradeReplaceChainID(genDoc, networkConfig)
148164

149-
// replace bridge contract admin
165+
// replace bridge contract admin, if address and new admin present
150166
if networkConfig.Contracts != nil && networkConfig.Contracts.TokenBridge != nil {
151167
ASIGenesisUpgradeReplaceBridgeAdmin(jsonData, networkConfig)
152168
}
153169

170+
// update mobix staking contract, if address present
171+
if networkConfig.Contracts != nil && networkConfig.Contracts.MobixStaking != nil {
172+
ASIGenesisUpgradeUpdateMobixStakingContract(jsonData, networkConfig)
173+
}
174+
154175
manifest := ASIUpgradeManifest{}
155176

156177
// replace almanac contract state
@@ -208,6 +229,105 @@ func ASIGenesisUpgradeCmd(defaultNodeHome string) *cobra.Command {
208229
return cmd
209230
}
210231

232+
type Bytes []byte
233+
234+
func (a Bytes) StartsWith(with []byte) bool {
235+
return len(a) >= len(with) && bytes.Compare(a[0:len(with)], with) == 0
236+
}
237+
238+
func ASIGenesisUpgradeUpdateMobixStakingContract(jsonData map[string]interface{}, networkInfo NetworkConfig) {
239+
contracts := jsonData["wasm"].(map[string]interface{})["contracts"].([]interface{})
240+
MobixStakingContractAddress := networkInfo.Contracts.MobixStaking.Addr
241+
242+
re := regexp.MustCompile(fmt.Sprintf(`%s%s1([%s]{%d,%d})$`, OldAddrPrefix, "", Bech32Chars, AddrDataLength+AddrChecksumLength, MaxAddrDataLength))
243+
244+
for _, contract := range contracts {
245+
if contract.(map[string]interface{})["contract_address"] == MobixStakingContractAddress {
246+
mobixContractStates := contract.(map[string]interface{})["contract_state"].([]interface{})
247+
for _, val := range mobixContractStates {
248+
state := val.(map[string]interface{})
249+
hexKey := state["key"].(string)
250+
b64Value := state["value"].(string)
251+
252+
valueBytes, err := base64.StdEncoding.DecodeString(b64Value)
253+
if err != nil {
254+
panic(err)
255+
}
256+
257+
updatedKey := hexKey
258+
updatedValue := b64Value
259+
260+
keyBytes, err := hex.DecodeString(hexKey)
261+
if err != nil {
262+
panic(err)
263+
}
264+
265+
_keyBytes := Bytes(keyBytes)
266+
switch {
267+
case _keyBytes.StartsWith(stakesKey):
268+
updatedKey = replaceAddressInContractStateKey(keyBytes, stakesKey)
269+
case _keyBytes.StartsWith(unbondEntriesKey):
270+
updatedKey = replaceAddressInContractStateKey(keyBytes, unbondEntriesKey)
271+
case _keyBytes.StartsWith(configKey):
272+
updatedValue = replaceAddressInContractStateValue(re, string(valueBytes))
273+
}
274+
275+
val = map[string]interface{}{
276+
"key": updatedKey,
277+
"value": updatedValue,
278+
}
279+
}
280+
281+
return
282+
}
283+
}
284+
285+
panic("mobix staking contract not found")
286+
}
287+
288+
func replaceAddressInContractStateValue(re *regexp.Regexp, value string) string {
289+
var newValue []byte
290+
291+
// replace value
292+
valJson := make(map[string]interface{})
293+
if err := json.Unmarshal([]byte(value), &valJson); err != nil {
294+
panic(err)
295+
}
296+
297+
var err error
298+
replaceAddresses(AccAddressPrefix, valJson, AddrDataLength+AddrChecksumLength)
299+
newValue, err = json.Marshal(valJson)
300+
if err != nil {
301+
panic(err)
302+
}
303+
304+
// return new value
305+
return base64.StdEncoding.EncodeToString(newValue)
306+
}
307+
308+
func prefixStringWithLength(val string) []byte {
309+
length := len(val)
310+
311+
if length > 0xFFFF {
312+
panic("length of input string does fit in to uint16")
313+
}
314+
315+
byteArray := []byte("00" + val)
316+
binary.BigEndian.PutUint16(byteArray, uint16(length))
317+
318+
return byteArray
319+
}
320+
321+
func replaceAddressInContractStateKey(keyBytes []byte, prefix []byte) string {
322+
newAddr, err := convertAddressToASI(string(keyBytes[len(prefix):]), AccAddressPrefix)
323+
if err != nil {
324+
panic(err)
325+
}
326+
key := append(prefix, []byte(newAddr)...)
327+
328+
return hex.EncodeToString(key)
329+
}
330+
211331
func ASIGenesisUpgradeReplaceDenomMetadata(jsonData map[string]interface{}, networkInfo NetworkConfig) {
212332
type jsonMap map[string]interface{}
213333

@@ -657,9 +777,10 @@ type DenomInfo struct {
657777
}
658778

659779
type Contracts struct {
660-
TokenBridge *TokenBridge
661-
Almanac *Almanac
662-
AName *AName
780+
TokenBridge *TokenBridge
781+
Almanac *Almanac
782+
AName *AName
783+
MobixStaking *MobixStaking
663784
}
664785

665786
type TokenBridge struct {
@@ -674,3 +795,7 @@ type Almanac struct {
674795
type AName struct {
675796
Addr string
676797
}
798+
799+
type MobixStaking struct {
800+
Addr string
801+
}

0 commit comments

Comments
 (0)