MCAI · Missing evidence
transferFrom renamed
Renames transferFrom, which the token’s interface requires, so the contract no longer compiles.
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 11 ETH- –The DeFiHackLabs reproduction of the attack: not runThe contract did not compile.test/poc.t.sol:MCAI_PoC:testExploit()
Security obligations
not run- –The tax wallet cannot move an ordinary holder’s tokens without approvaltest/hidden/security.t.sol:MCAI_Security:test_taxwallet_cannot_move_holder_tokens_without_approval()
- –The tax wallet cannot move the pool’s tokens without approvaltest/hidden/security.t.sol:MCAI_Security:test_taxwallet_cannot_move_pair_tokens_without_approval()
- –With approval, the tax wallet’s allowance is debited by exactly what it movestest/hidden/security.t.sol:MCAI_Security:test_taxwallet_transferFrom_debits_allowance()
- –No one can burn a holder’s tokens to the dead wallet without approvaltest/hidden/security.t.sol:MCAI_Security:test_unapproved_spender_cannot_burn_to_dead_wallet()
Legitimate use · behaviour
not run- –Buying through the pool the incident used still workstest/hidden/regression.t.sol:MCAI_Regression:test_amm_buy_works()
- –Approve, then transferFrom, works and debits the allowance exactlytest/hidden/regression.t.sol:MCAI_Regression:test_approved_transferFrom_works_and_debits_allowance()
- –Token metadata and the pool’s balance are intacttest/hidden/regression.t.sol:MCAI_Regression:test_metadata_preserved()
- –A holder-to-holder transfer workstest/hidden/regression.t.sol:MCAI_Regression:test_normal_transfer_works()
- –With approval, the tax wallet can still spend like anyone elsetest/hidden/regression.t.sol:MCAI_Regression:test_taxwallet_transferFrom_with_approval_moves_tokens()
- –transferFrom takes exactly the amount out of the sendertest/hidden/regression.t.sol:MCAI_Regression:test_transferFrom_debits_the_sender_exactly()
- –A spender with no approval still cannot move tokenstest/hidden/regression.t.sol:MCAI_Regression:test_unapproved_spender_cannot_move_tokens()
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@@ -35,7 +35,7 @@35353636 function approve(address spender, uint256 amount) external returns (bool);373738− function transferFrom(38+ function transferFromRenamed(3939 address sender,4040 address recipient,4141 uint256 amount
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/mcai_2025_01 \
--patch worked_example/mcai_2025_01/controls/abi_rename_transferFrom/Token.sol \
--backend local --sha256Expected output: core a133c9ddf396a4546015090ced6a0f0229f35526f2b7fb0374e7063acc6add19 and strict 8433f35c387053373af13cf7e033930537b671a06d662051c77f4f07012b977b.
To check a downloaded grade file instead: shasum -a 256 grade.strict.json prints the strict hash.
Control note
from the repositorytransferFrom renamed (removed from the ABI). The contract implements IERC20, so the project stops compiling. Expected: inconclusive/compile_failed, score 0 (a compile failure is never credited as a block).