pragma solidity ^0.6.2;
contract Ico {
mapping(address => uint256) amountMap; // 每个用户众筹数量
uint256 public totalErc20Amount; // 总分发的ERC20数量
uint256 public totalEthAmount; // 众筹的总ETH数量
uint256 public minValue = 1 ether; // 最小金额限制
address payable owner; // 众筹发起人
bool status; // 众筹状态
ERC20 erc20;
constructor() public{
owner = msg.sender;
status = true;
}
// 众筹ETH
function crowdFunding() public payable{
require(status,"crowd funding is close"); // 确保还在众筹阶段
require(msg.value >= minValue,"crowd funding value must be > 1 ether");
amountMap[msg.sender] += msg.value; // 用户众筹金额增加记录账本
uint256 beforeTotalEthAmount = totalEthAmount; // 用来防止溢出攻击
totalEthAmount += msg.value; // 总众筹资产增加
assert(beforeTotalEthAmount <= totalEthAmount); // 防止溢出攻击
}
// 项目方获取众筹资产
function turnOutEth(uint256 _value,address _ercContractAddress) public onlyOwner{
owner.transfer(address(this).balance); // 所有众筹ETH转入项目方钱包地址
erc20 = ERC20(_ercContractAddress); // 初始化ERC20代币合约
bool success = erc20.transferFrom(owner,address(this),_value); // 项目方转入ERC20代币
require(success,"transferFrom is fail"); // 确保转账成功
totalErc20Amount = _value; // 更新用户总分配ERC20数量
status = false; // 众筹结束
}
// 领取代币
function turnOutErc() public{
require(!status,"crowd funding is not close"); // 确保众筹结束
uint256 turnOutAmount = amountMap[msg.sender] * totalErc20Amount / totalEthAmount; // 计算单个用户能得到的ERC20数量
bool success = erc20.transfer(msg.sender,turnOutAmount); // 转出ERC20给用户
require(success,"transfer is fail"); // 确保转账成功
amountMap[msg.sender] = 0; // 预防重复领取
}
// 仅限管理员操作
modifier onlyOwner(){
require(msg.sender == owner, "No authority");
_;
}
}
interface ERC20{
function transfer(address,uint256) external returns(bool);
function transferFrom(address,address,uint256) external returns(bool);
}
网友评论