Skip to content

TIP-7702: Add a new tx type that permanently sets the code for an EOA #728

Open
0 of 1 issue completed
@aiden3885

Description

@aiden3885
tip: 7702
title: Set EOA account code
description: Add a new tx type that permanently sets the code for an EOA
authors: ---
status: ---
type: Standards Track
category: Core
created: 2025-02-18

Summary

This tip is aiming to introduce EIP-7702 into Tron to enhance the functionality of EOAs. It elucidates the primary characteristics of EIP-7702 and compares some differences in implementing this feature between Ethereum and Tron.

Abstract

Introduce a novel transaction type that incorporates a series of authorization tuples, each consisting of [chain_id, address, nonce, r, s, v]. For each of these tuples, a delegation designator (0xef0100 + address) is written into the code of the signing account. All subsequent code executions must load and execute the code referenced by this designator.

Motivation

There is a lot of interest in adding short-term functionality improvements to EOAs, increasing the usability of applications and in some cases allowing improved security. Three particular applications include:

  • Batching: allowing multiple operations from the same user in one atomic transaction. One common example is an TRC-20 approval followed by spending that approval, a common workflow in DEXes that requires two transactions today. Advanced use cases of batching occasionally involve dependencies: the output of the first operation is part of the input to the second operation.
  • Sponsorship: account X pays for a transaction on behalf of account Y. Account X could be paid in some other TRC-20 for this service, or it could be an application operator including the transactions of its users for free.
  • Privilege de-escalation: users can sign sub-keys and give them specific permissions that are much weaker than global access to the account. For example, you could imagine a permission to spend TRC-20 tokens but not TRX, or to spend up to 1% of the total balance per day, or to interact only with a specific application.

Specification

Set Code Transaction

A new transaction type "set code transaction" is introduced. The transaction contains a authrization_list, which is a list of tuples that store the address to code which the signer desires to execute in the context of their EOA. The transaction is considered invalid if the length of authorization_list is zero. Each tuple consists of [chain_id, address, nonce, r, s, v].

The transaction is also considered invalid when any field in an authorization
tuple cannot fit within the following bounds:

assert auth.chain_id < 2**256
assert auth.nonce < 2**64
assert auth.v < 2**8
assert auth.r < 2**256
assert auth.s < 2**256

Behavior

For each [chain_id, address, nonce, r, s, v] tuple do the following:

  1. Verify the chain id is either 0 or the chain's current ID.
  2. Verify the nonce is less than 2**64 - 1.
  3. authority = ecrecover(keccak(rlp([chain_id, address, nonce])), r, s, v)
    • s value must be less than or equal to secp256k1n/2, as specified in EIP-2.
  4. Verify the code of authority is either empty or already delegated.
  5. Verify the nonce of authority is equal to nonce. In case authority does not exist in the repository, verify that nonce is equal to 0.
  6. Set the code of authority to be 0xef0100 || address. This is a delegation designation.
    • As a special case, if address is 0x0000000000000000000000000000000000000000 do not write the designation. Clear the account's code and reset the account's code hash to empty.
  7. Increase the nonce of authority by one.

If any of the above steps fail, immediately stop processing that tuple and continue to the next tuple in the list. It will in the case of multiple tuples for the same authority, set the code using the address in the last valid occurrence.

Note that the signer of an authorization tuple may be different than tx.origin of the transaction.

If transaction execution results in failure (any exceptional condition or code reverting), setting delegation designations is not rolled back.

Delegation Designation

This designator requires all code executing operations to follow the address pointer to get the account's executable code, and requires all other code reading operations to act only on the delegation designator (0xef0100 || address). The following reading instructions are impacted: EXTCODESIZE, EXTCODECOPY, EXTCODEHASH, and the following executing instructions are impacted: CALL, CALLCODE, STATICCALL, DELEGATECALL, as well as transactions with destination targeting the code with delegation designation.

For example, EXTCODESIZE would return 23 (the size of 0xef0100 || address), EXTCODEHASH would return keccak256(0xef0100 || address), and CALL would load the code from address and execute it in the context of authority.

CODESIZE and CODECOPY instructions operate on executable code, as before. Note that in a delegated execution CODESIZE and CODECOPY produce different result comparing to EXTCODESIZE and EXTCODECOPY of execution target.

