ETH Price: $3,122.30 (-1.42%)
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Token Holdings

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Set Ethereum Rat...74905792019-04-02 18:33:012128 days ago1554229981IN
0x311d7455...C72737c5d
0 ETH0.000093373
Set Bitcoin Rate74905672019-04-02 18:29:572128 days ago1554229797IN
0x311d7455...C72737c5d
0 ETH0.000092653
Set Ethereum Rat...74764032019-03-31 13:36:392131 days ago1554039399IN
0x311d7455...C72737c5d
0 ETH0.00009963.2
Set Bitcoin Rate74764032019-03-31 13:36:392131 days ago1554039399IN
0x311d7455...C72737c5d
0 ETH0.000092653
Set Bitcoin Rate74720682019-03-30 21:19:402131 days ago1553980780IN
0x311d7455...C72737c5d
0 ETH0.000061762
Set Ethereum Rat...74628762019-03-29 10:28:372133 days ago1553855317IN
0x311d7455...C72737c5d
0 ETH0.000093373
Set Bitcoin Rate74625822019-03-29 9:24:422133 days ago1553851482IN
0x311d7455...C72737c5d
0 ETH0.000030881
Set Ethereum Rat...74551992019-03-28 5:39:182134 days ago1553751558IN
0x311d7455...C72737c5d
0 ETH0.000062252
Set Bitcoin Rate74551952019-03-28 5:38:382134 days ago1553751518IN
0x311d7455...C72737c5d
0 ETH0.000061762
Set Ethereum Rat...74464262019-03-26 20:53:182135 days ago1553633598IN
0x311d7455...C72737c5d
0 ETH0.000031121
Set Bitcoin Rate74464102019-03-26 20:49:222135 days ago1553633362IN
0x311d7455...C72737c5d
0 ETH0.000030881
Set Ethereum Rat...74401812019-03-25 21:15:422136 days ago1553548542IN
0x311d7455...C72737c5d
0 ETH0.000062252
Set Bitcoin Rate74401632019-03-25 21:12:142136 days ago1553548334IN
0x311d7455...C72737c5d
0 ETH0.000061762
Set Bitcoin Rate74266142019-03-23 18:49:222138 days ago1553366962IN
0x311d7455...C72737c5d
0 ETH0.000046321.5
Set Ethereum Rat...74185652019-03-22 12:34:392140 days ago1553258079IN
0x311d7455...C72737c5d
0 ETH0.000031121
Set Bitcoin Rate74185432019-03-22 12:30:472140 days ago1553257847IN
0x311d7455...C72737c5d
0 ETH0.000030881
Set Ethereum Rat...74040362019-03-20 6:09:502142 days ago1553062190IN
0x311d7455...C72737c5d
0 ETH0.000062252
Set Bitcoin Rate74038722019-03-20 5:36:472142 days ago1553060207IN
0x311d7455...C72737c5d
0 ETH0.000061762
Set Ethereum Rat...73945742019-03-18 18:43:202143 days ago1552934600IN
0x311d7455...C72737c5d
0 ETH0.000062252
Set Bitcoin Rate73945692019-03-18 18:42:262143 days ago1552934546IN
0x311d7455...C72737c5d
0 ETH0.000061762
Set Ethereum Rat...73884952019-03-17 19:51:312144 days ago1552852291IN
0x311d7455...C72737c5d
0 ETH0.000031121
Set Bitcoin Rate73884812019-03-17 19:49:222144 days ago1552852162IN
0x311d7455...C72737c5d
0 ETH0.000030881
Set Ethereum Rat...73820182019-03-16 19:43:162145 days ago1552765396IN
0x311d7455...C72737c5d
0 ETH0.000062252
Set Bitcoin Rate73819952019-03-16 19:38:362145 days ago1552765116IN
0x311d7455...C72737c5d
0 ETH0.000030881
Set Ethereum Rat...73755792019-03-15 19:55:332146 days ago1552679733IN
0x311d7455...C72737c5d
0 ETH0.000062252
View all transactions

Latest 8 internal transactions

Advanced mode:
Parent Transaction Hash Block
From
To
58965542018-07-03 5:22:312402 days ago1530595351
0x311d7455...C72737c5d
1 ETH
53014272018-03-22 13:40:432505 days ago1521726043
0x311d7455...C72737c5d
20.14470449 ETH
51947642018-03-04 11:54:092523 days ago1520164449
0x311d7455...C72737c5d
11.5 ETH
51171912018-02-19 6:50:352536 days ago1519023035
0x311d7455...C72737c5d
74.1 ETH
50460762018-02-07 8:36:312548 days ago1517992591
0x311d7455...C72737c5d
13.48421569 ETH
49989452018-01-30 9:19:182556 days ago1517303958
0x311d7455...C72737c5d
16.56446276 ETH
49592142018-01-23 17:10:332563 days ago1516727433
0x311d7455...C72737c5d
41.14 ETH
49190962018-01-16 17:17:112570 days ago1516123031
0x311d7455...C72737c5d
27.8676533 ETH
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
Tokensale

Compiler Version
v0.4.19+commit.c4cbbb05

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2018-02-01
*/

pragma solidity ^0.4.11;

/**
 * @title SafeMath
 * @dev Math operations with safety checks that throw on error
 */
library SafeMath {
  function mul(uint256 a, uint256 b) internal constant returns (uint256) {
    uint256 c = a * b;
    assert(a == 0 || c / a == b);
    return c;
  }

  function div(uint256 a, uint256 b) internal constant returns (uint256) {
    // assert(b > 0); // Solidity automatically throws when dividing by 0
    uint256 c = a / b;
    // assert(a == b * c + a % b); // There is no case in which this doesn't hold
    return c;
  }

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

  function add(uint256 a, uint256 b) internal constant returns (uint256) {
    uint256 c = a + b;
    assert(c >= a);
    return c;
  }
}

