Calculated from recorded token losses using historical USD prices at the incident time.
0x3bba4fb6de00dd38df3ad68e51c19fe575a95a296e0632028f101c5199b6f7140x4d4d05e1205e3a412ae1469c99e0d954113aa76fEthereumIn Ethereum mainnet transaction 0x3bba4fb6de00dd38df3ad68e51c19fe575a95a296e0632028f101c5199b6f714, an unprivileged attacker used a 70 WETH Balancer flash loan to move the PNT price on the public WETH/PNT Uniswap V2 pool, then called the public Burner contract at 0x4d4d05e1205e3a412ae1469c99e0d954113aa76f to convert the Burner's ETH, WBTC, and USDT balances into PNT through Kyber at the manipulated rate. The attacker then sold the earlier-acquired PNT back into WETH, repaid the flash loan, and realized a net ETH gain.
The root cause is an ACT attack surface in the Burner design: convertAndBurn(address[]) was callable by anyone, and the Burner routed conversions through Kyber with minConversionRate = 1, which provided no meaningful slippage protection against same-transaction price manipulation.
The relevant victim component is the pNetwork PNT Burner, a public maintenance contract intended to convert any trapped assets it held into PNT, burn half of the acquired PNT, and forward the other half to unburnedDestination at 0x28f4eca52462760255b25f80e64d54c1c5687a61.
The exploitable pre-state at block 19917290 is deterministic and confirmed by forked state plus the collected balance diff: the Burner held 1553202311489518237 wei, 716800 WBTC satoshis, and 331717060 USDT base units, while remaining unpaused and configured to burn 50% of acquired PNT.
The price-discovery path was not isolated from manipulation. The seed trace shows Kyber routing into public PNT liquidity after the attacker had already moved the Uniswap V2 WETH/PNT pool in the same transaction.
This is an ATTACK-class issue caused by exposing value-moving treasury logic to arbitrary callers while omitting execution-price protection. The Burner accepted a caller-supplied list of assets and converted full balances held by the contract. It then executed Kyber trades with minConversionRate = 1, which semantically means the trade would accept any non-zero rate returned by routed liquidity. That design let the attacker manufacture a temporary on-chain PNT price, force the Burner to transact at that price, and then unwind into the artificial demand the Burner itself created. The violated invariant is straightforward: treasury assets must not be converted at attacker-manipulated rates. The concrete breakpoint is the Burner conversion path that spends Burner-held balances through Kyber without a real slippage floor.
The verified Burner behavior, as summarized in the analysis and corroborated by the seed trace, is:
function convertAndBurn(address[] calldata tokens) external {
for each token in tokens {
_convert(token);
}
_burnAndForwardPnt();
}
function _convert(address srcToken) internal {
uint256 amount = fullBalanceHeldByBurner(srcToken);
kyberNetwork.trade(srcToken, amount, PNT, address(this), BIG_LIMIT, 1, kyberFeeWallet);
}
The seed trace confirms the exploit path directly:
BalancerVault::flashLoan(..., [WETH], [70000000000000000000], ...)
UniswapV2Router02::swapExactTokensForTokensSupportingFeeOnTransferTokens(
70000000000000000000, 0, [WETH, PNT], helper, ...
)
0x4d4d05e1205e3A412ae1469C99e0d954113aa76F::convertAndBurn(
[0x0000000000000000000000000000000000000000, WBTC, USDT]
)
0x818E6FECD516Ecc3849DAf6845e3EC868087B755::trade(..., 1, ...)
Three specific Kyber trade invocations in the trace show the Burner converting its ETH, WBTC, and USDT balances after the opening price move:
trade(ETH, 1553202311489518237, PNT, Burner, 1e36, 1, ...)
trade(WBTC, 716800, PNT, Burner, 1e36, 1, ...)
trade(USDT, 331717060, PNT, Burner, 1e36, 1, ...)
The balance diff proves that the Burner was drained of the converted assets:
{
"burner_eth_delta": "-1553202311489518237",
"burner_wbtc_delta": "-716800",
"burner_usdt_delta": "-331717060"
}
The same artifacts show the post-conversion PNT side effects expected from the contract design: treasury address 0x28f4eca52462760255b25f80e64d54c1c5687a61 received 2220986643805599260958 PNT, while PNT total supply decreased because half of the acquired PNT was burned.
The adversary cluster consists of EOA 0xe6dcf87256866e293b825708bf1f5df8f07519b3 and helper contract 0x1bcc8378943aaee2d99a4e73ddf6c01f62825844, which the EOA deployed earlier in transaction 0x73257c44898a004f2e95b4ccc1fa3288bef1a431593b8b671e2f7cd1e9b4271a.
The exploit transaction then proceeded in one end-to-end bundle:
70 WETH from Balancer Vault 0xBA12222222228d8Ba445958a75a0704d566BF2C8.0x77bbc2b409c2c75e4999e8e3eb8309efff37cf2d, pushing the PNT price up.[ETH, WBTC, USDT], forcing it to convert all trapped balances into overpriced PNT through Kyber.The trace shows the opening and closing swap legs around the Burner call:
UniswapV2Router02::swapExactTokensForTokensSupportingFeeOnTransferTokens(
70000000000000000000, 0, [WETH, PNT], helper, ...
)
...
UniswapV2Router02::swapExactTokensForTokensSupportingFeeOnTransferTokens(
1868726451213386974206315, 0, [PNT, WETH], helper, ...
)
The seed balance diff shows the attacker EOA balance rising from 0.289519962417528561 ETH to 1.990643793670068419 ETH, a delta of 1.701123831252539858 ETH. The transaction receipt values recorded in the analysis put gas cost at 0.025161263375540175 ETH, confirming profitable realization.
The measurable victim-side loss is the forced conversion of every non-PNT asset held by the Burner at the start of the exploit block:
1553202311489518237 wei716800 satoshis331717060 base unitsThose assets were not stolen by direct transfer from the Burner to the attacker. Instead, the Burner overpaid for PNT in manipulated conditions, burned half of what it bought, sent the other half to the treasury destination, and left the attacker with the mispricing spread as ETH profit.
0x3bba4fb6de00dd38df3ad68e51c19fe575a95a296e0632028f101c5199b6f7140x73257c44898a004f2e95b4ccc1fa3288bef1a431593b8b671e2f7cd1e9b4271a0x4d4d05e1205e3a412ae1469c99e0d954113aa76f0x89ab32156e46f46d02ade3fecbe5fc4243b9aaed/workspace/session/artifacts/collector/seed/1/0x3bba4fb6de00dd38df3ad68e51c19fe575a95a296e0632028f101c5199b6f714/metadata.json/workspace/session/artifacts/collector/seed/1/0x3bba4fb6de00dd38df3ad68e51c19fe575a95a296e0632028f101c5199b6f714/trace.cast.log/workspace/session/artifacts/collector/seed/1/0x3bba4fb6de00dd38df3ad68e51c19fe575a95a296e0632028f101c5199b6f714/balance_diff.jsonhttps://etherscan.io/address/0x4d4d05e1205e3a412ae1469c99e0d954113aa76f#code