UPCX $70M Case Research: When a ProxyAdmin Key Became the Protocol
UPCX is not interesting because the attacker found a clever arithmetic bug. It is interesting because the on-chain system did exactly what the privileged key told it to do. The attacker reportedly gained control over an administrative address, used it to perform a malicious upgrade through ProxyAdmin, then executed withdrawByAdmin to drain 18.4M UPC, about $70M, from management accounts.
This reconstruction uses Halborn's April 2025 explanation, Cyvers/UPCX-linked reporting, and SmartContractsHacking/Incrypthos summaries. Public source for the exact upgraded implementation is limited, so the code below is representative of the upgrade pattern and privileged-drain primitive.
The takeaway: upgrade authority is protocol authority. If one compromised key can change implementation logic, every downstream access-control check can be rewritten after the compromise.
Target architecture: upgradeable control plane
Upgradeable proxies split contract state from contract logic:
Proxy
storage + user-facing address
delegates calls to implementation
ProxyAdmin
privileged controller
can upgrade proxy implementation
Implementation
logic contract
executes in proxy storage context
That design is normal. The risk is centralization: whoever controls ProxyAdmin can replace the contract's behavior.
Representative shape:
contract ProxyAdmin {
address public owner;
function upgrade(address proxy, address implementation) external onlyOwner {
ITransparentUpgradeableProxy(proxy).upgradeTo(implementation);
}
}
If owner is a single hot key, the entire protocol depends on that hot key.
Root cause: compromised upgrade authority
Public reporting frames the incident as a private-key compromise. The attacker gained access to a privileged project address and used the associated authority to upgrade the ProxyAdmin-controlled contract path.
The malicious implementation then exposed or used an admin withdrawal primitive:
contract MaliciousImplementation {
IERC20 public immutable UPC;
function withdrawByAdmin(address from, address to, uint256 amount) external {
// After malicious upgrade, the implementation defines its own rules.
// If this executes in the proxy's context, existing balances/allowances
// and management-account bookkeeping can be drained.
UPC.transferFrom(from, to, amount);
}
}
The exact function shape may differ, but the security lesson does not: once the attacker controls the implementation, the original source-level guarantees are no longer the code being executed.
Attack chain
- Compromise a privileged administrative key. The public post-incident reports do not disclose the off-chain compromise vector, but the attacker had authority over the upgrade path.
- Execute a malicious upgrade. The attacker uses the privileged address to change the ProxyAdmin-controlled implementation.
- Expose a withdrawal primitive. The new logic includes or enables
withdrawByAdmin. - Drain management accounts. The attacker transfers 18.4M UPC from multiple management accounts.
- Leave funds parked. Public dashboards reported the funds remained in an attacker-controlled wallet shortly after the event.
- Protocol response. UPCX paused/froze deposits and withdrawals and moved remaining project-controlled tokens to safer addresses.
Representative execution:
// Step 1: attacker has the ProxyAdmin owner key.
proxyAdmin.upgrade(upcxProxy, maliciousImplementation);
// Step 2: same proxy address now executes malicious logic.
IUpcxBackdoor(upcxProxy).withdrawByAdmin(
managementAccountA,
attacker,
18_400_000e18
);
This is why "audited implementation code" is not enough. The implementation can be replaced.
Why this bypasses normal smart-contract review
An audit can verify that version N of a contract has correct onlyOwner checks. It cannot protect users if:
- the owner key is a single point of failure,
- upgrades have no timelock,
- users cannot monitor or exit before an upgrade takes effect,
- the upgraded implementation is not subject to the same review path,
- emergency controls are held by the same compromised authority.
The control-plane invariant should have been:
No single compromised credential can both change code and drain assets before detection.
UPCX appears to have violated that invariant.
Transaction and address trail
Public references identify:
- Incident date: April 1, 2025
- Loss: 18.4M UPC, roughly $70M
- Technique: compromised administrative key, ProxyAdmin upgrade,
withdrawByAdmin - Attacker destination described by SmartContractsHacking as
0xFf7...334 - Primary public alert:
https://x.com/CyversAlerts/status/1907046941906653633 - UPCX acknowledgement:
https://x.com/Upcxofficial/status/1907024397497749647
I am not treating the abbreviated attacker address as sufficient for precise forensic reproduction. It is included only to match public summaries.
What I would change
- Move ProxyAdmin authority to multisig or MPC. One key should never be enough to upgrade contracts that control treasury-scale assets.
- Timelock upgrades. Users and monitors need time to inspect new implementations before execution.
- Separate upgrade and withdrawal authority. The same role should not be able to both change logic and move funds immediately.
- Monitor implementation changes. Any
Upgraded(address)event on high-value proxies should page humans and bots. - Use emergency pause with separate keys. The emergency brake must not depend on the same compromised admin key.
Confidence notes
- Firm: public reports agree the exploit was driven by compromised privileged authority and a malicious/unauthorized upgrade path.
- Firm: public reports place the loss at about 18.4M UPC, roughly $70M.
- Firm:
withdrawByAdminis named in multiple reports as the drain primitive. - Unclear: the off-chain method used to obtain the administrative key has not been publicly proven.
- Representative: code shows the security shape of ProxyAdmin compromise, not verified UPCX source.
Sources
- Halborn — Explained: The UPCX Hack (April 2025):
https://www.halborn.com/blog/post/explained-the-upcx-hack-april-2025 - SmartContractsHacking — UPCX Hack:
https://smartcontractshacking.com/hacks/upcx-hack-2025 - Incrypthos — UPCX Platform Suffers $70M Private Key Compromise and Contract Upgrade Exploit:
https://incrypthos.com/security/upcx-platform-suffers-70-million-private-key-compromise-and-contract-upgrade-exploit/ - Cyvers alert:
https://x.com/CyversAlerts/status/1907046941906653633 - UPCX acknowledgement:
https://x.com/Upcxofficial/status/1907024397497749647
