tip-7710.md
July 23, 2026 ยท View on GitHub
tip: 7710
title: Smart Contract Permission Delegation
description: Minimal interfaces for granting and redeeming smart-account permissions
author: yanghang8612@gmail.com
discussions-to: https://github.com/tronprotocol/tips/issues/882
status: Draft
type: Standards Track
category: TRC
created: 2026-05-26
requires: 1271
Simple Summary
Let smart accounts grant discoverable, scoped, and revocable application permissions through a standard manager interface.
Abstract
This standard adapts ERC-7710 to define how a smart account (the delegator) grants an address (the delegate) permission to execute actions through a Delegation Manager. It standardizes redemption, the minimum execution-mode subset, and the base data needed for wallets to discover, display, revoke, and track a permission.
The caveat or enforcer system that limits a permission is deliberately implementation-defined. TRC-7710 is compatible with TRC-4337 but does not require it.
Motivation
Session permissions, subscriptions, scoped spending, social recovery, and agent automation currently require wallet-specific contracts and confirmation flows. A common redemption interface lets accounts and applications interoperate while preserving freedom to innovate in caveat design.
On TRON, permission delegation in this document is application-layer authority over a smart contract account. It is unrelated to Stake 2.0 resource delegation of energy or bandwidth. Wallets SHOULD label it "App permissions" or "Session permissions" and avoid an unqualified "delegation" label.
Specification
The key words "MUST", "MUST NOT", "REQUIRED", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" are to be interpreted as described in RFC 2119 and RFC 8174.
Roles
- Delegator: the smart account whose authority is granted.
- Delegate: the address permitted to redeem the grant.
- Target account: the smart account against which execution occurs. In V1 it is the delegator.
- Delegation Manager: the contract that validates permission context, revocation, expiry, and signatures before calling the target account.
- Permission context: implementation-defined evidence and restrictions supplied during redemption.
Redemption Interface
interface ITRC7710DelegationManager {
function redeemDelegations(
bytes[] calldata permissionContexts,
bytes32[] calldata modes,
bytes[] calldata executionCallData
) external;
}
All arrays MUST have the same length. For each index the manager MUST:
- parse and validate the permission context;
- establish the delegator, delegate, target account, manager domain, chain, expiry, nonce, identifier, and lifecycle state;
- require
msg.senderto be the delegate or validate an implementation-defined authorization from the delegate; - require
targetAccount == delegatorand verify that the account authorized this manager; - verify authorization over every base field and reject an expired, revoked, or already-consumed one-time permission;
- validate every applicable implementation-defined caveat; and
- invoke the target account using the corresponding execution mode and calldata.
redeemDelegations MUST be atomic across the whole batch: any parsing, authorization, lifecycle, caveat, or manager-to-account invocation failure MUST revert all redemptions in the call. Execution mode 0x01 affects only subcall failures inside an already validated redemption and MUST NOT suppress a failed permission check.
Minimum Permission Record
Even though permission-context encoding is implementation-defined, every grant MUST resolve to the following semantic fields:
struct PermissionRecord {
address delegator;
address targetAccount;
address delegate;
address verifyingContract;
uint256 chainId;
uint256 expiry;
uint256 nonce;
bytes32 permissionId;
bool revoked;
bool consumed;
}
For V1, targetAccount MUST equal delegator, and permissionId MUST be:
keccak256(abi.encode(
delegator,
targetAccount,
delegate,
verifyingContract,
chainId,
expiry,
nonce
))
The delegator's authorization MUST bind all of these preimage fields and every implementation-defined caveat or restriction in the permission context. nonce MUST uniquely identify the grant among otherwise equal base fields. chainId MUST be the TRC-712 value block.chainid & 0xffffffff, and verifyingContract MUST be the Delegation Manager performing redemption. Addresses are ABI-level 20-byte values with the TRON 0x41 prefix removed. The manager MUST validate the requested mode and execution calldata against the authorized caveats; an unrestricted permission represents broad authority and wallets MUST warn accordingly.
expiry is a Unix timestamp in seconds. Zero means no base expiry; otherwise the permission is expired when block.timestamp >= expiry.
The manager MUST provide an on-chain view that returns these fields or an equivalent individually queryable surface once the grant has been registered or successfully observed during redemption. Base lifecycle status does not prove that dynamic or private caveats currently pass.
Tracking and Revocation
interface ITRC7710PermissionRegistry {
event PermissionGranted(
bytes32 indexed permissionId,
address indexed delegator,
address indexed delegate,
address targetAccount,
address verifyingContract,
uint256 chainId,
uint256 expiry,
uint256 nonce
);
event PermissionRevoked(bytes32 indexed permissionId, address indexed revoker);
function getPermission(bytes32 permissionId)
external view returns (PermissionRecord memory permission, bool known);
function registerPermission(bytes calldata permissionContext)
external returns (bytes32 permissionId);
function revokePermission(
bytes32 permissionId,
bytes calldata revocationContext
) external;
function getPermissionStatus(bytes32 permissionId) external view returns (
bool known,
bool revoked,
bool consumed,
bool expired,
bool baseActive
);
function isPermissionRevoked(bytes32 permissionId) external view returns (bool);
}
Offline authorization remains valid and MUST NOT be rejected solely because a grant is not yet registered. registerPermission is the standard pre-registration path for making an offline grant discoverable before its first redemption; it MUST validate the permission context and authorization, recompute permissionId, persist the base record, and emit PermissionGranted.
On the first redemption of an unregistered grant, the manager MUST persist the same record and emit the same event before invoking the target account. For a one-time permission it MUST also set consumed = true before that invocation. The manager MUST hold a per-permissionId reentrancy lock across every external target invocation, including for reusable permissions. If the redemption or whole batch reverts, these state changes and events revert with it; otherwise they remain effective and prevent callback-based duplicate redemption.
Every grant MUST have a revocation path. Revocation MUST be authorized by the delegator or by an explicitly documented recovery authority chosen by the delegator. revocationContext MUST carry enough authenticated grant information to create a revocation tombstone even before registration or first redemption. A successful revocation MUST be immediately observable through isPermissionRevoked and MUST emit PermissionRevoked. Later registration or redemption of a tombstoned identifier MUST fail.
getPermissionStatus reports only base lifecycle state. baseActive MUST be false for missing, expired, revoked, consumed, wrong-chain, or wrong-manager records, but true does not mean that dynamic caveats or a proposed execution will pass. Wallets MUST simulate the complete redeemDelegations call when presenting current executability. One-time permission schemes MUST set consumed atomically with successful redemption.
Signature Validation and Domain Binding
When a delegator is a contract, the manager SHOULD use TRC-1271 for signature validation. The permission-context signature format remains framework-specific.
If TRC-712 is used, the domain MUST bind chainId = block.chainid & 0xffffffff and verifyingContract = DelegationManager. A signature bound only to the account or network is replayable through another manager and is non-compliant.
EOA signatures, typed-data struct definitions, validator selection, and caveat proofs are outside the minimal interface, but implementations MUST document them.
Execution Modes
TRC-7710 has a soft dependency on TRC-7579. It normatively consumes only this minimum subset:
- the first byte selects a single call (
0x00) or batch call (0x01); - the second byte selects revert-on-failure (
0x00) or non-reverting error handling (0x01); - single execution data is
abi.encodePacked(target, value, callData); and - batch execution data is
abi.encode(Execution[]), where each element is(address target, uint256 value, bytes callData).
For the minimum modes above, the four reserved bytes, four-byte mode selector, and 22-byte mode payload MUST all be zero. A non-zero custom selector or payload is allowed only when the account advertises support and the permission authorization and caveat validation explicitly bind the entire bytes32 mode; otherwise it MUST revert. An account MAY implement only the minimum modes and need not implement the complete TRC-7579 module surface.
This lets TRC-7710 implementations ship without waiting for every modular-account feature while committing to the same wire encoding.
When the target is a TRC-7579 account, the Delegation Manager MUST be installed as a type-2 executor and MUST invoke executeFromExecutor. An adapter for a non-TRC-7579 account is manager-specific and is not interoperable through the TRC-7710 execution bridge.
Caveats and Enforcers
Spend limits, time windows beyond the base expiry, target/selector allowlists, rate limits, and enforcer contracts are out of scope for V1. Implementations MAY use them, and every caveat supplied in a permission context MUST be checked before execution.
The absence of a standardized caveat library MUST NOT be interpreted as permission to omit revocation, expiry, or the base tracking fields. A companion standard may define interoperable caveats after the ecosystem converges.
Wallet Display
Before a user grants or redeems a permission, wallets SHOULD display:
- delegate and target smart account;
- Delegation Manager / verifying contract and network;
- expiry and current revocation state;
- whether the grant is registered, merely imported offline, or already consumed;
- permission identifier;
- single vs. batch execution capability; and
- when available, allowed targets/selectors, spending limits, recurrence, and other caveats.
Wallets SHOULD use "App permissions" or "Session permissions" in user-facing copy.
Rationale
Minimal Interface, Observable Lifecycle
The source interface intentionally leaves permission structures and caveats open. TRON retains that flexibility but standardizes the minimum semantic record and lifecycle because a non-discoverable or non-revocable grant would recreate the risks of forgotten unlimited approvals.
Relationship to Native Permissions
TIP-16/TIP-105 authorize keys and protocol operations directly. TRC-7710 authorizes application actions against a smart account through a manager and can enforce arbitrary caveats. Neither is a transparent substitute for the other.
Relationship to TRC-4337 and EIP-7702
The manager only needs a contract account capable of authenticated execution. It may be reached through TRC-4337, a future EIP-7702-style activation mechanism, or neither. This draft therefore avoids coupling permission semantics to one account-activation roadmap.
Backwards Compatibility
The standard introduces a new manager and account execution convention and does not change native resource delegation, native permissions, or existing smart accounts. Existing accounts can participate when they authorize a compliant manager and expose compatible execution.
Security Considerations
- A permission can be long-lived authority over all assets held by a smart account. Wallets MUST NOT present it as an ordinary login signature.
verifyingContractand the truncated TRC-712chainIdare mandatory replay boundaries.- Manager upgrades can change permission interpretation. Upgradeable managers SHOULD use timelocks, publish their implementation, and make the active implementation visible.
- Revocation status MUST be checked in the same redemption that executes the action; cached status is insufficient.
- Registration is not authorization: the manager MUST validate the grant proof during registration and redemption and MUST honor pre-registration revocation tombstones.
- Caveat enforcers are part of the authorization boundary. Failure, missing data, or insufficient energy SHOULD fail closed.
- Batch and non-reverting modes MUST NOT turn a failed permission check into a successful execution.
- Wallets SHOULD warn prominently about permissions without useful caveats even when the base record is valid.
Copyright
Copyright and related rights waived via CC0.