/* The authentication manager details user accounts that have access to certain priviledges and keeps a permanent ledger of who has and has had these rights. */
contract AuthenticationManager {
   
    /* Map addresses to admins */
    mapping (address => bool) adminAddresses;

    /* Map addresses to account readers */
    mapping (address => bool) accountReaderAddresses;

    /* Map addresses to account minters */
    mapping (address => bool) accountMinterAddresses;

    /* Details of all admins that have ever existed */
    address[] adminAudit;

    /* Details of all account readers that have ever existed */
    address[] accountReaderAudit;

    /* Details of all account minters that have ever existed */
    address[] accountMinterAudit;

    /* Fired whenever an admin is added to the contract. */
    event AdminAdded(address addedBy, address admin);

    /* Fired whenever an admin is removed from the contract. */
    event AdminRemoved(address removedBy, address admin);

    /* Fired whenever an account-reader contract is added. */
    event AccountReaderAdded(address addedBy, address account);

    /* Fired whenever an account-reader contract is removed. */
    event AccountReaderRemoved(address removedBy, address account);

    /* Fired whenever an account-minter contract is added. */
    event AccountMinterAdded(address addedBy, address account);

    /* Fired whenever an account-minter contract is removed. */
    event AccountMinterRemoved(address removedBy, address account);

    /* When this contract is first setup we use the creator as the first admin */    
    function AuthenticationManager() {
        /* Set the first admin to be the person creating the contract */
        adminAddresses[msg.sender] = true;
        AdminAdded(0, msg.sender);
        adminAudit.length++;
        adminAudit[adminAudit.length - 1] = msg.sender;
    }

    /* Gets whether or not the specified address is currently an admin */
    function isCurrentAdmin(address _address) constant returns (bool) {
        return adminAddresses[_address];
    }

    /* Gets whether or not the specified address has ever been an admin */
    function isCurrentOrPastAdmin(address _address) constant returns (bool) {
        for (uint256 i = 0; i < adminAudit.length; i++)
            if (adminAudit[i] == _address)
                return true;
        return false;
    }

    /* Gets whether or not the specified address is currently an account reader */
    function isCurrentAccountReader(address _address) constant returns (bool) {
        return accountReaderAddresses[_address];
    }

    /* Gets whether or not the specified address has ever been an admin */
    function isCurrentOrPastAccountReader(address _address) constant returns (bool) {
        for (uint256 i = 0; i < accountReaderAudit.length; i++)
            if (accountReaderAudit[i] == _address)
                return true;
        return false;
    }

    /* Gets whether or not the specified address is currently an account minter */
    function isCurrentAccountMinter(address _address) constant returns (bool) {
        return accountMinterAddresses[_address];
    }

    /* Gets whether or not the specified address has ever been an admin */
    function isCurrentOrPastAccountMinter(address _address) constant returns (bool) {
        for (uint256 i = 0; i < accountMinterAudit.length; i++)
            if (accountMinterAudit[i] == _address)
                return true;
        return false;
    }

    /* Adds a user to our list of admins */
    function addAdmin(address _address) {
        /* Ensure we're an admin */
        if (!isCurrentAdmin(msg.sender))
            throw;

        // Fail if this account is already admin
        if (adminAddresses[_address])
            throw;
        
        // Add the user
        adminAddresses[_address] = true;
        AdminAdded(msg.sender, _address);
        adminAudit.length++;
        adminAudit[adminAudit.length - 1] = _address;

    }

    /* Removes a user from our list of admins but keeps them in the history audit */
    function removeAdmin(address _address) {
        /* Ensure we're an admin */
        if (!isCurrentAdmin(msg.sender))
            throw;

        /* Don't allow removal of self */
        if (_address == msg.sender)
            throw;

        // Fail if this account is already non-admin
        if (!adminAddresses[_address])
            throw;

        /* Remove this admin user */
        adminAddresses[_address] = false;
        AdminRemoved(msg.sender, _address);
    }

    /* Adds a user/contract to our list of account readers */
    function addAccountReader(address _address) {
        /* Ensure we're an admin */
        if (!isCurrentAdmin(msg.sender))
            throw;

        // Fail if this account is already in the list
        if (accountReaderAddresses[_address])
            throw;
        
        // Add the account reader
        accountReaderAddresses[_address] = true;
        AccountReaderAdded(msg.sender, _address);
        accountReaderAudit.length++;
        accountReaderAudit[accountReaderAudit.length - 1] = _address;
    }

    /* Removes a user/contracts from our list of account readers but keeps them in the history audit */
    function removeAccountReader(address _address) {
        /* Ensure we're an admin */
        if (!isCurrentAdmin(msg.sender))
            throw;

        // Fail if this account is already not in the list
        if (!accountReaderAddresses[_address])
            throw;

        /* Remove this account reader */
        accountReaderAddresses[_address] = false;
        AccountReaderRemoved(msg.sender, _address);
    }

    /* Add a contract to our list of account minters */
    function addAccountMinter(address _address) {
        /* Ensure we're an admin */
        if (!isCurrentAdmin(msg.sender))
            throw;

        // Fail if this account is already in the list
        if (accountMinterAddresses[_address])
            throw;
        
        // Add the minter
        accountMinterAddresses[_address] = true;
        AccountMinterAdded(msg.sender, _address);
        accountMinterAudit.length++;
        accountMinterAudit[accountMinterAudit.length - 1] = _address;
    }

    /* Removes a user/contracts from our list of account readers but keeps them in the history audit */
    function removeAccountMinter(address _address) {
        /* Ensure we're an admin */
        if (!isCurrentAdmin(msg.sender))
            throw;

        // Fail if this account is already not in the list
        if (!accountMinterAddresses[_address])
            throw;

        /* Remove this minter account */
        accountMinterAddresses[_address] = false;
        AccountMinterRemoved(msg.sender, _address);
    }
}

