github.com/palisadeinc/bor@v0.0.0-20230615125219-ab7196213d15/signer/core/gnosis_safe.go (about) 1 package core 2 3 import ( 4 "fmt" 5 "math/big" 6 7 "github.com/ethereum/go-ethereum/common" 8 "github.com/ethereum/go-ethereum/common/hexutil" 9 "github.com/ethereum/go-ethereum/common/math" 10 "github.com/ethereum/go-ethereum/signer/core/apitypes" 11 ) 12 13 // GnosisSafeTx is a type to parse the safe-tx returned by the relayer, 14 // it also conforms to the API required by the Gnosis Safe tx relay service. 15 // See 'SafeMultisigTransaction' on https://safe-transaction.mainnet.gnosis.io/ 16 type GnosisSafeTx struct { 17 // These fields are only used on output 18 Signature hexutil.Bytes `json:"signature"` 19 SafeTxHash common.Hash `json:"contractTransactionHash"` 20 Sender common.MixedcaseAddress `json:"sender"` 21 // These fields are used both on input and output 22 Safe common.MixedcaseAddress `json:"safe"` 23 To common.MixedcaseAddress `json:"to"` 24 Value math.Decimal256 `json:"value"` 25 GasPrice math.Decimal256 `json:"gasPrice"` 26 Data *hexutil.Bytes `json:"data"` 27 Operation uint8 `json:"operation"` 28 GasToken common.Address `json:"gasToken"` 29 RefundReceiver common.Address `json:"refundReceiver"` 30 BaseGas big.Int `json:"baseGas"` 31 SafeTxGas big.Int `json:"safeTxGas"` 32 Nonce big.Int `json:"nonce"` 33 InputExpHash common.Hash `json:"safeTxHash"` 34 ChainId *math.HexOrDecimal256 `json:"chainId,omitempty"` 35 } 36 37 // ToTypedData converts the tx to a EIP-712 Typed Data structure for signing 38 func (tx *GnosisSafeTx) ToTypedData() apitypes.TypedData { 39 var data hexutil.Bytes 40 if tx.Data != nil { 41 data = *tx.Data 42 } 43 var domainType = []apitypes.Type{{Name: "verifyingContract", Type: "address"}} 44 if tx.ChainId != nil { 45 domainType = append([]apitypes.Type{{Name: "chainId", Type: "uint256"}}, domainType[0]) 46 } 47 48 gnosisTypedData := apitypes.TypedData{ 49 Types: apitypes.Types{ 50 "EIP712Domain": domainType, 51 "SafeTx": []apitypes.Type{ 52 {Name: "to", Type: "address"}, 53 {Name: "value", Type: "uint256"}, 54 {Name: "data", Type: "bytes"}, 55 {Name: "operation", Type: "uint8"}, 56 {Name: "safeTxGas", Type: "uint256"}, 57 {Name: "baseGas", Type: "uint256"}, 58 {Name: "gasPrice", Type: "uint256"}, 59 {Name: "gasToken", Type: "address"}, 60 {Name: "refundReceiver", Type: "address"}, 61 {Name: "nonce", Type: "uint256"}, 62 }, 63 }, 64 Domain: apitypes.TypedDataDomain{ 65 VerifyingContract: tx.Safe.Address().Hex(), 66 ChainId: tx.ChainId, 67 }, 68 PrimaryType: "SafeTx", 69 Message: apitypes.TypedDataMessage{ 70 "to": tx.To.Address().Hex(), 71 "value": tx.Value.String(), 72 "data": data, 73 "operation": fmt.Sprintf("%d", tx.Operation), 74 "safeTxGas": fmt.Sprintf("%#d", &tx.SafeTxGas), 75 "baseGas": fmt.Sprintf("%#d", &tx.BaseGas), 76 "gasPrice": tx.GasPrice.String(), 77 "gasToken": tx.GasToken.Hex(), 78 "refundReceiver": tx.RefundReceiver.Hex(), 79 "nonce": fmt.Sprintf("%d", tx.Nonce.Uint64()), 80 }, 81 } 82 return gnosisTypedData 83 } 84 85 // ArgsForValidation returns a SendTxArgs struct, which can be used for the 86 // common validations, e.g. look up 4byte destinations 87 func (tx *GnosisSafeTx) ArgsForValidation() *apitypes.SendTxArgs { 88 gp := hexutil.Big(tx.GasPrice) 89 args := &apitypes.SendTxArgs{ 90 From: tx.Safe, 91 To: &tx.To, 92 Gas: hexutil.Uint64(tx.SafeTxGas.Uint64()), 93 GasPrice: &gp, 94 Value: hexutil.Big(tx.Value), 95 Nonce: hexutil.Uint64(tx.Nonce.Uint64()), 96 Data: tx.Data, 97 Input: nil, 98 ChainID: (*hexutil.Big)(tx.ChainId), 99 } 100 return args 101 }