Blockwell

Modum Token

ERC20

This contract is an ERC20 token.

Name Modum Token
Symbol MOD
Decimals 0
Total Supply 21,266,200 MOD

About

Stats

Public Functions 21
Event Types 4
Code Size 19,367 bytes

Library Use

Uses SafeMath for uint256.

Approval Event

Parameters help
owner
address help
spender
address help
value
uint256 help

Payout Event

Parameters help
weiPerToken
uint256 help

Transfer Event

Parameters help
from
address help
to
address help
value
uint256 help

Voted Event

Parameters help
_addr
address help
option
bool help
votes
uint256 help

Account Event

Members
lastProposalStartTime
uint256 help
lastAirdropWei
uint256 help
lastAirdropClaimTime
uint256 help
bonusWei
uint256 help
valueModVote
uint256 help
valueMod
uint256 help

Proposal Event

Members
addr
string help
hash
bytes32 help
valueMod
uint256 help
startTime
uint256 help
yay
uint256 help
nay
uint256 help

Functions Expand All Collapse All

balanceOf keyboard_arrow_up

Parameters help

Name Type
_owner
address help

Properties

Visibility help public
Mutability help constant
Source Code
    function balanceOf(address _owner) public constant returns (uint256 balance) {
        return accounts[_owner].valueMod;
    }

transfer keyboard_arrow_up

Parameters help

Name Type
_to
address help
_value
uint256 help

Properties

Visibility help public
Mutability help transaction
Source Code
    function transfer(address _to, uint256 _value) public returns (bool success) {
        require(mintDone);
        require(_value > 0);
        Account memory tmpFrom = accounts[msg.sender];
        require(tmpFrom.valueMod >= _value);

        Account storage from = updateAccount(msg.sender, UpdateMode.Both);
        Account storage to = updateAccount(_to, UpdateMode.Both);
        from.valueMod = from.valueMod.sub(_value);
        to.valueMod = to.valueMod.add(_value);
        Transfer(msg.sender, _to, _value);
        return true;
    }

allowance keyboard_arrow_up

Parameters help

Name Type
_owner
address help
_spender
address help

Properties

Visibility help public
Mutability help constant
Source Code
    function allowance(address _owner, address _spender) public constant returns (uint256 remaining) {
        return allowed[_owner][_spender];
    }

transferFrom keyboard_arrow_up

Parameters help

Name Type
_from
address help
_to
address help
_value
uint256 help

Properties

Visibility help public
Mutability help transaction
Source Code
    function transferFrom(address _from, address _to, uint256 _value) public returns (bool success) {
        require(mintDone);
        require(_value > 0);
        Account memory tmpFrom = accounts[_from];
        require(tmpFrom.valueMod >= _value);
        require(allowed[_from][msg.sender] >= _value);

        Account storage from = updateAccount(_from, UpdateMode.Both);
        Account storage to = updateAccount(_to, UpdateMode.Both);
        from.valueMod = from.valueMod.sub(_value);
        to.valueMod = to.valueMod.add(_value);
        allowed[_from][msg.sender] = allowed[_from][msg.sender].sub(_value);
        Transfer(msg.sender, _to, _value);
        return true;
    }

approve keyboard_arrow_up

Parameters help

Name Type
_spender
address help
_value
uint256 help

Properties

Visibility help public
Mutability help transaction

Requirements help

One or more of the following:
Source Code
    function approve(address _spender, uint256 _value) public returns (bool) {
        // 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((_value == 0) || (allowed[msg.sender][_spender] == 0));

        allowed[msg.sender][_spender] = _value;
        Approval(msg.sender, _spender, _value);
        return true;
    }

transferOwnership keyboard_arrow_up

Parameters help

Name Type
_newOwner
address help

Properties

Visibility help public
Mutability help transaction
Source Code
    function transferOwnership(address _newOwner) public {
        require(msg.sender == owner);
        require(_newOwner != address(0));
        owner = _newOwner;
    }

votingProposal keyboard_arrow_up

Parameters help

Name Type
_addr
string help
_hash
bytes32 help
_value
uint256 help

Properties

Visibility help public
Mutability help transaction

Requirements help

