Skip to content

Instantly share code, notes, and snippets.

@0xc0de4c0ffee
Last active April 20, 2021 19:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save 0xc0de4c0ffee/5ffe2ecd4448e7c7daf1a98f2e90ece4 to your computer and use it in GitHub Desktop.
Save 0xc0de4c0ffee/5ffe2ecd4448e7c7daf1a98f2e90ece4 to your computer and use it in GitHub Desktop.
// SPDX-License-Identifier: WTFPL v4.20
pragma solidity >0.8.0;
interface iENS {
function setRecord(bytes32 node, address _owner, address _resolver, uint64 _ttl) external;
function setSubnodeRecord(bytes32 node, bytes32 label, address _owner, address _resolver, uint64 _ttl) external;
function setSubnodeOwner(bytes32 node, bytes32 label, address _owner) external returns(bytes32);
function setResolver(bytes32 node, address _resolver) external;
function setOwner(bytes32 node, address _owner) external;
function setTTL(bytes32 node, uint64 _ttl) external;
function setApprovalForAll(address operator, bool approved) external; // pre registration
function owner(bytes32 node) external view returns (address);
function resolver(bytes32 node) external view returns (address);
function ttl(bytes32 node) external view returns (uint64);
function recordExists(bytes32 node) external view returns (bool);
function isApprovedForAll(address _owner, address operator) external view returns (bool);
event NewOwner(bytes32 indexed node, bytes32 indexed label, address _owner);
event Transfer(bytes32 indexed node, address _owner);
event NewResolver(bytes32 indexed node, address _resolver);
event NewTTL(bytes32 indexed node, uint64 _ttl);
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
}
interface iERC20 {
function balanceOf(address _addr) external returns(uint);
function transfer(address _from, address _to, uint256 _value) external returns(bool);
function transferFrom(address _from, address _to, uint256 _value) external returns(bool);
}
interface iERC165 {
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
interface iERC721 is iERC165 {
function balanceOf(address owner) external view returns (uint256 balance);
function ownerOf(uint256 tokenId) external view returns (address owner);
function safeTransferFrom(address from, address to, uint256 tokenId) external;
function transferFrom(address from, address to, uint256 tokenId) external;
function approve(address to, uint256 tokenId) external;
function getApproved(uint256 tokenId) external view returns (address operator);
function setApprovalForAll(address operator, bool _approved) external;
function isApprovedForAll(address owner, address operator) external view returns (bool);
function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
}
interface iERC721Metadata is iERC721 {
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function tokenURI(uint256 tokenId) external view returns (string memory);
}
interface iERC1155 is iERC165 {
function balanceOf(address account, uint256 id) external view returns (uint256);
function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids) external view returns (uint256[] memory);
function setApprovalForAll(address operator, bool approved) external;
function isApprovedForAll(address account, address operator) external view returns (bool);
function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes calldata data) external;
function safeBatchTransferFrom(address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data) external;
event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);
event TransferBatch(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values);
event ApprovalForAll(address indexed account, address indexed operator, bool approved);
event URI(string value, uint256 indexed id);
}
library Logic {
function read() public view{
//bytes32 position = keccak256("diamond.standard.diamond.storage");
//assembly { ds.slot := position }
}
}
contract ERC165 {
function supportsInterface(bytes4 interfaceId) external pure returns (bool) {
return interfaceId == type(iERC165).interfaceId ||
interfaceId == type(iERC1155).interfaceId ||
interfaceId == type(iERC721Metadata).interfaceId;
}
}
contract Core {
address public ADMIN; // EOA, OR GU Admin Contract
iENS public ENS;
iERC20 public UBI;
bytes32 public immutable FREECLOUD = bytes32(0); // freecloud.eth namehash
bytes32 public immutable COLLECTIVE = bytes32(0); // collective.freecloud.eth namehash
bytes32 public immutable COLLECTION = bytes32(0); // collection.freecloud.eth namehash
uint8 public immutable decimals = 18;
string public constant name = "freecloud.eth";
string public constant symbol = "DUST";
mapping(address => uint64) public lastActive; // lock and disallow address reuse
mapping(bytes32 => address) private _approved;
mapping(address => mapping(address => uint64)) private _operator;
uint256 public totalCreators;
uint256 public totalCollectives;
uint256 public totalCollections;
uint256 public totalCreations;
// mapping(bytes32 => address) Map2Addr;
mapping(address => bytes32) Addr2Map;
mapping(bytes32 => bytes) public Contenthash;
mapping(bytes32 => bytes32) public Redirect;
mapping(bytes32 => mapping(address => bool)) private ownerOf;
mapping(bytes32 => Creator) internal _creators;
mapping(bytes32 => Collective) internal _collectives;
mapping(bytes32 => Collection) internal _collections;
mapping(bytes32 => Creation) internal _creations;
mapping(bytes32 => uint256) public totalSupply;
mapping(bytes32 => uint256) public _daiBalance;
mapping(bytes32 => uint256) public _ubiBalance;
function namehash(bytes32 node, bytes32 label) public pure returns(bytes32) {
return keccak256(abi.encodePacked(node, keccak256(abi.encodePacked(label))));
}
modifier addrInit(address addr) {
require(lastActive[addr] == 0, "Error: Address Already Used.");
lastActive[addr] = uint64(block.timestamp);
_;
}
modifier addrUpdate(address addr) {
require(lastActive[addr] > 9000, "Error: This address can't be reused.");
lastActive[addr] = uint64(block.timestamp);
_;
}
struct Creator { // artists
//uint64 joined; // joined date
uint16 collections; // number of albums
uint16 collectives; // member of bands
uint16 creations; // number of music/track NFT
uint32 fans; //
bytes32 name; // label of creator
address primary; // Primary active controller "Hot"
address backup; // secondary backup controller "Cold"
address PoH; // Human address
}
struct Collective { // group/ bands = creator
uint8 members; // number of members
uint16 collections; // total Albums
uint16 creations; // total tracks
uint32 fans; // number of fans
address manager; // manager address
bytes32 name; //
}
struct Collection { // Album
bytes32 by; // artist / collective
uint8 tracks; // number of tracks
//uint64 royalty; // base Royalty UBI
uint128 totalSupply;
}
struct Creation {
uint8 moon; // base to moon ratio
uint16 bar; // seconds per bar
uint16 timer; // seconds length of track
uint128 base; // base starting price
uint128 supply; // total NFT supply
uint128 price; // price tag
bytes32 collection; // album
bytes32 name; // title
}
//mapping(bytes32 => mapping(address => uint64)) collector;
modifier isAdmin() {
require(msg.sender == ADMIN, "Core: Only Admin");
_;
}
function isAuthorised(bytes32 node) internal view returns(bool){
}
modifier authorised(bytes32 node) {
require(isAuthorised(node));
_;
}
event ContenthashChanged(bytes32 indexed node, bytes hash);
function str_b32(string memory str) internal pure returns (bytes32 b32) {
assembly {
str := mload(add(b32, 32))
}
}
function b32_str(bytes32 _b32) public pure returns (string memory) {
return string(abi.encodePacked(_b32));
}
function isValidName(string memory str) public pure returns(bool ok) {
bytes memory _b = bytes(str);
if(_b.length < 32 && _b[0] != 0x2D && _b[0] != 0x30) { // can't start with zero / hyphen, max 32 * bytes1 = bytes32
uint i = 0;
ok = true;
while(ok && i < _b.length) {
// small caps a-z || 0-9 || "-" hyphen
ok = (_b[i] > 0x60 && _b[i] < 0x7B) || (_b[i] > 0x2F && _b[i] < 0x3A) || _b[i] == 0x2D;
i++;
}
// block punycoded format "xn--"
if((ok && _b[2] == 0x2D) && (_b[0] == 0x78 && _b[1] == 0x6E)) {
ok = false;
}
}
}
}
contract EIP712 is Core {
// keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)");
bytes32 public immutable PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;
//
bytes32 public immutable DOMAIN_SEPARATOR = 0x5e053d4308076b8b3966d832197af0284e834abfc18d362c9a366e1a17c80f35;
mapping(bytes32 => uint64) public _lock;
function verify(address signer, bytes32 digest, uint8 v, bytes32 r, bytes32 s) external pure returns(bool) {
return (signer == ecrecover(digest, v, r, s) && signer != address(0));
}
function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external view {
require(deadline > block.timestamp, 'UniswapV2: EXPIRED');
bytes32 digest = keccak256(
abi.encodePacked(
'\x19\x01',
DOMAIN_SEPARATOR,
keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, deadline))
)
);
address recoveredAddress = ecrecover(digest, v, r, s);
require(recoveredAddress != address(0) && recoveredAddress == owner, 'UniswapV2: INVALID_SIGNATURE');
//_approve(owner, spender, value);
}
}
contract Creators is Core {
event NewCreator(bytes32 indexed name, bytes32 indexed namehash);
function newCreator(address primary, bytes32 name, bytes calldata _contenthash) external addrInit(primary) {
bytes32 _namehash = namehash(FREECLOUD, name);
Creator storage creator = _creators[_namehash];
require(creator.backup == address(0), "Creators: Nick already registered");
creator.name = name;
creator.primary = primary;
Addr2Map[primary] = _namehash;
ENS.setSubnodeRecord(FREECLOUD, name, address(this), address(this), 9000);
Contenthash[_namehash] = _contenthash;
emit ContenthashChanged(_namehash, _contenthash);
emit NewCreator(name, _namehash);
}
function creatorAlias(bytes32 _alias) external {
bytes32 _namehash = Addr2Map[msg.sender];
require(msg.sender == _creators[_namehash].primary || msg.sender == _creators[_namehash].backup,"Creators: Only creator keys can set alias.");
require(ENS.owner(_alias) != address(this), "ENS : alias is owned by this contract address");
require(ENS.resolver(_alias) == address(this), "ENS : resolver isn't set to this contract address");
require(Redirect[_alias] == bytes32(0), "Redirect already set");
Redirect[_alias] = _namehash;
emit ContenthashChanged(_alias, Contenthash[_namehash]);
}
event NewBackupKey(bytes32 indexed _namehash, address by, address backup);
function newBackupKey(address backup) addrInit(backup) external {
bytes32 _namehash = Addr2Map[msg.sender];
Creator storage creator = _creators[_namehash];
require((msg.sender == creator.primary && creator.backup == address(0)) || msg.sender == creator.backup, "Creators: Only backup key can change backup.");
creator.backup = backup;
emit NewBackupKey(_namehash, msg.sender, backup);
}
event NewPrimaryKey(bytes32 indexed _namehash, address by, address backup);
function newPrimaryKey(address primary) addrInit(primary) external {
bytes32 _namehash = Addr2Map[msg.sender];
Creator storage creator = _creators[_namehash];
require(msg.sender == creator.backup,"Creators: Only backup key can change primary.");
creator.primary = primary;
emit NewPrimaryKey(_namehash, msg.sender, primary);
}
function Lock() external {
bytes32 _namehash = Addr2Map[msg.sender];
Creator storage creator = _creators[_namehash];
require((creator.primary == msg.sender || msg.sender == creator.backup), "Creators: Only backup or primary key can lock.");
creator.primary = address(418);
emit NewPrimaryKey(_namehash, msg.sender, address(418));
}
event AdminLock(bytes32 indexed _namehash, uint16 indexed reason, bytes content);
function adminLock(bytes32 _namehash, uint16 _reason, bytes memory _contenthash) isAdmin external {
Creator storage creator = _creators[_namehash];
creator.primary = address(uint160(_reason));
creator.backup = address(uint160(_reason));
emit AdminLock(_namehash, _reason, _contenthash);
}
event AdminUnlock(bytes32 indexed _namehash, uint16 indexed reason, bytes content);
function adminUnlock(bytes32 _namehash, address backup, uint16 _reason, bytes memory _contenthash) isAdmin external {
Creator storage creator = _creators[_namehash];
require(creator.primary == creator.backup && uint160(creator.backup) <= type(uint16).max, "Namehash not locked");
creator.backup = backup;
emit AdminUnlock(_namehash, _reason, _contenthash);
}
}
contract Collectives is Core {
event NewCollective(bytes32 indexed hash, bytes32 name);
event NewMember(bytes32 indexed colllection, bytes32 indexed creator);
mapping(bytes32 => mapping(bytes32 => uint64)) internal Members;
function newCollective(bytes32 _name, address manager, bytes calldata _contenthash) external isAdmin {
bytes32 _namehash = namehash(COLLECTIVE, _name);
Collective storage collective = _collectives[_namehash];
require(collective.manager == address(0), "Collectives: Nick already registered");
ENS.setSubnodeRecord(COLLECTIVE, _name, address(this), address(this), 9000);
collective.manager = manager;
collective.name = _name;
emit NewCollective(_namehash, _name);
Contenthash[_namehash] = _contenthash;
emit ContenthashChanged(_namehash, _contenthash);
}
function addMembers(bytes32 _namehash, bytes32[] calldata members) external {
Collective storage collective = _collectives[_namehash];
require(msg.sender == collective.manager, "Only Manager");
collective.members += members.length;
for(uint i= 0; i < members.length; i++) {
require(uint160(_creators[members[i]].backup) > 9000, "Creator Not Active");
require(Members[_namehash][members[i]] == 0, "Already Member");
Members[_namehash][members[i]] = uint64(block.timestamp);
emit NewMember(_namehash, members[i]);
}
}
function addMember(bytes32 _namehash, bytes32 member) external {
Collective storage collective = _collectives[_namehash];
require(msg.sender == collective.manager, "Only Manager");
collective.members++;
require(uint160(_creators[member].backup) > 9000, "Creator Not Active");
require(Members[_namehash][member] == 0, "Already Member");
Members[_namehash][member] = uint64(block.timestamp);
emit NewMember(_namehash, member);
}
function rageQuit(bytes32 _namehash) external {
bytes32 member = Addr2Map[msg.sender];
Collective storage collective = _collectives[_namehash];
require(Members[_namehash][member] > 9000, "Not Member");
require(msg.sender == _creators[member].backup, "Only backup Keys can rage quit");
Members[_namehash][member] = uint64(501);
emit NewMember(_namehash, member);
uint256 _dai = _daiBalance[_namehash][member]
collective.members--;
}
}
contract AFreecloud is ERC165, EIP712 {
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment