diff --git a/cmd/puppeth/wizard_genesis.go b/cmd/puppeth/wizard_genesis.go
index 6b3d8479b77e2f5d0b626a82668edbf455c09e08..f4dd814f976c0827190198c21aff7e4a55607083 100644
--- a/cmd/puppeth/wizard_genesis.go
+++ b/cmd/puppeth/wizard_genesis.go
@@ -108,11 +108,12 @@ func (w *wizard) makeGenesis() {
 		genesis.Difficulty = big.NewInt(1)
 		genesis.GasLimit = 10000000
 		genesis.Config.Bor = &params.BorConfig{
-			Period:            1,
-			ProducerDelay:     5,
-			Sprint:            60,
-			ValidatorContract: "0x0000000000000000000000000000000000001000",
-			Heimdall:          "http://localhost:1317",
+			Period:                1,
+			ProducerDelay:         5,
+			Sprint:                60,
+			ValidatorContract:     "0x0000000000000000000000000000000000001000",
+			StateReceiverContract: "0x0000000000000000000000000000000000001001",
+			Heimdall:              "http://localhost:1317",
 		}
 
 		// We also need the initial list of signers
diff --git a/consensus/bor/bor.go b/consensus/bor/bor.go
index 12a3bcc76ea4a85cec3e200b24483b3d36561590..219aa5620c7457a9a3854254060a99fbcb5a13e5 100644
--- a/consensus/bor/bor.go
+++ b/consensus/bor/bor.go
@@ -40,7 +40,8 @@ import (
 	"golang.org/x/crypto/sha3"
 )
 
-const validatorsetABI = `[{"constant":true,"inputs":[{"name":"span","type":"uint256"}],"name":"getSpan","outputs":[{"name":"number","type":"uint256"},{"name":"startBlock","type":"uint256"},{"name":"endBlock","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"number","type":"uint256"}],"name":"getBorValidators","outputs":[{"name":"","type":"address[]"},{"name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"newSpan","type":"uint256"},{"name":"startBlock","type":"uint256"},{"name":"endBlock","type":"uint256"},{"name":"validatorBytes","type":"bytes"},{"name":"producerBytes","type":"bytes"}],"name":"commitSpan","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"proposeSpan","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"currentSpanNumber","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getNextSpan","outputs":[{"name":"number","type":"uint256"},{"name":"startBlock","type":"uint256"},{"name":"endBlock","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getInitialValidators","outputs":[{"name":"","type":"address[]"},{"name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"spanProposalPending","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getCurrentSpan","outputs":[{"name":"number","type":"uint256"},{"name":"startBlock","type":"uint256"},{"name":"endBlock","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"number","type":"uint256"}],"name":"getSpanByBlock","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getValidators","outputs":[{"name":"","type":"address[]"},{"name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"vote","type":"bytes"},{"name":"sigs","type":"bytes"},{"name":"txBytes","type":"bytes"},{"name":"proof","type":"bytes"}],"name":"validateValidatorSet","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}]`
+const validatorsetABI = `[{"constant":true,"inputs":[{"name":"span","type":"uint256"}],"name":"getSpan","outputs":[{"name":"number","type":"uint256"},{"name":"startBlock","type":"uint256"},{"name":"endBlock","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"number","type":"uint256"}],"name":"getBorValidators","outputs":[{"name":"","type":"address[]"},{"name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"span","type":"uint256"},{"name":"signer","type":"address"}],"name":"isProducer","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"newSpan","type":"uint256"},{"name":"startBlock","type":"uint256"},{"name":"endBlock","type":"uint256"},{"name":"validatorBytes","type":"bytes"},{"name":"producerBytes","type":"bytes"}],"name":"commitSpan","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"span","type":"uint256"},{"name":"signer","type":"address"}],"name":"isValidator","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"proposeSpan","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"currentSpanNumber","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getNextSpan","outputs":[{"name":"number","type":"uint256"},{"name":"startBlock","type":"uint256"},{"name":"endBlock","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getInitialValidators","outputs":[{"name":"","type":"address[]"},{"name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"spanProposalPending","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getCurrentSpan","outputs":[{"name":"number","type":"uint256"},{"name":"startBlock","type":"uint256"},{"name":"endBlock","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"number","type":"uint256"}],"name":"getSpanByBlock","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getValidators","outputs":[{"name":"","type":"address[]"},{"name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"vote","type":"bytes"},{"name":"sigs","type":"bytes"},{"name":"txBytes","type":"bytes"},{"name":"proof","type":"bytes"}],"name":"validateValidatorSet","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}]`
+const stateReceiverABI = `[{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"states","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"recordBytes","type":"bytes"}],"name":"commitState","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getPendingStates","outputs":[{"name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"SYSTEM_ADDRESS","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"validatorSet","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"vote","type":"bytes"},{"name":"sigs","type":"bytes"},{"name":"txBytes","type":"bytes"},{"name":"proof","type":"bytes"}],"name":"validateValidatorSet","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"isValidatorSetContract","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"stateId","type":"uint256"}],"name":"proposeState","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"signer","type":"address"}],"name":"isProducer","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"signer","type":"address"}],"name":"isValidator","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"}]`
 
 const (
 	checkpointInterval = 1024 // Number of blocks after which to save the vote snapshot to the database
@@ -246,9 +247,10 @@ type Bor struct {
 	signFn SignerFn       // Signer function to authorize hashes with
 	lock   sync.RWMutex   // Protects the signer fields
 
-	ethAPI          *ethapi.PublicBlockChainAPI
-	validatorSetABI abi.ABI
-	httpClient      http.Client
+	ethAPI           *ethapi.PublicBlockChainAPI
+	validatorSetABI  abi.ABI
+	stateReceiverABI abi.ABI
+	httpClient       http.Client
 
 	// The fields below are for testing only
 	fakeDiff bool // Skip difficulty verifications
@@ -272,14 +274,16 @@ func New(
 	recents, _ := lru.NewARC(inmemorySnapshots)
 	signatures, _ := lru.NewARC(inmemorySignatures)
 	vABI, _ := abi.JSON(strings.NewReader(validatorsetABI))
+	sABI, _ := abi.JSON(strings.NewReader(stateReceiverABI))
 	c := &Bor{
-		chainConfig:     chainConfig,
-		config:          borConfig,
-		db:              db,
-		ethAPI:          ethAPI,
-		recents:         recents,
-		signatures:      signatures,
-		validatorSetABI: vABI,
+		chainConfig:      chainConfig,
+		config:           borConfig,
+		db:               db,
+		ethAPI:           ethAPI,
+		recents:          recents,
+		signatures:       signatures,
+		validatorSetABI:  vABI,
+		stateReceiverABI: sABI,
 		httpClient: http.Client{
 			Timeout: time.Duration(5 * time.Second),
 		},
@@ -663,10 +667,19 @@ func (c *Bor) Prepare(chain consensus.ChainReader, header *types.Header) error {
 func (c *Bor) Finalize(chain consensus.ChainReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header) {
 	// commit span
 	if header.Number.Uint64()%c.config.Sprint == 0 {
-		if err := c.checkAndCommitSpan(state, header, chainContext{Chain: chain, Bor: c}); err != nil {
+		cx := chainContext{Chain: chain, Bor: c}
+
+		// check and commit span
+		if err := c.checkAndCommitSpan(state, header, cx); err != nil {
 			fmt.Println("Error while committing span", err)
 			// return nil, err
 		}
+
+		// commit statees
+		if err := c.CommitStates(state, header, cx); err != nil {
+			fmt.Println("Error while committing states", err)
+			// return nil, err
+		}
 	}
 
 	// No block rewards in PoA, so the state remains as is and uncles are dropped
@@ -679,11 +692,20 @@ func (c *Bor) Finalize(chain consensus.ChainReader, header *types.Header, state
 func (c *Bor) FinalizeAndAssemble(chain consensus.ChainReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt) (*types.Block, error) {
 	// commit span
 	if header.Number.Uint64()%c.config.Sprint == 0 {
-		err := c.checkAndCommitSpan(state, header, chainContext{Chain: chain, Bor: c})
+		cx := chainContext{Chain: chain, Bor: c}
+
+		// check and commit span
+		err := c.checkAndCommitSpan(state, header, cx)
 		if err != nil {
 			fmt.Println("Error while committing span", err)
 			// return nil, err
 		}
+
+		// commit statees
+		if err := c.CommitStates(state, header, cx); err != nil {
+			fmt.Println("Error while committing states", err)
+			// return nil, err
+		}
 	}
 
 	// No block rewards in PoA, so the state remains as is and uncles are dropped
@@ -1083,6 +1105,100 @@ func (c *Bor) commitSpan(
 	return applyMessage(msg, state, header, c.chainConfig, chain)
 }
 
+// GetPendingStateProposals get pending state proposals
+func (c *Bor) GetPendingStateProposals(snapshotNumber uint64) ([]*big.Int, error) {
+	// block
+	blockNr := rpc.BlockNumber(snapshotNumber)
+
+	// method
+	method := "getPendingStates"
+
+	data, err := c.stateReceiverABI.Pack(method)
+	if err != nil {
+		fmt.Println("Unable to pack tx for getPendingStates", "error", err)
+		return nil, err
+	}
+
+	ctx, cancel := context.WithCancel(context.Background())
+	defer cancel() // cancel when we are finished consuming integers
+
+	msgData := (hexutil.Bytes)(data)
+	toAddress := common.HexToAddress(c.config.StateReceiverContract)
+	gas := (hexutil.Uint64)(uint64(math.MaxUint64 / 2))
+	result, err := c.ethAPI.Call(ctx, ethapi.CallArgs{
+		Gas:  &gas,
+		To:   &toAddress,
+		Data: &msgData,
+	}, blockNr)
+	if err != nil {
+		return nil, err
+	}
+
+	var ret = new([]*big.Int)
+	if err := c.stateReceiverABI.Unpack(ret, method, result); err != nil {
+		return nil, err
+	}
+
+	return *ret, nil
+}
+
+// CommitStates commit states
+func (c *Bor) CommitStates(
+	state *state.StateDB,
+	header *types.Header,
+	chain core.ChainContext,
+) error {
+	// get pending state proposals
+	stateIds, err := c.GetPendingStateProposals(header.Number.Uint64() - 1)
+	if err != nil {
+		return err
+	}
+
+	// state ids
+	if len(stateIds) > 0 {
+		fmt.Println("Found new proposed states", len(stateIds))
+	}
+
+	method := "commitState"
+
+	// itereate through state ids
+	for _, stateID := range stateIds {
+		// fetch from heimdall
+		response, err := FetchFromHeimdall(c.httpClient, c.chainConfig.Bor.Heimdall, "clerk", "event-record", strconv.FormatUint(stateID.Uint64(), 10))
+		if err != nil {
+			return err
+		}
+
+		// get event record
+		var eventRecord EventRecord
+		if err := json.Unmarshal(response.Result, &eventRecord); err != nil {
+			return err
+		}
+
+		recordBytes, err := rlp.EncodeToBytes(eventRecord)
+		if err != nil {
+			return err
+		}
+
+		// get packed data for commit state
+		data, err := c.stateReceiverABI.Pack(method, recordBytes)
+		if err != nil {
+			fmt.Println("Unable to pack tx for commitState", "error", err)
+			return err
+		}
+
+		// get system message
+		msg := getSystemMessage(common.HexToAddress(c.config.StateReceiverContract), data)
+
+		// apply message
+		if err := applyMessage(msg, state, header, c.chainConfig, chain); err != nil {
+			return err
+		}
+	}
+
+	return nil
+}
+
 //
 // Private methods
 //
diff --git a/consensus/bor/clerk.go b/consensus/bor/clerk.go
new file mode 100644
index 0000000000000000000000000000000000000000..70ea4e46643ace974fd2025ea259609be15ededa
--- /dev/null
+++ b/consensus/bor/clerk.go
@@ -0,0 +1,14 @@
+package bor
+
+import (
+	"github.com/ethereum/go-ethereum/common"
+)
+
+// EventRecord represents state record
+type EventRecord struct {
+	ID       uint64         `json:"id" yaml:"id"`
+	Contract common.Address `json:"contract" yaml:"contract"`
+	Data     []byte         `json:"data" yaml:"data"`
+	TxHash   common.Hash    `json:"tx_hash" yaml:"tx_hash"`
+	LogIndex uint64         `json:"log_index" yaml:"log_index"`
+}
diff --git a/consensus/bor/snapshot.go b/consensus/bor/snapshot.go
index 19734062b4eda1fc6e9295436c69a54351b95d57..8b91360e92f43de979b32e29fec8cf9e382addb3 100644
--- a/consensus/bor/snapshot.go
+++ b/consensus/bor/snapshot.go
@@ -241,8 +241,6 @@ func (s *Snapshot) apply(headers []*types.Header) (*Snapshot, error) {
 
 		// add recents
 		snap.Recents[number] = signer
-		// TODO remove
-		fmt.Println("Recent signer", "number", number, "signer", signer.Hex())
 	}
 	snap.Number += uint64(len(headers))
 	snap.Hash = headers[len(headers)-1].Hash()
diff --git a/params/config.go b/params/config.go
index 202dc7a1e1f354c2df359b48077038240da584a3..611b2052d61c1193b4c24488ea8d61da858f8248 100644
--- a/params/config.go
+++ b/params/config.go
@@ -316,11 +316,12 @@ func (c *CliqueConfig) String() string {
 
 // BorConfig is the consensus engine configs for Matic bor based sealing.
 type BorConfig struct {
-	Period            uint64 `json:"period"`            // Number of seconds between blocks to enforce
-	ProducerDelay     uint64 `json:"producerDelay"`     // Number of seconds delay between two producer interval
-	Sprint            uint64 `json:"sprint"`            // Epoch length to proposer
-	ValidatorContract string `json:"validatorContract"` // Validator set contract
-	Heimdall          string `json:"heimdall"`          // heimdall light client url
+	Period                uint64 `json:"period"`                // Number of seconds between blocks to enforce
+	ProducerDelay         uint64 `json:"producerDelay"`         // Number of seconds delay between two producer interval
+	Sprint                uint64 `json:"sprint"`                // Epoch length to proposer
+	ValidatorContract     string `json:"validatorContract"`     // Validator set contract
+	StateReceiverContract string `json:"stateReceiverContract"` // State receiver contract
+	Heimdall              string `json:"heimdall"`              // heimdall light client url
 }
 
 // String implements the stringer interface, returning the consensus engine details.