diff --git a/consensus/bor/bor.go b/consensus/bor/bor.go
index 4b1a7ad05cb9daef64deb2ec081c0c6576e7ab4e..790fe86cf587a0594c8a0ffef821a1b72b9ba77e 100644
--- a/consensus/bor/bor.go
+++ b/consensus/bor/bor.go
@@ -62,7 +62,6 @@ var (
 
 	validatorHeaderBytesLength = common.AddressLength + 20 // address + power
 	systemAddress              = common.HexToAddress("0xffffFFFfFFffffffffffffffFfFFFfffFFFfFFfE")
-	stateFetchLimit            = 50
 )
 
 // Various error messages to mark blocks invalid. These should be private to
@@ -1076,67 +1075,29 @@ func (c *Bor) CommitStates(
 	chain chainContext,
 ) error {
 	number := header.Number.Uint64()
-	lastSync, err := c.GenesisContractsClient.LastStateSyncTime(number - 1)
-	if err != nil {
-		return err
-	}
+	// lastSync, err := c.GenesisContractsClient.LastStateSyncTime(number - 1)
+	// if err != nil {
+	// 	return err
+	// }
 	_lastStateID, err := c.GenesisContractsClient.LastStateId(number - 1)
 	if err != nil {
 		return err
 	}
 
-	from := lastSync
 	to := time.Unix(int64(chain.Chain.GetHeaderByNumber(number-c.config.Sprint).Time), 0)
 	lastStateID := _lastStateID.Uint64()
-	fmt.Println("to Uint64", lastStateID)
-	if !from.Before(to) {
-		return nil
-	}
 	log.Info(
 		"Fetching state updates from Heimdall",
-		"from", from.Format(time.RFC3339),
+		"fromID", lastStateID+1,
 		"to", to.Format(time.RFC3339))
-
-	page := 1
-	eventRecords := make([]*EventRecordWithTime, 0)
-	for {
-		queryParams := fmt.Sprintf("from-time=%d&to-time=%d&page=%d&limit=%d", from.Unix(), to.Unix(), page, stateFetchLimit)
-		log.Info("Fetching state sync events", "queryParams", queryParams)
-		response, err := c.HeimdallClient.FetchWithRetry("clerk/event-record/list", queryParams)
-		if err != nil {
-			return err
-		}
-		var _eventRecords []*EventRecordWithTime
-		if response.Result == nil { // status 204
-			break
-		}
-		if err := json.Unmarshal(response.Result, &_eventRecords); err != nil {
-			return err
-		}
-		eventRecords = append(eventRecords, _eventRecords...)
-		if len(_eventRecords) < stateFetchLimit {
-			break
-		}
-		page++
-	}
-
-	sort.SliceStable(eventRecords, func(i, j int) bool {
-		return eventRecords[i].ID < eventRecords[j].ID
-	})
-
-	for _, e := range eventRecords {
-		fmt.Println("here", e.ID)
-	}
+	eventRecords, err := c.HeimdallClient.FetchStateSyncEvents(lastStateID+1, to.Unix())
 
 	chainID := c.chainConfig.ChainID.String()
 	for _, eventRecord := range eventRecords {
-		fmt.Println(eventRecord.ID, lastStateID)
 		if eventRecord.ID <= lastStateID {
-			fmt.Println("continuiing", lastStateID)
 			continue
 		}
-		if err := validateEventRecord(eventRecord, number, from, to, lastStateID, chainID); err != nil {
-			fmt.Println("breaking", err.Error())
+		if err := validateEventRecord(eventRecord, number, to, lastStateID, chainID); err != nil {
 			log.Error(err.Error())
 			break
 		}
@@ -1152,19 +1113,17 @@ func (c *Bor) CommitStates(
 		}()
 
 		if err := c.GenesisContractsClient.CommitState(eventRecord, state, header, chain); err != nil {
-			fmt.Println("erred", err)
 			return err
 		}
 		lastStateID++
 	}
-	fmt.Println("lastStateID is", lastStateID)
 	return nil
 }
 
-func validateEventRecord(eventRecord *EventRecordWithTime, number uint64, from, to time.Time, lastStateID uint64, chainID string) error {
+func validateEventRecord(eventRecord *EventRecordWithTime, number uint64, to time.Time, lastStateID uint64, chainID string) error {
 	// event id should be sequential and event.Time should lie in the range [from, to)
-	if lastStateID+1 != eventRecord.ID || eventRecord.ChainID != chainID || eventRecord.Time.Before(from) || !eventRecord.Time.Before(to) {
-		return &InvalidStateReceivedError{number, lastStateID, &from, &to, eventRecord}
+	if lastStateID+1 != eventRecord.ID || eventRecord.ChainID != chainID || !eventRecord.Time.Before(to) {
+		return &InvalidStateReceivedError{number, lastStateID, &to, eventRecord}
 	}
 	return nil
 }
@@ -1178,28 +1137,6 @@ func (c *Bor) SetHeimdallClient(h IHeimdallClient) {
 	c.HeimdallClient = h
 }
 
-func isProposeSpanAction(tx *types.Transaction, validatorContract string) bool {
-	// keccak256('proposeSpan()').slice(0, 4)
-	proposeSpanSig, _ := hex.DecodeString("4b0e4d17")
-	if tx.Data() == nil || len(tx.Data()) < 4 {
-		return false
-	}
-
-	return bytes.Compare(proposeSpanSig, tx.Data()[:4]) == 0 &&
-		tx.To().String() == validatorContract
-}
-
-func isProposeStateAction(tx *types.Transaction, stateReceiverContract string) bool {
-	// keccak256('proposeState(uint256)').slice(0, 4)
-	proposeStateSig, _ := hex.DecodeString("ede01f17")
-	if tx.Data() == nil || len(tx.Data()) < 4 {
-		return false
-	}
-
-	return bytes.Compare(proposeStateSig, tx.Data()[:4]) == 0 &&
-		tx.To().String() == stateReceiverContract
-}
-
 //
 // Private methods
 //
diff --git a/consensus/bor/bor_test/bor_test.go b/consensus/bor/bor_test/bor_test.go
index dd282c9e5f48b8241fff9a631f079e427b8a8f90..2994143d12a5f7d28271723d0436b9a0fa564a36 100644
--- a/consensus/bor/bor_test/bor_test.go
+++ b/consensus/bor/bor_test/bor_test.go
@@ -3,20 +3,17 @@ package bortest
 import (
 	"encoding/hex"
 	"encoding/json"
-	"fmt"
 	"math/big"
 	"testing"
 	"time"
 
-	"github.com/maticnetwork/bor/consensus/bor"
-	"github.com/maticnetwork/bor/core/rawdb"
-
-	"github.com/maticnetwork/bor/crypto"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/mock"
 
+	"github.com/maticnetwork/bor/consensus/bor"
+	"github.com/maticnetwork/bor/core/rawdb"
 	"github.com/maticnetwork/bor/core/types"
-
+	"github.com/maticnetwork/bor/crypto"
 	"github.com/maticnetwork/bor/mocks"
 )
 
@@ -36,7 +33,7 @@ func TestInsertingSpanSizeBlocks(t *testing.T) {
 
 	db := init.ethereum.ChainDb()
 	block := init.genesis.ToBlock(db)
-	to := int64(block.Header().Time)
+	// to := int64(block.Header().Time)
 
 	// Insert sprintSize # of blocks so that span is fetched at the start of a new sprint
 	for i := uint64(1); i <= spanSize; i++ {
@@ -45,7 +42,6 @@ func TestInsertingSpanSizeBlocks(t *testing.T) {
 	}
 
 	assert.True(t, h.AssertCalled(t, "FetchWithRetry", spanPath, ""))
-	assert.True(t, h.AssertCalled(t, "FetchWithRetry", clerkPath, fmt.Sprintf(clerkQueryParams, 0, to, 1)))
 	validators, err := _bor.GetCurrentValidators(sprintSize, spanSize) // check validator set at the first block of new span
 	if err != nil {
 		t.Fatalf("%s", err)
@@ -80,39 +76,22 @@ func TestFetchStateSyncEvents(t *testing.T) {
 	h.On("FetchWithRetry", spanPath, "").Return(res, nil)
 
 	// B.2 Mock State Sync events
-	// read heimdall api response from file
-	res = stateSyncEventsPayload(t)
-	var _eventRecords []*bor.EventRecordWithTime
-	if err := json.Unmarshal(res.Result, &_eventRecords); err != nil {
-		t.Fatalf("%s", err)
-	}
-
-	// use that as a sample to generate bor.stateFetchLimit events
-	eventRecords := generateFakeStateSyncEvents(_eventRecords[0], 50)
-	_res, _ := json.Marshal(eventRecords)
-	response := bor.ResponseWithHeight{Height: "0"}
-	if err := json.Unmarshal(_res, &response.Result); err != nil {
-		t.Fatalf("%s", err)
-	}
-
-	// at # sprintSize, events are fetched for the interval [from, (block-sprint).Time)
-	from := 0
+	fromID := uint64(1)
+	// at # sprintSize, events are fetched for [fromID, (block-sprint).Time)
 	to := int64(chain.GetHeaderByNumber(0).Time)
-	page := 1
-	query1Params := fmt.Sprintf(clerkQueryParams, from, to, page)
-	h.On("FetchWithRetry", clerkPath, query1Params).Return(&response, nil)
+	eventCount := 50
 
-	page = 2
-	query2Params := fmt.Sprintf(clerkQueryParams, from, to, page)
-	h.On("FetchWithRetry", clerkPath, query2Params).Return(&bor.ResponseWithHeight{}, nil)
+	sample := getSampleEventRecord(t)
+	sample.Time = time.Unix(to-int64(eventCount+1), 0) // last event.Time will be just < to
+	eventRecords := generateFakeStateSyncEvents(sample, eventCount)
+	h.On("FetchStateSyncEvents", fromID, to).Return(eventRecords, nil)
 	_bor.SetHeimdallClient(h)
 
 	block = buildNextBlock(t, _bor, chain, block, nil, init.genesis.Config.Bor)
 	insertNewBlock(t, chain, block)
 
 	assert.True(t, h.AssertCalled(t, "FetchWithRetry", spanPath, ""))
-	assert.True(t, h.AssertCalled(t, "FetchWithRetry", clerkPath, query1Params))
-	assert.True(t, h.AssertCalled(t, "FetchWithRetry", clerkPath, query2Params))
+	assert.True(t, h.AssertCalled(t, "FetchStateSyncEvents", fromID, to))
 }
 
 func TestFetchStateSyncEvents_2(t *testing.T) {
@@ -121,64 +100,58 @@ func TestFetchStateSyncEvents_2(t *testing.T) {
 	engine := init.ethereum.Engine()
 	_bor := engine.(*bor.Bor)
 
-	// A. Insert blocks for 0th sprint
-	db := init.ethereum.ChainDb()
-	block := init.genesis.ToBlock(db)
-	// Insert sprintSize # of blocks so that span is fetched at the start of a new sprint
-	for i := uint64(1); i < sprintSize; i++ {
-		block = buildNextBlock(t, _bor, chain, block, nil, init.genesis.Config.Bor)
-		insertNewBlock(t, chain, block)
-	}
-
-	// B. Before inserting 1st block of the next sprint, mock heimdall deps
-	// B.1 Mock /bor/span/1
+	// Mock /bor/span/1
 	res, _ := loadSpanFromFile(t)
 	h := &mocks.IHeimdallClient{}
 	h.On("FetchWithRetry", spanPath, "").Return(res, nil)
 
-	// B.2 Mock State Sync events
-	// read heimdall api response from file
-	res = stateSyncEventsPayload(t)
-	var _eventRecords []*bor.EventRecordWithTime
-	if err := json.Unmarshal(res.Result, &_eventRecords); err != nil {
-		t.Fatalf("%s", err)
-	}
-	sample := _eventRecords[0]
+	// Mock State Sync events
+	// at # sprintSize, events are fetched for [fromID, (block-sprint).Time)
+	fromID := uint64(1)
+	to := int64(chain.GetHeaderByNumber(0).Time)
+	sample := getSampleEventRecord(t)
 
-	// First query will be from [0, (block-sprint).Time]
-	// Insert 4 events are in this time range
+	// First query will be from [id=1, (block-sprint).Time]
+	// Insert 5 events in this time range
 	eventRecords := []*bor.EventRecordWithTime{
-		buildStateEvent(sample, 2, 3), // id = 2, time = 3
+		buildStateEvent(sample, 1, 3), // id = 1, time = 1
+		buildStateEvent(sample, 2, 1), // id = 2, time = 3
 		buildStateEvent(sample, 3, 2), // id = 3, time = 2
-		buildStateEvent(sample, 1, 1), // id = 1, time = 1
-		// event with id 4 is missing
-		buildStateEvent(sample, 5, 4), // id = 5, time = 4
-	}
-	_res, _ := json.Marshal(eventRecords)
-	response := bor.ResponseWithHeight{Height: "0"}
-	if err := json.Unmarshal(_res, &response.Result); err != nil {
-		t.Fatalf("%s", err)
+		// event with id 5 is missing
+		buildStateEvent(sample, 4, 5), // id = 4, time = 5
+		buildStateEvent(sample, 6, 4), // id = 6, time = 4
 	}
-
-	from := 0
-	to := int64(chain.GetHeaderByNumber(0).Time)
-	page := 1
-	queryParams := fmt.Sprintf(clerkQueryParams, from, to, page)
-	h.On("FetchWithRetry", clerkPath, queryParams).Return(&response, nil)
-
-	page = 2
-	query2Params := fmt.Sprintf(clerkQueryParams, from, to, page)
-	h.On("FetchWithRetry", clerkPath, query2Params).Return(&bor.ResponseWithHeight{}, nil)
+	h.On("FetchStateSyncEvents", fromID, to).Return(eventRecords, nil)
 	_bor.SetHeimdallClient(h)
 
-	block = buildNextBlock(t, _bor, chain, block, nil, init.genesis.Config.Bor)
-	insertNewBlock(t, chain, block)
-
+	// Insert blocks for 0th sprint
+	db := init.ethereum.ChainDb()
+	block := init.genesis.ToBlock(db)
+	for i := uint64(1); i <= sprintSize; i++ {
+		block = buildNextBlock(t, _bor, chain, block, nil, init.genesis.Config.Bor)
+		insertNewBlock(t, chain, block)
+	}
 	assert.True(t, h.AssertCalled(t, "FetchWithRetry", spanPath, ""))
-	assert.True(t, h.AssertCalled(t, "FetchWithRetry", clerkPath, queryParams))
+	assert.True(t, h.AssertCalled(t, "FetchStateSyncEvents", fromID, to))
 	lastStateID, _ := _bor.GenesisContractsClient.LastStateId(sprintSize)
-	assert.Equal(t, uint64(3), lastStateID.Uint64())
-	fmt.Println("lastStateId after", lastStateID)
+	// state 6 was not written
+	assert.Equal(t, uint64(4), lastStateID.Uint64())
+
+	//
+	fromID = uint64(5)
+	to = int64(chain.GetHeaderByNumber(sprintSize).Time)
+	eventRecords = []*bor.EventRecordWithTime{
+		buildStateEvent(sample, 5, 7),
+		buildStateEvent(sample, 6, 4),
+	}
+	h.On("FetchStateSyncEvents", fromID, to).Return(eventRecords, nil)
+	for i := sprintSize + 1; i <= spanSize; i++ {
+		block = buildNextBlock(t, _bor, chain, block, nil, init.genesis.Config.Bor)
+		insertNewBlock(t, chain, block)
+	}
+	assert.True(t, h.AssertCalled(t, "FetchStateSyncEvents", fromID, to))
+	lastStateID, _ = _bor.GenesisContractsClient.LastStateId(spanSize)
+	assert.Equal(t, uint64(6), lastStateID.Uint64())
 }
 
 func TestOutOfTurnSigning(t *testing.T) {
@@ -257,15 +230,17 @@ func getMockedHeimdallClient(t *testing.T) (*mocks.IHeimdallClient, *bor.Heimdal
 	res, heimdallSpan := loadSpanFromFile(t)
 	h := &mocks.IHeimdallClient{}
 	h.On("FetchWithRetry", "bor/span/1", "").Return(res, nil)
-	h.On("FetchWithRetry", mock.AnythingOfType("string"), mock.AnythingOfType("string")).Return(stateSyncEventsPayload(t), nil)
+	h.On(
+		"FetchStateSyncEvents",
+		mock.AnythingOfType("uint64"),
+		mock.AnythingOfType("int64")).Return([]*bor.EventRecordWithTime{getSampleEventRecord(t)}, nil)
 	return h, heimdallSpan
 }
 
 func generateFakeStateSyncEvents(sample *bor.EventRecordWithTime, count int) []*bor.EventRecordWithTime {
 	events := make([]*bor.EventRecordWithTime, count)
 	event := *sample
-	event.ID = 0
-	event.Time = time.Now()
+	event.ID = 1
 	events[0] = &bor.EventRecordWithTime{}
 	*events[0] = event
 	for i := 1; i < count; i++ {
@@ -283,3 +258,13 @@ func buildStateEvent(sample *bor.EventRecordWithTime, id uint64, timeStamp int64
 	event.Time = time.Unix(timeStamp, 0)
 	return &event
 }
+
+func getSampleEventRecord(t *testing.T) *bor.EventRecordWithTime {
+	res := stateSyncEventsPayload(t)
+	var _eventRecords []*bor.EventRecordWithTime
+	if err := json.Unmarshal(res.Result, &_eventRecords); err != nil {
+		t.Fatalf("%s", err)
+	}
+	_eventRecords[0].Time = time.Unix(1, 0)
+	return _eventRecords[0]
+}
diff --git a/consensus/bor/bor_test/genesis.json b/consensus/bor/bor_test/genesis.json
index 93f3cdbd3d0ec194773de5dc2abd5551343a3b17..ca21f42e1ac5f30cf8bb6a34908b5afe49c796eb 100644
--- a/consensus/bor/bor_test/genesis.json
+++ b/consensus/bor/bor_test/genesis.json
@@ -31,7 +31,7 @@
     },
     "0000000000000000000000000000000000001001": {
       "balance": "0x0",
-      "code": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c806319494a17146100515780633434735f146100ec5780634c7af28e146101365780635407ca6714610154575b600080fd5b6100d26004803603604081101561006757600080fd5b81019080803590602001909291908035906020019064010000000081111561008e57600080fd5b8201836020820111156100a057600080fd5b803590602001918460018302840111640100000000831117156100c257600080fd5b9091929391929390505050610172565b604051808215151515815260200191505060405180910390f35b6100f4610441565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61013e610459565b6040518082815260200191505060405180910390f35b61015c61045f565b6040518082815260200191505060405180910390f35b600073fffffffffffffffffffffffffffffffffffffffe73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146101c057600080fd5b83600081905550606061021e61021985858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610465565b610493565b9050600061023f8260008151811061023257fe5b6020026020010151610570565b9050806001805401146102ba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f537461746549647320617265206e6f742073657175656e7469616c000000000081525060200191505060405180910390fd5b60016000815480929190600101919050555060006102eb836001815181106102de57fe5b60200260200101516105e1565b9050606061030c846002815181106102ff57fe5b6020026020010151610604565b905061031782610690565b15610436576000624c4b409050606084836040516024018083815260200180602001828103825283818151815260200191508051906020019080838360005b83811015610371578082015181840152602081019050610356565b50505050905090810190601f16801561039e5780820380516001836020036101000a031916815260200191505b5093505050506040516020818303038152906040527f26c53bea000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050905060008082516020840160008887f1965050505b505050509392505050565b73fffffffffffffffffffffffffffffffffffffffe81565b60005481565b60015481565b61046d610910565b600060208301905060405180604001604052808451815260200182815250915050919050565b606061049e826106a9565b6104a757600080fd5b60006104b2836106f7565b90506060816040519080825280602002602001820160405280156104f057816020015b6104dd61092a565b8152602001906001900390816104d55790505b50905060006105028560200151610768565b8560200151019050600080600090505b8481101561056357610523836107f1565b915060405180604001604052808381526020018481525084828151811061054657fe5b602002602001018190525081830192508080600101915050610512565b5082945050505050919050565b600080826000015111801561058a57506021826000015111155b61059357600080fd5b60006105a28360200151610768565b905060008184600001510390506000808386602001510190508051915060208310156105d557826020036101000a820491505b81945050505050919050565b600060158260000151146105f457600080fd5b6105fd82610570565b9050919050565b6060600082600001511161061757600080fd5b60006106268360200151610768565b905060008184600001510390506060816040519080825280601f01601f1916602001820160405280156106685781602001600182028038833980820191505090505b50905060008160200190506106848487602001510182856108a9565b81945050505050919050565b600080823b905060008163ffffffff1611915050919050565b600080826000015114156106c057600090506106f2565b60008083602001519050805160001a915060c060ff168260ff1610156106eb576000925050506106f2565b6001925050505b919050565b6000808260000151141561070e5760009050610763565b600080905060006107228460200151610768565b84602001510190506000846000015185602001510190505b8082101561075c5761074b826107f1565b82019150828060010193505061073a565b8293505050505b919050565b600080825160001a9050608060ff168110156107885760009150506107ec565b60b860ff168110806107ad575060c060ff1681101580156107ac575060f860ff1681105b5b156107bc5760019150506107ec565b60c060ff168110156107dc5760018060b80360ff168203019150506107ec565b60018060f80360ff168203019150505b919050565b6000806000835160001a9050608060ff16811015610812576001915061089f565b60b860ff1681101561082f576001608060ff16820301915061089e565b60c060ff1681101561085f5760b78103600185019450806020036101000a8551046001820181019350505061089d565b60f860ff1681101561087c57600160c060ff16820301915061089c565b60f78103600185019450806020036101000a855104600182018101935050505b5b5b5b8192505050919050565b60008114156108b75761090b565b5b602060ff1681106108e75782518252602060ff1683019250602060ff1682019150602060ff16810390506108b8565b6000600182602060ff16036101000a03905080198451168184511681811785525050505b505050565b604051806040016040528060008152602001600081525090565b60405180604001604052806000815260200160008152509056fea265627a7a72315820517dba64036af56cf58779d5f7ff3abb8279cf161ce9a6ad2c3f7cb1a1f1090764736f6c634300050c0032"
+      "code": "0x608060405234801561001057600080fd5b50600436106100415760003560e01c806319494a17146100465780633434735f146100e15780635407ca671461012b575b600080fd5b6100c76004803603604081101561005c57600080fd5b81019080803590602001909291908035906020019064010000000081111561008357600080fd5b82018360208201111561009557600080fd5b803590602001918460018302840111640100000000831117156100b757600080fd5b9091929391929390505050610149565b604051808215151515815260200191505060405180910390f35b6100e9610411565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610133610429565b6040518082815260200191505060405180910390f35b600073fffffffffffffffffffffffffffffffffffffffe73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461019757600080fd5b60606101ee6101e985858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061042f565b61045d565b9050600061020f8260008151811061020257fe5b602002602001015161053a565b9050806001600054011461028b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f537461746549647320617265206e6f742073657175656e7469616c000000000081525060200191505060405180910390fd5b600080815480929190600101919050555060006102bb836001815181106102ae57fe5b60200260200101516105ab565b905060606102dc846002815181106102cf57fe5b60200260200101516105ce565b90506102e78261065a565b15610406576000624c4b409050606084836040516024018083815260200180602001828103825283818151815260200191508051906020019080838360005b83811015610341578082015181840152602081019050610326565b50505050905090810190601f16801561036e5780820380516001836020036101000a031916815260200191505b5093505050506040516020818303038152906040527f26c53bea000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050905060008082516020840160008887f1965050505b505050509392505050565b73fffffffffffffffffffffffffffffffffffffffe81565b60005481565b6104376108da565b600060208301905060405180604001604052808451815260200182815250915050919050565b606061046882610673565b61047157600080fd5b600061047c836106c1565b90506060816040519080825280602002602001820160405280156104ba57816020015b6104a76108f4565b81526020019060019003908161049f5790505b50905060006104cc8560200151610732565b8560200151019050600080600090505b8481101561052d576104ed836107bb565b915060405180604001604052808381526020018481525084828151811061051057fe5b6020026020010181905250818301925080806001019150506104dc565b5082945050505050919050565b600080826000015111801561055457506021826000015111155b61055d57600080fd5b600061056c8360200151610732565b9050600081846000015103905060008083866020015101905080519150602083101561059f57826020036101000a820491505b81945050505050919050565b600060158260000151146105be57600080fd5b6105c78261053a565b9050919050565b606060008260000151116105e157600080fd5b60006105f08360200151610732565b905060008184600001510390506060816040519080825280601f01601f1916602001820160405280156106325781602001600182028038833980820191505090505b509050600081602001905061064e848760200151018285610873565b81945050505050919050565b600080823b905060008163ffffffff1611915050919050565b6000808260000151141561068a57600090506106bc565b60008083602001519050805160001a915060c060ff168260ff1610156106b5576000925050506106bc565b6001925050505b919050565b600080826000015114156106d8576000905061072d565b600080905060006106ec8460200151610732565b84602001510190506000846000015185602001510190505b8082101561072657610715826107bb565b820191508280600101935050610704565b8293505050505b919050565b600080825160001a9050608060ff168110156107525760009150506107b6565b60b860ff16811080610777575060c060ff168110158015610776575060f860ff1681105b5b156107865760019150506107b6565b60c060ff168110156107a65760018060b80360ff168203019150506107b6565b60018060f80360ff168203019150505b919050565b6000806000835160001a9050608060ff168110156107dc5760019150610869565b60b860ff168110156107f9576001608060ff168203019150610868565b60c060ff168110156108295760b78103600185019450806020036101000a85510460018201810193505050610867565b60f860ff1681101561084657600160c060ff168203019150610866565b60f78103600185019450806020036101000a855104600182018101935050505b5b5b5b8192505050919050565b6000811415610881576108d5565b5b602060ff1681106108b15782518252602060ff1683019250602060ff1682019150602060ff1681039050610882565b6000600182602060ff16036101000a03905080198451168184511681811785525050505b505050565b604051806040016040528060008152602001600081525090565b60405180604001604052806000815260200160008152509056fea265627a7a723158206e562292874be6a994dcfabfea65957791c1491194eeb7dea6f7eaf1390c036e64736f6c634300050c0032"
     },
     "0000000000000000000000000000000000001010": {
       "balance": "0x204fce28085b549b31600000",
diff --git a/consensus/bor/errors.go b/consensus/bor/errors.go
index 1a72d42f29fd8a9c97a50f6005a0d4208b477331..a1e60d1e219e50241996df3199dd720d43abbac8 100644
--- a/consensus/bor/errors.go
+++ b/consensus/bor/errors.go
@@ -128,17 +128,15 @@ func (e *WrongDifficultyError) Error() string {
 type InvalidStateReceivedError struct {
 	Number      uint64
 	LastStateID uint64
-	From        *time.Time
 	To          *time.Time
 	Event       *EventRecordWithTime
 }
 
 func (e *InvalidStateReceivedError) Error() string {
 	return fmt.Sprintf(
-		"Received invalid event %s at block %d. Requested events from %s to %s. lastStateID was %d.",
+		"Received invalid event %s at block %d. Requested events until %s. Last state id was %d",
 		e.Event,
 		e.Number,
-		e.From.Format(time.RFC3339),
 		e.To.Format(time.RFC3339),
 		e.LastStateID,
 	)
diff --git a/consensus/bor/genesis_contracts_client.go b/consensus/bor/genesis_contracts_client.go
index cc65e9b1cbb43b3f3a94c5afe14d1eca23e3913d..17323f278d973ebb6561d4063b8d6d781d3cc79a 100644
--- a/consensus/bor/genesis_contracts_client.go
+++ b/consensus/bor/genesis_contracts_client.go
@@ -4,9 +4,7 @@ import (
 	"context"
 	"math"
 	"math/big"
-
 	"strings"
-	"time"
 
 	"github.com/maticnetwork/bor/accounts/abi"
 	"github.com/maticnetwork/bor/common"
@@ -30,7 +28,7 @@ type GenesisContractsClient struct {
 }
 
 const validatorsetABI = `[{"constant":true,"inputs":[],"name":"SPRINT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"SYSTEM_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"CHAIN","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"FIRST_END_BLOCK","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"producers","outputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"power","type":"uint256"},{"internalType":"address","name":"signer","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"ROUND_TYPE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"BOR_ID","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"spanNumbers","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"VOTE_TYPE","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"validators","outputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"power","type":"uint256"},{"internalType":"address","name":"signer","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"spans","outputs":[{"internalType":"uint256","name":"number","type":"uint256"},{"internalType":"uint256","name":"startBlock","type":"uint256"},{"internalType":"uint256","name":"endBlock","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"startBlock","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"endBlock","type":"uint256"}],"name":"NewSpan","type":"event"},{"constant":true,"inputs":[],"name":"currentSprint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"span","type":"uint256"}],"name":"getSpan","outputs":[{"internalType":"uint256","name":"number","type":"uint256"},{"internalType":"uint256","name":"startBlock","type":"uint256"},{"internalType":"uint256","name":"endBlock","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getCurrentSpan","outputs":[{"internalType":"uint256","name":"number","type":"uint256"},{"internalType":"uint256","name":"startBlock","type":"uint256"},{"internalType":"uint256","name":"endBlock","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getNextSpan","outputs":[{"internalType":"uint256","name":"number","type":"uint256"},{"internalType":"uint256","name":"startBlock","type":"uint256"},{"internalType":"uint256","name":"endBlock","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"number","type":"uint256"}],"name":"getSpanByBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"currentSpanNumber","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"span","type":"uint256"}],"name":"getValidatorsTotalStakeBySpan","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"span","type":"uint256"}],"name":"getProducersTotalStakeBySpan","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"span","type":"uint256"},{"internalType":"address","name":"signer","type":"address"}],"name":"getValidatorBySigner","outputs":[{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"power","type":"uint256"},{"internalType":"address","name":"signer","type":"address"}],"internalType":"struct BorValidatorSet.Validator","name":"result","type":"tuple"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"span","type":"uint256"},{"internalType":"address","name":"signer","type":"address"}],"name":"isValidator","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"span","type":"uint256"},{"internalType":"address","name":"signer","type":"address"}],"name":"isProducer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"signer","type":"address"}],"name":"isCurrentValidator","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"signer","type":"address"}],"name":"isCurrentProducer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"number","type":"uint256"}],"name":"getBorValidators","outputs":[{"internalType":"address[]","name":"","type":"address[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getInitialValidators","outputs":[{"internalType":"address[]","name":"","type":"address[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getValidators","outputs":[{"internalType":"address[]","name":"","type":"address[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"newSpan","type":"uint256"},{"internalType":"uint256","name":"startBlock","type":"uint256"},{"internalType":"uint256","name":"endBlock","type":"uint256"},{"internalType":"bytes","name":"validatorBytes","type":"bytes"},{"internalType":"bytes","name":"producerBytes","type":"bytes"}],"name":"commitSpan","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"span","type":"uint256"},{"internalType":"bytes32","name":"dataHash","type":"bytes32"},{"internalType":"bytes","name":"sigs","type":"bytes"}],"name":"getStakePowerBySigs","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"rootHash","type":"bytes32"},{"internalType":"bytes32","name":"leaf","type":"bytes32"},{"internalType":"bytes","name":"proof","type":"bytes"}],"name":"checkMembership","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"d","type":"bytes32"}],"name":"leafNode","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"left","type":"bytes32"},{"internalType":"bytes32","name":"right","type":"bytes32"}],"name":"innerNode","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"pure","type":"function"}]`
-const stateReceiverABI = `[{"constant":true,"inputs":[],"name":"SYSTEM_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"lastStateSyncTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"lastStateId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"syncTime","type":"uint256"},{"internalType":"bytes","name":"recordBytes","type":"bytes"}],"name":"commitState","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"}]`
+const stateReceiverABI = `[{"constant":true,"inputs":[],"name":"SYSTEM_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"lastStateId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"syncTime","type":"uint256"},{"internalType":"bytes","name":"recordBytes","type":"bytes"}],"name":"commitState","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"}]`
 
 func NewGenesisContractsClient(
 	chainConfig *params.ChainConfig,
@@ -76,33 +74,6 @@ func (gc *GenesisContractsClient) CommitState(
 	return nil
 }
 
-func (gc *GenesisContractsClient) LastStateSyncTime(snapshotNumber uint64) (time.Time, error) {
-	method := "lastStateSyncTime"
-	data, err := gc.stateReceiverABI.Pack(method)
-	if err != nil {
-		log.Error("Unable to pack tx for getLastSyncTime", "error", err)
-		return time.Time{}, err
-	}
-
-	msgData := (hexutil.Bytes)(data)
-	toAddress := common.HexToAddress(gc.StateReceiverContract)
-	gas := (hexutil.Uint64)(uint64(math.MaxUint64 / 2))
-	result, err := gc.ethAPI.Call(context.Background(), ethapi.CallArgs{
-		Gas:  &gas,
-		To:   &toAddress,
-		Data: &msgData,
-	}, rpc.BlockNumber(snapshotNumber))
-	if err != nil {
-		return time.Time{}, err
-	}
-
-	var ret = new(*big.Int)
-	if err := gc.stateReceiverABI.Unpack(ret, method, result); err != nil {
-		return time.Time{}, err
-	}
-	return time.Unix((*ret).Int64(), 0), nil
-}
-
 func (gc *GenesisContractsClient) LastStateId(snapshotNumber uint64) (*big.Int, error) {
 	method := "lastStateId"
 	data, err := gc.stateReceiverABI.Pack(method)
diff --git a/consensus/bor/rest.go b/consensus/bor/rest.go
index 14bfb7853cff5224b318607276aa284d5920e4da..35ac91622fd02d1e90435a9969ed56ad75404121 100644
--- a/consensus/bor/rest.go
+++ b/consensus/bor/rest.go
@@ -6,11 +6,16 @@ import (
 	"io/ioutil"
 	"net/http"
 	"net/url"
+	"sort"
 	"time"
 
 	"github.com/maticnetwork/bor/log"
 )
 
+var (
+	stateFetchLimit = 50
+)
+
 // ResponseWithHeight defines a response object type that wraps an original
 // response with a height.
 type ResponseWithHeight struct {
@@ -21,6 +26,7 @@ type ResponseWithHeight struct {
 type IHeimdallClient interface {
 	Fetch(path string, query string) (*ResponseWithHeight, error)
 	FetchWithRetry(path string, query string) (*ResponseWithHeight, error)
+	FetchStateSyncEvents(fromID uint64, to int64) ([]*EventRecordWithTime, error)
 }
 
 type HeimdallClient struct {
@@ -38,6 +44,36 @@ func NewHeimdallClient(urlString string) (*HeimdallClient, error) {
 	return h, nil
 }
 
+func (h *HeimdallClient) FetchStateSyncEvents(fromID uint64, to int64) ([]*EventRecordWithTime, error) {
+	page := 1
+	eventRecords := make([]*EventRecordWithTime, 0)
+	for {
+		queryParams := fmt.Sprintf("from-id=%d&to-time=%d&page=%d&limit=%d", fromID, to, page, stateFetchLimit)
+		log.Info("Fetching state sync events", "queryParams", queryParams)
+		response, err := h.FetchWithRetry("clerk/event-record/list", queryParams)
+		if err != nil {
+			return nil, err
+		}
+		var _eventRecords []*EventRecordWithTime
+		if response.Result == nil { // status 204
+			break
+		}
+		if err := json.Unmarshal(response.Result, &_eventRecords); err != nil {
+			return nil, err
+		}
+		eventRecords = append(eventRecords, _eventRecords...)
+		if len(_eventRecords) < stateFetchLimit {
+			break
+		}
+		page++
+	}
+
+	sort.SliceStable(eventRecords, func(i, j int) bool {
+		return eventRecords[i].ID < eventRecords[j].ID
+	})
+	return eventRecords, nil
+}
+
 // Fetch fetches response from heimdall
 func (h *HeimdallClient) Fetch(rawPath string, rawQuery string) (*ResponseWithHeight, error) {
 	u, err := url.Parse(h.urlString)
diff --git a/mocks/IHeimdallClient.go b/mocks/IHeimdallClient.go
index 5bc7cb6e6202515f35507a06f905c2311964fa6e..d6037d2162de114cfa0905e9fd7a79fe424de8cd 100644
--- a/mocks/IHeimdallClient.go
+++ b/mocks/IHeimdallClient.go
@@ -35,6 +35,29 @@ func (_m *IHeimdallClient) Fetch(path string, query string) (*bor.ResponseWithHe
 	return r0, r1
 }
 
+// FetchStateSyncEvents provides a mock function with given fields: fromID, to
+func (_m *IHeimdallClient) FetchStateSyncEvents(fromID uint64, to int64) ([]*bor.EventRecordWithTime, error) {
+	ret := _m.Called(fromID, to)
+
+	var r0 []*bor.EventRecordWithTime
+	if rf, ok := ret.Get(0).(func(uint64, int64) []*bor.EventRecordWithTime); ok {
+		r0 = rf(fromID, to)
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).([]*bor.EventRecordWithTime)
+		}
+	}
+
+	var r1 error
+	if rf, ok := ret.Get(1).(func(uint64, int64) error); ok {
+		r1 = rf(fromID, to)
+	} else {
+		r1 = ret.Error(1)
+	}
+
+	return r0, r1
+}
+
 // FetchWithRetry provides a mock function with given fields: path, query
 func (_m *IHeimdallClient) FetchWithRetry(path string, query string) (*bor.ResponseWithHeight, error) {
 	ret := _m.Called(path, query)