diff --git a/cmd/lotus-shed/main.go b/cmd/lotus-shed/main.go
index 749ff2945..8b58dae38 100644
--- a/cmd/lotus-shed/main.go
+++ b/cmd/lotus-shed/main.go
@@ -21,6 +21,7 @@ func main() {
 		peerkeyCmd,
 		noncefix,
 		bigIntParseCmd,
+		staterootStatsCmd,
 	}
 
 	app := &cli.App{
@@ -28,6 +29,14 @@ func main() {
 		Usage:    "A place for all the lotus tools",
 		Version:  build.BuildVersion,
 		Commands: local,
+		Flags: []cli.Flag{
+			&cli.StringFlag{
+				Name:    "repo",
+				EnvVars: []string{"LOTUS_PATH"},
+				Hidden:  true,
+				Value:   "~/.lotus", // TODO: Consider XDG_DATA_HOME
+			},
+		},
 	}
 
 	if err := app.Run(os.Args); err != nil {
diff --git a/cmd/lotus-shed/stateroot-stats.go b/cmd/lotus-shed/stateroot-stats.go
new file mode 100644
index 000000000..89bd0bb47
--- /dev/null
+++ b/cmd/lotus-shed/stateroot-stats.go
@@ -0,0 +1,94 @@
+package main
+
+import (
+	"fmt"
+
+	"gopkg.in/urfave/cli.v2"
+
+	"github.com/ipfs/go-cid"
+
+	"github.com/filecoin-project/lotus/chain/types"
+	lcli "github.com/filecoin-project/lotus/cli"
+)
+
+var staterootStatsCmd = &cli.Command{
+	Name:        "stateroot-stats",
+	Description: "Walk down the chain and collect stats-obj changes between tipsets",
+	Flags: []cli.Flag{
+		&cli.StringFlag{
+			Name:  "tipset",
+			Usage: "specify tipset to start from",
+		},
+		&cli.IntFlag{
+			Name:  "count",
+			Usage: "number of tipsets to count back",
+			Value: 30,
+		},
+		&cli.BoolFlag{
+			Name:  "diff",
+			Usage: "compare tipset with previous",
+			Value: false,
+		},
+	},
+	Action: func(cctx *cli.Context) error {
+		api, closer, err := lcli.GetFullNodeAPI(cctx)
+		if err != nil {
+			return err
+		}
+
+		defer closer()
+		ctx := lcli.ReqContext(cctx)
+
+		ts, err := lcli.LoadTipSet(ctx, cctx, api)
+		if err != nil {
+			return err
+		}
+
+		if ts == nil {
+			ts, err = api.ChainHead(ctx)
+			if err != nil {
+				return err
+			}
+		}
+
+		fn := func(ts *types.TipSet) (cid.Cid, []cid.Cid) {
+			blk := ts.Blocks()[0]
+			strt := blk.ParentStateRoot
+			cids := blk.Parents
+
+			return strt, cids
+		}
+
+		count := cctx.Int("count")
+		diff := cctx.Bool("diff")
+
+		fmt.Printf("Height\tSize\tLinks\tObj\tBase\n")
+		for i := 0; i < count; i++ {
+			if ts.Height() == 0 {
+				return nil
+			}
+			strt, cids := fn(ts)
+
+			k := types.NewTipSetKey(cids...)
+			ts, err = api.ChainGetTipSet(ctx, k)
+			if err != nil {
+				return err
+			}
+
+			pstrt, _ := fn(ts)
+
+			if !diff {
+				pstrt = cid.Undef
+			}
+
+			stats, err := api.ChainStatObj(ctx, strt, pstrt)
+			if err != nil {
+				return err
+			}
+
+			fmt.Printf("%d\t%d\t%d\t%s\t%s\n", ts.Height(), stats.Size, stats.Links, strt, pstrt)
+		}
+
+		return nil
+	},
+}