Source Code
    function votingProposal(string _addr, bytes32 _hash, uint256 _value) public {
        require(msg.sender == owner); // proposal ony by onwer
        require(!isProposalActive()); // no proposal is active, cannot vote in parallel
        require(_value <= lockedTokens); //proposal cannot be larger than remaining locked tokens
        require(_value > 0); //there needs to be locked tokens to make proposal, at least 1 locked token
        require(_hash != bytes32(0)); //hash need to be set
        require(bytes(_addr).length > 0); //the address need to be set and non-empty
        require(mintDone); //minting phase needs to be over
        //in case of negative vote, wait 90 days. If no lastNegativeVoting have
        //occured, lastNegativeVoting is 0 and now is always larger than 14.1.1970
        //(1.1.1970 plus blockingDuration).
        require(now >= lastNegativeVoting.add(blockingDuration));

        currentProposal = Proposal(_addr, _hash, _value, now, 0, 0);
    }

vote keyboard_arrow_up

Parameters help

Name Type
_vote
bool help

Properties

Visibility help public
Mutability help transaction

Requirements help

Source Code
    function vote(bool _vote) public returns (uint256) {
        require(isVoteOngoing()); // vote needs to be ongoing
        Account storage account = updateAccount(msg.sender, UpdateMode.Vote);
        uint256 votes = account.valueModVote; //available votes
        require(votes > 0); //voter must have a vote left, either by not voting yet, or have modum tokens

        if(_vote) {
            currentProposal.yay = currentProposal.yay.add(votes);
        }
        else {
            currentProposal.nay = currentProposal.nay.add(votes);
        }

        account.valueModVote = 0;
        Voted(msg.sender, _vote, votes);
        return votes;
    }

showVotes keyboard_arrow_up

Parameters help

Name Type
_addr
address help

Properties

Visibility help public
Mutability help constant
Source Code
    function showVotes(address _addr) public constant returns (uint256) {
        Account memory account = accounts[_addr];
        if(account.lastProposalStartTime < currentProposal.startTime || // the user did set his token power yet
            (account.lastProposalStartTime == 0 && currentProposal.startTime == 0)) {
            return account.valueMod;
        }
        return account.valueModVote;
    }

claimVotingProposal keyboard_arrow_up

Parameters help

This function has no parameters.

Properties

Visibility help public
Mutability help transaction
Source Code
    function claimVotingProposal() public {
        require(msg.sender == owner); //only owner can claim proposal
        require(isProposalActive()); // proposal active
        require(isVotingPhaseOver()); // voting has already ended

        if(currentProposal.yay > currentProposal.nay && currentProposal.valueMod > 0) {
            //Vote was accepted
            Account storage account = updateAccount(owner, UpdateMode.Both);
            uint256 valueMod = currentProposal.valueMod;
            account.valueMod = account.valueMod.add(valueMod); //add tokens to owner
            totalSupply = totalSupply.add(valueMod);
            lockedTokens = lockedTokens.sub(valueMod);
        } else if(currentProposal.yay <= currentProposal.nay) {
            //in case of a negative vote, set the time of this negative
            //vote to the end of the negative voting period.
            //This will prevent any new voting to be conducted.
            lastNegativeVoting = currentProposal.startTime.add(votingDuration);
        }
        delete currentProposal; //proposal ended
    }

isProposalActive keyboard_arrow_up

Parameters help

This function has no parameters.

Properties

Visibility help public
Mutability help constant
Source Code
    function isProposalActive() public constant returns (bool)  {
        return currentProposal.hash != bytes32(0);
    }

isVoteOngoing keyboard_arrow_up

Parameters help

This function has no parameters.

Properties

Visibility help public
Mutability help constant
Source Code
    function isVoteOngoing() public constant returns (bool)  {
        return isProposalActive()
            && now >= currentProposal.startTime
            && now < currentProposal.startTime.add(votingDuration);
        //its safe to use it for longer periods:
        //https://ethereum.stackexchange.com/questions/6795/is-block-timestamp-safe-for-longer-time-periods
    }

isVotingPhaseOver keyboard_arrow_up

Parameters help

This function has no parameters.

Properties

Visibility help public
Mutability help constant
Source Code
    function isVotingPhaseOver() public constant returns (bool)  {
        //its safe to use it for longer periods:
        //https://ethereum.stackexchange.com/questions/6795/is-block-timestamp-safe-for-longer-time-periods
        return now >= currentProposal.startTime.add(votingDuration);
    }

mint keyboard_arrow_up

Parameters help

Name Type
_recipient
address[] help
_value
uint256[] help

Properties

