# Entendendo e implementando a EIP-7702

> Digamos que você esteja tentando executar uma transação atômica complexa, tudo em uma, que exige fazer swap de tokens, adicionar liquidez e fazer staking de recompensas. Só que a sua carteira Ethereum comum, uma EOA, não consegue fazer transações em lote.

Por Shodipo Ayomide, publicado em 27 de set. de 2025. Versão web: https://blog.shodipoayomide.com/pt/understanding-and-implementing-eip-7702

![Entendendo e implementando a EIP-7702](https://blog.shodipoayomide.com/banners/understanding-and-implementing-eip-7702.png)

Digamos que você esteja tentando executar uma transação atômica complexa, tudo em uma, que exige fazer swap de tokens, adicionar liquidez e fazer staking de recompensas. Só que a sua carteira Ethereum comum, uma EOA, não consegue fazer transações em lote. Então você vai precisar assinar três transações separadas, pagar gas três vezes, o que é um grande não, e depois rezar para os bots de MEV não te darem um sandwich entre um passo e outro.

Essa é uma das conversas mais quentes no ecossistema `EVM` ultimamente, como exatamente a gente dá superpoderes para carteiras comuns sem quebrar tudo ao mesmo tempo?

Duas `EIPs` surgiram desse desafio, a `EIP-3074` e, depois, a `EIP-7702`. As duas buscam fechar a distância entre uma `EOA` simples e as `smart contract accounts`, mas elas têm abordagens diferentes para delegar autoridade. Uma oferece um poder persistente, em que as coisas podem dar muito errado e as suas carteiras podem ser drenadas. A outra pode te dar tanto delegação persistente quanto delegação temporária, que pode sumir no momento em que a sua transação é executada on-chain.

Vamos falar sobre por que essa diferença importa e como a proposta do Vitalik pode ter acabado de salvar o Ethereum de um potencial pesadelo de segurança.

## EIP-2718 - Envelope de transação tipada

Antes de entrar no assunto da delegação, existe uma peça importante de infra que torna tudo isso possível, que é a `EIP-2718`. Pense nela como o sistema de contêineres de transporte do Ethereum para transações.

```typescript
// before eip-2718 all transactions looked the same
const legacyTx = rlp([nonce, gasPrice, gasLimit, to, value, data, v, r, s]);

// after eip-2718 transactions can now be typed
const typedTx = TransactionType || TransactionPayload;
```

A `EIP-2718` introduz os `Typed Transaction Envelopes`, em que `TransactionType || TransactionPayload` é uma transação válida. O `TransactionType` identifica o formato da transação, enquanto o `Payload` contém o conteúdo da transação. Agora, esse sistema de wrapper significa que a gente pode introduzir comportamentos de transação totalmente novos sem quebrar a funcionalidade existente.

Ao trazer um tipo de transação envelope, só precisamos garantir a compatibilidade retroativa com as transações existentes e, a partir daí, só precisamos resolver o problema bem mais simples de garantir que não exista conflito de numeração entre `TransactionTypes`. Então, quando a `EIP-7702` precisou introduzir o seu mecanismo de delegação temporária, ela pôde simplesmente definir um novo tipo de transação, por exemplo, `0x04`, sem exigir nenhuma mudança na própria `EVM`.

## EIP-3074 - Abordagem de delegação persistente

A [EIP-3074](https://eips.ethereum.org/EIPS/eip-3074) teve uma abordagem ousada para delegação, dando às `EOAs` a capacidade de delegar autoridade permanentemente para smart contracts usando dois novos `opcodes` da `EVM` - `AUTH` e `AUTHCALL`.

### Como AUTH e AUTHCALL funcionam

O mecanismo é direto

```solidity
// user signs an auth message
bytes32 commit = keccak256(abi.encode(invokerAddress, batchActions));
bytes memory signature = signMessage(userPrivateKey, commit);

// invoker contract calls AUTH opcode
AUTH(commit, signature.v, signature.r, signature.s);
// This sets the 'authorized' context variable to user's address

// now invoker can make calls as the user
AUTHCALL(gasLimit, targetContract, 0, 0, calldata, calldataLength, 0, 0);
```

O `AUTH` recebe quatro parâmetros, o `commit` e os `yParity`, `r` e `s` da assinatura, e se a assinatura for válida e o endereço do signatário for igual à authority, a variável de contexto authorized recebe essa authority. Depois, o `AUTHCALL` permite que o contrato invoker autorizado envie transações, com o `CALLER` definido como o endereço autorizado em vez do invoker.

Agora, imagine um contrato invoker que conseguisse lidar com transações em lote

```solidity
contract BatchInvoker {
    struct BatchCall {
        address target;
        bytes data;
        uint256 value;
    }
    
    function executeBatch(
        BatchCall[] calldata calls,
        bytes32 commit,
        uint8 v, bytes32 r, bytes32 s
    ) external {
        // authorize the user
        AUTH(commit, v, r, s);
        
        // Execute all calls as the user
        for (uint i = 0; i < calls.length; i++) {
            AUTHCALL(
                gasleft(),
                calls[i].target,
                calls[i].value,
                0, // valueExt (must be 0 for now)
                // ... calldata parameters
            );
        }
    }
}
```

Por mais empolgante que isso seja, esses dois `opcodes` levantaram uma série de preocupações de segurança na comunidade `EVM`. A variável de contexto `authorized` persiste ao longo de um único frame de execução do contrato, mas não é repassada em nenhuma chamada, incluindo `DELEGATECALL`. Basicamente, isso significa que a autorização fica ativa durante todo o escopo da transação.

O problema de verdade não é a natureza temporária dentro de uma transação, é o que acontece quando você tem contratos invoker muito usados. Se no fim todo mundo vai usar smart accounts, os `opcodes` `AUTH` e `AUTHCALL` podem virar um enorme fardo técnico e adicionar complexidade à própria `EVM`.

O que acontece quando um contrato invoker popular como o de cima tem um bug? De repente, todo usuário que já autorizou aquele contrato pode estar em risco. Uma atualização maliciosa, um edge case esquecido, um integer overflow e pronto, começa uma drenagem em massa.

O ecossistema `EVM` percebeu que isso criava uma dinâmica estranha. O modelo de segurança da `EIP-3074` depende muito do contrato invoker. Como vários usuários podem depender da mesma lógica de invoker, uma vulnerabilidade ou exploit em um invoker poderia comprometer os ativos ou as permissões de muitos usuários de uma vez só, e é por isso que a `EIP-3074` foi retirada.

## EIP-7702 - A solução de delegação flexível

Agora, a [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702), proposta pelo Vitalik em maio de 2024, chegou à `mainnet` via o `pectra upgrade` em maio de 2025 e introduz uma nova abordagem mais enxuta, permitindo que `EOAs` funcionem temporariamente como smart contracts durante uma única transação, o que é algo enorme!

Em vez de novos `opcodes`, a `EIP-7702` aproveita o sistema de envelope de transação da `EIP-2718's` para introduzir um novo tipo de transação

```typescript
interface EIP7702Transaction {
    chainId: number;
    nonce: number;
    maxPriorityFeePerGas: bigint;
    maxFeePerGas: bigint;
    gasLimit: bigint;
    to: string;
    value: bigint;
    data: Uint8Array;
    accessList: AccessList;
    authorizationList: Authorization[];
}

interface Authorization {
    chainId: number;
    address: string;  // the address of the contract code to delegate to
    nonce: number;
    yParity: 0 | 1;
    r: Uint8Array;
    s: Uint8Array;
}
```

Para cada objeto de autorização, um indicador de delegação `(0xef0100 || address)` é gravado no code da conta que autoriza. Todas as operações que executam code precisam carregar e executar o code para o qual a delegação aponta.

### Como a persistência da delegação funciona de verdade
É aqui que muita gente se confunde. A `EIP-7702` evoluiu desde o seu rascunho original. No começo, a proposta foi pensada para deixar as `EOAs` temporariamente smart por só uma transação. Mas a versão final te dá controle sobre quanto tempo a delegação dura.

```javascript
function processEIP7702Transaction(tx) {
    // verify all auth signatures
    for (const auth of tx.authorizationList) {
        const signer = recoverSigner(auth);
        if (signer !== getAddressFromAuth(auth)) {
            throw new Error("Invalid authorization");
        }
    }
    
    // set delegation pointers (these persist after transaction)
    for (const auth of tx.authorizationList) {
        const eoaAddress = getAddressFromAuth(auth);
        
        // set delegation pointer - 0xef0100 || contract_address
        const delegationPointer = concat(['0xef0100', auth.address]);
        setCode(eoaAddress, delegationPointer);
        
        // nowm this delegation PERSISTS unless explicitly cleared
    }
    
    // execute the transaction normally
    executeTransaction(tx);
    
    // no auto cleanup, delegation stays active
}
```

**NOTA:** Se a execução de uma transação `7702` falhar, os indicadores de delegação já processados não sofrem rollback e persistem, a menos que sejam limpos explicitamente definindo o endereço de delegação como `0x0` em uma transação `7702` subsequente.

Isso significa que você tem três padrões de delegação:

- Delegação persistente: Define a delegação e continua usando ela ao longo de várias transações
- Delegação temporária: Define a delegação para casos de uso específicos, como delegar para um `Batching Contract` por um dia, e a delegação em si é persistente até que ela seja limpa.

### Opções temporárias E persistentes

O lado bom da `EIP-7702` é que ela te dá a opção de escolher. Quer uma delegação temporária para uma transação complexa pontual? Dá para fazer. Quer fazer o upgrade da sua `EOA` de forma persistente para ela agir como uma smart contract wallet? Dá para fazer também.

Para delegação temporária, aqui vai um exemplo

```typescript
// one off delegation
const tempDelegationTx = {
    type: 0x04,
    authorizationList: [{
        address: batchExecutorContract,
        // ... auth details
    }],
    to: userAddress,
    data: encodeBatchCall([
        // execute your complex operation
        swapTokens(),
        addLiquidity(), 
        stakeRewards(),
    ])
};
```
E para Delegação Persistente, aqui vai um exemplo

```typescript
// upgrade EOA to smart wallet
const persistentDelegationTx = {
    type: 0x04,
    authorizationList: [{
        address: smartWalletImplementation,
        // ... auth details  
    }],
    to: userAddress,
    data: encodeCall("initializeSmartFeatures", [])
    // this delegation persists for future txns
};

// later txns can now use smart wallet features
const futureTransaction = {
    to: userAddress, // your EOA will now execute smart wallet code
    data: encodeCall("batchExecute", [multipleOperations])
    // no new auth needed
};
```

### Por que a 7702 é mais segura

A principal diferença entre a `EIP-3074` e a `EIP-7702` não é só temporário vs. persistente, é sobre distribuição de risco e controle. A `EIP-3074` cria um ponto único de falha compartilhado, em que o problema de um contrato popular pode afetar milhares de usuários. A `EIP-7702` isola cada transação, então os bugs só podem afetar aquela transação específica. A `EIP-7702` é totalmente compatível com o `ERC-4337` existente e não exige novos `opcodes`. Basicamente, isso significa que as carteiras podem adotar aos poucos sem quebrar nenhum sistema existente.

O insight crítico é que são as `wallets`, e não os `dApps`, que gerenciam as delegações. Então o consenso geral é permitir que só as carteiras gerenciem delegações, o que significa:

- Os dApps não conseguem controlar a sua delegação diretamente
- Os provedores de carteira implementam uma lógica de delegação revisada e auditada
- O risco é distribuído entre muitas implementações, em vez de concentrado em alguns poucos contratos invoker populares

## O que os devs precisam saber

Se você está construindo uma aplicação que vai suportar a `EIP-7702`, aqui vão algumas coisas técnicas para observar

1. **Mudanças na construção de transações**
A sua lógica de montagem de transações precisa lidar com authorization lists

```typescript
// old: simple EOA transaction
const tx = {
    to: contractAddress,
    data: encodedCall,
    // ... standard fields
};

// new way with eip-7702 delegation
const tx = {
    type: 0x04,
    to: userAddress, // calling user's own address
    data: encodeBatchCall([
        contract.interface.encodeFunctionData("swap", [tokenA, tokenB, amount]),
        contract.interface.encodeFunctionData("addLiquidity", [lpTokens]),
        contract.interface.encodeFunctionData("stake", [lpAmount])
    ]),
    authorizationList: [{
        address: batchExecutorImplementation,
        // ... authorization signature
    }],
    // ... standard fields
};
```

2. **Complexidade na estimativa de gas**
Se a EOA decidir revogar o controle do smart contract, outra transação `7702` precisa ser enviada para definir a delegação de volta para `0x0`. Isso significa que a sua estimativa de gas precisa levar em conta

- Verificação da assinatura de autorização
- Configuração do ponteiro de code
- Execução de fato
- Overhead de limpeza

3. **Suporte a assinaturas de smart contract**
A `EIP-7702` habilita a verificação de assinatura `EIP-1271` para `EOAs`. Isso significa que a sua `EOA` **atualizada** pode assinar mensagens usando métodos alternativos como `passkeys`, mantendo ao mesmo tempo a compatibilidade retroativa.

```solidity
// your EOA can now implement smart signature verification
function isValidSignature(bytes32 hash, bytes signature) external view returns (bytes4) {
    // can verify passkey signatures, multisig, etc.
    if (verifyPasskeySignature(hash, signature)) {
        return 0x1626ba7e; // EIP-1271 magic value
    }
    return 0xffffffff;
}
```

## Links essenciais

- [EIP-2718: Typed Transaction Envelope](https://eips.ethereum.org/EIPS/eip-2718) - O sistema de envelope de transação que serve de base
- [EIP-3074: AUTH and AUTHCALL opcodes](https://eips.ethereum.org/EIPS/eip-3074) - A proposta de delegação persistente
- [EIP-7702: Set EOA account code for one transaction](https://eips.ethereum.org/EIPS/eip-7702) - A proposta de delegação temporária
- [Discussão no Ethereum Magicians](https://ethereum-magicians.org/t/eip-set-eoa-account-code-for-one-transaction/19923) - Debate da comunidade sobre a EIP-7702
- [Roadmap de Account Abstraction do Vitalik](https://ethereum-magicians.org/t/eip-set-eoa-account-code-for-one-transaction/19923)