// parse a raw bitcoin transaction byte array
library BTC {
    // Convert a variable integer into something useful and return it and
    // the index to after it.
    function parseVarInt(bytes txBytes, uint pos) returns (uint, uint) {
        // the first byte tells us how big the integer is
        var ibit = uint8(txBytes[pos]);
        pos += 1;  // skip ibit

        if (ibit < 0xfd) {
            return (ibit, pos);
        } else if (ibit == 0xfd) {
            return (getBytesLE(txBytes, pos, 16), pos + 2);
        } else if (ibit == 0xfe) {
            return (getBytesLE(txBytes, pos, 32), pos + 4);
        } else if (ibit == 0xff) {
            return (getBytesLE(txBytes, pos, 64), pos + 8);
        }
    }
    // convert little endian bytes to uint
    function getBytesLE(bytes data, uint pos, uint bits) returns (uint) {
        if (bits == 8) {
            return uint8(data[pos]);
        } else if (bits == 16) {
            return uint16(data[pos])
                 + uint16(data[pos + 1]) * 2 ** 8;
        } else if (bits == 32) {
            return uint32(data[pos])
                 + uint32(data[pos + 1]) * 2 ** 8
                 + uint32(data[pos + 2]) * 2 ** 16
                 + uint32(data[pos + 3]) * 2 ** 24;
        } else if (bits == 64) {
            return uint64(data[pos])
                 + uint64(data[pos + 1]) * 2 ** 8
                 + uint64(data[pos + 2]) * 2 ** 16
                 + uint64(data[pos + 3]) * 2 ** 24
                 + uint64(data[pos + 4]) * 2 ** 32
                 + uint64(data[pos + 5]) * 2 ** 40
                 + uint64(data[pos + 6]) * 2 ** 48
                 + uint64(data[pos + 7]) * 2 ** 56;
        }
    }
    // scan the full transaction bytes and return the first two output
    // values (in satoshis) and addresses (in binary)
    function getFirstTwoOutputs(bytes txBytes)
             returns (uint, bytes20, uint, bytes20)
    {
        uint pos;
        uint[] memory input_script_lens = new uint[](2);
        uint[] memory output_script_lens = new uint[](2);
        uint[] memory script_starts = new uint[](2);
        uint[] memory output_values = new uint[](2);
        bytes20[] memory output_addresses = new bytes20[](2);

        pos = 4;  // skip version

        (input_script_lens, pos) = scanInputs(txBytes, pos, 0);

        (output_values, script_starts, output_script_lens, pos) = scanOutputs(txBytes, pos, 2);

        for (uint i = 0; i < 2; i++) {
            var pkhash = parseOutputScript(txBytes, script_starts[i], output_script_lens[i]);
            output_addresses[i] = pkhash;
        }

        return (output_values[0], output_addresses[0],
                output_values[1], output_addresses[1]);
    }
    // Check whether `btcAddress` is in the transaction outputs *and*
    // whether *at least* `value` has been sent to it.
    function checkValueSent(bytes txBytes, bytes20 btcAddress, uint value)
             returns (bool)
    {
        uint pos = 4;  // skip version
        (, pos) = scanInputs(txBytes, pos, 0);  // find end of inputs

        // scan *all* the outputs and find where they are
        var (output_values, script_starts, output_script_lens,) = scanOutputs(txBytes, pos, 0);

        // look at each output and check whether it at least value to btcAddress
        for (uint i = 0; i < output_values.length; i++) {
            var pkhash = parseOutputScript(txBytes, script_starts[i], output_script_lens[i]);
            if (pkhash == btcAddress && output_values[i] >= value) {
                return true;
            }
        }
    }
    // scan the inputs and find the script lengths.
    // return an array of script lengths and the end position
    // of the inputs.
    // takes a 'stop' argument which sets the maximum number of
    // outputs to scan through. stop=0 => scan all.
    function scanInputs(bytes txBytes, uint pos, uint stop)
             returns (uint[], uint)
    {
        uint n_inputs;
        uint halt;
        uint script_len;

        (n_inputs, pos) = parseVarInt(txBytes, pos);

        if (stop == 0 || stop > n_inputs) {
            halt = n_inputs;
        } else {
            halt = stop;
        }

        uint[] memory script_lens = new uint[](halt);

        for (var i = 0; i < halt; i++) {
            pos += 36;  // skip outpoint
            (script_len, pos) = parseVarInt(txBytes, pos);
            script_lens[i] = script_len;
            pos += script_len + 4;  // skip sig_script, seq
        }

        return (script_lens, pos);
    }
    // scan the outputs and find the values and script lengths.
    // return array of values, array of script lengths and the
    // end position of the outputs.
    // takes a 'stop' argument which sets the maximum number of
    // outputs to scan through. stop=0 => scan all.
    function scanOutputs(bytes txBytes, uint pos, uint stop)
             returns (uint[], uint[], uint[], uint)
    {
        uint n_outputs;
        uint halt;
        uint script_len;

        (n_outputs, pos) = parseVarInt(txBytes, pos);

        if (stop == 0 || stop > n_outputs) {
            halt = n_outputs;
        } else {
            halt = stop;
        }

        uint[] memory script_starts = new uint[](halt);
        uint[] memory script_lens = new uint[](halt);
        uint[] memory output_values = new uint[](halt);

        for (var i = 0; i < halt; i++) {
            output_values[i] = getBytesLE(txBytes, pos, 64);
            pos += 8;

            (script_len, pos) = parseVarInt(txBytes, pos);
            script_starts[i] = pos;
            script_lens[i] = script_len;
            pos += script_len;
        }

        return (output_values, script_starts, script_lens, pos);
    }
    // Slice 20 contiguous bytes from bytes `data`, starting at `start`
    function sliceBytes20(bytes data, uint start) returns (bytes20) {
        uint160 slice = 0;
        for (uint160 i = 0; i < 20; i++) {
            slice += uint160(data[i + start]) << (8 * (19 - i));
        }
        return bytes20(slice);
    }
    // returns true if the bytes located in txBytes by pos and
    // script_len represent a P2PKH script
    function isP2PKH(bytes txBytes, uint pos, uint script_len) returns (bool) {
        return (script_len == 25)           // 20 byte pubkeyhash + 5 bytes of script
            && (txBytes[pos] == 0x76)       // OP_DUP
            && (txBytes[pos + 1] == 0xa9)   // OP_HASH160
            && (txBytes[pos + 2] == 0x14)   // bytes to push
            && (txBytes[pos + 23] == 0x88)  // OP_EQUALVERIFY
            && (txBytes[pos + 24] == 0xac); // OP_CHECKSIG
    }
    // returns true if the bytes located in txBytes by pos and
    // script_len represent a P2SH script
    function isP2SH(bytes txBytes, uint pos, uint script_len) returns (bool) {
        return (script_len == 23)           // 20 byte scripthash + 3 bytes of script
            && (txBytes[pos + 0] == 0xa9)   // OP_HASH160
            && (txBytes[pos + 1] == 0x14)   // bytes to push
            && (txBytes[pos + 22] == 0x87); // OP_EQUAL
    }
    // Get the pubkeyhash / scripthash from an output script. Assumes
    // pay-to-pubkey-hash (P2PKH) or pay-to-script-hash (P2SH) outputs.
    // Returns the pubkeyhash/ scripthash, or zero if unknown output.
    function parseOutputScript(bytes txBytes, uint pos, uint script_len)
             returns (bytes20)
    {
        if (isP2PKH(txBytes, pos, script_len)) {
            return sliceBytes20(txBytes, pos + 3);
        } else if (isP2SH(txBytes, pos, script_len)) {
            return sliceBytes20(txBytes, pos + 2);
        } else {
            return;
        }
    }
}

contract LockinManager {
    using SafeMath for uint256;

    /*Defines the structure for a lock*/
    struct Lock {
        uint256 amount;
        uint256 unlockDate;
        uint256 lockedFor;
    }
    
    /*Object of Lock*/    
    Lock lock;

    /*Value of default lock days*/
    uint256 defaultAllowedLock = 7;

    /* mapping of list of locked address with array of locks for a particular address */
    mapping (address => Lock[]) public lockedAddresses;

    /* mapping of valid contracts with their lockin timestamp */
    mapping (address => uint256) public allowedContracts;

    /* list of locked days mapped with their locked timestamp*/
    mapping (uint => uint256) public allowedLocks;

    /* Defines our interface to the token contract */
    Token token;

    /* Defines the admin contract we interface with for credentails. */
    AuthenticationManager authenticationManager;

     /* Fired whenever lock day is added by the admin. */
    event LockedDayAdded(address _admin, uint256 _daysLocked, uint256 timestamp);

     /* Fired whenever lock day is removed by the admin. */
    event LockedDayRemoved(address _admin, uint256 _daysLocked, uint256 timestamp);

     /* Fired whenever valid contract is added by the admin. */
    event ValidContractAdded(address _admin, address _validAddress, uint256 timestamp);

     /* Fired whenever valid contract is removed by the admin. */
    event ValidContractRemoved(address _admin, address _validAddress, uint256 timestamp);

    /* Create a new instance of this fund with links to other contracts that are required. */
    function LockinManager(address _token, address _authenticationManager) {
      
        /* Setup access to our other contracts and validate their versions */
        token  = Token(_token);
        authenticationManager = AuthenticationManager(_authenticationManager);
    }
   
    /* This modifier allows a method to only be called by current admins */
    modifier adminOnly {
        if (!authenticationManager.isCurrentAdmin(msg.sender)) throw;
        _;
    }

    /* This modifier allows a method to only be called by token contract */
    modifier validContractOnly {
        require(allowedContracts[msg.sender] != 0);

        _;
    }

    /* Gets the length of locked values for an account */
    function getLocks(address _owner) validContractOnly constant returns (uint256) {
        return lockedAddresses[_owner].length;
    }

    function getLock(address _owner, uint256 count) validContractOnly returns(uint256 amount, uint256 unlockDate, uint256 lockedFor) {
        amount     = lockedAddresses[_owner][count].amount;
        unlockDate = lockedAddresses[_owner][count].unlockDate;
        lockedFor   = lockedAddresses[_owner][count].lockedFor;
    }
    
    /* Gets amount for which an address is locked with locked index */
    function getLocksAmount(address _owner, uint256 count) validContractOnly returns(uint256 amount) {        
        amount = lockedAddresses[_owner][count].amount;
    }

    /* Gets unlocked timestamp for which an address is locked with locked index */
    function getLocksUnlockDate(address _owner, uint256 count) validContractOnly returns(uint256 unlockDate) {
        unlockDate = lockedAddresses[_owner][count].unlockDate;
    }

    /* Gets days for which an address is locked with locked index */
    function getLocksLockedFor(address _owner, uint256 count) validContractOnly returns(uint256 lockedFor) {
        lockedFor = lockedAddresses[_owner][count].lockedFor;
    }

    /* Locks tokens for an address for the default number of days */
    function defaultLockin(address _address, uint256 _value) validContractOnly
    {
        lockIt(_address, _value, defaultAllowedLock);
    }

    /* locks tokens for sender for n days*/
    function lockForDays(uint256 _value, uint256 _days) 
    {
        require( ! ifInAllowedLocks(_days));        

        require(token.availableBalance(msg.sender) >= _value);
        
        lockIt(msg.sender, _value, _days);     
    }

    function lockIt(address _address, uint256 _value, uint256 _days) internal {

        // expiry will be calculated as 24 * 60 * 60
        uint256 _expiry = now + _days.mul(86400);
        lockedAddresses[_address].push(Lock(_value, _expiry, _days));        
    }

    /* check if input day is present in locked days */
    function ifInAllowedLocks(uint256 _days) constant returns(bool) {
        return allowedLocks[_days] == 0;
    }

    /* Adds a day to our list of allowedLocks */
    function addAllowedLock(uint _day) adminOnly {

        // Fail if day is already present in locked days
        if (allowedLocks[_day] != 0)
            throw;
        
        // Add day in locked days 
        allowedLocks[_day] = now;
        LockedDayAdded(msg.sender, _day, now);
    }

    /* Remove allowed Lock */
    function removeAllowedLock(uint _day) adminOnly {

        // Fail if day doesnot exist in allowedLocks
        if ( allowedLocks[_day] ==  0)
            throw;

        /* Remove locked day  */
        allowedLocks[_day] = 0;
        LockedDayRemoved(msg.sender, _day, now);
    }

    /* Adds a address to our list of allowedContracts */
    function addValidContract(address _address) adminOnly {

        // Fail if address is already present in valid contracts
        if (allowedContracts[_address] != 0)
            throw;
        
        // add an address in allowedContracts
        allowedContracts[_address] = now;

        ValidContractAdded(msg.sender, _address, now);
    }

    /* Removes allowed contract from the list of allowedContracts */
    function removeValidContract(address _address) adminOnly {

        // Fail if address doesnot exist in allowedContracts
        if ( allowedContracts[_address] ==  0)
            throw;

        /* Remove allowed contract from allowedContracts  */
        allowedContracts[_address] = 0;

        ValidContractRemoved(msg.sender, _address, now);
    }

    /* Set default allowed lock */
    function setDefaultAllowedLock(uint _days) adminOnly {
        defaultAllowedLock = _days;
    }
}

