accounts, signer: implement gnosis safe support (#21593)

* accounts, signer: implement gnosis safe support

* common/math: add type for marshalling big to dec

* accounts, signer: properly sign gnosis requests

* signer, clef: implement account_signGnosisTx

* signer: fix auditlog print, change rpc-name (signGnosisTx to signGnosisSafeTx)

* signer: pass validation-messages/warnings to the UI for gnonsis-safe txs

* signer/core: minor change to validationmessages of typed data
This commit is contained in:
Martin Holst Swende
2020-09-29 17:40:08 +02:00
committed by GitHub
parent 6c8310ebb4
commit dad26582b6
8 changed files with 395 additions and 15 deletions

View File

@ -17,6 +17,7 @@
package core_test
import (
"bytes"
"context"
"encoding/json"
"fmt"
@ -414,3 +415,119 @@ func TestFuzzerFiles(t *testing.T) {
typedData.Format()
}
}
var gnosisTypedData = `
{
"types": {
"EIP712Domain": [
{ "type": "address", "name": "verifyingContract" }
],
"SafeTx": [
{ "type": "address", "name": "to" },
{ "type": "uint256", "name": "value" },
{ "type": "bytes", "name": "data" },
{ "type": "uint8", "name": "operation" },
{ "type": "uint256", "name": "safeTxGas" },
{ "type": "uint256", "name": "baseGas" },
{ "type": "uint256", "name": "gasPrice" },
{ "type": "address", "name": "gasToken" },
{ "type": "address", "name": "refundReceiver" },
{ "type": "uint256", "name": "nonce" }
]
},
"domain": {
"verifyingContract": "0x25a6c4BBd32B2424A9c99aEB0584Ad12045382B3"
},
"primaryType": "SafeTx",
"message": {
"to": "0x9eE457023bB3De16D51A003a247BaEaD7fce313D",
"value": "20000000000000000",
"data": "0x",
"operation": 0,
"safeTxGas": 27845,
"baseGas": 0,
"gasPrice": "0",
"gasToken": "0x0000000000000000000000000000000000000000",
"refundReceiver": "0x0000000000000000000000000000000000000000",
"nonce": 3
}
}`
var gnosisTx = `
{
"safe": "0x25a6c4BBd32B2424A9c99aEB0584Ad12045382B3",
"to": "0x9eE457023bB3De16D51A003a247BaEaD7fce313D",
"value": "20000000000000000",
"data": null,
"operation": 0,
"gasToken": "0x0000000000000000000000000000000000000000",
"safeTxGas": 27845,
"baseGas": 0,
"gasPrice": "0",
"refundReceiver": "0x0000000000000000000000000000000000000000",
"nonce": 3,
"executionDate": null,
"submissionDate": "2020-09-15T21:59:23.815748Z",
"modified": "2020-09-15T21:59:23.815748Z",
"blockNumber": null,
"transactionHash": null,
"safeTxHash": "0x28bae2bd58d894a1d9b69e5e9fde3570c4b98a6fc5499aefb54fb830137e831f",
"executor": null,
"isExecuted": false,
"isSuccessful": null,
"ethGasPrice": null,
"gasUsed": null,
"fee": null,
"origin": null,
"dataDecoded": null,
"confirmationsRequired": null,
"confirmations": [
{
"owner": "0xAd2e180019FCa9e55CADe76E4487F126Fd08DA34",
"submissionDate": "2020-09-15T21:59:28.281243Z",
"transactionHash": null,
"confirmationType": "CONFIRMATION",
"signature": "0x5e562065a0cb15d766dac0cd49eb6d196a41183af302c4ecad45f1a81958d7797753f04424a9b0aa1cb0448e4ec8e189540fbcdda7530ef9b9d95dfc2d36cb521b",
"signatureType": "EOA"
}
],
"signatures": null
}
`
// TestGnosisTypedData tests the scenario where a user submits a full EIP-712
// struct without using the gnosis-specific endpoint
func TestGnosisTypedData(t *testing.T) {
var td core.TypedData
err := json.Unmarshal([]byte(gnosisTypedData), &td)
if err != nil {
t.Fatalf("unmarshalling failed '%v'", err)
}
_, sighash, err := sign(td)
if err != nil {
t.Fatal(err)
}
expSigHash := common.FromHex("0x28bae2bd58d894a1d9b69e5e9fde3570c4b98a6fc5499aefb54fb830137e831f")
if !bytes.Equal(expSigHash, sighash) {
t.Fatalf("Error, got %x, wanted %x", sighash, expSigHash)
}
}
// TestGnosisCustomData tests the scenario where a user submits only the gnosis-safe
// specific data, and we fill the TypedData struct on our side
func TestGnosisCustomData(t *testing.T) {
var tx core.GnosisSafeTx
err := json.Unmarshal([]byte(gnosisTx), &tx)
if err != nil {
t.Fatal(err)
}
var td = tx.ToTypedData()
_, sighash, err := sign(td)
if err != nil {
t.Fatal(err)
}
expSigHash := common.FromHex("0x28bae2bd58d894a1d9b69e5e9fde3570c4b98a6fc5499aefb54fb830137e831f")
if !bytes.Equal(expSigHash, sighash) {
t.Fatalf("Error, got %x, wanted %x", sighash, expSigHash)
}
}