gnosis_safe.go 3.2 KB

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