/* The Token itself is a simple extension of the ERC20 that allows for granting other Token contracts special rights to act on behalf of all transfers. */
contract Token {
    using SafeMath for uint256;

    /* Map all our our balances for issued tokens */
    mapping (address => uint256) public balances;

    /* Map between users and their approval addresses and amounts */
    mapping(address => mapping (address => uint256)) allowed;

    /* List of all token holders */
    address[] allTokenHolders;

    /* The name of the contract */
    string public name;

    /* The symbol for the contract */
    string public symbol;

    /* How many DPs are in use in this contract */
    uint8 public decimals;

    /* Defines the current supply of the token in its own units */
    uint256 totalSupplyAmount = 0;
    
    /* Defines the address of the Refund Manager contract which is the only contract to destroy tokens. */
    address public refundManagerContractAddress;

    /* Defines the admin contract we interface with for credentails. */
    AuthenticationManager authenticationManager;

    /* Instance of lockin contract */
    LockinManager lockinManager;

    /** @dev Returns the balance that a given address has available for transfer.
      * @param _owner The address of the token owner.
      */
    function availableBalance(address _owner) constant returns(uint256) {
        
        uint256 length =  lockinManager.getLocks(_owner);
    
        uint256 lockedValue = 0;
        
        for(uint256 i = 0; i < length; i++) {

            if(lockinManager.getLocksUnlockDate(_owner, i) > now) {
                uint256 _value = lockinManager.getLocksAmount(_owner, i);    
                lockedValue = lockedValue.add(_value);                
            }
        }
        
        return balances[_owner].sub(lockedValue);
    }

    /* Fired when the fund is eventually closed. */
    event FundClosed();
    
    /* Our transfer event to fire whenever we shift SMRT around */
    event Transfer(address indexed from, address indexed to, uint256 value);
    
    /* Our approval event when one user approves another to control */
    event Approval(address indexed _owner, address indexed _spender, uint256 _value);

    /* Create a new instance of this fund with links to other contracts that are required. */
    function Token(address _authenticationManagerAddress) {
        // Setup defaults
        name = "PIE (Authorito Capital)";
        symbol = "PIE";
        decimals = 18;

        /* Setup access to our other contracts */
        authenticationManager = AuthenticationManager(_authenticationManagerAddress);        
    }

    modifier onlyPayloadSize(uint numwords) {
        assert(msg.data.length == numwords * 32 + 4);
        _;
    }

    /* This modifier allows a method to only be called by account readers */
    modifier accountReaderOnly {
        if (!authenticationManager.isCurrentAccountReader(msg.sender)) throw;
        _;
    }

    /* This modifier allows a method to only be called by current admins */
    modifier adminOnly {
        if (!authenticationManager.isCurrentAdmin(msg.sender)) throw;
        _;
    }   
    
    function setLockinManagerAddress(address _lockinManager) adminOnly {
        lockinManager = LockinManager(_lockinManager);
    }

    function setRefundManagerContract(address _refundManagerContractAddress) adminOnly {
        refundManagerContractAddress = _refundManagerContractAddress;
    }

    /* Transfer funds between two addresses that are not the current msg.sender - this requires approval to have been set separately and follows standard ERC20 guidelines */
    function transferFrom(address _from, address _to, uint256 _amount) onlyPayloadSize(3) returns (bool) {
        
        if (availableBalance(_from) >= _amount && allowed[_from][msg.sender] >= _amount && _amount > 0 && balances[_to].add(_amount) > balances[_to]) {
            bool isNew = balances[_to] == 0;
            balances[_from] = balances[_from].sub(_amount);
            allowed[_from][msg.sender] = allowed[_from][msg.sender].sub(_amount);
            balances[_to] = balances[_to].add(_amount);
            if (isNew)
                tokenOwnerAdd(_to);
            if (balances[_from] == 0)
                tokenOwnerRemove(_from);
            Transfer(_from, _to, _amount);
            return true;
        }
        return false;
    }

    /* Returns the total number of holders of this currency. */
    function tokenHolderCount() accountReaderOnly constant returns (uint256) {
        return allTokenHolders.length;
    }

    /* Gets the token holder at the specified index. */
    function tokenHolder(uint256 _index) accountReaderOnly constant returns (address) {
        return allTokenHolders[_index];
    }
 
    /* Adds an approval for the specified account to spend money of the message sender up to the defined limit */
    function approve(address _spender, uint256 _amount) onlyPayloadSize(2) returns (bool success) {
        allowed[msg.sender][_spender] = _amount;
        Approval(msg.sender, _spender, _amount);
        return true;
    }

    /* Gets the current allowance that has been approved for the specified spender of the owner address */
    function allowance(address _owner, address _spender) constant returns (uint256 remaining) {
        return allowed[_owner][_spender];
    }

    /* Gets the total supply available of this token */
    function totalSupply() constant returns (uint256) {
        return totalSupplyAmount;
    }

    /* Gets the balance of a specified account */
    function balanceOf(address _owner) constant returns (uint256 balance) {
        return balances[_owner];
    }

    /* Transfer the balance from owner's account to another account */
    function transfer(address _to, uint256 _amount) onlyPayloadSize(2) returns (bool) {
                
        /* Check if sender has balance and for overflows */
        if (availableBalance(msg.sender) < _amount || balances[_to].add(_amount) < balances[_to])
            return false;

        /* Do a check to see if they are new, if so we'll want to add it to our array */
        bool isRecipientNew = balances[_to] == 0;

        /* Add and subtract new balances */
        balances[msg.sender] = balances[msg.sender].sub(_amount);
        balances[_to] = balances[_to].add(_amount);
        
        /* Consolidate arrays if they are new or if sender now has empty balance */
        if (isRecipientNew)
            tokenOwnerAdd(_to);
        if (balances[msg.sender] <= 0)
            tokenOwnerRemove(msg.sender);

        /* Fire notification event */
        Transfer(msg.sender, _to, _amount);
        return true; 
    }

    /* If the specified address is not in our owner list, add them - this can be called by descendents to ensure the database is kept up to date. */
    function tokenOwnerAdd(address _addr) internal {
        /* First check if they already exist */
        uint256 tokenHolderCount = allTokenHolders.length;
        for (uint256 i = 0; i < tokenHolderCount; i++)
            if (allTokenHolders[i] == _addr)
                /* Already found so we can abort now */
                return;
        
        /* They don't seem to exist, so let's add them */
        allTokenHolders.length++;
        allTokenHolders[allTokenHolders.length - 1] = _addr;
    }

    /* If the specified address is in our owner list, remove them - this can be called by descendents to ensure the database is kept up to date. */
    function tokenOwnerRemove(address _addr) internal {
        /* Find out where in our array they are */
        uint256 tokenHolderCount = allTokenHolders.length;
        uint256 foundIndex = 0;
        bool found = false;
        uint256 i;
        for (i = 0; i < tokenHolderCount; i++)
            if (allTokenHolders[i] == _addr) {
                foundIndex = i;
                found = true;
                break;
            }
        
        /* If we didn't find them just return */
        if (!found)
            return;
        
        /* We now need to shuffle down the array */
        for (i = foundIndex; i < tokenHolderCount - 1; i++)
            allTokenHolders[i] = allTokenHolders[i + 1];
        allTokenHolders.length--;
    }

    /* Mint new tokens - this can only be done by special callers (i.e. the ICO management) during the ICO phase. */
    function mintTokens(address _address, uint256 _amount) onlyPayloadSize(2) {

        /* if it is comming from account minter */
        if ( ! authenticationManager.isCurrentAccountMinter(msg.sender))
            throw;

        /* Mint the tokens for the new address*/
        bool isNew = balances[_address] == 0;
        totalSupplyAmount = totalSupplyAmount.add(_amount);
        balances[_address] = balances[_address].add(_amount);

        lockinManager.defaultLockin(_address, _amount);        

        if (isNew)
            tokenOwnerAdd(_address);
        Transfer(0, _address, _amount);
    }

    /** This will destroy the tokens of the investor and called by sale contract only at the time of refund. */
    function destroyTokens(address _investor, uint256 tokenCount) returns (bool) {
        
        /* Can only be called by refund manager, also refund manager address must not be empty */
        if ( refundManagerContractAddress  == 0x0 || msg.sender != refundManagerContractAddress)
            throw;

        uint256 balance = availableBalance(_investor);

        if (balance < tokenCount) {
            return false;
        }

        balances[_investor] -= tokenCount;
        totalSupplyAmount -= tokenCount;

        if(balances[_investor] <= 0)
            tokenOwnerRemove(_investor);

        return true;
    }
}