Visibility help public
Mutability help transaction
Source Code
    function mint(address[] _recipient, uint256[] _value) public {
        require(msg.sender == owner); //only owner can claim proposal
        require(!mintDone); //only during minting
        //require(_recipient.length == _value.length); //input need to be of same size
        //we know what we are doing... remove check to save gas

        //we want to mint a couple of accounts
        for (uint8 i=0; i<_recipient.length; i++) {
            
            //require(lockedTokens.add(totalSupply).add(_value[i]) <= maxTokens);
            //do the check in the mintDone

            //121 gas can be saved by creating temporary variables
            address tmpRecipient = _recipient[i];
            uint tmpValue = _value[i];

            //no need to update account, as we have not set minting to true. This means
            //nobody can start a proposal (isVoteOngoing() is always false) and airdrop
            //cannot be done either totalDropPerUnlockedToken is 0 thus, bonus is always
            //zero.
            Account storage account = accounts[tmpRecipient];
            account.valueMod = account.valueMod.add(tmpValue);
            //if this remains 0, we cannot calculate the time period when the user claimed
            //his airdrop, thus, set it to now
            account.lastAirdropClaimTime = now;
            totalSupply = totalSupply.add(tmpValue); //create the tokens and add to recipient
            Transfer(msg.sender, tmpRecipient, tmpValue);
        }
    }

setMintDone keyboard_arrow_up

Parameters help

This function has no parameters.

Properties

Visibility help public
Mutability help transaction
Source Code
    function setMintDone() public {
        require(msg.sender == owner);
        require(!mintDone); //only in minting phase
        //here we check that we never exceed the 30mio max tokens. This includes
        //the locked and the unlocked tokens.
        require(lockedTokens.add(totalSupply) <= maxTokens);
        mintDone = true; //end the minting
    }

constructor keyboard_arrow_up

Parameters help

This function has no parameters.

Properties

Visibility help public
Mutability help payable
Source Code
    function() public payable {
        require(mintDone); //minting needs to be over
        require(msg.sender == owner); //ETH payment need to be one-way only, from modum to tokenholders, confirmed by Lykke
        payout(msg.value);
    }

payBonus keyboard_arrow_up

Parameters help

Name Type
_addr
address[] help

Properties

Visibility help public
Mutability help payable
Source Code
    function payBonus(address[] _addr) public payable {
        require(msg.sender == owner);  //ETH payment need to be one-way only, from modum to tokenholders, confirmed by Lykke
        uint256 totalWei = 0;
        for (uint8 i=0; i<_addr.length; i++) {
            Account storage account = updateAccount(_addr[i], UpdateMode.Wei);
            if(now >= account.lastAirdropClaimTime + redistributionTimeout) {
                totalWei += account.bonusWei;
                account.bonusWei = 0;
                account.lastAirdropClaimTime = now;
            } else {
                revert();
            }
        }
        payout(msg.value.add(totalWei));
    }

showBonus keyboard_arrow_up

Parameters help

Name Type
_addr
address help

Properties

Visibility help public
Mutability help constant
Source Code
    function showBonus(address _addr) public constant returns (uint256) {
        uint256 bonus = totalDropPerUnlockedToken.sub(accounts[_addr].lastAirdropWei);
        if(bonus != 0) {
            return accounts[_addr].bonusWei.add(bonus.mul(accounts[_addr].valueMod));
        }
        return accounts[_addr].bonusWei;
    }

claimBonus keyboard_arrow_up

Parameters help

This function has no parameters.

Properties

Visibility help public
Mutability help transaction

Requirements help

Source Code
    function claimBonus() public returns (uint256) {
        require(mintDone); //minting needs to be over

        Account storage account = updateAccount(msg.sender, UpdateMode.Wei);
        uint256 sendValue = account.bonusWei; //fetch the values

        if(sendValue != 0) {
            account.bonusWei = 0; //set to zero (before, against reentry)
            account.lastAirdropClaimTime = now; //mark as collected now
            msg.sender.transfer(sendValue); //send the bonus to the correct account
            return sendValue;
        }
        return 0;
    }

increaseApproval keyboard_arrow_up

Parameters help

Name Type
_spender
address help
_addedValue
uint256 help

Properties

Visibility help public
Mutability help transaction
Source Code
    function increaseApproval(address _spender, uint256 _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;
    }

decreaseApproval keyboard_arrow_up

Parameters help

Name Type
_spender
address help
_subtractedValue
uint256 help

Properties

Visibility help public
Mutability help transaction
Source Code
    function decreaseApproval(address _spender, uint256 _subtractedValue) public returns (bool success) {
        uint256 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;
    }