Skip to content

pragma solidity ^ 0.4.17; library SafeMath { function mul(uint a, uint b) internal pure returns(uint) { uint c = a * b; assert(a == 0 || c / a == b); return c; } function sub(uint a, uint b) internal pure returns(uint) { assert(b <= a); return a - b; } function add(uint a, uint b) internal pure returns(uint) { uint c = a + b; assert(c >= a && c …

Notifications You must be signed in to change notification settings

makinternational/MAK

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 

Repository files navigation

pragma solidity ^ 0.4.17;

library SafeMath {

function mul(uint a, uint b) internal pure returns(uint) {
    uint c = a * b;
    assert(a == 0 || c / a == b);
    return c;
}

function sub(uint a, uint b) internal pure  returns(uint) {
    assert(b <= a);
    return a - b;
}

function add(uint a, uint b) internal  pure returns(uint) {
    uint c = a + b;
    assert(c >= a && c >= b);
    return c;
}

}

contract ERC20 { uint public totalSupply;

function balanceOf(address who) public view returns(uint);

function allowance(address owner, address spender) public view returns(uint);

function transfer(address to, uint value) public returns(bool ok);

function transferFrom(address from, address to, uint value) public returns(bool ok);

function approve(address spender, uint value) public returns(bool ok);

event Transfer(address indexed from, address indexed to, uint value);
event Approval(address indexed owner, address indexed spender, uint value);

}

/**

  • @title Ownable

  • @dev The Ownable contract has an owner address, and provides basic authorization control

  • functions, this simplifies the implementation of "user permissions". */ contract Ownable {

    address public owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**

    • @dev The Ownable constructor sets the original owner of the contract to the sender
    • account. */ function Ownable() public { owner = msg.sender; }

    /**

    • @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(msg.sender == owner); _; }

    /**

    • @dev Allows the current owner to transfer control of the contract to a newOwner.
    • @param newOwner The address to transfer ownership to. */ function transferOwnership(address newOwner) onlyOwner public { require(newOwner != address(0)); OwnershipTransferred(owner, newOwner); owner = newOwner; }

}

/**

  • @title Pausable

  • @dev Base contract which allows children to implement an emergency stop mechanism. */ contract Pausable is Ownable { event Pause(); event Unpause();

    bool public paused = false;

/**

  • @dev Modifier to make a function callable only when the contract is not paused. */ modifier whenNotPaused() { require(!paused); _; }

/**

  • @dev Modifier to make a function callable only when the contract is paused. */ modifier whenPaused() { require(paused); _; }

/**

  • @dev called by the owner to pause, triggers stopped state */ function pause() public onlyOwner whenNotPaused { paused = true; Pause(); }

/**

  • @dev called by the owner to unpause, returns to normal state */ function unpause() public onlyOwner whenPaused { paused = false; Unpause(); } }

// Whitelist smart contract // This smart contract keeps list of addresses to whitelist contract WhiteList is Ownable {

mapping(address => bool) public whiteList;
uint public totalWhiteListed; //white listed users number

event LogWhiteListed(address indexed user, uint whiteListedNum);
event LogWhiteListedMultiple(uint whiteListedNum);
event LogRemoveWhiteListed(address indexed user);

// @notice it will return status of white listing
// @return true if user is white listed and false if is not
function isWhiteListed(address _user) external view returns (bool) {

    return whiteList[_user]; 
}

// @notice it will remove whitelisted user
// @param _contributor {address} of user to unwhitelist
function removeFromWhiteList(address _user) external onlyOwner() returns (bool) {
   
    require(whiteList[_user] == true);
    whiteList[_user] = false;
    totalWhiteListed--;
    LogRemoveWhiteListed(_user);
    return true;
}

// @notice it will white list one member
// @param _user {address} of user to whitelist
// @return true if successful
function addToWhiteList(address _user) external onlyOwner()  returns (bool) {

    if (whiteList[_user] != true) {
        whiteList[_user] = true;
        totalWhiteListed++;
        LogWhiteListed(_user, totalWhiteListed);            
    }
    return true;
}

// @notice it will white list multiple members
// @param _user {address[]} of users to whitelist
// @return true if successful
function addToWhiteListMultiple(address[] _users) external onlyOwner()  returns (bool) {

    for (uint i = 0; i < _users.length; ++i) {

        if (whiteList[_users[i]] != true) {
            whiteList[_users[i]] = true;
            totalWhiteListed++;                          
        }           
    }
    LogWhiteListedMultiple(totalWhiteListed); 
    return true;
}

}

// @note this contract can be inherited by Crowdsale and TeamAllocation contracts and // control release of tokens through even time release based on the inputted duration time interval contract TokenVesting is Ownable { using SafeMath for uint;

struct TokenHolder {
    uint weiReceived; // amount of ETH contributed
    uint tokensToSend; // amount of tokens  sent  
    bool refunded; // true if user has been refunded       
    uint releasedAmount; // amount released through vesting schedule
    bool revoked; // true if right to continue vesting is revoked
}

event Released(uint256 amount, uint256 tokenDecimals);
event ContractUpdated(bool done);

uint256 public cliff;  // time in  when vesting should begin
uint256 public startCountDown;  // time when countdown starts
uint256 public duration; // duration of period in which vesting takes place   
Token public token;  // token contract containing tokens
mapping(address => TokenHolder) public tokenHolders; //tokenHolder list
WhiteList public whiteList; // whitelist contract
uint256 public presaleBonus;

// @note constructor 
/**
function TokenVesting(uint256 _start, uint256 _cliff, uint256 _duration) public {   
     require(_cliff <= _duration);   
    duration = _duration;
    cliff = _start.add(_cliff);
    startCountDown = _start;         
    ContractUpdated(true);                    
}
*/
// @notice Specify address of token contract
// @param _tokenAddress {address} address of token contract
// @return res {bool}
function initilizeVestingAndTokenAndWhiteList(Token _tokenAddress, 
                                    uint256 _start, 
                                    uint256 _cliff, 
                                    uint256 _duration,
                                    uint256 _presaleBonus, 
                                    WhiteList _whiteList) external onlyOwner() returns(bool res) {
    require(_cliff <= _duration);   
    require(_tokenAddress != address(0));
    duration = _duration;
    cliff = _start.add(_cliff);
    startCountDown = _start;  
    token = _tokenAddress; 
    whiteList = _whiteList;
    presaleBonus = _presaleBonus;
    ContractUpdated(true);
    return true;    
}

// @notice Specify address of token contract
// @param _tokenAddress {address} address of token contract
// @return res {bool}
function initilizeVestingAndToken(Token _tokenAddress, 
                                    uint256 _start, 
                                    uint256 _cliff, 
                                    uint256 _duration,
                                    uint256 _presaleBonus
                                    ) external onlyOwner() returns(bool res) {
    require(_cliff <= _duration);   
    require(_tokenAddress != address(0));
    duration = _duration;
    cliff = _start.add(_cliff);
    startCountDown = _start;  
    token = _tokenAddress;        
    presaleBonus = _presaleBonus;
    ContractUpdated(true);
    return true;    
}

function returnVestingSchedule() external view returns (uint, uint, uint) {

    return (duration, cliff, startCountDown);
}

// @note owner can revoke access to continue vesting of tokens
// @param _user {address} of user to revoke their right to vesting
function revoke(address _user) public onlyOwner() {

    TokenHolder storage tokenHolder = tokenHolders[_user];
    tokenHolder.revoked = true; 
}

function vestedAmountAvailable() public view returns (uint amount, uint decimals) {

    TokenHolder storage tokenHolder = tokenHolders[msg.sender];
    uint tokensToRelease = vestedAmount(tokenHolder.tokensToSend);

 //   if (tokenHolder.releasedAmount + tokensToRelease > tokenHolder.tokensToSend)
  //      return (tokenHolder.tokensToSend - tokenHolder.releasedAmount, token.decimals());
 //   else 
    return (tokensToRelease - tokenHolder.releasedAmount, token.decimals());
}

// @notice Transfers vested available tokens to beneficiary   
function release() public {

    TokenHolder storage tokenHolder = tokenHolders[msg.sender];        
    // check if right to vesting is not revoked
    require(!tokenHolder.revoked);                                   
    uint tokensToRelease = vestedAmount(tokenHolder.tokensToSend);      
    uint currentTokenToRelease = tokensToRelease - tokenHolder.releasedAmount;
    tokenHolder.releasedAmount += currentTokenToRelease;            
    token.transfer(msg.sender, currentTokenToRelease);

    Released(currentTokenToRelease, token.decimals());
}

// @notice this function will determine vested amount
// @param _totalBalance {uint} total balance of tokens assigned to this user
// @return {uint} amount of tokens available to transfer
function vestedAmount(uint _totalBalance) public view returns (uint) {

    if (now < cliff) {
        return 0;
    } else if (now >= startCountDown.add(duration)) {
        return _totalBalance;
    } else {
        return _totalBalance.mul(now.sub(startCountDown)) / duration;
    }
}

}

// Crowdsale Smart Contract // This smart contract collects ETH and in return sends tokens to the Backers contract Crowdsale is Pausable, TokenVesting {

using SafeMath for uint;

address public multisigETH; // Multisig contract that will receive the ETH
address public commissionAddress;  // address to deposit commissions
uint public tokensForTeam; // tokens for the team
uint public ethReceivedPresale; // Number of ETH received in presale
uint public ethReceivedMain; // Number of ETH received in main sale
uint public totalTokensSent; // Number of tokens sent to ETH contributors
uint public tokensSentMain;
uint public tokensSentPresale;       
uint public tokensSentDev;         
uint public startBlock; // Crowdsale start block
uint public endBlock; // Crowdsale end block
uint public maxCap; // Maximum number of token to sell
uint public minCap; // Minimum number of ETH to raise
uint public minContributionMainSale; // Minimum amount to contribute in main sale
uint public minContributionPresale; // Minimum amount to contribut in presale
uint public maxContribution;
bool public crowdsaleClosed; // Is crowdsale still on going
uint public tokenPriceWei;
uint public refundCount;
uint public totalRefunded;
uint public campaignDurationDays; // campaign duration in days 
uint public firstPeriod; 
uint public secondPeriod; 
uint public thirdPeriod; 
uint public firstBonus; 
uint public secondBonus;
uint public thirdBonus;
uint public multiplier;
uint public status;    
Step public currentStep;  // To allow for controlled steps of the campaign 

// Looping through Backer
//mapping(address => Backer) public backers; //backer list
address[] public holdersIndex;   // to be able to itarate through backers when distributing the tokens
address[] public devIndex;   // to be able to itarate through backers when distributing the tokens

// @notice to set and determine steps of crowdsale
enum Step {      
    FundingPreSale,     // presale mode
    FundingMainSale,  // public mode
    Refunding  // in case campaign failed during this step contributors will be able to receive refunds
}

// @notice to verify if action is not performed out of the campaing range
modifier respectTimeFrame() {
    if ((block.number < startBlock) || (block.number > endBlock)) 
        revert();
    _;
}

modifier minCapNotReached() {
    if (totalTokensSent >= minCap) 
        revert();
    _;
}

// Events
event LogReceivedETH(address indexed backer, uint amount, uint tokenAmount);
event LogStarted(uint startBlockLog, uint endBlockLog);
event LogFinalized(bool success);  
event LogRefundETH(address indexed backer, uint amount);
event LogStepAdvanced();
event LogDevTokensAllocated(address indexed dev, uint amount);
event LogNonVestedTokensSent(address indexed user, uint amount);

// Crowdsale  {constructor}
// @notice fired when contract is crated. Initilizes all constnat variables.
function Crowdsale(uint _decimalPoints,
                    address _multisigETH,
                    uint _toekensForTeam, 
                    uint _minContributionPresale,
                    uint _minContributionMainSale,
                    uint _maxContribution,                        
                    uint _maxCap, 
                    uint _minCap, 
                    uint _tokenPriceWei, 
                    uint _campaignDurationDays,
                    uint _firstPeriod, 
                    uint _secondPeriod, 
                    uint _thirdPeriod, 
                    uint _firstBonus, 
                    uint _secondBonus,
                    uint _thirdBonus) public {
    multiplier = 10**_decimalPoints;
    multisigETH = _multisigETH; 
    tokensForTeam = _toekensForTeam * multiplier; 
    minContributionPresale = _minContributionPresale; 
    minContributionMainSale = _minContributionMainSale;
    maxContribution = _maxContribution;       
    maxCap = _maxCap * multiplier;       
    minCap = _minCap * multiplier;
    tokenPriceWei = _tokenPriceWei;
    campaignDurationDays = _campaignDurationDays;
    firstPeriod = _firstPeriod; 
    secondPeriod = _secondPeriod; 
    thirdPeriod = _thirdPeriod;
    firstBonus = _firstBonus;
    secondBonus = _secondBonus;
    thirdBonus = _thirdBonus;       
    //TODO replace this address below with correct address.
    commissionAddress = 0x326B5E9b8B2ebf415F9e91b42c7911279d296ea1;
    //commissionAddress = 0x853A3F142430658A32f75A0dc891b98BF4bDF5c1;
    currentStep = Step.FundingPreSale; 
}

// @notice to populate website with status of the sale 
function returnWebsiteData() external view returns(uint, 
    uint, uint, uint, uint, uint, uint, uint, uint, uint, bool, bool, uint, Step) {

    return (startBlock, endBlock, numberOfBackers(), ethReceivedPresale + ethReceivedMain, maxCap, minCap, 
            totalTokensSent, tokenPriceWei, minContributionPresale, minContributionMainSale, 
            paused, crowdsaleClosed, token.decimals(), currentStep);
}

// @notice this function will determine status of crowdsale
function determineStatus() external view returns (uint) {
   
    if (crowdsaleClosed)            // ICO finihsed
        return 1;   

    if (block.number < endBlock && totalTokensSent < maxCap - 100)   // ICO in progress
        return 2;            

    if (totalTokensSent < minCap && block.number > endBlock)      // ICO failed    
        return 3;            

    if (endBlock == 0)           // ICO hasn't been started yet 
        return 4;            

    return 0;         
} 

// {fallback function}
// @notice It will call internal function which handels allocation of Ether and calculates tokens.
function () public payable {    
         
    contribute(msg.sender);
}

// @notice to allow for contribution from interface
function contributePublic() external payable {
    contribute(msg.sender);
}

// @notice set the step of the campaign from presale to public sale
// contract is deployed in presale mode
// WARNING: there is no way to go back
function advanceStep() external onlyOwner() {
    currentStep = Step.FundingMainSale;
    LogStepAdvanced();
}

// @notice It will be called by owner to start the sale    
function start() external onlyOwner() {
    startBlock = block.number;
    endBlock = startBlock + (4*60*24*campaignDurationDays); // assumption is that one block takes 15 sec. 
    crowdsaleClosed = false;
    LogStarted(startBlock, endBlock);
}

// @notice This function will finalize the sale.
// It will only execute if predetermined sale time passed or all tokens are sold.
function finalize() external onlyOwner() {

    require(!crowdsaleClosed);                       
    require(block.number >= endBlock || totalTokensSent > maxCap - 1000);
                // - 1000 is used to allow closing of the campaing when contribution is near 
                // finished as exact amount of maxCap might be not feasible e.g. you can't easily buy few tokens. 
                // when min contribution is 0.1 Eth.  

    require(totalTokensSent >= minCap);
    crowdsaleClosed = true;
    
    // transfer commission portion to the platform
    commissionAddress.transfer(determineCommissions());         
    
    // transfer remaning funds to the campaign wallet
    multisigETH.transfer(this.balance);
    
    /*if (!token.transfer(owner, token.balanceOf(this))) 
        revert(); // transfer tokens to admin account  
        
    if (!token.burn(this, token.balanceOf(this))) 
        revert();  // burn all the tokens remaining in the contract   */
    token.unlock();    // release lock from transfering tokens. 

    LogFinalized(true);        
}

// @notice it will allow contributors to get refund in case campaign failed
// @return {bool} true if successful
function refund() external whenNotPaused returns (bool) {      
    
    uint totalEtherReceived = ethReceivedPresale + ethReceivedMain;

    require(totalEtherReceived < minCap);  // ensure that campaign failed
    require(this.balance > 0);  // contract will hold 0 ether at the end of campaign.
                                // contract needs to be funded through fundContract() 
    TokenHolder storage backer = tokenHolders[msg.sender];

    require(backer.weiReceived > 0);  // ensure that user has sent contribution
    require(!backer.refunded);        // ensure that user hasn't been refunded yet

    backer.refunded = true;  // save refund status to true
    refundCount++;
    totalRefunded += backer.weiReceived;

    if (!token.burn(msg.sender, backer.tokensToSend)) // burn tokens
        revert();        
    msg.sender.transfer(backer.weiReceived);  // send back the contribution 
    LogRefundETH(msg.sender, backer.weiReceived);
    return true;
}

// @notice allocate tokens to dev/team/advisors
// @param _dev {address} 
// @param _amount {uint} amount of tokens
function devAllocation(address _dev, uint _amount) external onlyOwner() returns (bool) {

    require(_dev != address(0));
    require(crowdsaleClosed); 
    require(totalTokensSent.add(_amount) <= token.totalSupply());
    devIndex.push(_dev);
    TokenHolder storage tokenHolder = tokenHolders[_dev];
    tokenHolder.tokensToSend = _amount;
    tokensSentDev += _amount;
    totalTokensSent += _amount;        
    LogDevTokensAllocated(_dev, _amount); // Register event
    return true;

}

// @notice Failsafe drain
function drain(uint _amount) external onlyOwner() {
    owner.transfer(_amount);           
}

// @notice transfer tokens which are not subject to vesting
// @param _recipient {addres}
// @param _amont {uint} amount to transfer
function transferTokens(address _recipient, uint _amount) external onlyOwner() returns (bool) {

    require(_recipient != address(0));
    if (!token.transfer(_recipient, _amount))
        revert();
    LogNonVestedTokensSent(_recipient, _amount);
}

// @notice determine amount of commissions for the platform    
function determineCommissions() public view returns (uint) {
 
    if (this.balance <= 500 ether) {
        return (this.balance * 10)/100;
    }else if (this.balance <= 1000 ether) {
        return (this.balance * 8)/100;
    }else if (this.balance < 10000 ether) {
        return (this.balance * 6)/100;
    }else {
        return (this.balance * 6)/100;
    }
}

// @notice return number of contributors
// @return  {uint} number of contributors
function numberOfBackers() public view returns (uint) {
    return holdersIndex.length;
}

// @notice It will be called by fallback function whenever ether is sent to it
// @param  _backer {address} address of beneficiary
// @return res {bool} true if transaction was successful
function contribute(address _backer) internal whenNotPaused respectTimeFrame returns(bool res) {

    //require(msg.value <= maxContribution);

    if (whiteList != address(0))  // if whitelist initialized verify member whitelist status
        require(whiteList.isWhiteListed(_backer));  // ensure that user is whitelisted
      
    uint tokensToSend = calculateNoOfTokensToSend(); // calculate number of tokens

    // Ensure that max cap hasn't been reached
    require(totalTokensSent + tokensToSend <= maxCap);
    
    TokenHolder storage backer = tokenHolders[_backer];

    if (backer.weiReceived == 0)
        holdersIndex.push(_backer);

    if (Step.FundingMainSale == currentStep) { // Update the total Ether received and tokens sent during public sale
        require(msg.value >= minContributionMainSale); // stop when required minimum is not met    
        ethReceivedMain = ethReceivedMain.add(msg.value);
        tokensSentMain += tokensToSend;
    }else {  
        require(msg.value >= minContributionPresale); // stop when required minimum is not met
        ethReceivedPresale = ethReceivedPresale.add(msg.value); 
        tokensSentPresale += tokensToSend;
    }  
   
    backer.tokensToSend += tokensToSend;
    backer.weiReceived = backer.weiReceived.add(msg.value);       
    totalTokensSent += tokensToSend;      
    
    // tokens are not transferrd to contributors during this phase
    // tokens will be transferred based on the vesting schedule, when contributor
    // calls release() function of this contract
    LogReceivedETH(_backer, msg.value, tokensToSend); // Register event
    return true;
}

// @notice This function will return number of tokens based on time intervals in the campaign
function calculateNoOfTokensToSend() internal view returns (uint) {

    uint tokenAmount = msg.value.mul(multiplier) / tokenPriceWei;

    if (Step.FundingMainSale == currentStep) {
    
        if (block.number <= startBlock + firstPeriod) {  
            return  tokenAmount + tokenAmount.mul(firstBonus) / 100;
        }else if (block.number <= startBlock + secondPeriod) {
            return  tokenAmount + tokenAmount.mul(secondBonus) / 100; 
        }else if (block.number <= startBlock + thirdPeriod) { 
            return  tokenAmount + tokenAmount.mul(thirdBonus) / 100;        
        }else {              
            return  tokenAmount; 
        }
    }else 
        return  tokenAmount + tokenAmount.mul(presaleBonus) / 100;
}  

}