contract Tokensale {
    using SafeMath for uint256;
    
    /* Defines whether or not the  Token Contract address has yet been set.  */
    bool public tokenContractDefined = false;
    
    /* Defines whether or not we are in the Sale phase */
    bool public salePhase = true;

    /* Defines the sale price of ethereum during Sale */
    uint256 public ethereumSaleRate = 700; // The number of tokens to be minted for every ETH

    /* Defines the sale price of bitcoin during Sale */
    uint256 public bitcoinSaleRate = 14000; // The number of tokens to be minted for every BTC

    /* Defines our interface to the  Token contract. */
    Token token;

    /* Defines the admin contract we interface with for credentails. */
    AuthenticationManager authenticationManager;

    /* Claimed Transactions from btc relay. */
    mapping(uint256 => bool) public transactionsClaimed;

    /* Defines the minimum ethereum to invest during Sale */
    uint256 public minimunEthereumToInvest = 0;

    /* Defines the minimum btc to invest during Sale */
    uint256 public minimunBTCToInvest = 0;

    /* Defines our event fired when the Sale is closed */
    event SaleClosed();

    /* Defines our event fired when the Sale is reopened */
    event SaleStarted();

    /* Ethereum Rate updated by the admin. */
    event EthereumRateUpdated(uint256 rate, uint256 timestamp);

    /* Bitcoin Rate updated by the admin. */
    event BitcoinRateUpdated(uint256 rate, uint256 timestamp);

    /* Minimun Ethereum Investment updated by the admin. */
    event MinimumEthereumInvestmentUpdated(uint256 _value, uint256 timestamp);

    /* Minimun Bitcoin Investment updated by the admin. */
    event MinimumBitcoinInvestmentUpdated(uint256 _value, uint256 timestamp);

    /* Ensures that once the Sale is over this contract cannot be used until the point it is destructed. */
    modifier onlyDuringSale {

        if (!tokenContractDefined || (!salePhase)) throw;
        _;
    }

    /* This modifier allows a method to only be called by current admins */
    modifier adminOnly {
        if (!authenticationManager.isCurrentAdmin(msg.sender)) throw;
        _;
    }

    /* Create the  token sale and define the address of the main authentication Manager address. */
    function Tokensale(address _authenticationManagerAddress) {        
                
        /* Setup access to our other contracts */
        authenticationManager = AuthenticationManager(_authenticationManagerAddress);
    }

    /* Set the Token contract address as a one-time operation.  This happens after all the contracts are created and no
       other functionality can be used until this is set. */
    function setTokenContractAddress(address _tokenContractAddress) adminOnly {
        /* This can only happen once in the lifetime of this contract */
        if (tokenContractDefined)
            throw;

        /* Setup access to our other contracts */
        token = Token(_tokenContractAddress);

        tokenContractDefined = true;
    }

    /* Run this function when transaction has been verified by the btc relay */
    function processBTCTransaction(bytes txn, uint256 _txHash, address ethereumAddress, bytes20 bitcoinAddress) adminOnly returns (uint256)
    {
        /* Transaction is already claimed */
        if(transactionsClaimed[_txHash] != false) 
            throw;

        var (outputValue1, outputAddress1, outputValue2, outputAddress2) = BTC.getFirstTwoOutputs(txn);

        if(BTC.checkValueSent(txn, bitcoinAddress, 1))
        {
            require(outputValue1 >= minimunBTCToInvest);

             //multiply by exchange rate
            uint256 tokensPurchased = outputValue1 * bitcoinSaleRate * (10**10);  

            token.mintTokens(ethereumAddress, tokensPurchased);

            transactionsClaimed[_txHash] = true;
        }
        else
        {
            // value was not sent to this btc address
            throw;
        }
    }

    function btcTransactionClaimed(uint256 _txHash) returns(bool) {
        return transactionsClaimed[_txHash];
    }   
    
    // fallback function can be used to buy tokens
    function () payable {
    
        buyTokens(msg.sender);
    
    }

    /* Handle receiving ether in Sale phase - we work out how much the user has bought, allocate a suitable balance and send their change */
    function buyTokens(address beneficiary) onlyDuringSale payable {

        require(beneficiary != 0x0);
        require(validPurchase());
        
        uint256 weiAmount = msg.value;

        uint256 tokensPurchased = weiAmount.mul(ethereumSaleRate);
        
        /* Increase their new balance if they actually purchased any */
        if (tokensPurchased > 0)
        {
            token.mintTokens(beneficiary, tokensPurchased);
        }
    }

    // @return true if the transaction can buy tokens
    function validPurchase() internal constant returns (bool) {

        bool nonZeroPurchase = ( msg.value != 0 && msg.value >= minimunEthereumToInvest);
        return nonZeroPurchase;
    }

    /* Rate on which */
    function setEthereumRate(uint256 _rate) adminOnly {

        ethereumSaleRate = _rate;

        /* Audit this */
        EthereumRateUpdated(ethereumSaleRate, now);
    }

      /* Rate on which */
    function setBitcoinRate(uint256 _rate) adminOnly {

        bitcoinSaleRate = _rate;

        /* Audit this */
        BitcoinRateUpdated(bitcoinSaleRate, now);
    }    

        /* update min Ethereum to invest */
    function setMinimumEthereumToInvest(uint256 _value) adminOnly {

        minimunEthereumToInvest = _value;

        /* Audit this */
        MinimumEthereumInvestmentUpdated(_value, now);
    }    

          /* update minimum Bitcoin to invest */
    function setMinimumBitcoinToInvest(uint256 _value) adminOnly {

        minimunBTCToInvest = _value;

        /* Audit this */
        MinimumBitcoinInvestmentUpdated(_value, now);
    }

      /* Close the Sale phase and transition to execution phase */
    function close() adminOnly onlyDuringSale {

        // Close the Sale
        salePhase = false;
        SaleClosed();

        // Withdraw funds to the caller
        if (!msg.sender.send(this.balance))
            throw;
    }

    /* Open the sale phase*/
    function openSale() adminOnly {        
        salePhase = true;
        SaleStarted();
    }
}

Contract Security Audit

Contract ABI

[{"constant":true,"inputs":[],"name":"ethereumSaleRate","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"bitcoinSaleRate","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_rate","type":"uint256"}],"name":"setBitcoinRate","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"openSale","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_txHash","type":"uint256"}],"name":"btcTransactionClaimed","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"transactionsClaimed","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_value","type":"uint256"}],"name":"setMinimumBitcoinToInvest","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"close","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"minimunEthereumToInvest","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"tokenContractDefined","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"minimunBTCToInvest","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_value","type":"uint256"}],"name":"setMinimumEthereumToInvest","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_tokenContractAddress","type":"address"}],"name":"setTokenContractAddress","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_rate","type":"uint256"}],"name":"setEthereumRate","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"salePhase","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"beneficiary","type":"address"}],"name":"buyTokens","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"txn","type":"bytes"},{"name":"_txHash","type":"uint256"},{"name":"ethereumAddress","type":"address"},{"name":"bitcoinAddress","type":"bytes20"}],"name":"processBTCTransaction","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_authenticationManagerAddress","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"anonymous":false,"inputs":[],"name":"SaleClosed","type":"event"},{"anonymous":false,"inputs":[],"name":"SaleStarted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"rate","type":"uint256"},{"indexed":false,"name":"timestamp","type":"uint256"}],"name":"EthereumRateUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"rate","type":"uint256"},{"indexed":false,"name":"timestamp","type":"uint256"}],"name":"BitcoinRateUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_value","type":"uint256"},{"indexed":false,"name":"timestamp","type":"uint256"}],"name":"MinimumEthereumInvestmentUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_value","type":"uint256"},{"indexed":false,"name":"timestamp","type":"uint256"}],"name":"MinimumBitcoinInvestmentUpdated","type":"event"}]

