/
gnosis_safe.go
94 lines (89 loc) · 3.37 KB
/
gnosis_safe.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
package core
import (
"fmt"
"math/big"
"github.com/celo-org/celo-blockchain/common"
"github.com/celo-org/celo-blockchain/common/hexutil"
"github.com/celo-org/celo-blockchain/common/math"
"github.com/celo-org/celo-blockchain/shared/signer"
"github.com/celo-org/celo-blockchain/signer/core/apitypes"
)
// GnosisSafeTx is a type to parse the safe-tx returned by the relayer,
// it also conforms to the API required by the Gnosis Safe tx relay service.
// See 'SafeMultisigTransaction' on https://safe-transaction.mainnet.gnosis.io/
type GnosisSafeTx struct {
// These fields are only used on output
Signature hexutil.Bytes `json:"signature"`
SafeTxHash common.Hash `json:"contractTransactionHash"`
Sender common.MixedcaseAddress `json:"sender"`
// These fields are used both on input and output
Safe common.MixedcaseAddress `json:"safe"`
To common.MixedcaseAddress `json:"to"`
Value math.Decimal256 `json:"value"`
GasPrice math.Decimal256 `json:"gasPrice"`
Data *hexutil.Bytes `json:"data"`
Operation uint8 `json:"operation"`
GasToken common.Address `json:"gasToken"`
RefundReceiver common.Address `json:"refundReceiver"`
BaseGas big.Int `json:"baseGas"`
SafeTxGas big.Int `json:"safeTxGas"`
Nonce big.Int `json:"nonce"`
InputExpHash common.Hash `json:"safeTxHash"`
}
// ToTypedData converts the tx to a EIP-712 Typed Data structure for signing
func (tx *GnosisSafeTx) ToTypedData() signer.TypedData {
var data hexutil.Bytes
if tx.Data != nil {
data = *tx.Data
}
gnosisTypedData := signer.TypedData{
Types: signer.Types{
"EIP712Domain": []signer.Type{{Name: "verifyingContract", Type: "address"}},
"SafeTx": []signer.Type{
{Name: "to", Type: "address"},
{Name: "value", Type: "uint256"},
{Name: "data", Type: "bytes"},
{Name: "operation", Type: "uint8"},
{Name: "safeTxGas", Type: "uint256"},
{Name: "baseGas", Type: "uint256"},
{Name: "gasPrice", Type: "uint256"},
{Name: "gasToken", Type: "address"},
{Name: "refundReceiver", Type: "address"},
{Name: "nonce", Type: "uint256"},
},
},
Domain: signer.TypedDataDomain{
VerifyingContract: tx.Safe.Address().Hex(),
},
PrimaryType: "SafeTx",
Message: signer.TypedDataMessage{
"to": tx.To.Address().Hex(),
"value": tx.Value.String(),
"data": data,
"operation": fmt.Sprintf("%d", tx.Operation),
"safeTxGas": fmt.Sprintf("%#d", &tx.SafeTxGas),
"baseGas": fmt.Sprintf("%#d", &tx.BaseGas),
"gasPrice": tx.GasPrice.String(),
"gasToken": tx.GasToken.Hex(),
"refundReceiver": tx.RefundReceiver.Hex(),
"nonce": fmt.Sprintf("%d", tx.Nonce.Uint64()),
},
}
return gnosisTypedData
}
// ArgsForValidation returns a SendTxArgs struct, which can be used for the
// common validations, e.g. look up 4byte destinations
func (tx *GnosisSafeTx) ArgsForValidation() *apitypes.SendTxArgs {
gp := hexutil.Big(tx.GasPrice)
args := &apitypes.SendTxArgs{
From: tx.Safe,
To: &tx.To,
Gas: hexutil.Uint64(tx.SafeTxGas.Uint64()),
GasPrice: &gp,
Value: hexutil.Big(tx.Value),
Nonce: hexutil.Uint64(tx.Nonce.Uint64()),
Data: tx.Data,
Input: nil,
}
return args
}