BUILD Governance Takeover and Unlimited Mint ACT Exploit
Exploit Transactions
0x544e5849b71b98393f41d641683586d0b519c46a2eeac9bcb351917f40258a850xe6f47156c24c7628b93c5abc0d663dc337e976781778aa6f630aa327977b4e600xff2cf5ec92983daf075967b5652a8682419e882bf447d8da4d222118bfd94fba0xc42f7af9ae94f6c5f480202c4bb268a24341d6cbe3aa0323eb4a99b0321c3fcd0x648ea1548c20542d9545b329f9c1b5f5265a0ec71686caa944376213bdb0327b0xc34c8a55776f9a02be163b5bcd52c21ac08df2c1da97f0f13e5618c7645266890x3a9868b67f3e2ec90a5e9d5fce9a8176dfd8189b2cc37a2ed8cd8e5016c74955Victim Addresses
0x5a6ebeb61a80b2a2a5e0b4d893d731358d888583Ethereum0x6e36556B3ee5Aa28Def2a8EC3DAe30eC2B208739EthereumLoss Breakdown
Similar Incidents
Beanstalk flash-loan governance takeover drains treasury assets
40%Audius Governance Reinitialization and Treasury AUDIO Drain
39%Unlimited-Mint Collateral Used to Over-Mint Debt Token
38%Qubit QBridge xETH Unbacked Mint ACT Opportunity
37%DeRace vesting proxy ownership takeover and emergency exit
34%GPv2Settlement allowance leak lets router drain WETH and USDC
32%Root Cause Analysis
BUILD Governance Takeover and Unlimited Mint ACT Exploit
1. Incident Overview TL;DR
An unprivileged adversary cluster on Ethereum mainnet exploited BUILD Governance and the BUILD token to seize mint authority and extract ETH profit. Using only public governance functions on Governance contract 0x5a6e...8583, the cluster created and passed proposal 7 whose calldata called BUILD.setGovernance(attackerEOA). After proposal 7 reached the executable state, attacker EOA 0xdcc8a38a3a1f4ef4d0b4984dcbb31627d0952c28 executed it, causing BUILD token contract 0x6e36...8739 to set its governance variable to this EOA.
Once governance was captured, the attacker used the now-privileged EOA to call BUILD.mint multiple times, creating large amounts of BUILD from nothing, then routed portions of the minted BUILD through 1inch and related DeFi infrastructure into WETH and native ETH. Balance diffs across the mint, swap, and withdraw transactions show the attacker’s native ETH balance increased by exactly 4.599762619888583463 ETH after gas over the attack window. The core root cause is that Governance’s execute function can arbitrarily reassign BUILD.governance, and BUILD’s mint and setGovernance functions enforce only require(msg.sender == governance) with no restriction that governance remain a neutral contract or that minting be capped, enabling an ACT-style anyone-can-take governance-capture and unlimited-mint exploit.
2. Key Background
BUILD Governance (0x5a6e...8583) is a token-locking governance system. Users lock a voting token to gain voting power, must meet proposalThreshold to create proposals, and proposals must accumulate quorumVotes in favor to pass. Once a proposal reaches the appropriate state, Governance exposes an execute(uint256,address,uint256,bytes) function that can call an arbitrary target contract with arbitrary calldata. There is no on-chain allowlist or guardrail limiting which contracts or functions can be invoked via execute.
The BUILD token (0x6e36...8739) is an ERC20 with a single governance address that fully controls minting and further delegation of this power. The critical functions are:
contract BUILD is ERC20, ERC20Detailed {
using SafeERC20 for IERC20;
using Address for address;
using SafeMath for uint;
address public governance;
constructor () public ERC20Detailed("BUILD Finance", "BUILD", 18) {
governance = msg.sender;
}
function mint(address account, uint amount) public {
require(msg.sender == governance, "!governance");
_mint(account, amount);
}
function setGovernance(address _governance) public {
require(msg.sender == governance, "!governance");
governance = _governance;
}
}
In the intended design, Governance is the contract that should hold the governance role on BUILD, so that BUILD minting decisions go through on-chain proposals and voting. However, nothing in BUILD enforces that governance remain a contract, or that it not be set to an EOA capable of minting directly for its own benefit. Nothing in Governance enforces that execute cannot be used to call BUILD.setGovernance to assign governance to an arbitrary address.
The adversary uses standard DeFi components to realize profit: a DSProxy instance to interact with Balancer-style pools, and 1inch AggregationRouterV4 to swap minted BUILD into WETH and then unwrap WETH to ETH. All of these components are permissionless and accessible to any EOA.
3. Vulnerability Analysis & Root Cause Summary
The vulnerability is an overpowered governance execute combined with unguarded governance role on the token, which collapses the intended separation between a neutral governance contract and profit-seeking EOAs. On the BUILD token, mint and setGovernance are both gated solely by require(msg.sender == governance) with no additional constraints. On the Governance contract, execute allows any passed proposal to call an arbitrary target with arbitrary calldata once its state indicates readiness for execution.
This combination means an adversary that accumulates enough voting power to pass a single proposal can schedule a call to BUILD.setGovernance(attackerEOA), then execute it to move BUILD.governance from Governance to their own EOA. Once that invariant is broken, the EOA can call BUILD.mint in a permissionless way, creating arbitrary BUILD supply and routing it through DEXes for ETH. The protocol never enforces that governance remain a contract, never restricts the set of callable functions via execute, and never caps minting. The root cause is thus a governance-takeover enabling unlimited minting, fully realizable under an ACT adversary model because all steps rely only on public governance rules, public contract code, and permissionless DeFi interactions.
4. Detailed Root Cause Analysis
Invariant and breakpoint
The critical invariant is:
For all times t, increases in
BUILD.totalSupplymust be authorized exclusively by a neutral governance contract that cannot directly mint BUILD for its own unilateral profit; equivalently, theBUILD.governancestorage slot must never be set to an EOA that can arbitragemint()for personal gain.
The concrete breakpoint operation is:
In transaction
0x544e5849b71b98393f41d641683586d0b519c46a2eeac9bcb351917f40258a85at block14182038, attacker EOA0xdcc8...callsGovernance.execute(7, BUILD, 0, data), wheredataencodesBUILD.setGovernance(0xdcc8...). The call pathGovernance.execute -> BUILD.setGovernanceupdates theBUILD.governancestorage slot from the Governance contract address to0xdcc8..., violating the invariant.
The seed transaction trace for this tx confirms that Governance is the entrypoint and that a call into BUILD is executed with calldata corresponding to setGovernance:
Seed transaction trace (cast run -vvvvv) for tx 0x544e...:
SM Address: 0x5a6ebeb61a80b2a2a5e0b4d893d731358d888583, caller:0xdcc8a38a3a1f4ef4d0b4984dcbb31627d0952c28
...
; Governance.execute(7, BUILD, 0, data) decodes and initiates an external call to BUILD
...
; downstream call targets BUILD 0x6e36...8739 with function selector matching setGovernance(address)
From this point onward, require(msg.sender == governance) on BUILD accepts 0xdcc8..., granting the attacker unrestricted access to mint and the ability to reassign governance again if desired.
Victim contracts and behavior
On the Governance contract (0x5a6e...8583):
votingPeriod,executionPeriod,quorumVotes, andproposalThresholdare static numerical parameters controlling the lifecycle of proposals.- Proposals specify a
target,value, anddata. Once a proposal passes and reaches a ready-to-execute state, anyone can callexecute(id, target, value, data)to perform the call. - There is no filtering on
targetordata; any contract and function can be invoked, including those that assign or escalate privileges.
On the BUILD token (0x6e36...8739):
governanceis initialized to the deployment caller (in practice, the Governance contract).mint(address,uint256)mints arbitrary amounts to anyaccountso long asmsg.sender == governance.setGovernance(address)reassignsgovernanceto any_governanceif called by the current governance.
The protocol assumes that Governance will always be the owner of governance on BUILD, but this is not enforced. There is no require that governance be a contract, nor any safeguard against proposals that reassign governance to an EOA.
Evidence of governance takeover
Governance txlists and traces around proposal 7 show the following sequence:
- EOA
0xd6dbed...approves BUILD to Governance and submits proposal 7 targeting BUILD with calldata encodingsetGovernance(0xdcc8...). - The same EOA and the attacker EOA vote on the proposal such that
forVotesexceedagainstVotesand meetquorumVotes, moving the proposal into the state where it can be executed. - In tx
0x544e...at block14182038, EOA0xdcc8...callsGovernance.execute(7, BUILD, 0, data). The seed trace confirms the external call from Governance into BUILD withsetGovernance(0xdcc8...), and storage diffs around the BUILDgovernanceslot show a change from the Governance address to0xdcc8....
Evidence of unlimited minting
Once BUILD.governance equals 0xdcc8..., the attacker submits three mint transactions:
0xe6f47156c24c7628b93c5abc0d663dc337e976781778aa6f630aa327977b4e60(block14182042, mechanismmint)0xff2cf5ec92983daf075967b5652a8682419e882bf447d8da4d222118bfd94fba(block14182048, mechanismmint)0xc42f7af9ae94f6c5f480202c4bb268a24341d6cbe3aa0323eb4a99b0321c3fcd(block14182054, mechanismmint)
Balance diffs for these txs show the BUILD token being created directly to the attacker:
// Example: tx 0xe6f4... (first mint)
{
"erc20_balance_deltas": [
{
"token": "0x6e36556b3ee5aa28def2a8ec3dae30ec2b208739",
"holder": "0xdcc8a38a3a1f4ef4d0b4984dcbb31627d0952c28",
"before": "0",
"after": "100000000000000000000000",
"delta": "100000000000000000000000",
"contract_name": "BUILD"
}
]
}
The other two mint transactions similarly show large positive BUILD deltas to 0xdcc8... (7,600 BUILD and 1,000,000 BUILD-equivalent amounts), with only small negative ETH deltas corresponding to gas costs. There is no incoming token spend from the attacker; BUILD appears from the zero address via mint.
Profit realization via swaps and withdraws
After minting, the attacker converts BUILD into WETH/ETH via DeFi infrastructure:
0x648ea1548c20542d9545b329f9c1b5f5265a0ec71686caa944376213bdb0327b(block14182050, mechanismswapvia 1inch)0xc34c8a55776f9a02be163b5bcd52c21ac08df2c1da97f0f13e5618c764526689(block14188829, mechanismswapvia 1inch)0x3a9868b67f3e2ec90a5e9d5fce9a8176dfd8189b2cc37a2ed8cd8e5016c74955(block14188842, mechanismwithdrawvia WETH)
The balance diffs for these txs show ETH inflows and BUILD outflows from the attacker:
// Example: tx 0x648e... (1inch swap)
{
"native_balance_deltas": [
{
"address": "0xdcc8a38a3a1f4ef4d0b4984dcbb31627d0952c28",
"before_wei": "353676727661241689",
"after_wei": "4831548861904691557",
"delta_wei": "4477872134243449868"
}
],
"erc20_balance_deltas": [
{
"token": "0x6e36556b3ee5aa28def2a8ec3dae30ec2b208739",
"holder": "0xdcc8a38a3a1f4ef4d0b4984dcbb31627d0952c28",
"before": "7600000000000000000000",
"after": "0",
"delta": "-7600000000000000000000",
"contract_name": "BUILD"
}
]
}
// Example: tx 0x3a98... (WETH.withdraw)
{
"native_balance_deltas": [
{
"address": "0xdcc8a38a3a1f4ef4d0b4984dcbb31627d0952c28",
"before_wei": "745679340714433351",
"after_wei": "897716860263569111",
"delta_wei": "152037519549135760"
}
]
}
Summing positive ETH deltas to 0xdcc8... across the swap/withdraw leg and subtracting the gas costs measured in the relevant mint/swap/withdraw txs yields a net ETH profit of 4.599762619888583463 ETH over the attack window. This net delta is encoded directly in the success predicate of root_cause.json and does not rely on estimated prices or off-chain data.
The exploit therefore consists of:
- Using public governance to reassign BUILD’s
governanceto an EOA. - Using the now-privileged EOA to mint BUILD at zero cost.
- Dumping minted BUILD into liquidity pools via 1inch and DSProxy to extract WETH/ETH.
All steps are permissionless and reproducible by any adversary that controls sufficient BUILD voting power to pass the governance proposal.
5. Adversary Flow Analysis
Adversary-related cluster
The adversary-related cluster accounts are:
- EOA 0xdcc8a38a3a1f4ef4d0b4984dcbb31627d0952c28 (Ethereum mainnet)
- Executes
Governance.execute(7, ...)in tx0x544e.... - Receives all minted BUILD in mint txs
0xe6f4...,0xff2c..., and0xc42f.... - Initiates 1inch and WETH interactions that convert BUILD/WETH into native ETH.
- Accumulates net profit of
4.599762619888583463ETH in native balance after gas.
- Executes
- EOA 0xd6dbed6297b539a11f1aab7907e7df7d9ffeda7e (Ethereum mainnet)
- Approves BUILD to Governance and creates proposal 7 with calldata
BUILD.setGovernance(0xdcc8...). - Votes in favor of proposal 7 and exchanges ETH with
0xdcc8..., supporting classification as a cooperating governance/trading address.
- Approves BUILD to Governance and creates proposal 7 with calldata
- DSProxy 0x40753fee22b6a7bf197ac25c3b31dc1e13e3d694 (Ethereum mainnet)
- A DSProxy instance built via DSProxyFactory from
0xdcc8.... - Only its owner or authorized authority can call
execute(address,bytes), so its interactions with Balancer and DEX pools are under attacker control.
- A DSProxy instance built via DSProxyFactory from
Lifecycle stages
-
Governance priming and proposal creation
- Tx
0xf8990741e0195b3616b0b1f422f59b405c2b655109f6ed05fa90e9b4738c48d1(block14169189, mechanismapprove): the adversary cluster approves BUILD to Governance, enabling token lock and voting. - Tx
0xfa9cca40f225745c2eac97521d979ddfa4edae589ff0f1b543b94345e52335e9(block14169198, mechanismgovernance_propose): proposal 7 is created with targetBUILDand calldata encodingsetGovernance(0xdcc8...). - Txs
0x9b116ef389e12c6ccb99fedd9f6dd881ea6a893d8d4a890928be45839932e024and0xb6edc1f0b5b2558aae3d886c1d52c15e0126021c91f052e0378ee707f6e85be8(blocks14169204and14182045, mechanismsgovernance_vote): adversary EOAs vote so thatforVotesexceedagainstVotesand meetquorumVotes, moving proposal 7 to a ready-to-execute state.
- Tx
-
Governance execution and mint authority capture
- Tx
0x544e5849b71b98393f41d641683586d0b519c46a2eeac9bcb351917f40258a85(block14182038, mechanismgovernance_execute):- EOA
0xdcc8...callsGovernance.execute(7, BUILD, 0, data). - Governance calls
BUILD.setGovernance(0xdcc8...). - The
BUILD.governancestorage slot is updated from0x5a6e...8583(Governance) to0xdcc8.... - From this point, BUILD’s
mintandsetGovernancefunctions accept0xdcc8...asmsg.sender.
- EOA
- Tx
-
Unlimited minting and ETH extraction
- Tx
0xe6f4...(block14182042, mechanismmint):BUILD.mintmints100,000BUILD-equivalent units directly to0xdcc8..., as shown by a +100,000 BUILD delta in the balance diff, with only gas cost in ETH. - Tx
0xff2c...(block14182048, mechanismmint):BUILD.mintmints7,600BUILD directly to0xdcc8.... - Tx
0xc42f...(block14182054, mechanismmint):BUILD.mintmints approximately1,000,000BUILD-equivalent units to0xdcc8.... - Tx
0x648e...(block14182050, mechanismswap): the attacker uses 1inch to swap 7,600 BUILD for ETH, with the balance diff showing a large positive ETH delta at0xdcc8...and a full depletion of the 7,600 BUILD. - Tx
0xc34c...(block14188829, mechanismswap): the attacker uses 1inchunoswapto route a ~1e24BUILD chunk through liquidity pools; balance diffs show large negative BUILD deltas from0xdcc8...into pools and relatively small ETH gas costs. - Tx
0x3a98...(block14188842, mechanismwithdraw): the attacker callsWETH.withdraw, converting WETH into0.152037519549135760ETH at0xdcc8..., as recorded in the native balance diff.
- Tx
Over these mint, swap, and withdraw transactions, the summed ETH inflows to 0xdcc8... minus gas outflows equal a net profit of 4.599762619888583463 ETH. No privileged roles, whitelists, or private channels are used; the only prerequisite is sufficient BUILD voting power to pass proposal 7 under the public Governance rules.
6. Impact & Losses
The directly evidenced financial impact on-chain is:
- ETH: at least
4.599762619888583463ETH of net profit realized by attacker EOA0xdcc8a38a3a1f4ef4d0b4984dcbb31627d0952c28over the core attack-leg transactions, after accounting for gas costs.
Beyond the ETH-denominated profit, the exploit causes unbounded inflation of BUILD supply under attacker control:
- BUILD’s total supply increases by more than
1,107,600BUILD units directly minted to0xdcc8...across the documented mint transactions. - Large amounts of BUILD are routed into DeFi liquidity pools (e.g., via DSProxy and 1inch), redistributing the new supply across LPs and other counterparties.
These effects degrade the integrity of BUILD Governance and the BUILD token:
- Governance’s assumption that mint authority is constrained by community decisions is broken once an EOA becomes
governance. - Liquidity providers and traders in BUILD pools are exposed to sudden inflation and dump pressure from attacker-minted supply.
- The exploit demonstrates that, under the current design, any adversary with sufficient BUILD voting power can reproduce the same governance-takeover and unlimited-mint cycle.
7. References
-
Contracts
- Governance contract (
0x5a6ebeb61a80b2a2a5e0b4d893d731358d888583) – source code as collected inartifacts/root_cause/data_collector/iter_1/contract/1/0x5a6e...8583/source/src/Contract.sol. Used to confirm proposal lifecycle, voting thresholds, and the behavior ofexecute(uint256,address,uint256,bytes). - BUILD token contract (
0x6e36556B3ee5Aa28Def2a8EC3DAe30eC2B208739) – source code as collected inartifacts/root_cause/data_collector/iter_1/contract/1/0x6e36...8739/source/src/Contract.sol. Used to confirmgovernancestorage, and the implementations ofmintandsetGovernance.
- Governance contract (
-
Key transactions
0xf8990741e0195b3616b0b1f422f59b405c2b655109f6ed05fa90e9b4738c48d1– BUILD approval to Governance (governance priming).0xfa9cca40f225745c2eac97521d979ddfa4edae589ff0f1b543b94345e52335e9– proposal 7 creation (BUILD.setGovernance(0xdcc8...)).0x9b116ef389e12c6ccb99fedd9f6dd881ea6a893d8d4a890928be45839932e024and0xb6edc1f0b5b2558aae3d886c1d52c15e0126021c91f052e0378ee707f6e85be8– governance votes for proposal 7.0x544e5849b71b98393f41d641683586d0b519c46a2eeac9bcb351917f40258a85– Governance execution of proposal 7, callingBUILD.setGovernance(0xdcc8...).0xe6f47156c24c7628b93c5abc0d663dc337e976781778aa6f630aa327977b4e60– first BUILD.mint to attacker (100,000 BUILD-equivalent).0xff2cf5ec92983daf075967b5652a8682419e882bf447d8da4d222118bfd94fba– second BUILD.mint to attacker (7,600 BUILD).0xc42f7af9ae94f6c5f480202c4bb268a24341d6cbe3aa0323eb4a99b0321c3fcd– third BUILD.mint to attacker (~1,000,000 BUILD-equivalent).0x648ea1548c20542d9545b329f9c1b5f5265a0ec71686caa944376213bdb0327b– 1inch swap converting 7,600 BUILD into ETH.0xc34c8a55776f9a02be163b5bcd52c21ac08df2c1da97f0f13e5618c764526689– 1inchunoswaprouting a ~1e24BUILD chunk through liquidity pools.0x3a9868b67f3e2ec90a5e9d5fce9a8176dfd8189b2cc37a2ed8cd8e5016c74955– WETH.withdraw converting WETH into0.152037519549135760ETH at the attacker EOA.
-
Traces and balance diffs
- Seed transaction trace for tx
0x544e...–artifacts/root_cause/seed/1/0x544e5849b71b98393f41d641683586d0b519c46a2eeac9bcb351917f40258a85/trace.cast.log. Confirms the call pathGovernance.execute -> BUILD.setGovernanceand the update of the governance slot. - Balance diffs for BUILD.mint txs –
artifacts/root_cause/data_collector/iter_2/tx/1/0xe6f4.../balance_diff.json,0xff2c.../balance_diff.json,0xc42f.../balance_diff.json. Used to verify BUILD supply creation and ETH gas costs. - Balance diffs for swap and withdraw txs –
artifacts/root_cause/data_collector/iter_3/tx/1/0x648e.../balance_diff.json,0xc34c.../balance_diff.json,0x3a98.../balance_diff.json. Used to compute the net+4.599762619888583463ETH change in the attacker’s native balance.
- Seed transaction trace for tx
-
Txlists and address-level context
- Governance-related txlists for
0xd6dbed...and0xdcc8...– collected under theartifacts/root_cause/data_collector/iter_3/address/...directory, providing context for governance participation, DSProxy deployment, and value transfers between the adversary addresses.
- Governance-related txlists for