Back to Home

Curio18(CRO18)

0x8ccf904e75bc...d0caf0b2bbcb
Spurious DragonExact Bytecode Match
Deployed June 20, 2017 (8 years ago)Block 3,902,090

Curio Cards v2 factory contract (Cards 17-19) with added thumbnail field, June 2017.

Token Information

Token Name
Curio18
Symbol
CRO18
Decimals
0

Key Facts

Deployment Block
3,902,090
Deployment Date
Jun 20, 2017, 07:06 AM
Code Size
5.8 KB
Transactions by Year
20171
20211
20231

Description

Cards 17-19 were deployed by a separate factory (0xeca65Be7...) from the original Curio Cards 1-17. The v2 factory added a sixth string field - thumbnail - a second IPFS hash for a card thumbnail image. This shifts the description field from storage slot 5 to slot 6 and adds a thumbnail() getter (selector 0x5afc2ab4). All three cards were created in the same factory session on June 20, 2017. Source recovered via bytecode archaeology: 19 of 20 function selectors matched the known 17b-erc20.sol source; the twentieth was identified as thumbnail() from storage analysis and the OpenChain signature database.

Source Verified

SolidityExact bytecode match(5,919 bytes)
Compiler: 60cc166

Exact bytecode match with solc 0.4.8+commit.60cc1668, optimizer OFF. Source recovered by adding string public thumbnail field (slot 5) to the known Curio Cards v1 source (17b-erc20.sol). Cards 17-19 were deployed by a different factory (0xeca65Be7...) using this updated contract.

Spurious Dragon Era

Continued DoS protection. State trie clearing.

Block span: 2,675,0004,369,999
November 22, 2016October 16, 2017

Bytecode Overview

Opcodes5,919
Unique Opcodes190
Jump Instructions244
Storage Operations78

Verified Source Available

Source verified through compiler archaeology and exact bytecode matching.

View Verification Proof
Show source code (Solidity)
pragma solidity ^0.4.8;

contract tokenRecipient { function receiveApproval(address _from, uint256 _value, address _token, bytes _extraData); }
contract owned {
    address public owner;

    function owned() {
        owner = msg.sender;
    }

    modifier onlyOwner {
        if (msg.sender != owner) throw;
        _;
    }

    function transferOwnership(address newOwner) onlyOwner {
        owner = newOwner;
    }
}


contract CardToken is owned {
    string public standard = 'Token 0.1';
    string public name;
    string public symbol;
    string public ipfs_hash;
    string public thumbnail;
    string public description;
    bool public isLocked;
    uint8 public decimals;
    uint256 public totalSupply;

    mapping (address => uint256) public balanceOf;
    mapping (address => mapping (address => uint256)) public allowance;

    event Transfer(address indexed from, address indexed to, uint256 value);

    function CardToken(
        uint256 initialSupply,
        string tokenName,
        string tokenSymbol,
        string tokenDescription,
        string ipfsHash,
        string thumbnailHash
        ) {
        balanceOf[msg.sender] = initialSupply;
        totalSupply = initialSupply;
        name = tokenName;
        symbol = tokenSymbol;
        description = tokenDescription;
        ipfs_hash = ipfsHash;
        thumbnail = thumbnailHash;
        decimals = 0;
    }

    function transfer(address _to, uint256 _value) {
        if (balanceOf[msg.sender] < _value) throw;
        if (balanceOf[_to] + _value < balanceOf[_to]) throw;
        balanceOf[msg.sender] -= _value;
        balanceOf[_to] += _value;
    }

    function approve(address _spender, uint256 _value)
        returns (bool success) {
        allowance[msg.sender][_spender] = _value;
        return true;
    }

    function approveAndCall(address _spender, uint256 _value, bytes _extraData)
        returns (bool success) {
        tokenRecipient spender = tokenRecipient(_spender);
        if (approve(_spender, _value)) {
            spender.receiveApproval(msg.sender, _value, this, _extraData);
            return true;
        }
    }

    function transferFrom(address _from, address _to, uint256 _value) returns (bool success) {
        if (balanceOf[_from] < _value) throw;
        if (balanceOf[_to] + _value < balanceOf[_to]) throw;
        if (_value > allowance[_from][msg.sender]) throw;
        balanceOf[_from] -= _value;
        balanceOf[_to] += _value;
        allowance[_from][msg.sender] -= _value;
        Transfer(_from, _to, _value);
        return true;
    }

    function mintToken(address target, uint256 mintedAmount) onlyOwner {
        if (isLocked) { throw; }

        balanceOf[target] += mintedAmount;
        totalSupply += mintedAmount;
        Transfer(0, this, mintedAmount);
        Transfer(this, target, mintedAmount);
    }

    function lock() onlyOwner  {
        isLocked = true;
    }

    function setDescription(string desc) onlyOwner {
         description = desc;
    }

    function () {
        throw;
    }
}

contract CardFactory {
    address[] public Cards;
    uint256 public CardCount;

    function CardFactory() {
        CardCount = 0;
    }

    function CreateCard(
        uint256 _initialAmount,
        string _name,
        string _symbol,
        string _desc,
        string _ipfshash,
        string _thumbnail
    ) returns (address) {
        CardToken newToken = (new CardToken(_initialAmount, _name, _symbol, _desc, _ipfshash, _thumbnail));
        Cards.push(address(newToken));
        CardCount++;
        newToken.transferOwnership(msg.sender);
        newToken.transfer(msg.sender, _initialAmount);
        return address(newToken);
    }

    function () {
        throw;
    }
}

External Links