// The token contract Token is ERC20, Ownable {

using SafeMath for uint;
// Public variables of the token
string public name;
string public symbol;
uint public decimals; // How many decimals to show.
string public version = "v0.1";
uint public totalSupply;
bool public locked;
address public crowdSaleAddress;

mapping(address => uint) public balances;
mapping(address => mapping(address => uint)) public allowed;

// Lock transfer during the ICO
modifier onlyUnlocked() {
    if (msg.sender != crowdSaleAddress && locked && msg.sender != owner) 
        revert();
    _;
}

modifier onlyAuthorized() {
    if (msg.sender != crowdSaleAddress && msg.sender != owner) 
        revert();
    _;
}

// The Token constructor     
function Token(uint _initialSupply,
        string _tokenName,
        uint _decimalUnits,
        string _tokenSymbol,
        string _version,
        address _crowdSaleAddress) public {      
    locked = true;  // Lock the transfer of tokens during the crowdsale
    totalSupply = _initialSupply * (10**_decimalUnits);     
                                    
    name = _tokenName; // Set the name for display purposes
    symbol = _tokenSymbol; // Set the symbol for display purposes
    decimals = _decimalUnits; // Amount of decimals for display purposes
    version = _version;
    crowdSaleAddress = _crowdSaleAddress;              
    balances[crowdSaleAddress] = totalSupply;   
}

