-
-
[原创]合约安全分析识别ICO骗局
-
2019-4-22 10:24 19946
-
一、 序言
ICO是一种依赖于区块链技术的新型融资方式,具有很多传统融资所不具备的优点,成功的ICO项目往往会给投资者带来高收益。但是,其中也不乏一些打着ICO的名义来诈骗的项目,这些项目会让投资者血本无归。本文从智能合约分析的角度来区别哪些项目是相对靠谱的,哪些项目是有较大安全风险的。
二、 ICO介绍
ICO是一种以初始产生数字加密货币作为投资回报的一种筹措资金的方式,类似于IPO(Initial Public Offering),IPO是通过一个可信的第三方(证券交易所)作为中介来筹措资金,ICO就是通过区块链技术作为可信担保来筹措资金。ICO具有降低融资门槛,流动性强,可全球性融资等优势。他可以让项目在最开始的阶段就直接面对投资者,若项目就有吸引力,那么可快速吸引全球投资者投资,免去了IPO种种繁琐手续和资质审核。
Ethereum(以太坊):ICO时募集3万余个比特币曾创下纪录。将智能合约理念推进到极致的区块链项目,让全世界重新认识区块链公有链的项目。
TheDAO:通过智能合约众筹了1.5亿美元的以太币,但由于合约中存在重入漏洞导致筹集的以太币被黑客窃取
三、 ICO合约安全详解
我们在审计以太坊智能合约时,发现有有些合约是具有ICO功能的。合约创建者编写合约接收投资者投资的以太币,然后返回给投资者一些自己发行的代币。当众筹成功后,合约创建者提取筹到的以太币作为项目的资金。若项目成功,投资者获得项目方的高额回馈。比如,Ethereum 众筹项目,当时众筹时eth作价2-3元转给投资者,若投资者一直持有eth,现在已经涨到1000多块。
但是有好多众筹项目并没有成功,此时投资者手中的代币就一文不值了,投资就打了水漂;甚至有些众筹本身就是个骗局,项目方筹得款项后,就提现跑路了。关于ICO的详解参考下面的链接:https://www.zhihu.com/question/60363636
本文我们从智能合约角度来分析众筹合约的安全性,在我们看来,某些众筹合约在合约代码实现上就像极了一个骗局,根本不值得投资。
我们先看一下,以太坊官方推荐的一个众筹合约的合约代码,链接如下:
https://www.ethereum.org/crowdsale
合约主要代码如下:
constructor(
address ifSuccessfulSendTo,
uint fundingGoalInEthers,
uint durationInMinutes,
uint etherCostOfEachToken,
address addressOfTokenUsedAsReward
) public {
beneficiary = ifSuccessfulSendTo;
fundingGoal = fundingGoalInEthers * 1 ether;
deadline = now + durationInMinutes * 1 minutes;
price = etherCostOfEachToken * 1 ether;
tokenReward = token(addressOfTokenUsedAsReward);
}
上面的构造函数显示了众筹合约的几个关键属性,beneficiary是众筹时项目方收取eth的地址,fundingGoal是所要众筹的eth的数量,deadline是众筹的截止日期,price是eth和众筹代币的价值关系,tokenReward是项目方的代币地址。
function () payable external {
require(!crowdsaleClosed);
uint amount = msg.value;
balanceOf[msg.sender] += amount;
amountRaised += amount;
tokenReward.transfer(msg.sender, amount / price);
emit FundTransfer(msg.sender, amount, true);
}
modifier afterDeadline() { if (now >= deadline) _; }
/**
* Check if goal was reached
*
* Checks if the goal or time limit has been reached and ends the campaign
*/
function checkGoalReached() public afterDeadline {
if (amountRaised >= fundingGoal){
fundingGoalReached = true;
emit GoalReached(beneficiary, amountRaised);
}
crowdsaleClosed = true;
}
/**
* Withdraw the funds
*
* Checks to see if goal or time limit has been reached, and if so, and the funding goal was reached,
* sends the entire amount to the beneficiary. If goal was not reached, each contributor can withdraw
* the amount they contributed.
*/
function safeWithdrawal() public afterDeadline {
if (!fundingGoalReached) {
uint amount = balanceOf[msg.sender];
balanceOf[msg.sender] = 0;
if (amount > 0) {
if (msg.sender.send(amount)) {
emit FundTransfer(msg.sender, amount, false);
} else {
balanceOf[msg.sender] = amount;
}
}
}
if (fundingGoalReached && beneficiary == msg.sender) {
if (msg.sender.send(amountRaised)) {
emit FundTransfer(beneficiary, amountRaised, false);
} else {
//If we fail to send the funds to beneficiary, unlock funders balance
fundingGoalReached = false;
}
}
}
}
上面的代码有3个函数,匿名函数function()payable 项目方用来接收eth,收到eth后,按照兑换比例给投资者转代币。CheckgogalReached用以判断众筹目标是否达成;safeWithdrawal()用来提取众筹的eth,若众筹目标达成,则eth转到项目方;若未达成,则退还eth到投资者。
从上面的合约代码可以看到,一个合理的众筹合约包含以下几个属性:
1 有明确的截止日期(deadline),
2 有明确的众筹数量(fundingGoal)
3 众筹时eth 兑换 代币比例是确定的
4 到deadline后,若众筹未达成,则退还eth给投资者
但是,在我们实际分析合约时,众筹合约写的是五花八门,有的就像后门合约,给投资者带来了极大的安全风险。下面我们就以区块链上的实际合约为例来分析下。
合约一:
https://etherscan.io/address/0xecfbc0c5bc5cf4a266c1a90db0a4fe79c82bcd93#code
众筹是没有fundingGoal的,这也就是说,项目所需的eth的不确定的。
合约筹集来的eth,多来就多得,少来就少得。没有fundingGoal当然也就不会判断否达成众筹目标了,投资者投资的eth只能进合约,根本没办法出合约,只能owner提取eth。
投资者是没有机会提取到投资的eth的。
function HYIPCrowdsale1(
address ifSuccessfulSendTo,
uint deadlineTimestamp,
uint etherCostOfEachToken,
HYIPToken addressOfTokenUsedAsReward
) {
beneficiary = ifSuccessfulSendTo;
deadline = deadlineTimestamp;
price = etherCostOfEachToken;
tokenReward = HYIPToken(addressOfTokenUsedAsReward);
}
/* The function without name is the default function that is called whenever anyone sends funds to a contract */
function () payable {
if (now >= deadline) throw;
uint amount = msg.value;
amountRaised += amount;
tokenReward.mint(msg.sender, amount / price);
}
function safeWithdrawal() onlyOwner {
beneficiary.transfer(amountRaised);
}
modifier onlyOwner() {
if (msg.sender != beneficiary) {
throw;
}
_;
}
合约二:
下面的合约更是“厉害”,上面我们说的标准众筹合约的4个属性,在这个合约里一个都没有,deadline没有,fundingGoal没有,eth/代币兑换比例 由owner随意设置, eth只能进入合约,并由owner提取,在任何情况下都不会返还给投资者。
contract xx is StandardToken, Ownable {
// Constants
string public constant name = "x";
string public constant symbol = "xx";
uint8 public constant decimals = 2;
uint256 public constant INITIAL_SUPPLY = 1000000000 * (10 ** uint256(decimals));
uint public amountRaised;
uint256 public buyPrice = 50000;
bool public crowdsaleClosed;
function xx() public {
totalSupply_ = INITIAL_SUPPLY;
balances[msg.sender] = INITIAL_SUPPLY;
Transfer(0x0, msg.sender, INITIAL_SUPPLY);
}
function setPrices(bool closebuy, uint256 newBuyPrice) onlyOwner public {
crowdsaleClosed = closebuy;
buyPrice = newBuyPrice;
}
function () external payable {
require(!crowdsaleClosed);
uint amount = msg.value ; // calculates the amount
amountRaised = amountRaised.add(amount);
_transfer(owner, msg.sender, amount.mul(buyPrice));
}
function safeWithdrawal(uint _value ) onlyOwner public {
if (_value == 0)
owner.transfer(address(this).balance);
else
owner.transfer(_value);
}
四、 总结
ICO作为一种新的融资方式有很多优点,但是由于流程简单,成本低,监管困难,这也滋生了很多以诈骗为目的的ICO。我们在对一个ICO做安全考量时,除了深入理解项目的背景及项目可信度,从智能合约的角度也可以了解下该项目是真的在做事情,还是在割韭菜。
[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法