diff --git a/contracts/SNTGiveaway.sol b/contracts/SNTGiveaway.sol index 02e4cdb..81fbeff 100644 --- a/contracts/SNTGiveaway.sol +++ b/contracts/SNTGiveaway.sol @@ -1,971 +1,15 @@ pragma solidity ^0.4.23; -interface ApproveAndCallFallBack { - function receiveApproval( - address from, - uint256 _amount, - address _token, - bytes _data - ) external; -} - - -contract Controlled { - - mapping(address => bool) controllers; - - /// @notice The address of the controller is the only address that can call - /// a function with this modifier - modifier onlyController { - require(controllers[msg.sender]); - _; - } - - address public controller; - - constructor() internal { - controllers[msg.sender] = true; - } - - function changeControllerAccess(address _controller, bool _access) public onlyController { - controllers[_controller] = _access; - } - - function changeController(address _newController) public onlyController { - controllers[msg.sender] = false; - controllers[_newController] = true; - } - -} - - - - - -/* - Copyright 2016, Jordi Baylina - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - */ -/** - * @title MiniMeToken Contract - * @author Jordi Baylina - * @dev This token contract's goal is to make it easy for anyone to clone this - * token using the token distribution at a given block, this will allow DAO's - * and DApps to upgrade their features in a decentralized manner without - * affecting the original token - * @dev It is ERC20 compliant, but still needs to under go further testing. - */ - - - -/** - * @dev The token controller contract must implement these functions - */ -interface TokenController { - /** - * @notice Called when `_owner` sends ether to the MiniMe Token contract - * @param _owner The address that sent the ether to create tokens - * @return True if the ether is accepted, false if it throws - */ - function proxyPayment(address _owner) external payable returns(bool); - - /** - * @notice Notifies the controller about a token transfer allowing the - * controller to react if desired - * @param _from The origin of the transfer - * @param _to The destination of the transfer - * @param _amount The amount of the transfer - * @return False if the controller does not authorize the transfer - */ - function onTransfer(address _from, address _to, uint _amount) external returns(bool); - - /** - * @notice Notifies the controller about an approval allowing the - * controller to react if desired - * @param _owner The address that calls `approve()` - * @param _spender The spender in the `approve()` call - * @param _amount The amount in the `approve()` call - * @return False if the controller does not authorize the approval - */ - function onApprove(address _owner, address _spender, uint _amount) external - returns(bool); -} - - - - - - -// Abstract contract for the full ERC 20 Token standard -// https://github.com/ethereum/EIPs/issues/20 - -interface ERC20Token { - - /** - * @notice send `_value` token to `_to` from `msg.sender` - * @param _to The address of the recipient - * @param _value The amount of token to be transferred - * @return Whether the transfer was successful or not - */ - function transfer(address _to, uint256 _value) external returns (bool success); - - /** - * @notice `msg.sender` approves `_spender` to spend `_value` tokens - * @param _spender The address of the account able to transfer the tokens - * @param _value The amount of tokens to be approved for transfer - * @return Whether the approval was successful or not - */ - function approve(address _spender, uint256 _value) external returns (bool success); - - /** - * @notice send `_value` token to `_to` from `_from` on the condition it is approved by `_from` - * @param _from The address of the sender - * @param _to The address of the recipient - * @param _value The amount of token to be transferred - * @return Whether the transfer was successful or not - */ - function transferFrom(address _from, address _to, uint256 _value) external returns (bool success); - - /** - * @param _owner The address from which the balance will be retrieved - * @return The balance - */ - function balanceOf(address _owner) external view returns (uint256 balance); - - /** - * @param _owner The address of the account owning tokens - * @param _spender The address of the account able to transfer the tokens - * @return Amount of remaining tokens allowed to spent - */ - function allowance(address _owner, address _spender) external view returns (uint256 remaining); - - /** - * @notice return total supply of tokens - */ - function totalSupply() external view returns (uint256 supply); - - event Transfer(address indexed _from, address indexed _to, uint256 _value); - event Approval(address indexed _owner, address indexed _spender, uint256 _value); -} - - -contract MiniMeTokenInterface is ERC20Token { - - /** - * @notice `msg.sender` approves `_spender` to send `_amount` tokens on - * its behalf, and then a function is triggered in the contract that is - * being approved, `_spender`. This allows users to use their tokens to - * interact with contracts in one function call instead of two - * @param _spender The address of the contract able to transfer the tokens - * @param _amount The amount of tokens to be approved for transfer - * @return True if the function call was successful - */ - function approveAndCall( - address _spender, - uint256 _amount, - bytes _extraData - ) - external - returns (bool success); - - /** - * @notice Creates a new clone token with the initial distribution being - * this token at `_snapshotBlock` - * @param _cloneTokenName Name of the clone token - * @param _cloneDecimalUnits Number of decimals of the smallest unit - * @param _cloneTokenSymbol Symbol of the clone token - * @param _snapshotBlock Block when the distribution of the parent token is - * copied to set the initial distribution of the new clone token; - * if the block is zero than the actual block, the current block is used - * @param _transfersEnabled True if transfers are allowed in the clone - * @return The address of the new MiniMeToken Contract - */ - function createCloneToken( - string _cloneTokenName, - uint8 _cloneDecimalUnits, - string _cloneTokenSymbol, - uint _snapshotBlock, - bool _transfersEnabled - ) - public - returns(address); - - /** - * @notice Generates `_amount` tokens that are assigned to `_owner` - * @param _owner The address that will be assigned the new tokens - * @param _amount The quantity of tokens generated - * @return True if the tokens are generated correctly - */ - function generateTokens( - address _owner, - uint _amount - ) - public - returns (bool); - - /** - * @notice Burns `_amount` tokens from `_owner` - * @param _owner The address that will lose the tokens - * @param _amount The quantity of tokens to burn - * @return True if the tokens are burned correctly - */ - function destroyTokens( - address _owner, - uint _amount - ) - public - returns (bool); - - /** - * @notice Enables token holders to transfer their tokens freely if true - * @param _transfersEnabled True if transfers are allowed in the clone - */ - function enableTransfers(bool _transfersEnabled) public; - - /** - * @notice This method can be used by the controller to extract mistakenly - * sent tokens to this contract. - * @param _token The address of the token contract that you want to recover - * set to 0 in case you want to extract ether. - */ - function claimTokens(address _token) public; - - /** - * @dev Queries the balance of `_owner` at a specific `_blockNumber` - * @param _owner The address from which the balance will be retrieved - * @param _blockNumber The block number when the balance is queried - * @return The balance at `_blockNumber` - */ - function balanceOfAt( - address _owner, - uint _blockNumber - ) - public - constant - returns (uint); - - /** - * @notice Total amount of tokens at a specific `_blockNumber`. - * @param _blockNumber The block number when the totalSupply is queried - * @return The total amount of tokens at `_blockNumber` - */ - function totalSupplyAt(uint _blockNumber) public view returns(uint); - -} - - - - -//////////////// -// MiniMeTokenFactory -//////////////// - -/** - * @dev This contract is used to generate clone contracts from a contract. - * In solidity this is the way to create a contract from a contract of the - * same class - */ -contract MiniMeTokenFactory { - - /** - * @notice Update the DApp by creating a new token with new functionalities - * the msg.sender becomes the controller of this clone token - * @param _parentToken Address of the token being cloned - * @param _snapshotBlock Block of the parent token that will - * determine the initial distribution of the clone token - * @param _tokenName Name of the new token - * @param _decimalUnits Number of decimals of the new token - * @param _tokenSymbol Token Symbol for the new token - * @param _transfersEnabled If true, tokens will be able to be transferred - * @return The address of the new token contract - */ - function createCloneToken( - address _parentToken, - uint _snapshotBlock, - string _tokenName, - uint8 _decimalUnits, - string _tokenSymbol, - bool _transfersEnabled - ) public returns (MiniMeToken) { - MiniMeToken newToken = new MiniMeToken( - this, - _parentToken, - _snapshotBlock, - _tokenName, - _decimalUnits, - _tokenSymbol, - _transfersEnabled - ); - - newToken.changeController(msg.sender); - return newToken; - } -} - -/** - * @dev The actual token contract, the default controller is the msg.sender - * that deploys the contract, so usually this token will be deployed by a - * token controller contract, which Giveth will call a "Campaign" - */ -contract MiniMeToken is MiniMeTokenInterface, Controlled { - - string public name; //The Token's name: e.g. DigixDAO Tokens - uint8 public decimals; //Number of decimals of the smallest unit - string public symbol; //An identifier: e.g. REP - string public version = "MMT_0.1"; //An arbitrary versioning scheme - - /** - * @dev `Checkpoint` is the structure that attaches a block number to a - * given value, the block number attached is the one that last changed the - * value - */ - struct Checkpoint { - - // `fromBlock` is the block number that the value was generated from - uint128 fromBlock; - - // `value` is the amount of tokens at a specific block number - uint128 value; - } - - // `parentToken` is the Token address that was cloned to produce this token; - // it will be 0x0 for a token that was not cloned - MiniMeToken public parentToken; - - // `parentSnapShotBlock` is the block number from the Parent Token that was - // used to determine the initial distribution of the Clone Token - uint public parentSnapShotBlock; - - // `creationBlock` is the block number that the Clone Token was created - uint public creationBlock; - - // `balances` is the map that tracks the balance of each address, in this - // contract when the balance changes the block number that the change - // occurred is also included in the map - mapping (address => Checkpoint[]) balances; - - // `allowed` tracks any extra transfer rights as in all ERC20 tokens - mapping (address => mapping (address => uint256)) allowed; - - // Tracks the history of the `totalSupply` of the token - Checkpoint[] totalSupplyHistory; - - // Flag that determines if the token is transferable or not. - bool public transfersEnabled; - - // The factory used to create new clone tokens - MiniMeTokenFactory public tokenFactory; - -//////////////// -// Constructor -//////////////// - - /** - * @notice Constructor to create a MiniMeToken - * @param _tokenFactory The address of the MiniMeTokenFactory contract that - * will create the Clone token contracts, the token factory needs to be - * deployed first - * @param _parentToken Address of the parent token, set to 0x0 if it is a - * new token - * @param _parentSnapShotBlock Block of the parent token that will - * determine the initial distribution of the clone token, set to 0 if it - * is a new token - * @param _tokenName Name of the new token - * @param _decimalUnits Number of decimals of the new token - * @param _tokenSymbol Token Symbol for the new token - * @param _transfersEnabled If true, tokens will be able to be transferred - */ - constructor( - address _tokenFactory, - address _parentToken, - uint _parentSnapShotBlock, - string _tokenName, - uint8 _decimalUnits, - string _tokenSymbol, - bool _transfersEnabled - ) - public - { - require(_tokenFactory != address(0)); //if not set, clone feature will not work properly - tokenFactory = MiniMeTokenFactory(_tokenFactory); - name = _tokenName; // Set the name - decimals = _decimalUnits; // Set the decimals - symbol = _tokenSymbol; // Set the symbol - parentToken = MiniMeToken(_parentToken); - parentSnapShotBlock = _parentSnapShotBlock; - transfersEnabled = _transfersEnabled; - creationBlock = block.number; - } - - -/////////////////// -// ERC20 Methods -/////////////////// - - /** - * @notice Send `_amount` tokens to `_to` from `msg.sender` - * @param _to The address of the recipient - * @param _amount The amount of tokens to be transferred - * @return Whether the transfer was successful or not - */ - function transfer(address _to, uint256 _amount) public returns (bool success) { - require(transfersEnabled); - return doTransfer(msg.sender, _to, _amount); - } - - /** - * @notice Send `_amount` tokens to `_to` from `_from` on the condition it - * is approved by `_from` - * @param _from The address holding the tokens being transferred - * @param _to The address of the recipient - * @param _amount The amount of tokens to be transferred - * @return True if the transfer was successful - */ - function transferFrom( - address _from, - address _to, - uint256 _amount - ) - public - returns (bool success) - { - - // The controller of this contract can move tokens around at will, - // this is important to recognize! Confirm that you trust the - // controller of this contract, which in most situations should be - // another open source smart contract or 0x0 - if (msg.sender != controller) { - require(transfersEnabled); - - // The standard ERC 20 transferFrom functionality - if (allowed[_from][msg.sender] < _amount) { - return false; - } - allowed[_from][msg.sender] -= _amount; - } - return doTransfer(_from, _to, _amount); - } - - /** - * @dev This is the actual transfer function in the token contract, it can - * only be called by other functions in this contract. - * @param _from The address holding the tokens being transferred - * @param _to The address of the recipient - * @param _amount The amount of tokens to be transferred - * @return True if the transfer was successful - */ - function doTransfer( - address _from, - address _to, - uint _amount - ) - internal - returns(bool) - { - - if (_amount == 0) { - return true; - } - - require(parentSnapShotBlock < block.number); - - // Do not allow transfer to 0x0 or the token contract itself - require((_to != 0) && (_to != address(this))); - - // If the amount being transfered is more than the balance of the - // account the transfer returns false - uint256 previousBalanceFrom = balanceOfAt(_from, block.number); - if (previousBalanceFrom < _amount) { - return false; - } - - // Alerts the token controller of the transfer - if (isContract(controller)) { - require(TokenController(controller).onTransfer(_from, _to, _amount)); - } - - // First update the balance array with the new value for the address - // sending the tokens - updateValueAtNow(balances[_from], previousBalanceFrom - _amount); - - // Then update the balance array with the new value for the address - // receiving the tokens - uint256 previousBalanceTo = balanceOfAt(_to, block.number); - require(previousBalanceTo + _amount >= previousBalanceTo); // Check for overflow - updateValueAtNow(balances[_to], previousBalanceTo + _amount); - - // An event to make the transfer easy to find on the blockchain - emit Transfer(_from, _to, _amount); - - return true; - } - - function doApprove( - address _from, - address _spender, - uint256 _amount - ) - internal - returns (bool) - { - require(transfersEnabled); - - // To change the approve amount you first have to reduce the addresses` - // allowance to zero by calling `approve(_spender,0)` if it is not - // already 0 to mitigate the race condition described here: - // https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 - require((_amount == 0) || (allowed[_from][_spender] == 0)); - - // Alerts the token controller of the approve function call - if (isContract(controller)) { - require(TokenController(controller).onApprove(_from, _spender, _amount)); - } - - allowed[_from][_spender] = _amount; - emit Approval(_from, _spender, _amount); - return true; - } - - /** - * @param _owner The address that's balance is being requested - * @return The balance of `_owner` at the current block - */ - function balanceOf(address _owner) external view returns (uint256 balance) { - return balanceOfAt(_owner, block.number); - } - - /** - * @notice `msg.sender` approves `_spender` to spend `_amount` tokens on - * its behalf. This is a modified version of the ERC20 approve function - * to be a little bit safer - * @param _spender The address of the account able to transfer the tokens - * @param _amount The amount of tokens to be approved for transfer - * @return True if the approval was successful - */ - function approve(address _spender, uint256 _amount) external returns (bool success) { - doApprove(msg.sender, _spender, _amount); - } - - /** - * @dev This function makes it easy to read the `allowed[]` map - * @param _owner The address of the account that owns the token - * @param _spender The address of the account able to transfer the tokens - * @return Amount of remaining tokens of _owner that _spender is allowed - * to spend - */ - function allowance( - address _owner, - address _spender - ) - external - view - returns (uint256 remaining) - { - return allowed[_owner][_spender]; - } - /** - * @notice `msg.sender` approves `_spender` to send `_amount` tokens on - * its behalf, and then a function is triggered in the contract that is - * being approved, `_spender`. This allows users to use their tokens to - * interact with contracts in one function call instead of two - * @param _spender The address of the contract able to transfer the tokens - * @param _amount The amount of tokens to be approved for transfer - * @return True if the function call was successful - */ - function approveAndCall( - address _spender, - uint256 _amount, - bytes _extraData - ) - external - returns (bool success) - { - require(doApprove(msg.sender, _spender, _amount)); - - ApproveAndCallFallBack(_spender).receiveApproval( - msg.sender, - _amount, - this, - _extraData - ); - - return true; - } - - /** - * @dev This function makes it easy to get the total number of tokens - * @return The total number of tokens - */ - function totalSupply() external view returns (uint) { - return totalSupplyAt(block.number); - } - - -//////////////// -// Query balance and totalSupply in History -//////////////// - - /** - * @dev Queries the balance of `_owner` at a specific `_blockNumber` - * @param _owner The address from which the balance will be retrieved - * @param _blockNumber The block number when the balance is queried - * @return The balance at `_blockNumber` - */ - function balanceOfAt( - address _owner, - uint _blockNumber - ) - public - view - returns (uint) - { - - // These next few lines are used when the balance of the token is - // requested before a check point was ever created for this token, it - // requires that the `parentToken.balanceOfAt` be queried at the - // genesis block for that token as this contains initial balance of - // this token - if ((balances[_owner].length == 0) || (balances[_owner][0].fromBlock > _blockNumber)) { - if (address(parentToken) != 0) { - return parentToken.balanceOfAt(_owner, min(_blockNumber, parentSnapShotBlock)); - } else { - // Has no parent - return 0; - } - - // This will return the expected balance during normal situations - } else { - return getValueAt(balances[_owner], _blockNumber); - } - } - - /** - * @notice Total amount of tokens at a specific `_blockNumber`. - * @param _blockNumber The block number when the totalSupply is queried - * @return The total amount of tokens at `_blockNumber` - */ - function totalSupplyAt(uint _blockNumber) public view returns(uint) { - - // These next few lines are used when the totalSupply of the token is - // requested before a check point was ever created for this token, it - // requires that the `parentToken.totalSupplyAt` be queried at the - // genesis block for this token as that contains totalSupply of this - // token at this block number. - if ((totalSupplyHistory.length == 0) || (totalSupplyHistory[0].fromBlock > _blockNumber)) { - if (address(parentToken) != 0) { - return parentToken.totalSupplyAt(min(_blockNumber, parentSnapShotBlock)); - } else { - return 0; - } - - // This will return the expected totalSupply during normal situations - } else { - return getValueAt(totalSupplyHistory, _blockNumber); - } - } - -//////////////// -// Clone Token Method -//////////////// - - /** - * @notice Creates a new clone token with the initial distribution being - * this token at `_snapshotBlock` - * @param _cloneTokenName Name of the clone token - * @param _cloneDecimalUnits Number of decimals of the smallest unit - * @param _cloneTokenSymbol Symbol of the clone token - * @param _snapshotBlock Block when the distribution of the parent token is - * copied to set the initial distribution of the new clone token; - * if the block is zero than the actual block, the current block is used - * @param _transfersEnabled True if transfers are allowed in the clone - * @return The address of the new MiniMeToken Contract - */ - function createCloneToken( - string _cloneTokenName, - uint8 _cloneDecimalUnits, - string _cloneTokenSymbol, - uint _snapshotBlock, - bool _transfersEnabled - ) - public - returns(address) - { - uint snapshotBlock = _snapshotBlock; - if (snapshotBlock == 0) { - snapshotBlock = block.number; - } - MiniMeToken cloneToken = tokenFactory.createCloneToken( - this, - snapshotBlock, - _cloneTokenName, - _cloneDecimalUnits, - _cloneTokenSymbol, - _transfersEnabled - ); - - cloneToken.changeController(msg.sender); - - // An event to make the token easy to find on the blockchain - emit NewCloneToken(address(cloneToken), snapshotBlock); - return address(cloneToken); - } - -//////////////// -// Generate and destroy tokens -//////////////// - - /** - * @notice Generates `_amount` tokens that are assigned to `_owner` - * @param _owner The address that will be assigned the new tokens - * @param _amount The quantity of tokens generated - * @return True if the tokens are generated correctly - */ - function generateTokens( - address _owner, - uint _amount - ) - public - onlyController - returns (bool) - { - uint curTotalSupply = totalSupplyAt(block.number); - require(curTotalSupply + _amount >= curTotalSupply); // Check for overflow - uint previousBalanceTo = balanceOfAt(_owner, block.number); - require(previousBalanceTo + _amount >= previousBalanceTo); // Check for overflow - updateValueAtNow(totalSupplyHistory, curTotalSupply + _amount); - updateValueAtNow(balances[_owner], previousBalanceTo + _amount); - emit Transfer(0, _owner, _amount); - return true; - } - - /** - * @notice Burns `_amount` tokens from `_owner` - * @param _owner The address that will lose the tokens - * @param _amount The quantity of tokens to burn - * @return True if the tokens are burned correctly - */ - function destroyTokens( - address _owner, - uint _amount - ) - public - onlyController - returns (bool) - { - uint curTotalSupply = totalSupplyAt(block.number); - require(curTotalSupply >= _amount); - uint previousBalanceFrom = balanceOfAt(_owner, block.number); - require(previousBalanceFrom >= _amount); - updateValueAtNow(totalSupplyHistory, curTotalSupply - _amount); - updateValueAtNow(balances[_owner], previousBalanceFrom - _amount); - emit Transfer(_owner, 0, _amount); - return true; - } - -//////////////// -// Enable tokens transfers -//////////////// - - /** - * @notice Enables token holders to transfer their tokens freely if true - * @param _transfersEnabled True if transfers are allowed in the clone - */ - function enableTransfers(bool _transfersEnabled) public onlyController { - transfersEnabled = _transfersEnabled; - } - -//////////////// -// Internal helper functions to query and set a value in a snapshot array -//////////////// - - /** - * @dev `getValueAt` retrieves the number of tokens at a given block number - * @param checkpoints The history of values being queried - * @param _block The block number to retrieve the value at - * @return The number of tokens being queried - */ - function getValueAt( - Checkpoint[] storage checkpoints, - uint _block - ) - view - internal - returns (uint) - { - if (checkpoints.length == 0) { - return 0; - } - - // Shortcut for the actual value - if (_block >= checkpoints[checkpoints.length-1].fromBlock) { - return checkpoints[checkpoints.length-1].value; - } - if (_block < checkpoints[0].fromBlock) { - return 0; - } - - // Binary search of the value in the array - uint min = 0; - uint max = checkpoints.length-1; - while (max > min) { - uint mid = (max + min + 1) / 2; - if (checkpoints[mid].fromBlock<=_block) { - min = mid; - } else { - max = mid-1; - } - } - return checkpoints[min].value; - } - - /** - * @dev `updateValueAtNow` used to update the `balances` map and the - * `totalSupplyHistory` - * @param checkpoints The history of data being updated - * @param _value The new number of tokens - */ - function updateValueAtNow(Checkpoint[] storage checkpoints, uint _value) internal { - if ( - (checkpoints.length == 0) || - (checkpoints[checkpoints.length - 1].fromBlock < block.number)) - { - Checkpoint storage newCheckPoint = checkpoints[checkpoints.length++]; - newCheckPoint.fromBlock = uint128(block.number); - newCheckPoint.value = uint128(_value); - } else { - Checkpoint storage oldCheckPoint = checkpoints[checkpoints.length-1]; - oldCheckPoint.value = uint128(_value); - } - } - - /** - * @dev Internal function to determine if an address is a contract - * @param _addr The address being queried - * @return True if `_addr` is a contract - */ - function isContract(address _addr) internal view returns(bool) { - uint size; - if (_addr == 0) { - return false; - } - assembly { - size := extcodesize(_addr) - } - return size > 0; - } - - /** - * @dev Helper function to return a min betwen the two uints - */ - function min(uint a, uint b) internal returns (uint) { - return a < b ? a : b; - } - - /** - * @notice The fallback function: If the contract's controller has not been - * set to 0, then the `proxyPayment` method is called which relays the - * ether and creates tokens as described in the token controller contract - */ - function () public payable { - require(isContract(controller)); - require(TokenController(controller).proxyPayment.value(msg.value)(msg.sender)); - } - -////////// -// Safety Methods -////////// - - /** - * @notice This method can be used by the controller to extract mistakenly - * sent tokens to this contract. - * @param _token The address of the token contract that you want to recover - * set to 0 in case you want to extract ether. - */ - function claimTokens(address _token) public onlyController { - if (_token == 0x0) { - controller.transfer(address(this).balance); - return; - } - - MiniMeToken token = MiniMeToken(_token); - uint balance = token.balanceOf(address(this)); - token.transfer(controller, balance); - emit ClaimedTokens(_token, controller, balance); - } - -//////////////// -// Events -//////////////// - event ClaimedTokens(address indexed _token, address indexed _controller, uint _amount); - event Transfer(address indexed _from, address indexed _to, uint256 _amount); - event NewCloneToken(address indexed _cloneToken, uint snapshotBlock); - event Approval( - address indexed _owner, - address indexed _spender, - uint256 _amount - ); - -} -/** - * @title MerkleProof - * @dev Merkle proof verification based on - * https://github.com/ameensol/merkle-tree-solidity/blob/master/src/MerkleProof.sol - */ -library MerkleProof { - /** - * @dev Verifies a Merkle proof proving the existence of a leaf in a Merkle tree. Assumes that each pair of leaves - * and each pair of pre-images are sorted. - * @param _proof Merkle proof containing sibling hashes on the branch from the leaf to the root of the Merkle tree - * @param _root Merkle root - * @param _leaf Leaf of Merkle tree - */ - function verifyProof( - bytes32[] _proof, - bytes32 _root, - bytes32 _leaf - ) - internal - pure - returns (bool) - { - bytes32 computedHash = _leaf; - - for (uint256 i = 0; i < _proof.length; i++) { - bytes32 proofElement = _proof[i]; - - if (computedHash < proofElement) { - // Hash(current computed hash + current element of the proof) - computedHash = keccak256(abi.encodePacked(computedHash, proofElement)); - } else { - // Hash(current element of the proof + current computed hash) - computedHash = keccak256(abi.encodePacked(proofElement, computedHash)); - } - } - - // Check if the computed hash (root) is equal to the provided root - return computedHash == _root; - } -} - +import "./common/MerkleProof.sol"; +import "./common/Controlled.sol"; +import "./token/ERC20Token.sol"; contract SNTGiveaway is Controlled { mapping(address => bool) public sentToAddress; mapping(bytes5 => bool) public codeUsed; - MiniMeToken public SNT; + ERC20Token public SNT; uint public ethAmount; uint public sntAmount; @@ -979,7 +23,7 @@ contract SNTGiveaway is Controlled { /// @param _sntAmount uint Amount of SNT in wei to send /// @param _root bytes32 Merkle tree root constructor(address _sntAddress, uint _ethAmount, uint _sntAmount, bytes32 _root) public { - SNT = MiniMeToken(_sntAddress); + SNT = ERC20Token(_sntAddress); ethAmount = _ethAmount; sntAmount = _sntAmount; root = _root; diff --git a/contracts/common/Controlled.sol b/contracts/common/Controlled.sol index 889270e..b78dcea 100644 --- a/contracts/common/Controlled.sol +++ b/contracts/common/Controlled.sol @@ -2,7 +2,7 @@ pragma solidity ^0.4.23; contract Controlled { - mapping(address => bool) controllers; + mapping(address => bool) public controllers; /// @notice The address of the controller is the only address that can call /// a function with this modifier @@ -15,6 +15,7 @@ contract Controlled { constructor() internal { controllers[msg.sender] = true; + controller = msg.sender; } function changeControllerAccess(address _controller, bool _access) public onlyController {