Blockchain

79AU: burned LP tokens leave the token administrator in control

On October 7, a privileged address moved 79AU out of its pool, after which recipients sold it back for USDT. Burning LP tokens had left that authority intact. The project says it upgraded security and recovered 15,000 BNB. A completed transfer confirms the return. Holders still need an account of the remaining administrator powers and the returned funds.

Warm-paper concept illustration: burned LP receipts sit beside a trading pool while an administrator key opens a separate token-withdrawal route.
In this article

“LP burned” is an easy promise to take comfort in. Liquidity-provider (LP) tokens are receipts for a share of a trading pool. A project sends them to a dead address, and holders reasonably expect the pool's money to stay put. At 79th Vault, the DeFi project behind 79AU, the incident started elsewhere. On October 7, an address with token-operating authority moved 79AU from the pool to two selling addresses. The pool held fewer tokens, its quoted price rose, and the recipients sold those tokens back into it for USDT.

On October 9, 79th Vault announced that it had recovered 15,000 BNB, with plans to restore liquidity and burn the resulting LP tokens. Receiving returned money is welcome progress. Yet LP had already been burned before the drain. Holders deciding whether to trust that assurance still need to know what the token administrator can do to the pool. Two actual withdrawal transactions explain why that authority deserves more attention than a burn percentage.

1 Two contracts keep the pool reserves and token balances

79AU is a BNB Chain token at 0xc35e…a9ca. The affected 79AU/USDT pair is 0x02d5…da09. Its factory() returns 0xcA143Ce32Fe78f1f7019d7d551a6402fC5350c73, matching the BSC factory in PancakeSwap's official V2 address table.

There are two sets of records to keep in mind. The pair contract stores reserve numbers for trading. The 79AU contract records how much 79AU each address owns. The pool's token holdings are a balance assigned to the pool address in that second contract. The pair reads that balance and uses it alongside USDT to settle trades. Authority to change the balance at the token layer therefore reaches data on which the pool's pricing depends.

LP tokens represent a share received after depositing both assets into a pool. A holder can return those receipts to redeem a proportional amount of the assets. Sending them to 0x000000000000000000000000000000000000dEaD, commonly called burning LP, removes that portion from ordinary control. Administrator rights in the underlying token contract exist independently of LP ownership and survive the transfer of LP tokens.

In PancakeSwap's archived reference implementation, PancakePair.sol:134–155, burn() distributes both assets according to the returned LP share. This older source illustrates redemption, with fee parameters specific to that historical version. The observed 79AU withdrawals called a separate entry point in the token contract.

2 Two token withdrawals with no USDT payment in the same transaction

At 07:41:04 UTC on October 7, 0x019b…5ca3 called the 79AU contract with input beginning 0x2a2c5923. The receipt for 0x93a9…eaaf records 500,000 79AU moving from the pair to 0xf219…0938, followed by a pair Sync event updating reserves. Four seconds later, 0xf737…a7d6 followed the same route, sending another 500,000 tokens to 0xc3e9…a099.

Each receipt contains a 79AU Transfer and a pair Sync, with no USDT transfer or LP-redemption event in that transaction. The three 32-byte input fields correspond to the pool address, recipient and token amount. With the token's 18 decimals, the amount decodes to 500,000. The called contract, arguments and balance-update events are visible. Without publicly verifiable source for this privileged function, its name and internal checks cannot be established from a four-byte selector.

Caller:  0x019bd8ed017d11af0eb24d28dcdd0f9930c85ca3
Target:  79AU 0xc35ef0564751a27b468f791113c686c8eebaa9ca
Entry:   0x2a2c5923
Field 1: pool 0x02d50b93e65d4572af5db2eeb6dd3c6ff08fda09
Field 2: recipient address
Field 3: 500000 × 10^18
Receipt: 79AU Transfer (pool → recipient), pair Sync

The same address made both calls, sending tokens to different recipients. Taking tokens out of the pool and selling them were separate actions. The privileged address performed the first step, and the recipients could perform the second. Revoking the withdrawal address can stop it obtaining more inventory. Tokens already transferred to other addresses remain available for subsequent trades. In its October 8 announcement, the project says the attacker obtained an operator's private key. Public transactions identify the authorized address's actions. Establishing who controlled it and how the key was obtained still requires investigative evidence.

Bitquery's full investigation attributes approximately 14.35 million USDT to the two selling routes combined. That is its aggregation as of October 8 at 12:53 UTC. The two directly retrieved receipts explain the withdrawal mechanism below, while the aggregate loss retains Bitquery's attribution.

3 Remove tokens first, then sell them at the revised price

Consider a pool with 100 tokens and 1,000 USDT. Ignoring fees, its product x × y = k is 100,000 and its marginal quote is roughly 10 USDT per token. An ordinary buyer pays USDT to receive tokens. Both quantities change, and the product constraint preserves the relationship between the assets through the swap.

Replace that purchase with an administrator withdrawal: remove 50 tokens without paying USDT, then make the pair accept the new balances. Reserves become 50 tokens and 1,000 USDT. Their product falls to 50,000 and the marginal quote rises to 20. The recipient can now sell its 50 tokens back. Selling those tokens restores the token reserve to 100, which under the revised product leaves only 500 USDT in the pool. The seller receives the other 500. The quote of 20 applies to a vanishingly small sale. As the recipient sells 50 tokens, the price of subsequent units keeps falling. The whole order's proceeds follow the reserve change, not a multiplication of 50 by 20.

