-
Notifications
You must be signed in to change notification settings - Fork 565
/
Copy pathKYCCrowdsale.sol
82 lines (63 loc) · 3.13 KB
/
KYCCrowdsale.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
import "./CrowdsaleBase.sol";
import "./AllocatedCrowdsaleMixin.sol";
import "./KYCPayloadDeserializer.sol";
/**
* A crowdsale that allows buys only from signed payload with server-side specified limits and price.
*
* The token distribution happens as in the allocated crowdsale.
*
*/
contract KYCCrowdsale is AllocatedCrowdsaleMixin, KYCPayloadDeserializer {
/* Server holds the private key to this address to sign incoming buy payloads to signal we have KYC records in the books for these users. */
address public signerAddress;
/* A new server-side signer key was set to be effective */
event SignerChanged(address signer);
/**
* Constructor.
*/
function KYCCrowdsale(address _token, PricingStrategy _pricingStrategy, address _multisigWallet, uint _start, uint _end, uint _minimumFundingGoal, address _beneficiary) CrowdsaleBase(_token, _pricingStrategy, _multisigWallet, _start, _end, _minimumFundingGoal) AllocatedCrowdsaleMixin(_beneficiary) {
}
/**
* A token purchase with anti-money laundering
*
* ©return tokenAmount How many tokens where bought
*/
function buyWithKYCData(bytes dataframe, uint8 v, bytes32 r, bytes32 s) public payable returns(uint tokenAmount) {
uint _tokenAmount;
uint multiplier = 10 ** 18;
// Perform signature check for normal addresses
// (not deployment accounts, etc.)
if(earlyParticipantWhitelist[msg.sender]) {
// Deployment provided early participant list is for deployment and diagnostics
// For test purchases use this faux customer id 0x1000
_tokenAmount = investInternal(msg.sender, 0x1000);
} else {
// User comes through the server, check that the signature to ensure ther server
// side KYC has passed for this customer id and whitelisted Ethereum address
bytes32 hash = sha256(dataframe);
var (whitelistedAddress, customerId, minETH, maxETH, pricingInfo) = getKYCPayload(dataframe);
// Check that the KYC data is signed by our server
require(ecrecover(hash, v, r, s) == signerAddress);
// Only whitelisted address can participate the transaction
require(whitelistedAddress == msg.sender);
// Server gives us information what is the buy price for this user
uint256 tokensTotal = calculateTokens(msg.value, pricingInfo);
_tokenAmount = buyTokens(msg.sender, customerId, tokensTotal);
}
if(!earlyParticipantWhitelist[msg.sender]) {
// We assume there is no serious min and max fluctuations for the customer, unless
// especially set in the server side per customer manual override.
// Otherwise the customer can reuse old data payload with different min or max value
// to work around the per customer cap.
require(investedAmountOf[msg.sender] >= minETH * multiplier / 10000);
require(investedAmountOf[msg.sender] <= maxETH * multiplier / 10000);
}
return _tokenAmount;
}
/// @dev This function can set the server side address
/// @param _signerAddress The address derived from server's private key
function setSignerAddress(address _signerAddress) onlyOwner {
signerAddress = _signerAddress;
SignerChanged(signerAddress);
}
}