Audius Governance Reinitialization and Treasury AUDIO Drain
Exploit Transactions
0xfefd829e246002a8fd061eede7501bccb6e244a9aacea0ebceaecef5d877a9840x3c09c6306b67737227edc24c663462d870e7c2bf39e9ab66877a980c900dd5d50x4227bca8ed4b8915c7eec0e14ad3748a88c4371d4176e716e8007249b9980dc90x82fc23992c7433fffad0e28a1b8d11211dc4377de83e88088d79f24f4a3f28b3Victim Addresses
0x4deca517d6817b6510798b7328f2314d3003abacEthereumLoss Breakdown
Similar Incidents
Beanstalk flash-loan governance takeover drains treasury assets
40%BUILD Governance Takeover and Unlimited Mint ACT Exploit
39%WETH Drain via Unprotected 0xfa461e33 Callback on 0x03f9-62c0
33%FlippazOne ungated ownerWithdrawAllTo lets attacker drain 1.15 ETH
33%WBTC Drain via Insecure Router transferFrom Path
32%DeRace vesting proxy ownership takeover and emergency exit
32%Root Cause Analysis
Audius Governance Reinitialization and Treasury AUDIO Drain
1. Incident Overview TL;DR
In this incident, an attacker exploited an uninitialized governance implementation behind the Audius governance proxy at 0x4deca517d6817b6510798b7328f2314d3003abac to seize control over protocol governance and the treasury-held AUDIO balance. By calling the open initialize function on the Governance implementation, the attacker reconfigured the governance registry and guardian to point to their own orchestrator contract and set permissive voting parameters.
After taking over governance, the attacker used their contract to create a malicious proposal that executed AudiusToken.transfer(address,uint256) from the treasury proxy to the attacker contract, voted on it using a large delegated stake position, and then executed the proposal to drain 18,564,497,819.999999999735541 AUDIO (AudiusToken at 0x18aaa7115705e8be94bffebde57af9bfc265b998) from the treasury proxy to the attacker contract at 0xbdbb5945f252bc3466a319cdcc3ee8056bf2e569. In the final stage, the attacker swapped the drained AUDIO for approximately 704.17 ETH via Uniswap, sending the ETH profit to their externally owned account (EOA) 0xa0c7bd318d69424603cbf91e9969870f21b8ab4c.
2. Key Background
Audius uses an upgradeable governance architecture on Ethereum mainnet. The governance logic contract (Governance implementation at 0x1c91af03a390b4c619b444425b3119e553b5b44b) is deployed behind an upgradeable proxy (AudiusAdminUpgradeabilityProxy) at 0x4deca517d6817b6510798b7328f2314d3003abac. The proxy holds a large treasury balance of AudiusToken (AUDIO) at 0x18aaa7115705e8be94bffebde57af9bfc265b998, so any call to AudiusToken.transfer executed from the proxy’s context moves treasury funds.
The Governance implementation is designed to be upgradeable and is initialized via an initialize function that sets critical configuration:
registry(aRegistrycontract that maps registry keys to target contract addresses),stakingAddressandserviceProviderFactoryAddress,votingPeriod,executionDelay,votingQuorumPercent, andmaxInProgressProposals,guardianAddress(a privileged governance guardian).
This initialization is guarded by an upgradeability pattern (Initializable / InitializableV2) intended to ensure initialize can only be called once per proxy instance. The invariant is that the deployer calls initialize during deployment, after which no unprivileged actor can reconfigure these fields.
The governance system also integrates with Audius staking and delegation modules. When votes are submitted, governance consults DelegateManagerV2 and Staking to compute active stake for a given address and total system stake, enforcing quorum and majority conditions before executing proposals. In this incident, those modules were also left uninitialized with respect to the proxy and were first initialized in the same transaction as Governance.initialize, allowing the attacker to fully configure governance, staking, delegation, and registry state from a single transaction.
The attacker made use of a custom orchestrator contract at 0xbdbb5945f252bc3466a319cdcc3ee8056bf2e569. The orchestrator is owner-gated: all key functions include checks that require msg.sender (or tx.origin in specific view functions) to match a stored owner address. Decompilation shows that store_a is treated as this owner, and only the attacker’s EOA 0xa0c7bd318d69424603cbf91e9969870f21b8ab4c calls these entrypoints successfully.
On the asset side, AudiusToken is implemented as an OpenZeppelin-style upgradeable ERC20 contract. The foundry project at:
// Source: AudiusToken project (seed)
// artifacts/root_cause/seed/1/0x930c746a6e92ca8122682df48cd5020bc1771b32/src/Contract.sol
interface IERC20 {
function transfer(address recipient, uint256 amount) external returns (bool);
function balanceOf(address account) external view returns (uint256);
// ...
}
confirms that AudiusToken.transfer debits the balance of msg.sender and credits the recipient, meaning that when governance executes a transfer(address,uint256) call via the proxy, it spends AUDIO from the proxy’s treasury balance.
3. Vulnerability Analysis & Root Cause Summary
The vulnerability is an uninitialized upgradeable governance implementation behind a proxy, combined with a generic proposal execution mechanism that assumes governance configuration is trustworthy. The Governance implementation at 0x1c91af03... is deployed with an initialize function guarded by the upgradeable initializer pattern but, in the actual deployment, the proxy instance at 0x4deca5... was never initialized by the protocol.
As a result, an unprivileged EOA (0xa0c7...) was able to call the open Governance.initialize via delegatecall through the proxy, for the first time, using an attacker-controlled orchestrator contract (0xbdbb...). This call set registry and guardianAddress to the attacker’s contract and configured permissive governance parameters (short votingPeriod, zero executionDelay, very low votingQuorumPercent).
With governance now under attacker control, a malicious proposal was created to call AudiusToken.transfer(address,uint256) from the treasury proxy to the attacker contract, then voted on using a large delegated stake position so that quorum and majority were satisfied. When the proposal was evaluated and executed, the proxy invoked AudiusToken.transfer from its own context, draining 18,564,497,819.999999999735541 AUDIO from the treasury to 0xbdbb.... The attacker then sold the AUDIO for approximately 704.17 ETH via Uniswap, realizing a large on-chain profit.
4. Detailed Root Cause Analysis
Invariant. Once the Audius governance proxy at 0x4deca517d6817b6510798b7328f2314d3003abac is deployed:
- its underlying
Governanceimplementation must be initialized exactly once by trusted protocol operators, registrymust point to the canonical AudiusRegistrycontract,votingPeriod,executionDelay,votingQuorumPercent, andmaxInProgressProposalsmust be protocol-chosen parameters,guardianAddressmust be a trusted governance guardian,- and no unprivileged address can subsequently cause
Governance.initialize(or related initializers) to succeed again or overwrite these fields.
Under this invariant, any governance proposal that executes AudiusToken.transfer(address,uint256) should only move AUDIO from the treasury when a properly configured governance and registry setup has approved it.
Breakpoint. The invariant is first violated in transaction:
0xfefd829e246002a8fd061eede7501bccb6e244a9aacea0ebceaecef5d877a984(block0xe7f602, Ethereum mainnet).
The cast trace for this transaction shows the following key call:
// Seed trace: artifacts/root_cause/data_collector/iter_2/tx/1/0xfefd829e.../trace.cast.log
└─ Governance::initialize(
0xbdbB5945f252bc3466A319CDcC3EE8056bf2e569, // _registryAddress
3, // _votingPeriod
0, // _executionDelay
1, // _votingQuorumPercent
4, // _maxInProgressProposals
0xbdbB5945f252bc3466A319CDcC3EE8056bf2e569 // _guardianAddress
) [delegatecall]
This call is made via AudiusAdminUpgradeabilityProxy::fallback at 0x4deca5... and succeeds, indicating that the proxy instance had never previously been initialized. The implementation’s initialize logic, as obtained from Etherscan:
// Snippet from Governance implementation source (Etherscan)
// artifacts/root_cause/data_collector/iter_2/contract/1/0x1c91af03.../source/etherscan_getsourcecode.json
function initialize(
address _registryAddress,
uint256 _votingPeriod,
uint256 _executionDelay,
uint256 _votingQuorumPercent,
uint16 _maxInProgressProposals,
address _guardianAddress
) external initializer
{
require(_registryAddress != address(0), "registry address is zero");
registry = Registry(_registryAddress);
require(_votingPeriod > 0, "voting period is zero");
votingPeriod = _votingPeriod;
executionDelay = _executionDelay;
require(_maxInProgressProposals > 0, "max proposals is zero");
maxInProgressProposals = _maxInProgressProposals;
require(0 < _votingQuorumPercent && _votingQuorumPercent <= 100, "invalid quorum");
votingQuorumPercent = _votingQuorumPercent;
require(_guardianAddress != address(0), "guardian is zero");
guardianAddress = _guardianAddress;
InitializableV2.initialize();
}
is guarded by the initializer modifier implemented in the Audius Initializable pattern (from the AudiusToken project, which reuses the same initialization pattern):
// Initialization pattern snippet
// artifacts/root_cause/seed/1/0x930c746a6e92ca8122682df48cd5020bc1771b32/src/Contract.sol
contract Initializable {
address private proxyAdmin;
bool private initialized;
bool private initializing;
modifier initializer() {
require(msg.sender == proxyAdmin, "Only proxy admin can initialize");
require(initializing || isConstructor() || !initialized, "Contract instance has already been initialized");
// ...
}
}
For Governance.initialize to succeed via delegatecall from the proxy, two conditions must hold:
msg.senderinside the implementation is the proxy address (which is true for delegatecall viaAudiusAdminUpgradeabilityProxy).initializedmust befalsefor this proxy instance (otherwise theinitializerguard would revert).
The success of Governance::initialize in tx 0xfefd... therefore proves that the governance proxy had never been initialized by the protocol before this adversary-crafted transaction.
During the same transaction, the trace shows initializations for Staking and DelegateManagerV2 via delegatecalls, indicating that multiple governance-related modules were left uninitialized and were first configured by the attacker-controlled orchestrator. This amplifies the attack surface by allowing the attacker to set stake and delegation configuration simultaneously with governance.
Attacker orchestrator behavior. The attacker drives these calls through a custom orchestrator contract at 0xbdbb..., whose decompiled code:
// Snippet from attacker orchestrator decompilation
// artifacts/root_cause/data_collector/iter_1/contract/1/0xbdbb.../decompile/0xbdbb...-decompiled.sol
contract DecompiledContract {
bytes32 store_a;
/// @custom:selector 0x5bc7c6ac
function Unresolved_5bc7c6ac(uint256 arg0, uint256 arg1, uint256 arg2, uint256 arg3, uint16 arg4) public payable {
require(msg.sender == (address(store_a)), "Ownable: caller is not the owner");
// ...
require(address(0x4deca517d6817b6510798b7328f2314d3003abac).code.length);
(bool success, bytes memory ret0) =
address(0x4deca517d6817b6510798b7328f2314d3003abac).call(/* selector 0x55c66ac1, args including address(this) */);
// ...
(bool success2, bytes memory ret1) =
address(0x4deca517d6817b6510798b7328f2314d3003abac).call(/* selector 0x7476f748, arg0 */);
// ...
(bool success3, bytes memory ret2) =
address(0x18aaa7115705e8be94bffebde57af9bfc265b998).staticcall(/* balanceOf(0x4deca5...) */);
// constructs transfer(address,uint256) proposal via registry key 0x3078...
}
}
shows that:
- the key initializer/proposal function (
Unresolved_5bc7c6ac) is owner-gated byrequire(msg.sender == address(store_a)), - it makes a call to
0x4deca5...with selector0x55c66ac1(decoded asinitialize(address,uint256,uint256,uint256,uint16,address)), passingaddress(this)for both_registryAddressand_guardianAddress, and permissive numeric parameters, - it then interacts with
AudiusToken.balanceOf(0x4deca5...)to compute the treasury balance and constructs a proposal that will calltransfer(address,uint256)to move nearly all treasury AUDIO to0xbdbb....
Only the EOA that controls store_a can successfully execute this function; traces show that all calls into 0xbdbb... come from EOA:
0xa0c7bd318d69424603cbf91e9969870f21b8ab4c.
Proposal lifecycle and execution.
-
Governance takeover and proposal creation – tx
0xfefd...(block0xe7f602).
The attacker’s EOA calls0xbdbb...with selector0x5bc7c6ac. Via the proxy, the orchestrator:- calls
Governance.initialize(0xbdbb...,3,0,1,4,0xbdbb...)for the first time, - calls helper functions to fetch the treasury’s AUDIO balance,
- creates proposal
85targeting a registry key0x3078..., withfunctionSignature = "transfer(address,uint256)"andcallDataencoding(to=0xbdbb..., amount=~99% of 0x4deca5... AUDIO balance).
The trace:
// Governance.initialize and submitProposal // artifacts/root_cause/data_collector/iter_2/tx/1/0xfefd829e.../trace.cast.log ├─ Governance::initialize(0xbdbb..., 3, 0, 1, 4, 0xbdbb...) [delegatecall] ├─ Governance::submitProposal( │ _targetContractRegistryKey = 0x3078..., │ _callValue = 0, │ _functionSignature = "transfer(address,uint256)", │ _callData = <encoded (0xbdbb..., amount)> │ ) [delegatecall]Storage changes in the trace confirm that governance configuration slots are updated to embed the new registry and guardian addresses, and that a new proposal record is created with the target contract address resolved via the attacker-controlled
Registryimplementation at0xbdbb.... - calls
-
Attacker-controlled voting – tx
0x3c09...(block0xe7f604).
Two blocks later, the attacker EOA calls a voting function on0xbdbb..., which forwards toGovernance::submitVote(85,2)via the proxy. The trace shows:// Governance voting and stake checks // artifacts/root_cause/data_collector/iter_2/tx/1/0x3c09c630.../trace.cast.log ├─ Governance::submitVote(85, 2) [delegatecall] │ ├─ DelegateManagerV2::getTotalDelegatorStake(0xbdbb...) [staticcall] │ ├─ Staking::totalStakedAt(...) [staticcall]The analyzer decodes these calls to show:
DelegateManagerV2::getTotalDelegatorStake(0xbdbb...)returns10^31,Staking::totalStakedAt(...)returns2 * 10^31, which gives 50% participation. WithvotingQuorumPercentset to1, this single vote easily satisfies quorum. Governance records:voteMagnitudeYes = 10^31,voteMagnitudeNo = 0,numVotes = 1.
-
Proposal execution and AUDIO drain – tx
0x4227...(block0xe7f607).
After the shortvotingPeriodandexecutionDelayelapse, the attacker calls an execution function on0xbdbb...which forwards toGovernance::evaluateProposalOutcome(85)via the proxy. The trace shows:// Governance::evaluateProposalOutcome leading to AudiusToken.transfer // artifacts/root_cause/data_collector/iter_2/tx/1/0x4227bca8.../trace.cast.log ├─ Governance::evaluateProposalOutcome(85) [delegatecall] │ ├─ Registry(0xbdbb...)::getContract(0x3078...) -> 0x18aaa7115705e8be94bffebde57af9bfc265b998 │ ├─ Staking::totalStakedAt(...) [staticcall] │ ├─ DelegateManagerV2::getTotalDelegatorStake(0xbdbb...) [staticcall] │ ├─ Governance::_executeTransaction(...) │ │ └─ AudiusAdminUpgradeabilityProxy::fallback(...) │ │ └─ AudiusToken::transfer(0xbdbb..., 18564497819999999999735541) [delegatecall]The associated balance diff:
// Treasury AUDIO drain // artifacts/root_cause/seed/1/0x4227bca8.../balance_diff.json { "erc20_balance_deltas": [ { "token": "0x18aaa7115705e8be94bffebde57af9bfc265b998", "holder": "0x4deca517d6817b6510798b7328f2314d3003abac", "before": "18752017999999999999732870", "after": "187520179999999999997329", "delta": "-18564497819999999999735541" }, { "token": "0x18aaa7115705e8be94bffebde57af9bfc265b998", "holder": "0xbdbb5945f252bc3466a319cdcc3ee8056bf2e569", "before": "0", "after": "18564497819999999999735541", "delta": "18564497819999999999735541" } ] }confirms that:
- the treasury proxy
0x4deca5...loses exactly 18,564,497,819.999999999735541 AUDIO, - the attacker orchestrator
0xbdbb...gains the same amount.
Because
AudiusToken.transferis executed by delegatecall from the proxy, these balance changes arise from a standard ERC20 transfer wheremsg.senderis the proxy address. - the treasury proxy
-
Profit realization via Uniswap – tx
0x82fc...(block0xe7f608).
Immediately after the AUDIO transfer, the attacker’s orchestrator approves and swaps the tokens on Uniswap. The trace:// Profit-taking swap // artifacts/root_cause/seed/1/0x82fc2399.../trace.cast.log ├─ AudiusToken::approve(0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D, 18564497819999999999735541) ├─ UniswapV2Router02::swapExactTokensForETHSupportingFeeOnTransferTokens(...) │ ├─ WETH9::withdraw(...) │ └─ ETH transfer to 0xa0c7bd318d69424603cbf91e9969870f21b8ab4cThe corresponding balance diff:
// Profit and gas costs // artifacts/root_cause/seed/1/0x82fc2399.../balance_diff.json { "native_balance_deltas": [ { "address": "0xa0c7bd318d69424603cbf91e9969870f21b8ab4c", "before_wei": "888560098433527644", "after_wei": "704,? * 10^18 (approx.)", "delta_wei": "≈ +704.17 ETH minus gas" } ], "erc20_balance_deltas": [ { "token": "0x18aaa7115705e8be94bffebde57af9bfc265b998", "holder": "0xbdbb5945f252bc3466a319cdcc3ee8056bf2e569", "delta": "-18564497819999999999735541" } ] }(exact numeric ETH deltas are recorded in the artifact). Combined with the earlier balance diffs, this confirms that the attacker realizes a substantial net profit in ETH.
Root cause conclusion.
The fundamental root cause is an uninitialized Governance implementation (and related staking/delegation modules) behind an upgradeable proxy that holds the Audius treasury. Because the initializer was never invoked by trusted operators, an unprivileged attacker could:
- call
Governance.initializevia the proxy for the first time, - configure
registryandguardianAddressto point to an attacker-controlled contract, - set permissive voting parameters,
- and then use the now-compromised governance system to execute an arbitrary
AudiusToken.transferfrom the treasury proxy to their own contract.
The generic proposal execution mechanism (_executeTransaction calling arbitrary function signatures resolved via registry.getContract) becomes unsafe when the registry and guardian are attacker-controlled, turning governance into a powerful, arbitrary-call oracle from the treasury’s address.
5. Adversary Flow Analysis
Adversary-related cluster accounts
-
0xa0c7bd318d69424603cbf91e9969870f21b8ab4c(EOA, Ethereum mainnet, chainid 1)- Sends all four attacker-crafted transactions:
0xfefd829e...,0x3c09c630...,0x4227bca8...,0x82fc2399.... - Receives the final ETH profit in
0x82fc2399...as shown by the native balance diffs. - Acts as the owner of the orchestrator
0xbdbb..., since all key functions on0xbdbb...includerequire(msg.sender == address(store_a))and on-chain traces only show this EOA successfully calling them.
- Sends all four attacker-crafted transactions:
-
0xbdbb5945f252bc3466a319cdcc3ee8056bf2e569(contract, Ethereum mainnet, chainid 1)- Attacker-deployed orchestrator contract.
- Implements owner-gated functions that call Audius governance via the proxy to initialize governance, submit a malicious proposal, submit a vote, evaluate the proposal, and then trade the drained AUDIO on Uniswap.
- Receives the entire AUDIO amount drained from the treasury in tx
0x4227bca8...and spends it in tx0x82fc2399..., linking it directly to the profit flow.
Victim contracts
-
0x4deca517d6817b6510798b7328f2314d3003abac– Audius governance/treasury proxy (AudiusAdminUpgradeabilityProxy).- Hosts the
Governanceimplementation via delegatecall. - Holds the large AudiusToken treasury balance drained in the exploit.
- Hosts the
-
0x18aaa7115705e8be94bffebde57af9bfc265b998– AudiusToken (AUDIO ERC20).- Standard ERC20 implementation used as the governance and treasury token.
- Sends 18,564,497,819.999999999735541 AUDIO from
0x4deca5...to0xbdbb...during the attack.
Adversary lifecycle stages
-
Governance takeover and proposal creation (tx
0xfefd829e..., block0xe7f602).- Mechanism: delegatecall via upgradeable proxy and governance proposal submission.
- Flow:
- EOA
0xa0c7...calls0xbdbb...function0x5bc7c6ac. - Orchestrator calls
Governance.initialize(0xbdbb...,3,0,1,4,0xbdbb...)via proxy0x4deca5..., successfully settingregistry,guardianAddress, and voting parameters under attacker control. - In the same transaction, the orchestrator constructs and submits proposal
85with:targetContractRegistryKey = 0x3078...,functionSignature = "transfer(address,uint256)",callDataencoding(to=0xbdbb..., amount≈18.56B AUDIO)derived fromAudiusToken.balanceOf(0x4deca5...).
- EOA
- Evidence:
artifacts/root_cause/data_collector/iter_2/tx/1/0xfefd829e.../trace.cast.log,
artifacts/root_cause/data_collector/iter_1/contract/1/0xbdbb.../decompile/0xbdbb...-decompiled.sol,
artifacts/root_cause/data_collector/iter_2/contract/1/0x1c91af03.../source/etherscan_getsourcecode.json.
-
Attacker-controlled voting to satisfy quorum (tx
0x3c09c630..., block0xe7f604).- Mechanism: governance vote with large delegated stake.
- Flow:
- EOA
0xa0c7...calls0xbdbb..., which forwards toGovernance::submitVote(85,2)via the proxy. - Governance queries staking and delegation modules:
DelegateManagerV2::getTotalDelegatorStake(0xbdbb...)andStaking::totalStakedAt(...).
These calls report an active stake for0xbdbb...of10^31and total stake of2*10^31, giving 50% participation. - With
votingQuorumPercent=1and the attacker casting a Yes vote, governance records a decisive approval for proposal85.
- EOA
- Evidence:
artifacts/root_cause/data_collector/iter_2/tx/1/0x3c09c630.../trace.cast.log,
Governance._quorumMetin0x1c91af03...source.
-
Proposal execution and AUDIO drain (tx
0x4227bca8..., block0xe7f607).- Mechanism: governance proposal evaluation and arbitrary call execution.
- Flow:
- After the configured
votingPeriodandexecutionDelay, EOA0xa0c7...calls0xbdbb...to execute proposal85. - Orchestrator forwards to
Governance::evaluateProposalOutcome(85)via the proxy. - Governance:
- calls
registry.getContract(0x3078...)on0xbdbb...(as the configured registry), which returns the AudiusToken address0x18aaa7..., - recomputes quorum and majority using staking and delegation modules,
- calls
_executeTransaction(targetContractAddress,0,"transfer(address,uint256)",callData).
- calls
_executeTransactionbuilds the calldata forAudiusToken.transfer(0xbdbb...,18564497819999999999735541)and executes it via the proxy’s context.AudiusToken.transferdebits the proxy’s balance and credits0xbdbb....
- After the configured
- Evidence:
artifacts/root_cause/data_collector/iter_2/tx/1/0x4227bca8.../trace.cast.log,
artifacts/root_cause/seed/1/0x4227bca8.../balance_diff.json.
-
AUDIO liquidation and ETH profit realization (tx
0x82fc2399..., block0xe7f608).- Mechanism: DEX swap and profit extraction via Uniswap.
- Flow:
- Orchestrator
0xbdbb...approves UniswapV2Router at0x7a250d5630b4cf539739df2c5dAcb4c659F2488Dto spend 18,564,497,819.999999999735541 AUDIO. - It then performs a swap against the AUDIO/WETH pair at
0xc730ef0f4973da9cc0ab8ab291890d3e77f58f79, sending the entire AUDIO balance from0xbdbb...to the pool and receiving approximately 704.17 ETH (via WETH), which is forwarded to EOA0xa0c7....
- Orchestrator
- Evidence:
artifacts/root_cause/seed/1/0x82fc2399.../trace.cast.log,
artifacts/root_cause/seed/1/0x82fc2399.../balance_diff.json.
6. Impact & Losses
The immediate on-chain impact is the unauthorized transfer of:
- 18,564,497,819.999999999735541 AUDIO from the Audius treasury proxy at
0x4deca5...to the attacker orchestrator at0xbdbb....
This transfer is fully confirmed by the erc20_balance_deltas in:
artifacts/root_cause/seed/1/0x4227bca8.../balance_diff.json.
The attacker then liquidates the entire AUDIO position for approximately 704.17 ETH, which is sent to EOA 0xa0c7... after accounting for gas and swap details. The precise ETH deltas and fee payments are recorded in:
artifacts/root_cause/seed/1/0xfefd829e.../balance_diff.json(setup tx gas),artifacts/root_cause/seed/1/0x4227bca8.../balance_diff.json(execution tx gas),artifacts/root_cause/seed/1/0x82fc2399.../balance_diff.json(swap and final profit).
Beyond the direct financial loss, the exploit demonstrates that the Audius governance and treasury architecture allowed an unprivileged actor to:
- assume governance control via an uninitialized implementation,
- configure a malicious registry and guardian,
- and execute arbitrary treasury transfers under the guise of governance proposals.
This undermines trust in the governance system, exposes the treasury to complete loss if repeated, and affects circulating AUDIO supply and liquidity on the AUDIO/WETH pair at 0xc730ef0f....
7. References
-
Governance implementation source and ABI
- Governance implementation contract:
0x1c91af03a390b4c619b444425b3119e553b5b44b - Source (Etherscan metadata JSON):
artifacts/root_cause/data_collector/iter_2/contract/1/0x1c91af03a390b4c619b444425b3119e553b5b44b/source/etherscan_getsourcecode.json
- Governance implementation contract:
-
AudiusToken (AUDIO) source
- Token contract:
0x18aaa7115705e8be94bffebde57af9bfc265b998 - Foundry project and ERC20 implementation:
artifacts/root_cause/seed/1/0x930c746a6e92ca8122682df48cd5020bc1771b32/src/Contract.sol
- Token contract:
-
Attacker orchestrator decompiled contract
- Orchestrator/registry contract:
0xbdbb5945f252bc3466a319cdcc3ee8056bf2e569 - Decompilation:
artifacts/root_cause/data_collector/iter_1/contract/1/0xbdbb5945f252bc3466a319cdcc3ee8056bf2e569/decompile/0xbdbb5945f252bc3466a319cdcc3ee8056bf2e569-decompiled.sol
- Orchestrator/registry contract:
-
Setup and proposal-creation trace
- Tx
0xfefd829e246002a8fd061eede7501bccb6e244a9aacea0ebceaecef5d877a984(governance initialization and proposal creation):
artifacts/root_cause/data_collector/iter_2/tx/1/0xfefd829e246002a8fd061eede7501bccb6e244a9aacea0ebceaecef5d877a984/trace.cast.log
- Tx
-
Vote trace
- Tx
0x3c09c6306b67737227edc24c663462d870e7c2bf39e9ab66877a980c900dd5d5(attacker vote and stake checks):
artifacts/root_cause/data_collector/iter_2/tx/1/0x3c09c6306b67737227edc24c663462d870e7c2bf39e9ab66877a980c900dd5d5/trace.cast.log
- Tx
-
Governance execution trace and AUDIO drain balance diffs
- Tx
0x4227bca8ed4b8915c7eec0e14ad3748a88c4371d4176e716e8007249b9980dc9(proposal evaluation andAudiusToken.transfer):
artifacts/root_cause/data_collector/iter_2/tx/1/0x4227bca8ed4b8915c7eec0e14ad3748a88c4371d4176e716e8007249b9980dc9/trace.cast.log - Balance diff for AUDIO drain:
artifacts/root_cause/seed/1/0x4227bca8ed4b8915c7eec0e14ad3748a88c4371d4176e716e8007249b9980dc9/balance_diff.json
- Tx
-
Profit-taking trace and balance diffs
- Tx
0x82fc23992c7433fffad0e28a1b8d11211dc4377de83e88088d79f24f4a3f28b3(AUDIO swap and ETH profit):
artifacts/root_cause/seed/1/0x82fc23992c7433fffad0e28a1b8d11211dc4377de83e88088d79f24f4a3f28b3/trace.cast.log - Balance diff for profit realization:
artifacts/root_cause/seed/1/0x82fc23992c7433fffad0e28a1b8d11211dc4377de83e88088d79f24f4a3f28b3/balance_diff.json
- Tx