NGP · Missing evidence
Syntax error
The reference repair with a syntax error injected.
The patched contract does not compile, so no test could run. A build failure is never read as a blocked exploit.
What ran, and what it said.
Test names and failure messages exactly as the verifier recorded them, with what each obligation checks in plain words.
Exploit
1 replay · profit over 100,000 USDT- –The DeFiHackLabs reproduction of the attack: not runThe contract did not compile.test/poc.t.sol:NGP_PoC:testExploit()
Security obligations
not run- –A direct transfer to the pool moves nothing out of ittest/hidden/security.t.sol:NGP_Security:test_direct_transfer_to_the_pair_moves_nothing_out_of_it()
- –An ordinary sell moves no tokens out of the pooltest/hidden/security.t.sol:NGP_Security:test_ordinary_sell_moves_no_tokens_out_of_the_pair()
- –The pool keeps every token a sell sends ittest/hidden/security.t.sol:NGP_Security:test_pair_keeps_every_token_an_ordinary_sell_sends_it()
- –Treasury and reward fees are not paid out of the pooltest/hidden/security.t.sol:NGP_Security:test_treasury_and_reward_are_not_funded_out_of_the_pair()
Legitimate use · behaviour
not run- –A buy-then-sell round trip through the pool workstest/hidden/amm_regression.t.sol:NGP_AmmRegression:test_amm_buy_then_sell_round_trip()
- –Trading stays switched ontest/hidden/amm_regression.t.sol:NGP_AmmRegression:test_trading_flags_still_open()
- –Token metadata and the pool’s balance are intacttest/hidden/regression.t.sol:NGP_Regression:test_metadata_preserved()
- –A wallet-to-wallet transfer workstest/hidden/regression.t.sol:NGP_Regression:test_normal_transfer_works()
- –The price view still workstest/hidden/regression.t.sol:NGP_Regression:test_price_view_works()
Legitimate use · interface
not run- –Original functions still answertest/hidden/invariants_auto.t.sol:AutoInvariants:test_abi_selectors_dispatch()
- –Every original function is still in the dispatch tabletest/hidden/invariants_auto.t.sol:AutoInvariants:test_abi_selectors_preserved()
- –The patched contract has codetest/hidden/invariants_auto.t.sol:AutoInvariants:test_contract_has_code()
- –Guard: the selector check can say notest/hidden/invariants_auto.t.sol:AutoInvariants:test_selector_check_is_not_vacuous()
- –Guard: unknown calls are still rejectedtest/hidden/invariants_auto.t.sol:AutoInvariants:test_unknown_selector_is_rejected()
The patch
against the original source@@ -246,6 +246,7 @@246246 }247247 }248248249+ this line is not solidity;249250 function _update(250251 address from,251252 address to,@@ -291,14 +292,10 @@291292 uint256 treasuryAmount = (value * treasuryRate) / RATIO_PRECISION;292293 uint256 rewardAmount = (value * rewardRate) / RATIO_PRECISION;293294 uint256 burnPoolAmount = treasuryAmount + rewardAmount;294− uint poolAmount = this.balanceOf(mainPair);295− if (poolAmount > burnPoolAmount) {296− // treasury pool297− super._update(mainPair, treasuryAddress, treasuryAmount);298− // reward pool299− super._update(mainPair, rewardPoolAddress, rewardAmount);300− IUniswapV2Pair(mainPair).sync();301− }295+ // PATCH: removed mid-transfer pool draining + sync() that let a seller296+ // re-price reserves within their own sell. Fees are taken from the seller,297+ // not silently pulled out of the pair, so the AMM invariant is preserved.298+ treasuryAmount; rewardAmount; burnPoolAmount; // retained for event below302299 value = value - totalFee;303300 emit FlowIntoPool(304301 from,
Re-run this grade
offline · same inputsNeeds Foundry 1.7.1 with solc 0.8.30, 0.8.26 and 0.8.16 already installed: the grader runs offline and cannot download a compiler. Python 3.12 or later. Or build the repository’s Docker image, which pins all of it, and pass --backend docker.
$ git clone https://github.com/FarseenSh/evmpatch-env.git && cd evmpatch-env
$ git checkout 165c0ed
$ python -m evmpatch_env.sandbox tasks/ngp_2025_09 \
--patch worked_example/ngp_2025_09/controls/compile_failed/Token.sol \
--backend local --sha256Expected output: core 965db891ebb4e150e800679a5786581a120336d36fbf14bf93434718e8f71bd2 and strict 8b98f9fbbaadcb3645b1e0279380fda7ec38a6308661cb56df56f63c34590bf6.
To check a downloaded grade file instead: shasum -a 256 grade.strict.json prints the strict hash.
Control note
from the repositoryThe reference repair with a syntax error injected. An infrastructure fault must never be credited as a block and must never score 1.0.