The deployer's first version of the PNS token, from October 2017, with its own themed function names and an airdrop of 80,081.35 PNS to each new address.
Context
The deployer registered the token in the Parity token registry with the logo URL dar.sh/pns120.png. That logo led to the project website, penis.supply, which is now offline. The earliest archived copy (November 2018) links its Source Code button to Etherscan. Archived copies from October 2020 onward link it to github.com/tkresearch/PNS, which connects the deployer to the tkresearch GitHub account.
The repository contains one source file, pns.sol, committed on 21 December 2018. It is the later contract (0xce853db3359326dB6D03981C9fb42983BbCdd007), not this one. No public copy of this contract's original source has been found.
A BitcoinTalk announcement thread for PNS was posted on 15 November 2017 by the account PNS Token. It covers the later contract (0xce853db3359326dB6D03981C9fb42983BbCdd007), not this one. It describes a Twitter-based airdrop campaign, lists a Wix website, a Twitter account and a Telegram group, and does not name the deployer. One reply on the first page reports finding 80081,350 PNS in a wallet without knowing where it came from, which is the built-in airdrop balance.
Token Information
Key Facts
Description
Penis (PNS) is a token contract deployed on 17 October 2017. It is the deployer's first version of the PNS token. In place of the standard ERC-20 function names, it uses names the deployer wrote to fit the token's theme. Only name, symbol and decimals use the usual names.
Supply is created by an airdrop built into the balance logic. Any address that has never interacted with the contract reports a balance of 80,081.35 PNS. The first transfer to or from that address writes the amount to storage and adds it to the total supply. The constructor minted 641,291,450.80 PNS to the deployer, which is 8,008 times the airdrop amount. Airdrops stop once supply reaches the cap of 6,413,314,914.75 PNS, which is 80,085 times the airdrop amount. After the deployer's mint, the cap leaves room for 72,077 airdrops.
As of 8 November 2026, 5,180,062,124.75 PNS had been minted (80.8% of the cap), with 15,400 airdrops left.
Function names, with the matching ERC-20 function in brackets:
- allTheDongs() (totalSupply)
- swole() (balance of the caller)
- howSwole(address) (balanceOf)
- dispense(address,uint256) (transfer)
- squeezeOut(address,address,uint256) (transferFrom)
- swallow(address,uint256) (approve)
- sacSize(address,address) (allowance)
About 16 minutes later the same deployer created 0xFC8994b01627a9A56b93771e93223533B28ED6a8, which switched to standard ERC-20 function names and used the symbol SIM with a smaller airdrop and cap. Five minutes after that came 0xce853db3359326dB6D03981C9fb42983BbCdd007, the same code as SIM with the symbol PNS and this contract's airdrop and cap. That contract is the PNS token the project website promoted and the one announced on BitcoinTalk.
Source Verified
solc 0.4.8+commit.60cc1668, optimizer on, 200 runs. Runtime and creation code identical to the chain; only the 32-byte bzzr0 metadata hash differs. Public function names come from the deployed 4-byte selectors. They were recovered with dictionary and brute-force selector searches and each was confirmed with keccak256. Internal names (_allTheDongs, _load, _maxLoad, girth, sharedLoad, swallowed, shareLoad, getGirth) cannot be recovered from bytecode and are inferred from the public naming pattern. Comments are copied verbatim from the deployer's later contract, 0xce853db3359326dB6D03981C9fb42983BbCdd007.
Historian Categories
Heuristic Analysis
The following characteristics were detected through bytecode analysis and may not be accurate.
Byzantium Era
First Metropolis hard fork. Added zk-SNARK precompiles, REVERT opcode, and staticcall.
Bytecode Overview
Verified Source Available
Source verified through compiler archaeology (near-exact bytecode match).
Show source code (Solidity)
// Submitted by EthereumHistory (ethereumhistory.com)
pragma solidity ^0.4.8;
contract ERC20Interface {
function allTheDongs() public constant returns (uint256 supply);
function swole() public constant returns (uint256);
function howSwole(address _owner) public constant returns (uint256);
function dispense(address _to, uint256 _value) public returns (bool success);
function squeezeOut(address _from, address _to, uint256 _value) public returns (bool success);
function swallow(address _spender, uint256 _value) public returns (bool success);
function sacSize(address _owner, address _spender) public constant returns (uint256 remaining);
event Transfer(address indexed _from, address indexed _to, uint256 _value);
event Approval(address indexed _owner, address indexed _spender, uint256 _value);
}
// penispenispenispenis
// YOU get a penis, and YOU get a penis, and YOU get a penis!
contract Penis is ERC20Interface {
string public constant symbol = "PNS";
string public constant name = "Penis";
uint8 public constant decimals = 2;
uint256 _allTheDongs = 0;
uint256 _load = 8008135;
uint256 _maxLoad = _load * 80085;
mapping(address => uint256) girth;
mapping(address => bool) sharedLoad;
// Penis accepts request to tip-touch another Penis
mapping(address => mapping (address => uint256)) swallowed;
function Penis() {
sharedLoad[msg.sender] = true;
girth[msg.sender] = _load * 8008;
_allTheDongs = girth[msg.sender];
}
function allTheDongs() constant returns (uint256 supply) {
return _allTheDongs;
}
// What's my girth?
function swole() constant returns (uint256) {
return getGirth(msg.sender);
}
// What is the length of a particular Penis?
function howSwole(address _address) constant returns (uint256) {
return getGirth(_address);
}
// Tenderly remove hand from Penis and place on another Penis
function dispense(address _to, uint256 _amount) returns (bool success) {
shareLoad(msg.sender);
if (girth[msg.sender] >= _amount
&& _amount > 0) {
shareLoad(_to);
if (girth[_to] + _amount > girth[_to]) {
girth[msg.sender] -= _amount;
girth[_to] += _amount;
Transfer(msg.sender, _to, _amount);
return true;
} else {
return false;
}
} else {
return false;
}
}
// Perform the inevitable actions which cause release of that which each Penis
// is built to deliver. In EtherPenisLand there are only Penises, so this
// allows the transmission of one Penis's payload (or partial payload but that
// is not as much fun) INTO another Penis. This causes the Penisae to change
// form such that all may see the glory they each represent. Erections.
function squeezeOut(address _from, address _to, uint256 _amount) returns (bool success) {
shareLoad(_from);
if (girth[_from] >= _amount
&& swallowed[_from][msg.sender] >= _amount
&& _amount > 0) {
shareLoad(_to);
if (girth[_to] + _amount > girth[_to]) {
girth[_from] -= _amount;
swallowed[_from][msg.sender] -= _amount;
girth[_to] += _amount;
Transfer(_from, _to, _amount);
return true;
} else {
return false;
}
} else {
return false;
}
}
// Allow splooger to cause a payload release from your Penis, multiple times, up to
// the point at which no further release is possible..
function swallow(address _spender, uint256 _amount) returns (bool success) {
swallowed[msg.sender][_spender] = _amount;
Approval(msg.sender, _spender, _amount);
return true;
}
function sacSize(address _owner, address _spender) constant returns (uint256 remaining) {
return swallowed[_owner][_spender];
}
// internal privats
function shareLoad(address _address) internal returns (bool success) {
if (_allTheDongs < _maxLoad && !sharedLoad[_address]) {
sharedLoad[_address] = true;
girth[_address] = _load;
_allTheDongs += _load;
}
return true;
}
function getGirth(address _address) internal returns (uint256) {
if (_allTheDongs < _maxLoad && !sharedLoad[_address]) {
return girth[_address] + _load;
}
else {
return girth[_address];
}
}
}External Links
Related contracts
Penis
Same deployerThe deployer's second Penis token contract from October 2017, with standard ERC-20 function names, the symbol SIM and a 10,000 SIM airdrop per new address.
0xfc8994...8ed6a8October 17, 2017BancorQuickConverter
Same eraBancor's October 2017 router contract, converting tokens along a path of Bancor converters in one transaction.
0xf87a7e...dd38b1October 22, 2017BancorConverterExtensions
Same eraThe first BancorConverterExtensions, the lookup contract pointing Bancor converters at the current formula, gas price limit and quick converter.
0x97b155...64b103October 22, 2017Asteroid
Same eraERC20 token built on OpenZeppelin v1.3.0 with owner-restricted burn function. Deployed during the 2017-2018 ICO era.
0xd86e37...474375October 24, 2017CRYPTOCTEST
Same eraCryptoCats pre-launch test contract (Nov 2017). The first version to introduce cat names and the allInitialOwnersAssigned() initialization pattern.
0xd23ade...718456November 11, 2017Wallet
Same eraOwner-controlled multi-purpose wallet, first of 1,374 identical siblings. Accepts ETH, sweeps ERC-20 tokens, and implements ERC-223 tokenFallback. Source verified by EthereumHistory.
0x850c3b...ec517eDecember 7, 2017