diff --git a/accounts/abi/event_test.go b/accounts/abi/event_test.go
index a3899b4a6feebb0e29c63d56baab73db0a3fd70b..d966ad1dbf2882cc012ba189ec4f48a8354966bd 100644
--- a/accounts/abi/event_test.go
+++ b/accounts/abi/event_test.go
@@ -19,14 +19,51 @@ package abi
 import (
 	"bytes"
 	"reflect"
+	"encoding/hex"
+	"encoding/json"
+	"math/big"
 	"strings"
 	"testing"
 
 	"github.com/ethereum/go-ethereum/common"
 	"github.com/ethereum/go-ethereum/crypto"
+	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 )
 
+var jsonEventTransfer = []byte(`{
+  "anonymous": false,
+  "inputs": [
+    {
+      "indexed": true, "name": "from", "type": "address"
+    }, {
+      "indexed": true, "name": "to", "type": "address"
+    }, {
+      "indexed": false, "name": "value", "type": "uint256"
+  }],
+  "name": "Transfer",
+  "type": "event"
+}`)
+
+var jsonEventPledge = []byte(`{
+  "anonymous": false,
+  "inputs": [{
+      "indexed": false, "name": "who", "type": "address"
+    }, {
+      "indexed": false, "name": "wad", "type": "uint128"
+    }, {
+      "indexed": false, "name": "currency", "type": "bytes3"
+  }],
+  "name": "Pledge",
+  "type": "event"
+}`)
+
+// 1000000
+var transferData1 = "00000000000000000000000000000000000000000000000000000000000f4240"
+
+// "0x00Ce0d46d924CC8437c806721496599FC3FFA268", 2218516807680, "usd"
+var pledgeData1 = "00000000000000000000000000ce0d46d924cc8437c806721496599fc3ffa2680000000000000000000000000000000000000000000000000000020489e800007573640000000000000000000000000000000000000000000000000000000000"
+
 func TestEventId(t *testing.T) {
 	var table = []struct {
 		definition   string
@@ -77,3 +114,120 @@ func TestEventMultiValueWithArrayUnpack(t *testing.T) {
 	require.Equal(t, [2]uint8{1, 2}, rst.Value1)
 	require.Equal(t, uint8(3), rst.Value2)
 }
+
+func TestEventTupleUnpack(t *testing.T) {
+
+	type EventTransfer struct {
+		Value *big.Int
+	}
+
+	type EventPledge struct {
+		Who      common.Address
+		Wad      *big.Int
+		Currency [3]byte
+	}
+
+	type BadEventPledge struct {
+		Who      string
+		Wad      int
+		Currency [3]byte
+	}
+
+	bigint := new(big.Int)
+	bigintExpected := big.NewInt(1000000)
+	bigintExpected2 := big.NewInt(2218516807680)
+	addr := common.HexToAddress("0x00Ce0d46d924CC8437c806721496599FC3FFA268")
+	var testCases = []struct {
+		data     string
+		dest     interface{}
+		expected interface{}
+		jsonLog  []byte
+		error    string
+		name     string
+	}{{
+		transferData1,
+		&EventTransfer{},
+		&EventTransfer{Value: bigintExpected},
+		jsonEventTransfer,
+		"",
+		"Can unpack ERC20 Transfer event into structure",
+	}, {
+		transferData1,
+		&[]interface{}{&bigint},
+		&[]interface{}{&bigintExpected},
+		jsonEventTransfer,
+		"",
+		"Can unpack ERC20 Transfer event into slice",
+	}, {
+		pledgeData1,
+		&EventPledge{},
+		&EventPledge{
+			addr,
+			bigintExpected2,
+			[3]byte{'u', 's', 'd'}},
+		jsonEventPledge,
+		"",
+		"Can unpack Pledge event into structure",
+	}, {
+		pledgeData1,
+		&[]interface{}{&common.Address{}, &bigint, &[3]byte{}},
+		&[]interface{}{
+			&addr,
+			&bigintExpected2,
+			&[3]byte{'u', 's', 'd'}},
+		jsonEventPledge,
+		"",
+		"Can unpack Pledge event into slice",
+	}, {
+		pledgeData1,
+		&[]interface{}{new(int), 0, 0},
+		&[]interface{}{},
+		jsonEventPledge,
+		"abi: cannot unmarshal common.Address in to int",
+		"Can not unpack Pledge event into slice with wrong types",
+	}, {
+		pledgeData1,
+		&BadEventPledge{},
+		&BadEventPledge{},
+		jsonEventPledge,
+		"abi: cannot unmarshal common.Address in to string",
+		"Can not unpack Pledge event into struct with wrong filed types",
+	}, {
+		pledgeData1,
+		&[]interface{}{common.Address{}, new(big.Int)},
+		&[]interface{}{},
+		jsonEventPledge,
+		"abi: insufficient number of elements in the list/array for unpack, want 3, got 2",
+		"Can not unpack Pledge event into too short slice",
+	}, {
+		pledgeData1,
+		new(map[string]interface{}),
+		&[]interface{}{},
+		jsonEventPledge,
+		"abi: cannot unmarshal tuple into map[string]interface {}",
+		"Can not unpack Pledge event into map",
+	}}
+
+	for _, tc := range testCases {
+		assert := assert.New(t)
+		tc := tc
+		t.Run(tc.name, func(t *testing.T) {
+			err := unpackTestEventData(tc.dest, tc.data, tc.jsonLog, assert)
+			if tc.error == "" {
+				assert.Nil(err, "Should be able to unpack event data.")
+				assert.Equal(tc.expected, tc.dest)
+			} else {
+				assert.EqualError(err, tc.error)
+			}
+		})
+	}
+}
+
+func unpackTestEventData(dest interface{}, hexData string, jsonEvent []byte, assert *assert.Assertions) error {
+	data, err := hex.DecodeString(hexData)
+	assert.NoError(err, "Hex data should be a correct hex-string")
+	var e Event
+	assert.NoError(json.Unmarshal(jsonEvent, &e), "Should be able to unmarshal event ABI")
+	a := ABI{Events: map[string]Event{"e": e}}
+	return a.Unpack(dest, "e", data)
+}