EOSCrowdsale Contract Inspect
EOS these two days are raised fire, rub a hot, technical analysis of the EOS under the various contracts
project address
Https://github.com/EOSIO/eos-token-distribution
Project catalog
├ ─ ─ Dappfile // dapphub produced intelligent contract development tools
├── Makefile
├── bin
│ └─ deploy/ deploy the script
├── lib // third party dependent
│ ├ ─ ─ ds-auth / / authority control
│ ├ ─ ─ ds-exec
│ ├ ─ ─ ds-guard
│ ├ ─ ─ ds-math / / math operation
│ ├ ─ ─ ds-test / / test framework
│ ├ ─ ─ ds-token // Token framework
│ └── gnosis-multisig
└ ─ ─ src // source code
├ ─ ─ eos.sol
└── eos.t.sol
This project is developed using Dapphub's Smart Contract Development Framework.
Dapphub open source a lot of practical library, greatly simplifying the development costs of smart contracts.
Code analysis
Variable
DSToken public EOS; // EOS Token
Uint128 public totalSupply; // Token total
Uint128 public foundersAllocation; // The development team retains the share
String public foundersKey; // retain the share Holder Address
Uint public openTime; // window 0 start time
Uint public createFirstDay; // window 0 supply
Uint public startTime; // window 1 start time
Uint public numberOfDays; // window total
Uint public createPerDay; // daily supply
EOS ICO rules: the first five days for a window issued a total of 200 million Token. Five days later, every 23 hours for a window, issue 2 million Token.
Issued a total of 1 billion Token.
Constructor
// src / eos.sol
Function EOSSale (
Uint _numberOfDays,
Uint128 _totalSupply,
Uint _openTime,
Uint _startTime,
Uint128 _foundersAllocation,
String _foundersKey
) {
...
// window 0 Token supply
CreateFirstDay = wmul (totalSupply, 0.2 ether);
// window 1 and later daily Token supply
CreatePerDay = div (
Sub (sub (totalSupply, foundersAllocation), createFirstDay),
NumberOfDays
);
...
}
Wmul is a method provided by dapp_math. Dapp_math defines two precision: WAD and RAY, representing the 18-bit and 27-bit precision, respectively.
The beginning of w indicates that the operation has an accuracy of 18 bits.
Since solidity does not have a float type, it is possible to multiply by 0.2 by multiplying by 0.2 ether.
Initialize Token
// src / eos.sol
Function initialize (DSToken eos) auth {
...
EOS = eos;
// set the total supply
EOS.mint (totalSupply);
// keep Token to address 0xb1
EOS.push (0xb1, foundersAllocation);
Keys [0xb1] = foundersKey;
}
The mint method is provided by dapp_token to set the total supply of Token.
The share reserved by the development team is sent to 0xb1. This address is unavailable, equal to the amount of Token lost, but also to ensure that the total supply of Token unchanged.
EOS team does not need this token, because after the EOS line, the current Token will be converted to the EOS chain Token.
Window time
// each window is 23 hours long so that end-of-window rotates
// around the clock for all timezones.
Function dayFor (uint timestamp) constant returns (uint) {
Return timestamp <startTime
? 0
: Sub (timestamp, startTime) / 23 hours 1;
}
The first five days are window 0. After every 23 hours for a window.
The advantage of doing so is to make each window start time is rolling, different time zone investors more convenient to participate.
Buy logic
Function buyWithLimit (uint day, uint limit) payable {
// limit time
Assert (time ()> = openTime ** today () <= numberOfDays);
// minimum purchase price 0.01 ether
Assert (msg.value> = 0.01 ether);
// Purchase History
UserBuys [day] [msg.sender] = msg.value;
DailyTotals [day] = msg.value;
}
Token
Function claim (uint day) {
// prevent duplication
If (claimed [day] [msg.sender] || dailyTotals [day] == 0) {
Return;
}
// this will have small rounding errors, but the token is
// going to be truncated to 8 decimal places or less anyway
// when on its own chain.
Var dailyTotal = cast (dailyTotals [day]);
Var userTotal = cast (userBuys [day] [msg.sender]);
// Specify the Token supply for the window divided by the total amount of eth in this window
// get the conversion ratio
Var price = wdiv (cast (createOnDay (day)), dailyTotal);
// The conversion ratio is multiplied by the number of ethians paid by this user in the specified window
Var reward = wmul (price, userTotal);
// record the redemption flag
Cre [day] [msg.sender] = true;
// Carry out the transfer
EOS.push (msg.sender, reward);
}
Register the EOS co-key
Function register (string key) {
// After the end of the co-ordination no longer provide registration
Assert (today () <= numberOfDays 1);
Assert (bytes (key) .length <= 64);
Keys [msg.sender] = key;
}
The EOS team requires investors to generate their own EOS public and private keys before the end of the co-operation, and register the generated co-key in the contract.
So that after EOS officially on the line, the user can exchange the Token on the EOS.
ETH transfer
Function collect () auth {
// window 0 can not be transferred
Assert (today ()> 0);
// transfer the eth to the caller
Exec (msg.sender, this.balance);
}
Auth is the permission control method provided by dapp_auth, which ensures that the collect function can only be executed by the contract owner.
Security analysis
The EOS co-contracts use the permissions control provided by dapp_auth.
// src / eos.sol
// inherit DSAuth
Contract EOSSale is DSAuth {
}
// lib / ds-auth / src / auth.sol
Contract DSAuth is DSAuthEvents {
DSAuthority public authority;
Address public owner;
Function DSAuth () {
Owner = msg.sender;
}
}
DSAuth provides default permission control based on owner. The default initialization behavior sets the contract creator to owner.
While providing setOwner function, you can transfer control.
Function setOwner (address owner_)
Auth
{
Owner = owner_
LogSetOwner (owner);
}
SetOwner also needs to use auth to verify permissions.
Modifier auth {
Assert (isAuthorized (msg.sender, msg.sig));
_;
}
Function isAuthorized (address src, bytes4 sig)
Internal returns (bool)
{
// If the caller is the contract itself, through.
If (src == address (this)) {
Return true;
// If the caller is owner, pass.
} Else if (src == owner) {
Return true;
// If authority is not set, it fails.
} Else if (authority == DSAuthority (0)) {
Return false
} Else {
// Check if the caller has permission.
Return authority.canCall (src, this, sig);
}