606060405260008060006101000a81548160ff0219169083151502179055506001600060016101000a81548160ff0219169083151502179055506102bc6001556136b060025560006006556000600755341561005a57600080fd5b6040516020806115348339810160405280805190602001909190505080600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505061146d806100c76000396000f3006060604052600436106100f1576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063038e666f146100fc5780630502631714610125578063166280141461014e578063167ff46f1461017157806320940b13146101865780633050f769146101c1578063360821e8146101fc57806343d726d61461021f578063666fc4d414610234578063a970ef6e1461025d578063b107baa11461028a578063b1efbd6f146102b3578063b23d4854146102d6578063ce649b391461030f578063e4f2487a14610332578063ec8ac4d81461035f578063ee3a02291461038d575b6100fa3361043e565b005b341561010757600080fd5b61010f6105ad565b6040518082815260200191505060405180910390f35b341561013057600080fd5b6101386105b3565b6040518082815260200191505060405180910390f35b341561015957600080fd5b61016f60048080359060200190919050506105b9565b005b341561017c57600080fd5b6101846106ef565b005b341561019157600080fd5b6101a76004808035906020019091905050610823565b604051808215151515815260200191505060405180910390f35b34156101cc57600080fd5b6101e2600480803590602001909190505061084d565b604051808215151515815260200191505060405180910390f35b341561020757600080fd5b61021d600480803590602001909190505061086d565b005b341561022a57600080fd5b6102326109a1565b005b341561023f57600080fd5b610247610b5d565b6040518082815260200191505060405180910390f35b341561026857600080fd5b610270610b63565b604051808215151515815260200191505060405180910390f35b341561029557600080fd5b61029d610b75565b6040518082815260200191505060405180910390f35b34156102be57600080fd5b6102d46004808035906020019091905050610b7b565b005b34156102e157600080fd5b61030d600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610caf565b005b341561031a57600080fd5b6103306004808035906020019091905050610e11565b005b341561033d57600080fd5b610345610f47565b604051808215151515815260200191505060405180910390f35b61038b600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190505061043e565b005b341561039857600080fd5b610428600480803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509190803590602001909190803573ffffffffffffffffffffffffffffffffffffffff169060200190919080356bffffffffffffffffffffffff1916906020019091905050610f5a565b6040518082815260200191505060405180910390f35b6000806000809054906101000a900460ff1615806104695750600060019054906101000a900460ff16155b1561047357600080fd5b60008373ffffffffffffffffffffffffffffffffffffffff161415151561049957600080fd5b6104a16113ef565b15156104ac57600080fd5b3491506104c46001548361140e90919063ffffffff16565b905060008111156105a857600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f0dda65c84836040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050600060405180830381600087803b151561059357600080fd5b6102c65a03f115156105a457600080fd5b5050505b505050565b60015481565b60025481565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bbb896ad336000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600087803b151561067e57600080fd5b6102c65a03f1151561068f57600080fd5b5050506040518051905015156106a457600080fd5b806002819055507f5f2bf49af30808bbff24b0af5819f56ba193d8fc47b367615775ee2dd5f97dec60025442604051808381526020018281526020019250505060405180910390a150565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bbb896ad336000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600087803b15156107b457600080fd5b6102c65a03f115156107c557600080fd5b5050506040518051905015156107da57600080fd5b6001600060016101000a81548160ff0219169083151502179055507f912ee23dde46ec889d6748212cce445d667f7041597691dc89e8549ad8bc0acb60405160405180910390a1565b60006005600083815260200190815260200160002060009054906101000a900460ff169050919050565b60056020528060005260406000206000915054906101000a900460ff1681565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bbb896ad336000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600087803b151561093257600080fd5b6102c65a03f1151561094357600080fd5b50505060405180519050151561095857600080fd5b806007819055507f0f581aed4ee55ef244fb65c7f6dc5bc8dba3949c6677963e9f59c228d1486b128142604051808381526020018281526020019250505060405180910390a150565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bbb896ad336000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600087803b1515610a6657600080fd5b6102c65a03f11515610a7757600080fd5b505050604051805190501515610a8c57600080fd5b6000809054906101000a900460ff161580610ab45750600060019054906101000a900460ff16155b15610abe57600080fd5b60008060016101000a81548160ff0219169083151502179055507f4c013bd73202fde3c7cfe26ca486d0882f2c5b2fc9c761b15212f759bd2347dd60405160405180910390a13373ffffffffffffffffffffffffffffffffffffffff166108fc3073ffffffffffffffffffffffffffffffffffffffff16319081150290604051600060405180830381858888f193505050501515610b5b57600080fd5b565b60065481565b6000809054906101000a900460ff1681565b60075481565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bbb896ad336000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600087803b1515610c4057600080fd5b6102c65a03f11515610c5157600080fd5b505050604051805190501515610c6657600080fd5b806006819055507fc1ffc0a535dad619268801c820e9d9dcb693707a76982d938cf157d2166045298142604051808381526020018281526020019250505060405180910390a150565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bbb896ad336000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600087803b1515610d7457600080fd5b6102c65a03f11515610d8557600080fd5b505050604051805190501515610d9a57600080fd5b6000809054906101000a900460ff1615610db357600080fd5b80600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060016000806101000a81548160ff02191690831515021790555050565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bbb896ad336000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600087803b1515610ed657600080fd5b6102c65a03f11515610ee757600080fd5b505050604051805190501515610efc57600080fd5b806001819055507f911ff22b86be19d04e0e69cc90dd5eb2534d2782c97535811f664c6f82e9275360015442604051808381526020018281526020019250505060405180910390a150565b600060019054906101000a900460ff1681565b600080600080600080600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bbb896ad336000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600087803b151561102857600080fd5b6102c65a03f1151561103957600080fd5b50505060405180519050151561104e57600080fd5b60001515600560008b815260200190815260200160002060009054906101000a900460ff16151514151561108157600080fd5b73a9df6dd82d1193451404d78bffe8ae140fbedb6063e0303a2e8b6000604051608001526040518263ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018080602001828103825283818151815260200191508051906020019080838360005b838110156111105780820151818401526020810190506110f5565b50505050905090810190601f16801561113d5780820380516001836020036101000a031916815260200191505b509250505060806040518083038186803b151561115957600080fd5b6102c65a03f4151561116a57600080fd5b50505060405180519060200180519060200180519060200180519050945094509450945073a9df6dd82d1193451404d78bffe8ae140fbedb6063e57ea16d8b8960016000604051602001526040518463ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018080602001846bffffffffffffffffffffffff19166bffffffffffffffffffffffff19168152602001838152602001828103825285818151815260200191508051906020019080838360005b8381101561124a57808201518184015260208101905061122f565b50505050905090810190601f1680156112775780820380516001836020036101000a031916815260200191505b5094505050505060206040518083038186803b151561129557600080fd5b6102c65a03f415156112a657600080fd5b50505060405180519050156113dd5760075485101515156112c657600080fd5b6402540be4006002548602029050600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f0dda65c89836040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050600060405180830381600087803b151561139857600080fd5b6102c65a03f115156113a957600080fd5b5050506001600560008b815260200190815260200160002060006101000a81548160ff0219169083151502179055506113e2565b600080fd5b5050505050949350505050565b6000806000341415801561140557506006543410155b90508091505090565b6000808284029050600084148061142f575082848281151561142c57fe5b04145b151561143757fe5b80915050929150505600a165627a7a7230582096a5a452671d27e9b522559dcd7f98278a2a8e0e5dfa5ba39817895bb16d6a4d002900000000000000000000000064c14e2c286918803de6d965174ca6bc9048eafa

Deployed Bytecode

