gnosis_safe.go 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. // Copyright 2020 The go-ethereum Authors
  2. // This file is part of the go-ethereum library.
  3. //
  4. // The go-ethereum library is free software: you can redistribute it and/or modify
  5. // it under the terms of the GNU Lesser General Public License as published by
  6. // the Free Software Foundation, either version 3 of the License, or
  7. // (at your option) any later version.
  8. //
  9. // The go-ethereum library is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU Lesser General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU Lesser General Public License
  15. // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
  16. package core
  17. import (
  18. "fmt"
  19. "math/big"
  20. "github.com/ethereum/go-ethereum/common"
  21. "github.com/ethereum/go-ethereum/common/hexutil"
  22. "github.com/ethereum/go-ethereum/common/math"
  23. "github.com/ethereum/go-ethereum/signer/core/apitypes"
  24. )
  25. // GnosisSafeTx is a type to parse the safe-tx returned by the relayer,
  26. // it also conforms to the API required by the Gnosis Safe tx relay service.
  27. // See 'SafeMultisigTransaction' on https://safe-transaction.mainnet.gnosis.io/
  28. type GnosisSafeTx struct {
  29. // These fields are only used on output
  30. Signature hexutil.Bytes `json:"signature"`
  31. SafeTxHash common.Hash `json:"contractTransactionHash"`
  32. Sender common.MixedcaseAddress `json:"sender"`
  33. // These fields are used both on input and output
  34. Safe common.MixedcaseAddress `json:"safe"`
  35. To common.MixedcaseAddress `json:"to"`
  36. Value math.Decimal256 `json:"value"`
  37. GasPrice math.Decimal256 `json:"gasPrice"`
  38. Data *hexutil.Bytes `json:"data"`
  39. Operation uint8 `json:"operation"`
  40. GasToken common.Address `json:"gasToken"`
  41. RefundReceiver common.Address `json:"refundReceiver"`
  42. BaseGas big.Int `json:"baseGas"`
  43. SafeTxGas big.Int `json:"safeTxGas"`
  44. Nonce big.Int `json:"nonce"`
  45. InputExpHash common.Hash `json:"safeTxHash"`
  46. ChainId *math.HexOrDecimal256 `json:"chainId,omitempty"`
  47. }
  48. // ToTypedData converts the tx to a EIP-712 Typed Data structure for signing
  49. func (tx *GnosisSafeTx) ToTypedData() apitypes.TypedData {
  50. var data hexutil.Bytes
  51. if tx.Data != nil {
  52. data = *tx.Data
  53. }
  54. var domainType = []apitypes.Type{{Name: "verifyingContract", Type: "address"}}
  55. if tx.ChainId != nil {
  56. domainType = append([]apitypes.Type{{Name: "chainId", Type: "uint256"}}, domainType[0])
  57. }
  58. gnosisTypedData := apitypes.TypedData{
  59. Types: apitypes.Types{
  60. "EIP712Domain": domainType,
  61. "SafeTx": []apitypes.Type{
  62. {Name: "to", Type: "address"},
  63. {Name: "value", Type: "uint256"},
  64. {Name: "data", Type: "bytes"},
  65. {Name: "operation", Type: "uint8"},
  66. {Name: "safeTxGas", Type: "uint256"},
  67. {Name: "baseGas", Type: "uint256"},
  68. {Name: "gasPrice", Type: "uint256"},
  69. {Name: "gasToken", Type: "address"},
  70. {Name: "refundReceiver", Type: "address"},
  71. {Name: "nonce", Type: "uint256"},
  72. },
  73. },
  74. Domain: apitypes.TypedDataDomain{
  75. VerifyingContract: tx.Safe.Address().Hex(),
  76. ChainId: tx.ChainId,
  77. },
  78. PrimaryType: "SafeTx",
  79. Message: apitypes.TypedDataMessage{
  80. "to": tx.To.Address().Hex(),
  81. "value": tx.Value.String(),
  82. "data": data,
  83. "operation": fmt.Sprintf("%d", tx.Operation),
  84. "safeTxGas": fmt.Sprintf("%#d", &tx.SafeTxGas),
  85. "baseGas": fmt.Sprintf("%#d", &tx.BaseGas),
  86. "gasPrice": tx.GasPrice.String(),
  87. "gasToken": tx.GasToken.Hex(),
  88. "refundReceiver": tx.RefundReceiver.Hex(),
  89. "nonce": fmt.Sprintf("%d", tx.Nonce.Uint64()),
  90. },
  91. }
  92. return gnosisTypedData
  93. }
  94. // ArgsForValidation returns a SendTxArgs struct, which can be used for the
  95. // common validations, e.g. look up 4byte destinations
  96. func (tx *GnosisSafeTx) ArgsForValidation() *apitypes.SendTxArgs {
  97. gp := hexutil.Big(tx.GasPrice)
  98. args := &apitypes.SendTxArgs{
  99. From: tx.Safe,
  100. To: &tx.To,
  101. Gas: hexutil.Uint64(tx.SafeTxGas.Uint64()),
  102. GasPrice: &gp,
  103. Value: hexutil.Big(tx.Value),
  104. Nonce: hexutil.Uint64(tx.Nonce.Uint64()),
  105. Data: tx.Data,
  106. Input: nil,
  107. ChainID: (*hexutil.Big)(tx.ChainId),
  108. }
  109. return args
  110. }