/
axelar_proxy.go
139 lines (113 loc) · 3.66 KB
/
axelar_proxy.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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
package types
import (
fmt "fmt"
"math/big"
errorsmod "cosmossdk.io/errors"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/common"
)
var (
Address, _ = abi.NewType("address", "", nil)
AddressArr, _ = abi.NewType("address[]", "", nil)
Bytes, _ = abi.NewType("bytes", "", nil)
Uint256, _ = abi.NewType("uint256", "", nil)
HourInBlocks = uint64((60 * 60) / 12)
DefaultExecutableHeightThreshold = 72 * HourInBlocks
LogicCallMsgID = big.NewInt(0)
UpgradeMsgID = big.NewInt(1)
)
func (ccn AxelarContractCallNonce) ValidateBasic() error {
if ccn.Nonce == 0 {
return fmt.Errorf("nonce cannot be zero")
}
if ccn.ContractAddress == "" {
return fmt.Errorf("contract address cannot be empty")
}
if !common.IsHexAddress(ccn.ContractAddress) {
return errorsmod.Wrapf(ErrInvalidEVMAddress, "%s", ccn.ContractAddress)
}
if ccn.ChainId == 0 {
return fmt.Errorf("chain ID cannot be zero")
}
return nil
}
func (ud AxelarUpgradeData) ValidateBasic() error {
if ud.ChainId == 0 {
return fmt.Errorf("chain ID cannot be zero")
}
if ud.ExecutableHeightThreshold < 0 {
return fmt.Errorf("height threshold cannot be negative")
}
if len(ud.Payload) == 0 {
return fmt.Errorf("payload cannot be empty")
}
return nil
}
func EncodeLogicCallArgs(targetContract string, nonce uint64, deadline uint64, callData []byte) ([]byte, error) {
return abi.Arguments{
{Type: Uint256},
{Type: Address},
{Type: Uint256},
{Type: Uint256},
{Type: Bytes},
}.Pack(LogicCallMsgID, common.HexToAddress(targetContract), big.NewInt(int64(nonce)), big.NewInt(int64(deadline)), callData)
}
func DecodeLogicCallArgs(data []byte) (targetContract string, nonce uint64, deadline uint64, callData []byte, err error) {
args, err := abi.Arguments{
{Type: Uint256},
{Type: Address},
{Type: Uint256},
{Type: Uint256},
{Type: Bytes},
}.Unpack(data)
if err != nil {
return
}
// Unpack(data) error will catch overflow errors, but this will handle unambiguously invalid data
if msgID, ok := args[0].(*big.Int); !ok || msgID.Cmp(LogicCallMsgID) != 0 {
return "", 0, 0, nil, fmt.Errorf("invalid logic call args")
}
// Collin: Do we need to check for zero values in case these assertions somehow fail?
targetContractArg, _ := args[1].(common.Address)
targetContract = targetContractArg.String()
nonceArg, _ := args[2].(*big.Int)
nonce = nonceArg.Uint64()
deadlineArg, _ := args[3].(*big.Int)
deadline = deadlineArg.Uint64()
callData, _ = args[4].([]byte)
return
}
func EncodeUpgradeArgs(newAxelarProxy string, targets []string) ([]byte, error) {
targetAddrs := []common.Address{}
for _, target := range targets {
targetAddrs = append(targetAddrs, common.HexToAddress(target))
}
return abi.Arguments{
{Type: Uint256},
{Type: Address},
{Type: AddressArr},
}.Pack(UpgradeMsgID, common.HexToAddress(newAxelarProxy), targetAddrs)
}
func DecodeUpgradeArgs(data []byte) (newAxelarProxy string, targets []string, err error) {
args, err := abi.Arguments{
{Type: Uint256},
{Type: Address},
{Type: AddressArr},
}.Unpack(data)
if err != nil {
return
}
// Unpack(data) error will catch overflow errors, but this will handle unambiguously invalid data
if msgID, ok := args[0].(*big.Int); !ok || msgID.Cmp(UpgradeMsgID) != 0 {
return "", nil, fmt.Errorf("invalid upgrade args")
}
// Collin: Do we need to check for zero values in case these assertions somehow fail?
newAxelarProxyArg, _ := args[1].(common.Address)
newAxelarProxy = newAxelarProxyArg.String()
targetsArg, _ := args[2].([]common.Address)
targets = []string{}
for _, target := range targetsArg {
targets = append(targets, target.String())
}
return
}