diff --git a/api/api_full.go b/api/api_full.go
index 34dcb6f33f5..698bdde37a8 100644
--- a/api/api_full.go
+++ b/api/api_full.go
@@ -989,6 +989,10 @@ type F3ParticipationLease struct {
 	ValidityTerm uint64
 }
 
+func (l *F3ParticipationLease) ToInstance() uint64 {
+	return l.FromInstance + l.ValidityTerm
+}
+
 // EthSubscriber is the reverse interface to the client, called after EthSubscribe
 type EthSubscriber interface {
 	// note: the parameter is ethtypes.EthSubscriptionResponse serialized as json object
diff --git a/chain/lf3/participation_lease.go b/chain/lf3/participation_lease.go
index b1587c5351a..1b9afd3b736 100644
--- a/chain/lf3/participation_lease.go
+++ b/chain/lf3/participation_lease.go
@@ -114,7 +114,7 @@ func (l *leaser) getParticipantsByInstance(instance uint64) []uint64 {
 	defer l.mutex.Unlock()
 	var participants []uint64
 	for id, lease := range l.leases {
-		if instance > lease.FromInstance+lease.ValidityTerm {
+		if instance > lease.ToInstance() {
 			// Lazily delete the expired leases.
 			delete(l.leases, id)
 		} else {
@@ -152,7 +152,7 @@ func (l *leaser) validate(currentNetwork gpbft.NetworkName, currentInstance uint
 	// Combine the errors to remove significance of the order by which they are
 	// checked outside if this function.
 	var err error
-	if currentNetwork != lease.Network || currentInstance > lease.FromInstance+lease.ValidityTerm {
+	if currentNetwork != lease.Network || currentInstance > lease.ToInstance() {
 		err = multierr.Append(err, api.ErrF3ParticipationTicketExpired)
 	}
 	if l.issuer != lease.Issuer {
diff --git a/node/modules/storageminer.go b/node/modules/storageminer.go
index 46c0fa4e979..06395d3d180 100644
--- a/node/modules/storageminer.go
+++ b/node/modules/storageminer.go
@@ -468,7 +468,7 @@ func (p *f3Participator) tryF3Participate(ctx context.Context, ticket api.F3Part
 			log.Infow("Successfully acquired F3 participation lease.",
 				"issuer", lease.Issuer,
 				"not-before", lease.FromInstance,
-				"not-after", lease.FromInstance+lease.ValidityTerm,
+				"not-after", lease.ToInstance(),
 			)
 			p.previousTicket = ticket
 			return lease, true, nil
@@ -505,11 +505,11 @@ func (p *f3Participator) awaitLeaseExpiry(ctx context.Context, lease api.F3Parti
 			}
 			log.Errorw("Failed to check F3 progress while awaiting lease expiry. Retrying after backoff.", "attempts", p.backoff.Attempt(), "backoff", p.backoff.Duration(), "err", err)
 			p.backOff(ctx)
-		case progress.ID+2 >= lease.FromInstance+lease.ValidityTerm:
-			log.Infof("F3 progressed (%d) to within two instances of lease expiry (%d+%d). Renewing participation.", progress.ID, lease.FromInstance, lease.ValidityTerm)
+		case progress.ID+2 >= lease.ToInstance():
+			log.Infof("F3 progressed (%d) to within two instances of lease expiry (%d). Renewing participation.", progress.ID, lease.ToInstance())
 			return nil
 		default:
-			remainingInstanceLease := lease.ValidityTerm - progress.ID
+			remainingInstanceLease := lease.ToInstance() - progress.ID
 			log.Debugf("F3 participation lease is valid for further %d instances. Re-checking after %s.", remainingInstanceLease, p.checkProgressInterval)
 			p.backOffFor(ctx, p.checkProgressInterval)
 		}