function unlock() public onlyAuthorized {
    locked = false;
}

function lock() public onlyAuthorized {
    locked = true;
}

function burn(address _member, uint256 _value) public onlyAuthorized returns(bool) {
    require(balances[_member] >= _value);
    balances[_member] -= _value;
    totalSupply -= _value;
    Transfer(_member, 0x0, _value);
    return true;
}


// @notice transfer tokens to given address
// @param _to {address} address or recipient
// @param _value {uint} amount to transfer
// @return  {bool} true if successful
function transfer(address _to, uint _value) public onlyUnlocked returns(bool) {

    require(_to != address(0));
    require(balances[msg.sender] >= _value);
    balances[msg.sender] -= _value;
    balances[_to] += _value;
    Transfer(msg.sender, _to, _value);
    return true;
}

// @notice transfer tokens from given address to another address
// @param _from {address} from whom tokens are transferred
// @param _to {address} to whom tokens are transferred
// @param _value {uint} amount of tokens to transfer
// @return  {bool} true if successful
function transferFrom(address _from, address _to, uint256 _value) public onlyUnlocked returns(bool success) {

    require(_to != address(0));
    require(balances[_from] >= _value); // Check if the sender has enough
    require(_value <= allowed[_from][msg.sender]); // Check if allowed is greater or equal
    balances[_from] -= _value; // Subtract from the sender
    balances[_to] += _value; // Add the same to the recipient
    allowed[_from][msg.sender] -= _value;  // adjust allowed
    Transfer(_from, _to, _value);
    return true;
}

  // @notice to query balance of account