0x6060604052600436106100f1576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063038e666f146100fc5780630502631714610125578063166280141461014e578063167ff46f1461017157806320940b13146101865780633050f769146101c1578063360821e8146101fc57806343d726d61461021f578063666fc4d414610234578063a970ef6e1461025d578063b107baa11461028a578063b1efbd6f146102b3578063b23d4854146102d6578063ce649b391461030f578063e4f2487a14610332578063ec8ac4d81461035f578063ee3a02291461038d575b6100fa3361043e565b005b341561010757600080fd5b61010f6105ad565b6040518082815260200191505060405180910390f35b341561013057600080fd5b6101386105b3565b6040518082815260200191505060405180910390f35b341561015957600080fd5b61016f60048080359060200190919050506105b9565b005b341561017c57600080fd5b6101846106ef565b005b341561019157600080fd5b6101a76004808035906020019091905050610823565b604051808215151515815260200191505060405180910390f35b34156101cc57600080fd5b6101e2600480803590602001909190505061084d565b604051808215151515815260200191505060405180910390f35b341561020757600080fd5b61021d600480803590602001909190505061086d565b005b341561022a57600080fd5b6102326109a1565b005b341561023f57600080fd5b610247610b5d565b6040518082815260200191505060405180910390f35b341561026857600080fd5b610270610b63565b604051808215151515815260200191505060405180910390f35b341561029557600080fd5b61029d610b75565b6040518082815260200191505060405180910390f35b34156102be57600080fd5b6102d46004808035906020019091905050610b7b565b005b34156102e157600080fd5b61030d600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610caf565b005b341561031a57600080fd5b6103306004808035906020019091905050610e11565b005b341561033d57600080fd5b610345610f47565b604051808215151515815260200191505060405180910390f35b61038b600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190505061043e565b005b341561039857600080fd5b610428600480803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509190803590602001909190803573ffffffffffffffffffffffffffffffffffffffff169060200190919080356bffffffffffffffffffffffff1916906020019091905050610f5a565b6040518082815260200191505060405180910390f35b6000806000809054906101000a900460ff1615806104695750600060019054906101000a900460ff16155b1561047357600080fd5b60008373ffffffffffffffffffffffffffffffffffffffff161415151561049957600080fd5b6104a16113ef565b15156104ac57600080fd5b3491506104c46001548361140e90919063ffffffff16565b905060008111156105a857600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f0dda65c84836040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050600060405180830381600087803b151561059357600080fd5b6102c65a03f115156105a457600080fd5b5050505b505050565b60015481565b60025481565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bbb896ad336000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600087803b151561067e57600080fd5b6102c65a03f1151561068f57600080fd5b5050506040518051905015156106a457600080fd5b806002819055507f5f2bf49af30808bbff24b0af5819f56ba193d8fc47b367615775ee2dd5f97dec60025442604051808381526020018281526020019250505060405180910390a150565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bbb896ad336000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600087803b15156107b457600080fd5b6102c65a03f115156107c557600080fd5b5050506040518051905015156107da57600080fd5b6001600060016101000a81548160ff0219169083151502179055507f912ee23dde46ec889d6748212cce445d667f7041597691dc89e8549ad8bc0acb60405160405180910390a1565b60006005600083815260200190815260200160002060009054906101000a900460ff169050919050565b60056020528060005260406000206000915054906101000a900460ff1681565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bbb896ad336000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600087803b151561093257600080fd5b6102c65a03f1151561094357600080fd5b50505060405180519050151561095857600080fd5b806007819055507f0f581aed4ee55ef244fb65c7f6dc5bc8dba3949c6677963e9f59c228d1486b128142604051808381526020018281526020019250505060405180910390a150565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bbb896ad336000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600087803b1515610a6657600080fd5b6102c65a03f11515610a7757600080fd5b505050604051805190501515610a8c57600080fd5b6000809054906101000a900460ff161580610ab45750600060019054906101000a900460ff16155b15610abe57600080fd5b60008060016101000a81548160ff0219169083151502179055507f4c013bd73202fde3c7cfe26ca486d0882f2c5b2fc9c761b15212f759bd2347dd60405160405180910390a13373ffffffffffffffffffffffffffffffffffffffff166108fc3073ffffffffffffffffffffffffffffffffffffffff16319081150290604051600060405180830381858888f193505050501515610b5b57600080fd5b565b60065481565b6000809054906101000a900460ff1681565b60075481565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bbb896ad336000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600087803b1515610c4057600080fd5b6102c65a03f11515610c5157600080fd5b505050604051805190501515610c6657600080fd5b806006819055507fc1ffc0a535dad619268801c820e9d9dcb693707a76982d938cf157d2166045298142604051808381526020018281526020019250505060405180910390a150565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bbb896ad336000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600087803b1515610d7457600080fd5b6102c65a03f11515610d8557600080fd5b505050604051805190501515610d9a57600080fd5b6000809054906101000a900460ff1615610db357600080fd5b80600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060016000806101000a81548160ff02191690831515021790555050565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bbb896ad336000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600087803b1515610ed657600080fd5b6102c65a03f11515610ee757600080fd5b505050604051805190501515610efc57600080fd5b806001819055507f911ff22b86be19d04e0e69cc90dd5eb2534d2782c97535811f664c6f82e9275360015442604051808381526020018281526020019250505060405180910390a150565b600060019054906101000a900460ff1681565b600080600080600080600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bbb896ad336000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600087803b151561102857600080fd5b6102c65a03f1151561103957600080fd5b50505060405180519050151561104e57600080fd5b60001515600560008b815260200190815260200160002060009054906101000a900460ff16151514151561108157600080fd5b73a9df6dd82d1193451404d78bffe8ae140fbedb6063e0303a2e8b6000604051608001526040518263ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018080602001828103825283818151815260200191508051906020019080838360005b838110156111105780820151818401526020810190506110f5565b50505050905090810190601f16801561113d5780820380516001836020036101000a031916815260200191505b509250505060806040518083038186803b151561115957600080fd5b6102c65a03f4151561116a57600080fd5b50505060405180519060200180519060200180519060200180519050945094509450945073a9df6dd82d1193451404d78bffe8ae140fbedb6063e57ea16d8b8960016000604051602001526040518463ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018080602001846bffffffffffffffffffffffff19166bffffffffffffffffffffffff19168152602001838152602001828103825285818151815260200191508051906020019080838360005b8381101561124a57808201518184015260208101905061122f565b50505050905090810190601f1680156112775780820380516001836020036101000a031916815260200191505b5094505050505060206040518083038186803b151561129557600080fd5b6102c65a03f415156112a657600080fd5b50505060405180519050156113dd5760075485101515156112c657600080fd5b6402540be4006002548602029050600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f0dda65c89836040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050600060405180830381600087803b151561139857600080fd5b6102c65a03f115156113a957600080fd5b5050506001600560008b815260200190815260200160002060006101000a81548160ff0219169083151502179055506113e2565b600080fd5b5050505050949350505050565b6000806000341415801561140557506006543410155b90508091505090565b6000808284029050600084148061142f575082848281151561142c57fe5b04145b151561143757fe5b80915050929150505600a165627a7a7230582096a5a452671d27e9b522559dcd7f98278a2a8e0e5dfa5ba39817895bb16d6a4d0029

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

00000000000000000000000064c14e2c286918803de6d965174ca6bc9048eafa

-----Decoded View---------------
Arg [0] : _authenticationManagerAddress (address): 0x64c14e2C286918803DE6d965174cA6bc9048Eafa

-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 00000000000000000000000064c14e2c286918803de6d965174ca6bc9048eafa


Libraries Used


Swarm Source

bzzr://96a5a452671d27e9b522559dcd7f98278a2a8e0e5dfa5ba39817895bb16d6a4d

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.