﻿---
title: "Colisão de armazenamento do proxy: como upgrades corrompem o estado"
description: "O proxy mantém o estado enquanto o código de implementação muda. Entenda como layouts incompatíveis sobrescrevem saldos, proprietários e controles e como validar um upgrade."
image: "https://wiki.fcontext.com/og.png"
---

> Documentation Index
> Fetch the complete documentation index at: https://wiki.fcontext.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Colisão de armazenamento do proxy: como upgrades corrompem o estado

> Somente para fins educacionais; não constitui aconselhamento de investimento. Investimentos podem causar perdas.

<a id="answer"></a>

## Resposta direta

Uma colisão de armazenamento do proxy ocorre quando o código de implementação lê ou grava um slot do proxy com significado diferente daquele definido pelo layout que criou o estado existente. Um upgrade pode fazer um saldo parecer um endereço, apagar o proprietário, corromper o slot-base de um mapping ou sobrescrever dados de controle do upgrade.

Com `delegatecall`, o bytecode da implementação é executado no contexto do proxy: armazenamento, saldo e `address(this)` pertencem ao proxy. Nomes de variáveis não ficam registrados on-chain; a EVM segue apenas o slot e o deslocamento em bytes calculados pelo novo código.

Por isso, um upgrade precisa preservar o layout implantado, não apenas compilar ou expor as mesmas funções. Antes da autorização, compare os layouts gerados pelo compilador com a versão exata implantada.

<a id="mechanism"></a>

## Como funciona

Normalmente, Solidity posiciona variáveis de estado a partir do slot `0`, na ordem de declaração após a linearização C3 da herança. Valores menores que 32 bytes podem compartilhar um slot; structs e arrays têm regras adicionais, enquanto mappings e arrays dinâmicos derivam seus dados de um slot-base. Se esse slot mudar, a localização dos dados derivados também muda.

Há quatro limites de colisão distintos a auditar:

- **Proxy versus implementação:** campos do proxy, como implementação e administrador, não podem ocupar slots usados pelo estado da aplicação. O ERC-1967 define slots padronizados, evitados pelo compilador, para implementação, beacon e administrador.
- **Implementação antiga versus nova:** variáveis existentes precisam manter slots, deslocamentos e tipos compatíveis. Acrescentar uma variável no fim pode ser seguro; inserir, reordenar, remover ou mudar o tipo pode reinterpretar palavras existentes.
- **Herança:** adicionar estado a um contrato-base ou mudar a ordem de herança pode deslocar o armazenamento dos descendentes mesmo sem alterar o código-fonte deles.
- **Armazenamento reservado ou com namespace:** um gap usado corretamente reserva espaço para um contrato-base, e namespaces no estilo ERC-7201 isolam layouts. Nenhuma técnica permite mudanças arbitrárias dentro de um layout existente.

<a id="example"></a>

## Exemplo

Suponha que a versão 1 tenha este layout:

```solidity
uint256 totalAssets; // slot 0
address owner;       // slot 1
```

A versão 2 insere incorretamente uma variável no início:

```solidity
bool paused;         // slot 0, offset 0
uint256 totalAssets; // slot 1
address owner;       // slot 2
```

Após o upgrade, `paused` lê o byte inferior do antigo `totalAssets`, o novo `totalAssets` lê a palavra do antigo `owner` como inteiro e `owner` lê o que já estava no slot `2`, geralmente zero. As palavras originais continuam armazenadas, mas o novo código lhes atribui outros significados. Uma transação pode ter sucesso enquanto aplica autorização ou contabilidade a interpretações corrompidas.

<a id="risks"></a>

## Riscos e verificações de upgrade

- Gere o layout de armazenamento das duas implementações e compare slot, deslocamento, tipo e herança com o contrato de referência realmente implantado.
- Em um layout linear convencional, adicione variáveis somente no fim. Não reordene campos, mude tipos, remova e reutilize nem altere contratos-base sem provar compatibilidade.
- Ao consumir um gap, reduza-o pelo número exato de slots reservados usados. Com namespaces, mantenha identificadores únicos e valide mudanças dentro de cada namespace existente.
- Não trate o ERC-1967 como proteção completa. Ele separa metadados do proxy dos slots da aplicação atribuídos pelo compilador, mas não torna compatíveis dois layouts de implementação.
- Teste o upgrade e qualquer reinicializador em um fork ou snapshot de estado. Verifique antes e depois proprietários, funções, saldos, allowances, entradas de mappings, pausa, slots de implementação e controles de reversão ou emergência.

Se um upgrade já pode ter causado uma colisão, interrompa novos upgrades e chamadas que alterem estado quando a governança permitir. Preserve o número do bloco anterior e o bytecode, compare o armazenamento bruto dos slots afetados e peça a especialistas um plano de migração com revisão independente. Repetir upgrades sem um mapa de armazenamento comprovado pode destruir mais estado recuperável.

<a id="misconceptions"></a>

## Equívocos comuns

- **“Os nomes não mudaram, então o layout é seguro.”** Nomes não determinam posições. Tipos, ordem, empacotamento, herança e namespaces determinam.
- **“Excluir uma variável libera seu slot.”** O armazenamento do proxy persiste. Reutilizá-lo atribui novo significado à palavra antiga, salvo se uma migração revisada a apagar ou transformar.
- **“Uma transação de teste bem-sucedida prova compatibilidade.”** Ela pode tocar poucos slots. A validação e os testes de diferença de estado devem cobrir campos privilegiados, valores empacotados, mappings, arrays e armazenamento herdado.

<a id="related"></a>

## Tópicos relacionados

- [Risco de armazenamento do delegatecall](/pt-br/crypto/delegatecall-storage-risk/)
- [Tomada do inicializador](/pt-br/crypto/initializer-takeover/)
- [Contrato proxy](/pt-br/crypto/proxy-contract/)
- [Monitoramento de upgrades do proxy](/pt-br/crypto/proxy-upgrade-monitoring/)
- [Contrato atualizável](/pt-br/crypto/upgradeable-contract/)

<a id="sources"></a>

## Fontes

- [Introducción a los contratos inteligentes](https://docs.soliditylang.org/en/latest/introduction-to-smart-contracts.html) - Solidity Documentation (acesso: 2026-08-21)
- [Layout de variables de estado en almacenamiento](https://docs.soliditylang.org/en/latest/internals/layout_in_storage.html) - Solidity Documentation (acesso: 2026-08-21)
- [ERC-1967: slots de almacenamiento de proxy](https://eips.ethereum.org/EIPS/eip-1967) - Ethereum Improvement Proposals (acesso: 2026-08-21)
- [Cómo escribir contratos actualizables](https://docs.openzeppelin.com/upgrades-plugins/writing-upgradeable) - OpenZeppelin Documentation (acesso: 2026-08-21)

Source: https://wiki.fcontext.com/pt-br/crypto/proxy-storage-collision/index.mdx