// @return _owner {address} address of user to query balance
function balanceOf(address _owner) public view returns(uint balance) {
    return balances[_owner];
}

/**
* @dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender.
*
* Beware that changing an allowance with this method brings the risk that someone may use both the old
* and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this
* race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
* @param _spender The address which will spend the funds.
* @param _value The amount of tokens to be spent.
*/
function approve(address _spender, uint _value) public returns(bool) {
    allowed[msg.sender][_spender] = _value;
    Approval(msg.sender, _spender, _value);
    return true;
}

// @notice to query of allowance of one user to the other
// @param _owner {address} of the owner of the account
// @param _spender {address} of the spender of the account
// @return remaining {uint} amount of remaining allowance
function allowance(address _owner, address _spender) public view returns(uint remaining) {
    return allowed[_owner][_spender];
}

/**
* approve should be called when allowed[_spender] == 0. To increment
* allowed value is better to use this function to avoid 2 calls (and wait until
* the first transaction is mined)
* From MonolithDAO Token.sol
*/
function increaseApproval (address _spender, uint _addedValue) public returns (bool success) {
    allowed[msg.sender][_spender] = allowed[msg.sender][_spender].add(_addedValue);
    Approval(msg.sender, _spender, allowed[msg.sender][_spender]);
    return true;
}

function decreaseApproval (address _spender, uint _subtractedValue) public returns (bool success) {
    uint oldValue = allowed[msg.sender][_spender];
    if (_subtractedValue > oldValue) {
        allowed[msg.sender][_spender] = 0;
    } else {
        allowed[msg.sender][_spender] = oldValue.sub(_subtractedValue);
    }
    Approval(msg.sender, _spender, allowed[msg.sender][_spender]);
    return true;
}

}

About

pragma solidity ^ 0.4.17; library SafeMath { function mul(uint a, uint b) internal pure returns(uint) { uint c = a * b; assert(a == 0 || c / a == b); return c; } function sub(uint a, uint b) internal pure returns(uint) { assert(b <= a); return a - b; } function add(uint a, uint b) internal pure returns(uint) { uint c = a + b; assert(c >= a && c …

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published