Three-step fee-free model: the pool starts with 100 tokens and 1,000 USDT. Privileged removal leaves 50 and 1,000. Selling 50 back leaves 100 and 500, with 500 USDT paid to the seller.
Figure 1: an arithmetic model isolating reserve changes. These values are illustrative, with no reconstruction of 79AU's actual balances, taxes or loss size. View full size.

The receipt's Sync is an event reporting updated reserves. In the archived reference, _update():73–85 emits it after writing reserves. sync():198–200 is one entry point: it reads both balanceOf(pool) values and passes them to that update. Other operations also update reserves, so this event alone cannot reconstruct the token's internal call path here. Subsequent sales use the new reserves. A product check during a swap cannot replace controls over balance changes in the token contract.

A few local arithmetic operations provide a useful control. In the ordinary route, pay 1,000 USDT for 50 tokens, then sell those 50 back. Without fees, the proceeds exactly cover the original 1,000 USDT purchase. The privileged route omits the initial payment, so its 500 USDT proceeds come directly from the pre-existing liquidity.

# Fee-free arithmetic only; no wallet, RPC or transaction signing
normal_k = 100 * 1000
normal_buy_out = 100 - normal_k / 2000       # 50
normal_sell_out = 2000 - normal_k / 100      # 1000, offsetting the purchase

after_pull_k = 50 * 1000
privileged_sell_out = 1000 - after_pull_k / 100  # 500, no payment for the pull

Actual proceeds also depend on pool fees, token sell tax, intervening trades and repeated withdrawals. The project's public profile lists a 3.25% sell tax. Those factors require transaction-level accounting, so taking half of the USDT reserve in this model cannot be treated as a fixed loss ratio for the incident. The model explains why an ordinary sale can still take money after the pricing baseline changes.

4 Operating authority remained after the old address lost its role

OPERATOR_ROLE labels this set of operating permissions. Its on-chain identifier equals keccak256("OPERATOR_ROLE"). A hasRole query checks whether an address has been granted that role. At 08:24:04 UTC on October 7, a revocation transaction executed through multisig contract 0xca8a…2df. 79AU emitted RoleRevoked for the original withdrawal address, 0x019b…5ca3. Revocation neither retrieves previously transferred tokens nor stops recipients selling their remaining inventory.

At 12:37:24 UTC the next day, another multisig execution granted the same role to 0x205b…dd07, retaining and reallocating that authority. Its purpose, eligible source addresses, and per-call or cumulative limits all matter to the risk after recovery. Replacing a key addresses only part of that question.

The official October 11 update says the project completed system security upgrades, strengthening account permissions, operational controls and safeguards, while remaining operational. It gives no privileged-function source or specific amount and source-address restrictions. The upgrade statement therefore still needs to be connected to the contract permissions visible on-chain.

Read-only state at BNB Chain block 127323745, October 13 at 02:35:25 UTC, returns false for the old address's hasRole check and true for deployer 0xe45c…40bc and new operator 0x205b…dd07. At 02:59:54 UTC, block 127327011 identifies DEFAULT_ADMIN_ROLE as the role's administrator and confirms that multisig 0xca8a…2df holds it. Zero identifies that administrator role, whose holder can still grant or revoke membership.

For someone deciding whether to use this pool, a useful disclosure would spell out which balances an operator can move, whether that includes the pair, who approves the action and how limits are enforced. Routine rewards or settlement can be given powers confined to that task. Authority over arbitrary source addresses makes the relevant balances depend on the administrator keys' security.

5 Follow the 15,000 BNB beyond the receiving address

The return transaction linked by the project occurred at 08:54:18 UTC on October 9, in block 126607298. It succeeded, transferring 15,000 BNB from 0xa953…4f89 to the announced 0x2bfc…b7b2 address. Its input is empty and it contains no contract events. This is a direct BNB transfer to the recipient identified by the project.

The 14.35 million USDT is the investigation's combined proceeds from two selling routes. The 15,000 BNB is the return actually received at the project's address. The currencies and valuation times differ. Establishing the remaining shortfall requires complete outflows and recoveries valued at a common time, with the losses covered by the return identified. Dividing the two figures directly yields no meaningful recovery percentage.

The announcement says the recovered assets will be put into liquidity and the resulting LP burned. That involves further steps: converting or pairing assets, depositing them, receiving LP and moving those receipts. The BNB transaction ends at the project's receiving address. A subsequent liquidity deposit needs its own transaction trail. Outcomes for holders also depend on the arrangement: replenishing the pool improves tradable depth, while direct compensation changes particular users' balances. Each needs its own records.

The pool already has a newer share distribution. At block 127327011, the dead address holds approximately 90.41% of LP supply, calculated as balanceOf(0x…dEaD) / totalSupply() at that same block. This describes the distribution at that block. Attributing new shares to the returned BNB requires their deposit trail. The roughly 79% in the early investigation is a historical observation. Minting shares for deposits or surrendering them for redemption changes LP supply. Transfers to the dead address increase its balance. Ordinary swaps do not directly change LP supply. Recovery reporting should connect the new receipts to the transactions that created them.

6 Who can still move tokens from a replenished pool?

I would judge whether to use this pool by whether the new operator can touch its balance. If the project retains that capability, it should explain the purpose and constraints through source corresponding to the actual deployment. A multisig can reduce exposure to a single compromised key. The token permissions it manages still determine what its signers may authorize. Another LP-burn percentage leaves that question open.

The returned funds have reached the project's announced address. Holders now need the subsequent deposit or compensation trail and an explanation of whether the same token-moving capability is restricted, and where any restriction is enforced. Returned money can reduce this incident's losses. Making replenished liquidity harder to extract through the same route remains the part of recovery that needs an answer.