In case a delegation designator points to a precompile address, retrieved code is considered empty and CALL, CALLCODE, STATICCALL, DELEGATECALL instructions targeting this account will execute empty code, i.e. succeed with no execution given enough gas.

In case a delegation designator points to another designator, creating a potential chain or loop of designators, clients must retrieve only the first code and then stop following the designator chain.

The delegation designation can be revoked at any time by signing and sending an TIP-7702 authorization to a new target. Without such action, a delegation will remain valid in perpetuity.

Difference

Transaction

Ethereum introduce a new transaction type according to EIP-2718 standard. Tron hasn't implement this eip. We need to consider how to add the new transaction type that is compatible with Tron. Following is a feasible way:
Introduce a new contract type, SetCodeContract.

enum ContractType {
    ...
    SetCodeContract = 60;
}

And the data structure of SetCodeContract is:

message SetCodeContract {
    message Authority {
        bytes chainId = 1;
        bytes address = 2;
        int64 nonce = 3;
        bytes r = 4;
        bytes s = 5;
        byte v = 6;
    }
    repeated Authority authorityList = 1
}

Nonce

There is a nonce field in Ethereum accounts to prevent repay attacks on transactions. The authorization in EIP-7702 also use nonce for repay protection. Each authorization will increase the signer's nonce by 1. Tron account does not contain nonce, so it is necessary to consider how to prevent authorization replay attacks on Tron.

EIPs

Some eips have not been implemented on Tron, which will have an impact on EIP-7702.

EIP-2

s value must be less than or equal to secp256k1n/2, as specified in EIP-2, which is not implemented on tron.
Allowing transactions with any s value with 0 < s < secp256k1n, as is currently the case, opens a transaction malleability concern, as one can take any transaction, flip the s value from s to secp256k1n - s, flip the v value (27 -> 28, 28 -> 27), and the resulting signature would still be valid.

EIP-3541

The delegation designation uses the banned opcode 0xef from EIP-3541 to designate the code has a special purpose. EIP-3541 disallow new code starting with the 0xef byte to be deployed. Although codes starting with 0xef is rejected for execution on Tron , users can still deploy such codes, which may have an impact on our implementation of 7702. For example, if a user directly deploys a contract with 0xef0100+address, we cannot determine whether the code is deployed according to the 7702 standard, nor can we specify whether it should be executed according to the 7702 scheme or rejected.

Key Features

  1. After setting the account's code, it will be effective permanently until the next code setting or setting the code to empty.
  2. In case a delegation designator points to another designator, creating a potential chain or loop of designators, clients must retrieve only the first code and then stop following the designator chain.
  3. After setting up the delegation designator, the calldata contained in the 7702-transaction will continue to be executed.

Security Considerations

  1. Ensuring the security of proxy contracts. Must be careful when setting up delegate contratct.

  2. Once code exists in the EOA, it's possible for self-sponsored EIP-7702 transactions to have msg.sender == tx.origin anytime the code in the EOA dispatches a call. Without EIP-7702, this situation can only ever arise in the topmost execution layer of a transaction. Therefore, this EIP breaks that invariant and so it affects smart contracts containing require(msg.sender == tx.origin) checks. This check is used for at least three purposes:

    1. Ensuring that msg.sender is an EOA (given that tx.origin always has to be an EOA). This invariant does not depend on the execution layer depth and, therefore, is not affected.
    2. Protecting against atomic sandwich attacks like flash loans, which rely on the ability to modify state before and after the execution of the target contract as part of the same atomic transaction. This protection would be broken by this EIP. However, relying on tx.origin in this way is considered bad practice.
    3. Reentrancy verification.
  3. When a sponsor sends a transaction on behalf of an authority, there may be losses due to malicious users. For example, all assets could be withdrawn, or the nonce could be incremented, causing the transaction to fail. The sponsor then loses the gas fee and does not receive the authority's fee. Attention should be paid to this during design to avoid losses.

  4. Managing storage with caution to ensure that setting new code does not conflict with the original storage.

Sub-issues

Metadata

Metadata

Labels

enhancementNew feature or request

Type

No type

Projects

Status

To Do

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions