SAND token contract has migrated to a new address.
ERC-20
Old Contract
Overview
Max Total Supply
3,000,000,000 SAND
Holders
64 (0.00%)
Market
Onchain Market Cap
$0.00
Circulating Supply Market Cap
-
Other Info
Token Contract (WITH 18 Decimals)
Balance
4,888.88 SANDValue
$0.00Loading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Name:
AdminUpgradeabilityProxy
Compiler Version
v0.5.2+commit.1df8f40c
Contract Source Code (Solidity Standard Json-Input format)
// from https://github.com/zeppelinos/zos/blob/1cea266a672a1efc31915420af5eb5185173837c/packages/lib/contracts/upgradeability/AdminUpgradeabilityProxy.sol pragma solidity 0.5.2; import "./UpgradeabilityProxy.sol"; import "./ProxyAdmin.sol"; /** * @title AdminUpgradeabilityProxy * @dev This contract combines an upgradeability proxy with an authorization * mechanism for administrative tasks. * All external functions in this contract must be guarded by the * `ifAdmin` modifier. See ethereum/solidity#3864 for a Solidity * feature proposal that would enable this to be done automatically. */ contract AdminUpgradeabilityProxy is UpgradeabilityProxy { /** * @dev Emitted when the administration has been transferred. * @param previousAdmin Address of the previous admin. * @param newAdmin Address of the new admin. */ event AdminChanged(address previousAdmin, address newAdmin); /** * @dev Storage slot with the admin of the contract. * This is the keccak-256 hash of "org.zeppelinos.proxy.admin", and is * validated in the constructor. */ bytes32 private constant ADMIN_SLOT = 0x10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b; /** * @dev Modifier to check whether the `msg.sender` is the admin. * If it is, it will run the function. Otherwise, it will delegate the call * to the implementation. */ modifier ifAdmin() { if (msg.sender == _admin()) { _; } else { _fallback(); } } /** * Contract constructor. * It sets the `msg.sender` as the proxy administrator. * @param _implementation address of the initial implementation. * @param _data Data to send as msg.data to the implementation to initialize the proxied contract. * It should include the signature and the parameters of the function to be called, as described in * https://solidity.readthedocs.io/en/v0.4.24/abi-spec.html#function-selector-and-argument-encoding. * This parameter is optional, if no data is given the initialization call to proxied contract will be skipped. */ constructor(address payable _owner, address _implementation, bytes memory _data) UpgradeabilityProxy(_implementation, _data) public payable { assert(ADMIN_SLOT == keccak256("org.zeppelinos.proxy.admin")); ProxyAdmin proxyAdmin = new ProxyAdmin(this, _owner); // TODO cheaper creation : https://eips.ethereum.org/EIPS/eip-1167 emit AdminChanged(address(0), address(proxyAdmin)); _setAdmin(address(proxyAdmin)); } /** * @return The address of the proxy admin. */ function admin() external ifAdmin returns (address) { return _admin(); } /** * @return The address of the implementation. */ function implementation() external ifAdmin returns (address) { return _implementation(); } /** * @dev Changes the admin of the proxy. * Only the current admin can call this function. * @param newAdmin Address to transfer proxy administration to. */ function changeAdmin(address newAdmin) external ifAdmin { require(newAdmin != address(0), "Cannot change the admin of a proxy to the zero address"); emit AdminChanged(_admin(), newAdmin); _setAdmin(newAdmin); } /** * @dev Upgrade the backing implementation of the proxy. * Only the admin can call this function. * @param newImplementation Address of the new implementation. */ function upgradeTo(address newImplementation) external ifAdmin { _upgradeTo(newImplementation); } /** * @dev Upgrade the backing implementation of the proxy and call a function * on the new implementation. * This is useful to initialize the proxied contract. * @param newImplementation Address of the new implementation. * @param data Data to send as msg.data in the low level call. * It should include the signature and the parameters of the function to be called, as described in * https://solidity.readthedocs.io/en/v0.4.24/abi-spec.html#function-selector-and-argument-encoding. */ function upgradeToAndCall(address newImplementation, bytes calldata data) payable external ifAdmin { _upgradeTo(newImplementation); (bool success, bytes memory _) = newImplementation.delegatecall(data); require(success, "failed to call newImplementation"); } /** * @return The admin slot. */ function _admin() internal view returns (address adm) { bytes32 slot = ADMIN_SLOT; assembly { adm := sload(slot) } } /** * @dev Sets the address of the proxy admin. * @param newAdmin Address of the new proxy admin. */ function _setAdmin(address newAdmin) internal { bytes32 slot = ADMIN_SLOT; assembly { sstore(slot, newAdmin) } } /** * @dev Only fall back when the sender is not the admin. */ function _willFallback() internal { require(msg.sender != _admin(), "Cannot call fallback function from the proxy admin"); super._willFallback(); } }
pragma solidity 0.5.2; import "../../Libraries/BytesUtil.sol"; contract AssetApproveExtension { // will expect TheSandBox721 mapping(address => mapping(address => uint256)) approvalMessages; // TODO mapping(address => mapping (uint256 => bool)) usedApprovalMessages; // TODO remove as we can use erc1155 totkensReceived hook function setApprovalForAllAndCall(address _target, bytes memory _data) public payable returns(bytes memory){ require(BytesUtil.doFirstParamEqualsAddress(_data, msg.sender), "first param != sender"); _setApprovalForAllFrom(msg.sender, _target, true); (bool success, bytes memory returnData) = _target.call.value(msg.value)(_data); require(success, "Something went wrong with the extra call."); return returnData; } function approveAllViaSignedMessage(address _target, uint256 _nonce, bytes calldata signature) external { address signer; // TODO ecrecover(hash, v, r, s); require(approvalMessages[signer][_target]++ == _nonce); _setApprovalForAllFrom(signer, _target, true); } // TODO 2 signatures one for approve and one for call ? function approveAllAndCallViaSignedMessage(address _target, uint256 _nonce, bytes calldata _data, bytes calldata signature) external payable returns(bytes memory){ address signer; // TODO ecrecover(hash, v, r, s); require(BytesUtil.doFirstParamEqualsAddress(_data, signer), "first param != signer"); require(approvalMessages[signer][_target]++ == _nonce); _setApprovalForAllFrom(signer, _target, true); (bool success, bytes memory returnData) = _target.call.value(msg.value)(_data); require(success, "Something went wrong with the extra call."); return returnData; } function _setApprovalForAllFrom(address owner, address _operator, bool _approved) internal; }
pragma solidity 0.5.2; import "../Interfaces/ERC1155.sol"; import "../Libraries/AddressUtils.sol"; import "../Libraries/ObjectLib32.sol"; import "../Libraries/SafeMath.sol"; import "../Libraries/BytesUtil.sol"; import "../Interfaces/ERC721.sol"; import "../Interfaces/ERC721TokenReceiver.sol"; import "../Interfaces/ERC20.sol"; import "../Sand.sol"; import "./Interfaces/MintingFeeCollector.sol"; import { ProxyImplementation } from "../Libraries/ProxyImplementation.sol"; contract ERC1155ERC721 is ProxyImplementation, ERC1155, ERC721 { ////////////////// Super Operators /////////////////////////////////////////////////////// // Allowing extension without redeploy mapping(address => bool) internal mSuperOperators; address public admin; event AdminChanged(address oldAdmin, address newAdmin); function changeAdmin(address _admin) external { require(msg.sender == admin, "only admin can change admin"); emit AdminChanged(admin, _admin); admin = _admin; } event SuperOperator(address superOperator, bool enabled); function setSuperOperator(address _superOperator, bool _enabled) external { require(msg.sender == admin, "only admin is allowed to add super operators"); mSuperOperators[_superOperator] = _enabled; emit SuperOperator(_superOperator, _enabled); } function isSuperOperator(address who) public view returns(bool) { return mSuperOperators[who]; } ///////////////////////////////////////////////////////////////////////////////////////////// // LIBRARIES ///////////////////////////////////////////////////////////////////////// using AddressUtils for address; using ObjectLib32 for ObjectLib32.Operations; using ObjectLib32 for uint256; using SafeMath for uint256; /////////////////////////////////////////////////////////////////////////////////////////////// // CONSTANTS ////////////////////////////////////////////////////////////////////////////////// bytes4 constant private ERC1155_REJECTED = 0xafed434d; // keccak256("reject_erc1155_tokens()") bytes4 constant private ERC1155_RECEIVED = 0xf23a6e61; // TODO use latest spec // better yet : generate it bytes4 constant private ERC1155_BATCH_RECEIVED = 0xbc197c81; // TODO use latest spec // better yet : generate it bytes4 constant private ERC721_RECEIVED = 0x150b7a02; // TODO use latest spec // better yet : generate it /////////////////////////////////////////////////////////////////////////////////////////////// // STORAGE ///////////////////////////////////////////////////////////////////////////////////// uint88 nextSubId; mapping(address => uint256) numNFTPerAddress; // required for erc721 mapping(uint256 => address) owners; // required for erc721 mapping(address => mapping(uint256 => uint256)) packedTokenBalance; // required for erc1155 mapping(address => mapping(address => bool)) operatorsForAll; // required for erc721 and erc1155 mapping(uint256 => address) erc721_operators; // required for erc721 mapping(uint256 => address) creators; // use only for when changing original creator // TODO mapping (uint256 => string) public erc721_metadataURIs; // required for erc721 mapping (uint256 => bytes32) public erc1155_metadataURIHashes; // required for extraction uint256 public mintingFee; address feeCollector; Sand _sandContract; /////////////////////////////////////////////////////////////////////////////////////////////// constructor(Sand sand, address _feeCollector, address _admin) public { initERC1155ERC721(sand, _feeCollector, _admin); } function initERC1155ERC721(Sand sand, address _feeCollector, address _admin) public phase('ERC1155ERC721'){ nextSubId = 1; // set here to non-zero so it can cover the cost of first minting _sandContract = sand; feeCollector = _feeCollector; admin = _admin; } function sandContract() internal view returns(Sand) { return _sandContract; } function setFeeCollection(address _newFeeCollector, uint256 _newFee) external { require(msg.sender == feeCollector, "only feeCollector can update"); feeCollector = _newFeeCollector; mintingFee = _newFee; } function mint(address _sender, uint256 _sandAmount, uint88 _subId, string calldata _uri, uint256 _supply, address _owner, bytes calldata _data) external returns (uint256 tokenId) { require(_owner != address(0), "Invalid owner"); require(msg.sender == _sender || msg.sender == address(_sandContract), "sender != msg.sender && sandContract"); require(_sandAmount == mintingFee, "fee not matching"); if(_sandAmount > 0) { _sandContract.transferFrom(_sender, feeCollector, _sandAmount); } require(bytes(_uri).length > 0, "uri cannot be an empty string"); if(_subId == 0) { tokenId = uint256(_sender) * 2**(256-160) + 0 * 2**(256-160-8) + nextSubId; nextSubId++; } else { tokenId = uint256(_sender) * 2**(256-160) + 1 * 2**(256-160-8) + _subId; } _mint(_uri, _supply, _sender, _owner, tokenId, _data); if(feeCollector.isContract()) { MintingFeeCollector(feeCollector).single_minted(tokenId, _sandAmount); } } function _mint(string memory _uri, uint256 _supply, address _creator, address _owner, uint256 tokenId, bytes memory _data) internal { if(_supply == 1) { // ERC721 require(bytes(erc721_metadataURIs[tokenId]).length == 0, "tokenId already used"); numNFTPerAddress[_owner] ++; owners[tokenId] = _owner; emit Transfer(address(0), _owner, tokenId); erc721_metadataURIs[tokenId] = _uri; } else { require(uint256(erc1155_metadataURIHashes[tokenId]) == 0, "tokenId already used"); (uint256 bin, uint256 index) = tokenId.getTokenBinIndex(); packedTokenBalance[_owner][bin] = packedTokenBalance[_owner][bin].updateTokenBalance( index, _supply, ObjectLib32.Operations.REPLACE ); erc1155_metadataURIHashes[tokenId] = keccak256(abi.encodePacked(_uri)); } emit TransferSingle(_creator, address(0), _owner, tokenId, _supply); emit URI(_uri, tokenId); require(_checkERC1155AndCallSafeTransfer(_creator, address(0), _owner, tokenId, _supply, _data, _supply == 1, false)); } function mintMultiple(address _sender, uint256 _sandAmount, uint88 firstSubId, string calldata _uris, uint16[] calldata lengths, uint256[] calldata _supplies, address _owner, bytes calldata _data) external { require(_owner != address(0), "Invalid owner"); require(msg.sender == _sender || msg.sender == address(_sandContract), "sender != msg.sender && sandContract"); require(_sandAmount == mintingFee * _supplies.length, "fee not matching"); if(_sandAmount > 0) { _sandContract.transferFrom(_sender, feeCollector, _sandAmount); } require(lengths.length == _supplies.length, "Inconsistent array length between args lengths and supplies."); uint256[] memory tokenIds = generateTokenIds(_sender, firstSubId, _supplies.length); _mintBatchesWithNFTs(_sender, _uris, lengths, _supplies, 0, _owner, tokenIds[0]); emit TransferBatch(_sender, address(0), _owner, tokenIds, _supplies); require(_checkERC1155AndCallSafeBatchTransfer(_sender, address(0), _owner, tokenIds, _supplies, _data)); if(feeCollector.isContract()) { MintingFeeCollector(feeCollector).multiple_minted(tokenIds, mintingFee); } } function generateTokenIds(address _creator, uint88 firstSubId, uint256 numTokens) internal returns (uint256[] memory){ uint256[] memory tokenIds = new uint256[](numTokens); uint256 baseId; if(firstSubId == 0) { baseId = uint256(_creator) * 2**(256-160) + nextSubId; nextSubId = uint88(nextSubId + numTokens); } else { baseId = uint256(_creator) * 2**(256-160) + 1 * 2**(256-160-8) + firstSubId; } for(uint16 i = 0; i < numTokens; i++) { tokenIds[i] = baseId + i; } return tokenIds; } function mintMultipleWithNFT(address _sender, uint256 _sandAmount, uint88 firstSubId, string calldata _uris, uint16[] calldata lengths, uint256[] calldata _supplies, uint16 numNFTs, address _owner, bytes calldata _data) external { require(_owner != address(0), "Invalid owner"); require(msg.sender == _sender || msg.sender == address(_sandContract), "sender != msg.sender && sandContract"); require(lengths.length == _supplies.length + numNFTs, "Inconsistent array length between args lengths and supplies."); require(_sandAmount == mintingFee * lengths.length , "fee not matching"); if(_sandAmount > 0) { _sandContract.transferFrom(_sender, feeCollector, _sandAmount); } uint256[] memory tokenIds = generateTokenIds(_sender, firstSubId, lengths.length); _mintBatchesWithNFTs(_sender, _uris, lengths, _supplies, numNFTs, _owner, tokenIds[0]); emit TransferBatch(_sender, address(0), _owner, tokenIds, _supplies); require(_checkERC1155AndCallSafeBatchTransfer(_sender, address(0), _owner, tokenIds, _supplies, _data)); if(feeCollector.isContract()) { MintingFeeCollector(feeCollector).multiple_minted(tokenIds, mintingFee); } } function _mintBatchesWithNFTs(address _creator, string memory _uris, uint16[] memory lengths, uint256[] memory _supplies, uint16 numNFTs, address _owner, uint256 _firstId) internal { bytes memory stringBytes = bytes(_uris); uint32 readingPointer = _mintBatches(stringBytes, lengths, _supplies, _creator, _owner, _firstId); // deal with NFT last. they do not care of balance packing if(numNFTs > 0 ) { _mintNFTs(stringBytes, readingPointer, uint16(_supplies.length), lengths, numNFTs, _creator, _owner, _firstId); } } function _mintBatches(bytes memory stringBytes, uint16[] memory lengths, uint256[] memory _supplies, address _creator, address _owner, uint256 _firstId) internal returns (uint32 readingPointer) { readingPointer = 0x20; for (uint16 offset = 0; offset < uint16(_supplies.length); offset += 8) { readingPointer = _mintBatch(stringBytes, readingPointer, offset, lengths, _supplies, _creator, _owner, _firstId + offset); } } function _mintNFTs(bytes memory stringBytes, uint32 readingPointer, uint16 offset, uint16[] memory lengths, uint32 numNFTs, address _creator, address _owner, uint256 _firstId) internal { for (uint16 i = 0; i < numNFTs; i++) { numNFTPerAddress[_owner] ++; uint256 _id = _firstId+i+offset; require(bytes(erc721_metadataURIs[_id]).length == 0, "tokenId already used"); owners[_id] = _owner; emit Transfer(address(0), _owner, _id); uint ptr; assembly { ptr := add(stringBytes, readingPointer) } bytes memory tmp = BytesUtil.toBytes(ptr, lengths[offset + i]); readingPointer += lengths[offset + i]; erc721_metadataURIs[_id] = string(tmp); emit TransferSingle(_creator, address(0), _owner, _id, 1); emit URI(string(tmp), _id); } } function _mintBatch(bytes memory stringBytes, uint32 readingPointer, uint16 offset, uint16[] memory lengths, uint256[] memory _supplies, address _creator, address _owner, uint256 _fromId) internal returns(uint32 newReadingPointer) { uint16 batchSize = uint16(_supplies.length) - offset; if(batchSize > 8) { batchSize = 8;//ObjectLib32.TYPES_PER_UINT256; } (uint256 bin,) = _fromId.getTokenBinIndex(); (uint32 readingPointer, uint256 newBalance) = _packMintBatch( stringBytes, readingPointer, offset, lengths, _supplies, packedTokenBalance[_owner][bin], _fromId, batchSize ); packedTokenBalance[_owner][bin] = newBalance; return readingPointer; } function _packMintBatch( bytes memory stringBytes, uint32 readingPointer, uint16 offset, uint16[] memory lengths, uint256[] memory _supplies, uint256 _packedBalance, uint256 firstId, uint16 batchSize ) internal returns ( uint32 newReadingPointer, uint256 newBalance ) { newReadingPointer = readingPointer; newBalance = _packedBalance; (,uint256 index) = firstId.getTokenBinIndex(); for (uint256 i = 0; i < batchSize; i++) { require(uint256(erc1155_metadataURIHashes[firstId + i]) == 0, "tokenId already used"); uint256 j = offset + i; uint256 ptr; assembly { ptr := add(stringBytes, newReadingPointer) } bytes memory tmp = BytesUtil.toBytes(ptr, lengths[j]); newReadingPointer += lengths[j]; require(_supplies[j] > 1, "Minting with supply 1 not supported yet."); newBalance = newBalance.updateTokenBalance(index + i, _supplies[j], ObjectLib32.Operations.REPLACE); erc1155_metadataURIHashes[firstId + i] = keccak256(tmp); emit URI(string(tmp), firstId + i); } } function _transferFrom(address _from, address _to, uint256 _id, uint256 _value) internal { require(_to != address(0), "Invalid to address"); if(_from != msg.sender && msg.sender != address(_sandContract)) { require(mSuperOperators[msg.sender] || operatorsForAll[_from][msg.sender] || erc721_operators[_id] == msg.sender, "Operator not approved"); } if(owners[_id] != address(0)) { // NFT require(_value == 1, "cannot transfer nft if amount not 1"); numNFTPerAddress[_from] --; numNFTPerAddress[_to] ++; owners[_id] = _to; if(erc721_operators[_id] != address(0)) { erc721_operators[_id] = address(0); } emit Transfer(_from, _to, _id); } else { (uint256 bin, uint256 index) = (_id & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFF).getTokenBinIndex(); packedTokenBalance[_from][bin] = packedTokenBalance[_from][bin].updateTokenBalance( index, _value, ObjectLib32.Operations.SUB ); packedTokenBalance[_to][bin] = packedTokenBalance[_to][bin].updateTokenBalance( index, _value, ObjectLib32.Operations.ADD ); } emit TransferSingle(msg.sender == address(_sandContract) ? _from : msg.sender, _from, _to, _id, _value); } // function transferFrom(address _from, address _to, uint256 _id, uint256 _value) external { // _transferFrom(_from, _to, _id, _value); // } function safeTransferFrom(address _from, address _to, uint256 _id, uint256 _value, bytes calldata _data) external { _transferFrom(_from, _to, _id, _value); require(_checkERC1155AndCallSafeTransfer(msg.sender == address(_sandContract) ? _from : msg.sender, _from, _to, _id, _value, _data, false, false)); } // function batchTransferFrom(address _from, address _to, uint256[]calldata _ids, uint256[] calldata _values) external { // _batchTransferFrom(_from, _to, _ids, _values); // } function safeBatchTransferFrom(address _from, address _to, uint256[] calldata _ids, uint256[] calldata _values, bytes calldata _data) external { _batchTransferFrom(_from, _to, _ids, _values); require(_checkERC1155AndCallSafeBatchTransfer(msg.sender == address(_sandContract) ? _from : msg.sender, _from, _to, _ids, _values, _data)); } // NOTE: call data should be optimized to order _ids so packedBalance can be used efficiently function _batchTransferFrom(address _from, address _to, uint256[] memory _ids, uint256[] memory _values) internal { require(_ids.length == _values.length, "Inconsistent array length between args"); require(_to != address(0), "Invalid recipient"); bool authorized = mSuperOperators[msg.sender] || operatorsForAll[_from][msg.sender] || _from == msg.sender || msg.sender == address(_sandContract); uint256 bin; uint256 index; uint256 balFrom; uint256 balTo; // Last bin updated uint256 lastBin; for (uint256 i = 0; i < _ids.length; i++) { require(authorized || erc721_operators[_ids[i]] == msg.sender, "Operators not approved"); if(owners[_ids[i]] != address(0)) { // NFT require(owners[_ids[i]] == _from, "not owner"); require(_values[i] == 1, "cannot transfer nft if amount not 1"); numNFTPerAddress[_from] --; numNFTPerAddress[_to] ++; owners[_ids[i]] = _to; erc721_operators[_ids[i]] = address(0); emit Transfer(_from, _to, _ids[i]); } else { (bin, index) = (_ids[i] & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFF).getTokenBinIndex(); // If first bin if (i == 0) { lastBin = bin; balFrom = ObjectLib32.updateTokenBalance(packedTokenBalance[_from][bin], index, _values[i], ObjectLib32.Operations.SUB); balTo = ObjectLib32.updateTokenBalance(packedTokenBalance[_to][bin], index, _values[i], ObjectLib32.Operations.ADD); } else { // If new bin if (bin != lastBin) { // _ids need to be ordered appropriately to benefit for optimization // Update storage balance of previous bin packedTokenBalance[_from][lastBin] = balFrom; packedTokenBalance[_to][lastBin] = balTo; // Load current bin balance in memory balFrom = packedTokenBalance[_from][bin]; balTo = packedTokenBalance[_to][bin]; // Bin will be the most recent bin lastBin = bin; } // Update memory balance balFrom = balFrom.updateTokenBalance(index, _values[i], ObjectLib32.Operations.SUB); balTo = balTo.updateTokenBalance(index, _values[i], ObjectLib32.Operations.ADD); } } } if(bin != 0 || index != 0) { // at least one MCFT // Update storage of the last bin visited packedTokenBalance[_from][bin] = balFrom; packedTokenBalance[_to][bin] = balTo; } emit TransferBatch(msg.sender == address(_sandContract) ? _from : msg.sender, _from, _to, _ids, _values); } function balanceOf(address _owner, uint256 _id) public view returns (uint256) { if(owners[_id] != address(0)) { if(owners[_id] == _owner) { return 1; } else { return 0; } } (uint256 bin, uint256 index) = (_id & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFF).getTokenBinIndex(); return packedTokenBalance[_owner][bin].getValueInBin(index); } function balanceOfBatch(address[] calldata _owners, uint256[] calldata _ids) external view returns (uint256[] memory){ require(_owners.length == _ids.length, "Inconsistent array length between args"); uint256[] memory balances = new uint256[](_ids.length); for(uint256 i = 0; i < _ids.length; i++){ balances[i] = balanceOf(_owners[i], _ids[i]); } return balances; } function creatorOf(uint256 _id) public view returns (address) { address storedCreator = creators[_id]; if(storedCreator == address(0) && (owners[_id] != address(0) || uint256(erc1155_metadataURIHashes[_id]) != 0)) { return address(_id / 2**(256-160)); } return storedCreator; } // function transferCreatorship(uint256 _id, ) // TODO renable vy reinjecting supply into the token id ? // function supplyOf(uint256 _id) public pure returns (uint256) { // return uint56(_id) / 2**24; // } // Operators ///////////////////////////////////////////////////////////////////////////////////// function setApprovalForAllFor(address _sender, address _operator, bool _approved) external { require(msg.sender == _sender || msg.sender == address(_sandContract) || mSuperOperators[msg.sender], "require meta approval"); _setApprovalForAll(_sender, _operator, _approved); } function setApprovalForAll(address _operator, bool _approved) external { _setApprovalForAll(msg.sender, _operator, _approved); } function _setApprovalForAll(address _sender, address _operator, bool _approved) internal { require(!mSuperOperators[_operator], "super operator can't have their approvalForAll changed"); operatorsForAll[_sender][_operator] = _approved; emit ApprovalForAll(_sender, _operator, _approved); } function isApprovedForAll(address _owner, address _operator) external view returns (bool isOperator) { return operatorsForAll[_owner][_operator] || mSuperOperators[_operator]; } ////////////////////////////////////////////////////////////////////////////////////////////////////// // ERC721 /////////////////////////////////////// function balanceOf(address _owner) external view returns (uint256 _balance) { require(_owner != address(0)); return numNFTPerAddress[_owner]; } function ownerOf(uint256 _id) external view returns (address _owner){ _owner = owners[_id]; require(_owner != address(0)); } function approveFor(address _sender, address _operator, uint256 _id) external { address owner = owners[_id]; require(msg.sender == _sender || msg.sender == address(_sandContract) || mSuperOperators[msg.sender] || operatorsForAll[_sender][msg.sender], "require operators"); require(owner == _sender); erc721_operators[_id] = _operator; emit Approval(owner, _operator, _id); } function approve(address _operator, uint256 _id) external { address owner = owners[_id]; require(owner == msg.sender || mSuperOperators[msg.sender] || operatorsForAll[owner][msg.sender]); erc721_operators[_id] = _operator; emit Approval(owner, _operator, _id); } function getApproved(uint256 _id) external view returns (address _operator){ require(owners[_id] != address(0)); return erc721_operators[_id]; } function transferFrom(address _from, address _to, uint256 _id) external{ require(_to != address(0)); require(owners[_id] == _from); if(msg.sender != _from && msg.sender != address(_sandContract)) { require(operatorsForAll[_from][msg.sender] || erc721_operators[_id] == msg.sender || mSuperOperators[msg.sender], "Operator not approved"); } _transferFrom(_from, _to, _id, 1); require(_checkERC1155AndCallSafeTransfer(msg.sender == address(_sandContract) ? _from : msg.sender, _from, _to, _id, 1, "", true, false)); } function safeTransferFrom(address _from, address _to, uint256 _id) external { safeTransferFrom(_from, _to, _id, ""); } function safeTransferFrom(address _from, address _to, uint256 _id, bytes memory _data) public { require(_to != address(0)); require(owners[_id] == _from); if(msg.sender != _from && msg.sender != address(_sandContract)) { require(operatorsForAll[_from][msg.sender] || erc721_operators[_id] == msg.sender || mSuperOperators[msg.sender], "Operator not approved"); } _transferFrom(_from, _to, _id, 1); require(_checkERC1155AndCallSafeTransfer(msg.sender == address(_sandContract) ? _from : msg.sender, _from, _to, _id, 1, _data, true, true)); } function name() external pure returns (string memory _name) { return "ASSET NFT"; } function symbol() external pure returns (string memory _symbol) { return "ASSET"; } function tokenURI(uint256 _id) public view returns (string memory) { return string(erc721_metadataURIs[_id]); } //////////////////////////////////////////////////////////////////////////////////////////////////// function supportsInterface(bytes4 id) external view returns (bool) { // ERC1155 // ERC721 // ERC721 metadata return id == 0xd9b67a26 || id == 0x80ac58cd || id == 0x5b5e139f; } ///////////////////////////////////////// INTERNAL ////////////////////////////////////////////// function _checkERC1155AndCallSafeTransfer( address _operator, address _from, address _to, uint256 _id, uint256 _value, bytes memory _data, bool erc721, bool erc721Safe ) internal returns (bool) { if (!_to.isContract()) { return true; } (bool success, bytes memory returnData) = _to.call( abi.encodeWithSignature( "onERC1155Received(address,address,uint256,uint256,bytes)", _operator, _from, _id, _value, _data ) ); bytes4 retval = 0x0; if(returnData.length > 0) { assembly { retval := mload(add(returnData, 32)) } } if(retval == ERC1155_REJECTED) { return false; } else if(retval == ERC1155_RECEIVED) { return true; } else if(erc721) { if(erc721Safe) { return _checkERC721AndCallSafeTransfer(_operator, _from, _to, _id, _data); } else { return true; } } else { return false; } } function _checkERC1155AndCallSafeBatchTransfer( address _operator, address _from, address _to, uint256[] memory _ids, uint256[] memory _values, bytes memory _data ) internal returns (bool) { if (!_to.isContract()) { return true; } bytes4 retval = ERC1155TokenReceiver(_to).onERC1155BatchReceived( _operator, _from, _ids, _values, _data); return (retval == ERC1155_BATCH_RECEIVED); } function _checkERC721AndCallSafeTransfer( address _operator, address _from, address _to, uint256 _id, bytes memory _data ) internal returns (bool) { if (!_to.isContract()) { return true; } return (ERC721TokenReceiver(_to).onERC721Received(_operator, _from, _id, _data) == ERC721_RECEIVED); } ////////////////////////////// ERC721 EXTRACTION /////////////////////////////// event Extraction(uint256 indexed _fromId, uint256 _toId, string _uri); function _burnERC1155(address _from, uint256 _id, uint256 _amount) internal { (uint256 bin, uint256 index) = (_id & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFF).getTokenBinIndex(); packedTokenBalance[_from][bin] = packedTokenBalance[_from][bin].updateTokenBalance(index, _amount, ObjectLib32.Operations.SUB); packedTokenBalance[address(0)][bin] = packedTokenBalance[address(0)][bin].updateTokenBalance(index, _amount, ObjectLib32.Operations.ADD); emit TransferSingle(msg.sender == address(_sandContract) ? _from : msg.sender, _from, address(0), _id, _amount); } // TODO enable ? function extractERC721(address _sender, uint256 _id, string calldata _uri) external { require(msg.sender == _sender || msg.sender == address(_sandContract) || mSuperOperators[msg.sender], "require meta approval"); require(erc1155_metadataURIHashes[_id] != 0, "Not an ERC1155 Token"); require(erc1155_metadataURIHashes[_id] == keccak256(abi.encodePacked(_uri)), "URI hash does not match"); _burnERC1155(_sender, _id, 1); address creator = creatorOf(_id); uint256 newTokenId = uint256(creator) * 2**(256-160) + 0 * 2**(256-160-8) + nextSubId; nextSubId++; _mint(_uri, 1, creator, _sender, newTokenId, ""); emit Extraction(_id, newTokenId, _uri); } }
pragma solidity 0.5.2; interface MintingFeeCollector { function multiple_minted(uint256[] calldata tokenIds, uint256 feePerToken) external; function single_minted(uint256 tokenId, uint256 fee) external; }
pragma solidity 0.5.2; import "./Asset/ERC1155ERC721.sol"; import "./TheSandbox712.sol"; import "./Sand.sol"; contract Asset is ProxyImplementation, TheSandbox712, ERC1155ERC721 { // TODO remove TheSandbox712 unless we need to add Approval extension or other that require signed message constructor(Sand _sandContract, address _feeCollector, address _admin) public ERC1155ERC721(_sandContract, _feeCollector, _admin) { initAsset(_sandContract, _feeCollector, _admin); } function initAsset(Sand _sandContract, address _feeCollector, address _admin) public phase('ASSET') { init712(); initERC1155ERC721(_sandContract, _feeCollector, _admin); } }
pragma solidity 0.5.2; import "../Libraries/SigUtil.sol"; import "../Libraries/PriceUtil.sol"; import "../Sand.sol"; import "../Asset.sol"; import "../Interfaces/ERC20.sol"; import "../TheSandbox712.sol"; contract AssetSignedAuction is TheSandbox712{ bytes32 constant AUCTION_TYPEHASH = keccak256("Auction(address token,uint256 offerId,uint256 startingPrice,uint256 endingPrice,uint256 startedAt,uint256 duration,uint256 packs,bytes ids,bytes amounts)"); // TODO: review event values // TODO remove underscore event OfferClaimed( address indexed _seller, address indexed _buyer, address _token, uint256 _buyAmount, uint256[] _auctionData, uint256[] ids, uint256[] amounts, bytes _signature // TODO remove and use offerId ); event OfferCancelled(address indexed _seller, uint256 _offerId); uint256 constant MAX_UINT256 = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff; // Stack too deep, grouping parameters // AuctionData: uint256 constant AuctionData_OfferId = 0; uint256 constant AuctionData_StartingPrice = 1; uint256 constant AuctionData_EndingPrice = 2; uint256 constant AuctionData_StartedAt = 3; uint256 constant AuctionData_Duration = 4; uint256 constant AuctionData_Packs = 5; mapping (address => mapping (uint256 => uint256)) claimed; Asset asset; Sand sand; constructor(Sand _sand, Asset _asset) public { asset = _asset; sand = _sand; init712(); } function claimSellerOffer( address buyer, address payable seller, address token, uint256 buyAmount, uint256[] calldata auctionData, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata signature ) external payable { require(msg.sender == buyer || msg.sender == address(sand), "invalid buyer"); // TODO: do we remove seller from the argument list? and recover it ? require(seller == recover(token, auctionData, ids, amounts, signature), "Signature mismatches"); require(claimed[seller][auctionData[AuctionData_OfferId]] != MAX_UINT256, "Auction cancelled"); require(SafeMath.add(claimed[seller][auctionData[AuctionData_OfferId]], buyAmount) <= auctionData[AuctionData_Packs], "Buy amount exceeds sell amount"); require(auctionData[AuctionData_StartedAt] <= block.timestamp, "Auction didn't start yet"); require(auctionData[AuctionData_StartedAt] + auctionData[AuctionData_Duration] > block.timestamp, "Auction finished"); _executeDeal(token, buyer, seller, auctionData, ids, amounts, buyAmount); emit OfferClaimed(seller, buyer, token, buyAmount, auctionData, ids, amounts, signature); } function _executeDeal( address token, address buyer, address payable seller, uint256[] memory auctionData, uint256[] memory ids, uint256[] memory amounts, uint256 buyAmount ) internal { uint256 offer = PriceUtil.calculateCurrentPrice( auctionData[AuctionData_StartingPrice], auctionData[AuctionData_EndingPrice], auctionData[AuctionData_Duration], block.timestamp - auctionData[AuctionData_StartedAt] ) * buyAmount; claimed[seller][auctionData[AuctionData_OfferId]] += buyAmount; if(token != address(0)) { ERC20(token).transferFrom(buyer, seller, offer); // require approval/ for SAND we can add it to the list of defaultOperators / superOperators } else { require(buyer == msg.sender, "for ETH based offers, the buyer need to be the sender"); require(msg.value >= offer, "not enough ETH"); // in case the aucction could store ETH for other reasons seller.transfer(offer); msg.sender.transfer(msg.value - offer); } uint256[] memory packAmounts = new uint[](amounts.length); for(uint256 i = 0; i < packAmounts.length; i++){ packAmounts[i] = amounts[i] * buyAmount; } asset.safeBatchTransferFrom(seller, buyer, ids, packAmounts, ''); } function cancelSellerOffer(uint256 offerId) external { claimed[msg.sender][offerId] = MAX_UINT256; emit OfferCancelled(msg.sender, offerId); } // Make public for testing function recover(address token, uint256[] memory auctionData, uint256[] memory ids, uint256[] memory amounts, bytes memory signature) internal view returns (address) { return SigUtil.recover( // This recreates the message that was signed on the client. keccak256(abi.encodePacked("\x19\x01", domainSeparator(), hashAuction(token, auctionData, ids, amounts))), signature ); } function hashAuction(address token, uint256[] memory auctionData, uint256[] memory ids, uint256[] memory amounts) internal pure returns (bytes32) { return keccak256( abi.encode( AUCTION_TYPEHASH, token, auctionData[AuctionData_OfferId], auctionData[AuctionData_StartingPrice], auctionData[AuctionData_EndingPrice], auctionData[AuctionData_StartedAt], auctionData[AuctionData_Duration], auctionData[AuctionData_Packs], keccak256(abi.encodePacked(ids)), keccak256(abi.encodePacked(amounts)) ) ); } }
pragma solidity 0.5.2; import "../Libraries/SigUtil.sol"; import "../Libraries/PriceUtil.sol"; import "../Sand.sol"; import "../Asset.sol"; import "../Interfaces/ERC20.sol"; import "../TheSandbox712.sol"; contract BuyerMinting is TheSandbox712{ // bytes32 constant AUCTION_TYPEHASH = keccak256("MintAuction(address token,uint256 offerId,uint256 startingPrice,uint256 endingPrice,uint256 startedAt,uint256 duration,uint256 packs,string uris,bytes lengths,bytes _supplies)"); // mapping (address => mapping (uint256 => uint256)) claimed; // Asset asset; // Sand sand; // constructor(Sand _sand, Asset _asset) public { // asset = _asset; // sand = _sand; // init712(); // } // function claimMintOffer( // address buyer, // address payable seller, // address token, // uint256 buyAmount, // uint256[] calldata auctionData, // string uris, // uint256[] lengths, // uint256[] indexes, // uint256[] amounts, // bytes calldata signature // ) external payable { // if(notMintedYet) { // ids = asset.mintMultipleWithNFT(creator, sandAmount, uris, lengths, supplies, numNFTs, creator); // TODO minting should return the i // } else { // // TODO ids need to passed to the call and uris need to be checked // // => this means 2 asset with same uri can't exist => problem with extraction // } // uint256[] memory packAmounts = new uint[](amounts.length); // for(uint256 i = 0; i < packAmounts.length; i++){ // packAmounts[i] = amounts[i] * buyAmount; // } // asset.batchTransferFrom(seller, buyer, ids, packAmounts); // } }
pragma solidity 0.5.2; import "./Libraries/BytesUtil.sol"; import "./Libraries/AddressUtils.sol"; import "./Libraries/SigUtil.sol"; import "./Libraries/SafeMath.sol"; import "./Interfaces/ERC1271.sol"; import "./Interfaces/ERC20.sol"; import "./Interfaces/ERC1271Constants.sol"; import "./TheSandbox712.sol"; contract GenericMetaTransaction is TheSandbox712, ERC1271Constants{ using SafeMath for uint256; using AddressUtils for address; bytes32 constant ERC20METATRANSACTION_TYPEHASH = keccak256("ERC20MetaTransaction(address from,address to,address gasToken,bytes data,uint256 nonce,uint256 gasPrice,uint256 txGas,uint256 gasLimit,uint256 tokenGasPrice,address relayer)"); mapping(address => uint256) nonces; uint256 constant BASE_GAS = 112000; // TODO calculate accurately uint256 constant WORST_CASE_EPSILON = 10000; // TODO calculate accurately uint256 constant INIT_GAS = 23000; // TODO calculate accurately event MetaTx(bool success, bytes returnData); // TODO specify event as part of ERC-1776 constructor() public { init712(); } function ensureParametersValidity( address _from, address _gasToken, uint256[4] memory params, // _nonce, _gasPrice, _txGas, _tokenGasPrice address _relayer ) internal view { require(_relayer == address(0) || _relayer == msg.sender, "wrong relayer"); require(nonces[_from]+1 == params[0], "nonce out of order"); require(ERC20(_gasToken).balanceOf(_from) >= (params[2].add(BASE_GAS)).mul(params[3]), "_from not enough balance"); require(tx.gasprice == params[1], "gasPrice != signer gasPrice"); // need to provide same gasPrice as requested by signer // TODO consider allowing higher value } function encodeData( bytes32 typeHash, address _from, address _to, address _gasToken, bytes memory _data, uint256[4] memory params, address _relayer ) internal pure returns (bytes32) { return keccak256(abi.encode( typeHash, _from, _to, _gasToken, keccak256(_data), params[0], params[1], params[2], BASE_GAS + params[2], // expect signing gasLimit = BASE_GAS + txGas params[3], _relayer )); } function ensureCorrectSigner( address _from, address _to, address _gasToken, bytes memory _data, uint256[4] memory params, address _relayer, bytes memory _sig, bytes32 typeHash, bool signedOnBehalf ) internal view { bytes memory data = abi.encodePacked( "\x19\x01", domainSeparator(), encodeData( typeHash, _from, _to, _gasToken, _data, params, _relayer ) ); if(signedOnBehalf) { require(ERC1271(_from).isValidSignature(data, _sig) == ERC1271_MAGICVALUE, "invalid signature"); } else { address signer = SigUtil.recover(keccak256(data), _sig); require(signer == _from, "signer != _from"); } } function sendERC20Tokens(address _from, address _to, ERC20 _tokenContract, uint256 _amount, bytes calldata _data) external { require(msg.sender == address(this), "can only be called by own"); _tokenContract.transferFrom(_from, _to, _amount); bool success = true; bytes memory returnData; if(_to.isContract() || _data.length > 0){ (success, returnData) = _to.call(abi.encodeWithSignature("erc20_tokensReceived(address,address,uint256,bytes)", _from, _tokenContract, _amount, _data)); } require(success); } // function sendERC777Tokens(address _from, address _to, ERC777 _tokenContract, uint256 _amount, bytes calldata _data) external { // require(msg.sender == address(this), "can only be called by own"); // _tokenContract.operatorSend(_from, _to, _amount, _data); // } // TODO safe /unsafe version // function sendERC1155Tokens(address _from, address _to, ERC1155 _tokenContract, uint256 _tokenType, uint256 _amount, bytes calldata _data) external { // require(msg.sender == address(this), "can only be called by own"); // _tokenContract.transfer...(_from, _to, _amount, _data); // } // TODO safe /unsafe version // function sendERC721Tokens(address _from, address _to, ERC721 _tokenContract, uint256 _tokenType, bytes calldata _data) external { // require(msg.sender == address(this), "can only be called by own"); // _tokenContract.transferFrom(_from, _to, _amount, _data); // } function executeERC20MetaTx( address _from, address _to, address _gasToken, bytes calldata _data, uint256[4] calldata params, // _nonce, _gasPrice, _txGas, _tokenGasPrice address _relayer, bytes calldata _sig, address _tokenReceiver, bool signedOnBehalf ) external returns (bool, bytes memory) { require(msg.sender != address(this), "can only be called externaly"); uint256 initialGas = gasleft(); ensureParametersValidity(_from, _gasToken, params, _relayer); ensureCorrectSigner(_from, _to, _gasToken, _data, params, _relayer, _sig, ERC20METATRANSACTION_TYPEHASH, signedOnBehalf); return performERC20MetaTx(_from, _to, _gasToken, _data, params, initialGas, _tokenReceiver); } function performERC20MetaTx( address _from, address _to, address _gasToken, bytes memory _data, uint256[4] memory params, uint256 initialGas, address _tokenReceiver ) internal returns(bool, bytes memory) { nonces[_from] = params[0]; bool success; bytes memory returnData; if(_to == address(this)) { require(BytesUtil.doFirstParamEqualsAddress(_data, _from), "first param != _from"); uint256 gasAvailable = gasleft() - WORST_CASE_EPSILON; require(gasAvailable - gasAvailable/64 > params[2], "not enough gas"); (success, returnData) = _to.call.gas(params[2])(_data); } else { // can't accept any call since this contract willmost likely be approved by ERC20 or ERC777 contract and if those have function that // have such signature for example differentTransfer(uint256 amount, address from, ...) they would be vulnerable //so instead we define a meta_transaction hook uint256 gasAvailable = gasleft() - WORST_CASE_EPSILON; require(gasAvailable - gasAvailable/64 > params[2], "not enough gas"); (success, returnData) = _to.call.gas(params[2])(abi.encodeWithSignature("meta_transaction_received(address,bytes)", _from, _data)); } emit MetaTx(success, returnData); if(params[3] > 0) { uint256 gasConsumed = (initialGas + INIT_GAS) - gasleft(); if(gasConsumed > BASE_GAS + params[2]) { gasConsumed = BASE_GAS + params[2]; // idealy we would like to charge only max(BASE_GAS, gas consumed outside the inner call) + gas consumed as part of the inner call } ERC20(_gasToken).transferFrom(_from, _tokenReceiver, gasConsumed * params[3]); } return (success, returnData); } function meta_nonce(address _from) external view returns (uint256 nonce) { return nonces[_from]; } }
pragma solidity 0.5.2; /// @dev Note: the ERC-165 identifier for this interface is 0xf23a6e61. interface ERC1155TokenReceiver { /** @notice Handle the receipt of a single ERC1155 token type. @dev An ERC1155-compliant smart contract MUST call this function on the token recipient contract, at the end of a `safeTransferFrom` after the balance has been updated. This function MAY throw to revert and reject the transfer. Return of other than the magic value MUST result in the transaction being reverted. Note: The contract address is always the message sender. @param _operator The address which called `safeTransferFrom` function @param _from The address which previously owned the token @param _id An array containing the ids of the token being transferred @param _value An array containing the amount of tokens being transferred @param _data Additional data with no specified format @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` */ function onERC1155Received(address _operator, address _from, uint256 _id, uint256 _value, bytes calldata _data) external returns(bytes4); /** @notice Handle the receipt of multiple ERC1155 token types. @dev An ERC1155-compliant smart contract MUST call this function on the token recipient contract, at the end of a `safeBatchTransferFrom` after the balances have been updated. This function MAY throw to revert and reject the transfer. Return of other than the magic value WILL result in the transaction being reverted. Note: The contract address is always the message sender. @param _operator The address which called `safeTransferFrom` function @param _from The address which previously owned the token @param _ids An array containing ids of each token being transferred @param _values An array containing amounts of each token being transferred @param _data Additional data with no specified format @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` */ function onERC1155BatchReceived(address _operator, address _from, uint256[] calldata _ids, uint256[] calldata _values, bytes calldata _data) external returns(bytes4); } /// @dev Note: The ERC-165 identifier for this interface is 0xd9b67a26. interface ERC1155 { 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 _owner, address indexed _operator, bool _approved); event URI(string _value, uint256 indexed _id); event Name(string _value, uint256 indexed _id); function safeTransferFrom(address _from, address _to, uint256 _id, uint256 _value, bytes calldata _data) external; function safeBatchTransferFrom(address _from, address _to, uint256[] calldata _ids, uint256[] calldata _values, bytes calldata _data) external; function balanceOf(address _owner, uint256 _id) external view returns (uint256); function balanceOfBatch(address[] calldata _owners, uint256[] calldata _ids) external view returns (uint256[] memory); function setApprovalForAll(address _operator, bool _approved) external; function isApprovedForAll(address _owner, address _operator) external view returns (bool); }
pragma solidity 0.5.2; contract ERC1271 { /** * @dev Should return whether the signature provided is valid for the provided data * @param _data Arbitrary length data signed on the behalf of address(this) * @param _signature Signature byte array associated with _data * * MUST return the bytes4 magic value 0x20c13b0b when function passes. * MUST NOT modify state (using STATICCALL for solc < 0.5, view modifier for solc > 0.5) * MUST allow external calls */ function isValidSignature( bytes memory _data, bytes memory _signature) public view returns (bytes4 magicValue); }
pragma solidity 0.5.2; contract ERC1271Constants { bytes4 constant internal ERC1271_MAGICVALUE = 0x20c13b0b; }
pragma solidity 0.5.2; /** * @title ERC165 * @dev https://github.com/ethereum/EIPs/blob/master/EIPS/eip-165.md */ interface ERC165 { /** * @notice Query if a contract implements an interface * @param _interfaceId The interface identifier, as specified in ERC-165 * @dev Interface identification is specified in ERC-165. This function * uses less than 30,000 gas. */ function supportsInterface(bytes4 _interfaceId) external view returns (bool); }
pragma solidity 0.5.2; import "./ERC20Basic.sol"; /** * @title ERC20 interface * @dev see https://github.com/ethereum/EIPs/issues/20 */ /* interface */ contract ERC20 is ERC20Basic { function transferFrom(address from, address to, uint256 value) public returns (bool); function approve(address spender, uint256 value) public returns (bool); function allowance(address owner, address spender) public view returns (uint256); event Approval(address indexed owner, address indexed spender, uint256 value); }
pragma solidity 0.5.2; /** * @title ERC20Basic * @dev Simpler version of ERC20 interface * See https://github.com/ethereum/EIPs/issues/179 */ /* interface */ contract ERC20Basic { function totalSupply() public view returns (uint256); function balanceOf(address who) public view returns (uint256); function transfer(address to, uint256 value) public returns (bool); event Transfer(address indexed from, address indexed to, uint256 value); }
pragma solidity 0.5.2; /* interface */ contract ERC20Events { event Transfer(address indexed from, address indexed to, uint256 value); event Approval(address indexed owner, address indexed spender, uint256 value); }
/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This code has not been reviewed. * Do not use or deploy this code before reviewing it personally first. */ // solhint-disable-next-line compiler-fixed pragma solidity 0.5.2; import "./ERC20.sol"; /* interface */ contract ERC20WithMetadata is ERC20 { function name() public view returns (string memory); function symbol() public view returns (string memory); function decimals() public view returns (uint8); }
pragma solidity 0.5.2; import "./ERC165.sol"; import "./ERC721Events.sol"; /** * @title ERC721 Non-Fungible Token Standard basic interface * @dev see https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md */ /*interface*/ contract ERC721 is ERC165, ERC721Events { function balanceOf(address _owner) external view returns (uint256 _balance); function ownerOf(uint256 _tokenId) external view returns (address _owner); // function exists(uint256 _tokenId) external view returns (bool _exists); 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 transferFrom(address _from, address _to, uint256 _tokenId) external; function safeTransferFrom(address _from, address _to, uint256 _tokenId) external; function safeTransferFrom( address _from, address _to, uint256 _tokenId, bytes calldata _data ) external; }
pragma solidity 0.5.2; /** * @title ERC721 Non-Fungible Token Standard basic interface * @dev see https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md */ interface ERC721Events { 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 ); }
/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This code has not been reviewed. * Do not use or deploy this code before reviewing it personally first. */ // solhint-disable-next-line compiler-fixed pragma solidity 0.5.2; interface ERC721TokenReceiver { function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns(bytes4); }
/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This code has not been reviewed. * Do not use or deploy this code before reviewing it personally first. */ // solhint-disable-next-line compiler-fixed pragma solidity 0.5.2; /* interface */ contract ERC777Token { function name() public view returns (string memory); function symbol() public view returns (string memory); function totalSupply() public view returns (uint256); function balanceOf(address owner) public view returns (uint256); function granularity() public view returns (uint256); function defaultOperators() public view returns (address[] memory); function isOperatorFor(address operator, address tokenHolder) public view returns (bool); function authorizeOperator(address operator) public; function revokeOperator(address operator) public; function send(address to, uint256 amount, bytes memory data) public; function operatorSend(address from, address to, uint256 amount, bytes memory data, bytes memory operatorData) public; // function burn(uint256 amount, bytes data) public; // function operatorBurn(address from, uint256 amount, bytes data, bytes operatorData) public; event Sent( address indexed operator, address indexed from, address indexed to, uint256 amount, bytes data, bytes operatorData ); // solhint-disable-next-line separate-by-one-line-in-contract event Minted(address indexed operator, address indexed to, uint256 amount, bytes operatorData); event Burned(address indexed operator, address indexed from, uint256 amount, bytes data, bytes operatorData); event AuthorizedOperator(address indexed operator, address indexed tokenHolder); event RevokedOperator(address indexed operator, address indexed tokenHolder); }
pragma solidity 0.5.2; /* interface */ contract ERC777TokenEvents { event Sent( address indexed operator, address indexed from, address indexed to, uint256 amount, bytes data, bytes operatorData ); // solhint-disable-next-line separate-by-one-line-in-contract event Minted(address indexed operator, address indexed to, uint256 amount, bytes operatorData); event Burned(address indexed operator, address indexed from, uint256 amount, bytes data, bytes operatorData); event AuthorizedOperator(address indexed operator, address indexed tokenHolder); event RevokedOperator(address indexed operator, address indexed tokenHolder); }
/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This code has not been reviewed. * Do not use or deploy this code before reviewing it personally first. */ // solhint-disable-next-line compiler-fixed pragma solidity 0.5.2; /* interface */ contract ERC777TokensRecipient { function tokensReceived( address operator, address from, address to, uint256 amount, bytes memory data, bytes memory operatorData ) public; }
/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This code has not been reviewed. * Do not use or deploy this code before reviewing it personally first. */ // solhint-disable-next-line compiler-fixed pragma solidity 0.5.2; /* interface */ contract ERC777TokensSender { function tokensToSend( address operator, address from, address to, uint amount, bytes memory userData, bytes memory operatorData ) public; }
pragma solidity 0.5.2; import { ERC721Events } from "../../Interfaces/ERC721Events.sol"; import "../../Sand.sol"; contract ERC721BaseToken is ERC721Events /*ERC721*/ { mapping(address => uint256) numNFTPerAddress; mapping(uint256 => address) owners; mapping(address => mapping(address => bool)) operatorsForAll; mapping(uint256 => address) operators; mapping (uint256 => string) public metadataURIs; Sand sandContract; constructor(Sand sand) public { initERC721BaseToken(sand); } function initERC721BaseToken(Sand sand) public { sandContract = sand; } function _transferFrom(address _from, address _to, uint256 _id) internal { require(_to != address(0), "Invalid to address"); if(_from != msg.sender && msg.sender != address(sandContract)) { require(operatorsForAll[_from][msg.sender] || operators[_id] == msg.sender, "Operator not approved"); } numNFTPerAddress[_from] --; numNFTPerAddress[_to] ++; owners[_id] = _to; operators[_id] = address(0); emit Transfer(_from, _to, _id); } function balanceOf(address _owner) external view returns (uint256 _balance) { return numNFTPerAddress[_owner]; } function ownerOf(uint256 _id) external view returns (address _owner){ return owners[_id]; } function approveFor(address _sender, address _operator, uint256 _id) external { require(msg.sender == _sender || msg.sender == address(sandContract), "only msg.sender or sandContract can act on behalf of sender"); require(owners[_id] == _sender, "only owner can change operator"); operators[_id] = _operator; emit Approval(_sender, _operator, _id); } function approve(address _operator, uint256 _id) external { require(owners[_id] == msg.sender, "only owner can change operator"); operators[_id] = _operator; emit Approval(msg.sender, _operator, _id); } function getApproved(uint256 _id) external view returns (address _operator){ return operators[_id]; } function transferFrom(address _from, address _to, uint256 _id) external{ require(owners[_id] != address(0), "not an NFT"); require(owners[_id] == _from, "only owner can change operator"); _transferFrom(_from, _to, _id); } ///////////////////////////////////////////////////////////////////////////////////////////////////// function name() external pure returns (string memory _name) { return "SANDBOX LAND"; } function symbol() external pure returns (string memory _symbol) { return "SLD"; // TODO define symbol } function tokenURI(uint256 _id) public view returns (string memory) { return string(metadataURIs[_id]); } //////////////////////////////////////////////////////////////////////////////////////////////////// function supportsInterface(bytes4 ) // TODO _interfaceId) external view returns (bool) { return true; // TODO } // Operators ///////////////////////////////////////////////////////////////////////////////////// function setApprovalForAllFor(address _sender, address _operator, bool _approved) external { require(msg.sender == _sender || msg.sender == address(sandContract), "only msg.sender or _sandContract can act on behalf of sender"); _setApprovalForAll(_sender, _operator, _approved); } function setApprovalForAll(address _operator, bool _approved) external { _setApprovalForAll(msg.sender, _operator, _approved); } function _setApprovalForAll(address _sender, address _operator, bool _approved) internal { operatorsForAll[_sender][_operator] = _approved; emit ApprovalForAll(_sender, _operator, _approved); } function isApprovedForAll(address _owner, address _operator) external view returns (bool isOperator) { return operatorsForAll[_owner][_operator]; } }
pragma solidity 0.5.2; import "./Land/erc721/ERC721BaseToken.sol"; import "./Sand.sol"; contract Land is ProxyImplementation, ERC721BaseToken{ uint256 lastId; constructor(Sand _sandContract) public ERC721BaseToken(_sandContract) { lastId = 1; } // TODO : function mint(address _to) public { numNFTPerAddress[_to] ++; owners[++lastId] = _to; emit Transfer(address(0), _to, lastId); } }
pragma solidity 0.5.2; /** * Utility library of inline functions on addresses */ library AddressUtils { /** * Returns whether the target address is a contract * @dev This function will return false if invoked during the constructor of a contract, * as the code is not actually created until after the constructor finishes. * @param addr address to check * @return whether the target address is a contract */ function isContract(address addr) internal view returns (bool) { uint256 size; // XXX Currently there is no better way to check if there is a contract in an address // than to check the size of the code at that address. // See https://ethereum.stackexchange.com/a/14016/36603 // for more details about how this works. // TODO Check this again before the Serenity release, because all addresses will be // contracts then. // solium-disable-next-line security/no-inline-assembly assembly { size := extcodesize(addr) } return size > 0; } }
pragma solidity 0.5.2; library BytesUtil { function memcpy(uint dest, uint src, uint len) internal pure { // Copy word-length chunks while possible for(; len >= 32; len -= 32) { assembly { mstore(dest, mload(src)) } dest += 32; src += 32; } // Copy remaining bytes uint mask = 256 ** (32 - len) - 1; assembly { let srcpart := and(mload(src), not(mask)) let destpart := and(mload(dest), mask) mstore(dest, or(destpart, srcpart)) } } function toBytes(uint256 src, uint256 len) internal pure returns (bytes memory) { bytes memory ret = new bytes(len); uint retptr; assembly { retptr := add(ret, 32) } memcpy(retptr, src, len); return ret; } function toBytes(address a) internal pure returns (bytes memory b){ assembly { let m := mload(0x40) mstore(add(m, 20), xor(0x140000000000000000000000000000000000000000, a)) mstore(0x40, add(m, 52)) b := m } } function toBytes(uint256 a) internal pure returns (bytes memory b){ assembly { let m := mload(0x40) mstore(add(m, 32), a) mstore(0x40, add(m, 64)) b := m } } function doFirstParamEqualsAddress(bytes memory data, address _address) internal pure returns (bool){ if(data.length < (36 + 32)) { return false; } uint256 value; assembly { value := mload(add(data, 36)) } return value == uint256(_address); } function doParamEqualsUInt256(bytes memory data, uint256 i, uint256 value) internal pure returns (bool) { if(data.length < (36 + (i+1)*32)) { return false; } uint256 offset = 36 + i*32; uint256 valuePresent; assembly { valuePresent := mload(add(data, offset)) } return valuePresent == value; } function overrideFirst32BytesWithAddress(bytes memory data, address _address) internal pure returns (bytes memory){ uint dest; assembly {dest := add(data, 48)} // 48 = 32 (offset) + 4 (func sig) + 12 (address is only 20 bytes) bytes memory addressBytes = BytesUtil.toBytes(_address); uint src; assembly { src := add(addressBytes, 32) } memcpy(dest, src, 20); return data; } function overrideFirstTwo32BytesWithAddressAndInt(bytes memory data, address _address, uint256 _value) internal pure returns (bytes memory){ uint dest; uint src; assembly {dest := add(data, 48)} // 48 = 32 (offset) + 4 (func sig) + 12 (address is only 20 bytes) bytes memory bbytes = BytesUtil.toBytes(_address); assembly { src := add(bbytes, 32) } memcpy(dest, src, 20); assembly {dest := add(data, 68)} // 48 = 32 (offset) + 4 (func sig) + 32 (next slot) bbytes = BytesUtil.toBytes(_value); assembly { src := add(bbytes, 32) } memcpy(dest, src, 32); return data; } }
pragma solidity 0.5.2; contract ERC820Registry { function getManager(address addr) public view returns(address); function setManager(address addr, address newManager) public; function getInterfaceImplementer(address addr, bytes32 iHash) public view returns (address); function setInterfaceImplementer(address addr, bytes32 iHash, address implementer) public; } contract ERC820Implementer { ERC820Registry constant erc820Registry = ERC820Registry(0x820b586C8C28125366C998641B09DCbE7d4cBF06); function setInterfaceImplementation(string memory ifaceLabel, address impl) internal { bytes32 ifaceHash = keccak256(bytes(ifaceLabel)); erc820Registry.setInterfaceImplementer(address(this), ifaceHash, impl); } function interfaceAddr(address addr, string memory ifaceLabel) internal view returns(address) { bytes32 ifaceHash = keccak256(bytes(ifaceLabel)); return erc820Registry.getInterfaceImplementer(addr, ifaceHash); } function delegateManagement(address newManager) internal { erc820Registry.setManager(address(this), newManager); } }
pragma solidity 0.5.2; import "../ownership/Ownable.sol"; /** * @title Pausable * @dev Base contract which allows children to implement an emergency stop mechanism. */ contract Pausable is Ownable { event Pause(); event Unpause(); bool public paused = false; /** * @dev Modifier to make a function callable only when the contract is not paused. */ modifier whenNotPaused() { require(!paused); _; } /** * @dev Modifier to make a function callable only when the contract is paused. */ modifier whenPaused() { require(paused); _; } /** * @dev called by the owner to pause, triggers stopped state */ function pause() onlyOwner whenNotPaused public { paused = true; emit Pause(); } /** * @dev called by the owner to unpause, returns to normal state */ function unpause() onlyOwner whenPaused public { paused = false; emit Unpause(); } }
pragma solidity 0.5.2; import "./SafeMath.sol"; library ObjectLib { using SafeMath for uint256; enum Operations { ADD, SUB, REPLACE } // Constants regarding bin or chunk sizes for balance packing uint256 constant TYPES_BITS_SIZE = 16; // Max size of each object uint256 constant TYPES_PER_UINT256 = 256 / TYPES_BITS_SIZE; // Number of types per uint256 // // Objects and Tokens Functions // /** * @dev Return the bin number and index within that bin where ID is * @param _tokenId Object type * @return (Bin number, ID's index within that bin) */ function getTokenBinIndex(uint256 _tokenId) internal pure returns (uint256 bin, uint256 index) { bin = _tokenId * TYPES_BITS_SIZE / 256; index = _tokenId % TYPES_PER_UINT256; return (bin, index); } /** * @dev update the balance of a type provided in _binBalances * @param _binBalances Uint256 containing the balances of objects * @param _index Index of the object in the provided bin * @param _amount Value to update the type balance * @param _operation Which operation to conduct : * Operations.REPLACE : Replace type balance with _amount * Operations.ADD : ADD _amount to type balance * Operations.SUB : Substract _amount from type balance */ function updateTokenBalance( uint256 _binBalances, uint256 _index, uint256 _amount, Operations _operation) internal pure returns (uint256 newBinBalance) { uint256 objectBalance = 0; if (_operation == Operations.ADD) { objectBalance = getValueInBin(_binBalances, _index); newBinBalance = writeValueInBin(_binBalances, _index, objectBalance.add(_amount)); } else if (_operation == Operations.SUB) { objectBalance = getValueInBin(_binBalances, _index); newBinBalance = writeValueInBin(_binBalances, _index, objectBalance.sub(_amount)); } else if (_operation == Operations.REPLACE) { newBinBalance = writeValueInBin(_binBalances, _index, _amount); } else { revert("Invalid operation"); // Bad operation } return newBinBalance; } /* * @dev return value in _binValue at position _index * @param _binValue uint256 containing the balances of TYPES_PER_UINT256 types * @param _index index at which to retrieve value * @return Value at given _index in _bin */ function getValueInBin(uint256 _binValue, uint256 _index) internal pure returns (uint256) { // Mask to retrieve data for a given binData uint256 mask = (uint256(1) << TYPES_BITS_SIZE) - 1; // Shift amount uint256 rightShift = 256 - TYPES_BITS_SIZE * (_index + 1); return (_binValue >> rightShift) & mask; } /** * @dev return the updated _binValue after writing _amount at _index * @param _binValue uint256 containing the balances of TYPES_PER_UINT256 types * @param _index Index at which to retrieve value * @param _amount Value to store at _index in _bin * @return Value at given _index in _bin */ function writeValueInBin(uint256 _binValue, uint256 _index, uint256 _amount) internal pure returns (uint256) { require(_amount < 2**TYPES_BITS_SIZE, "Amount to write in bin is too large"); // Mask to retrieve data for a given binData uint256 mask = (uint256(1) << TYPES_BITS_SIZE) - 1; // Shift amount uint256 leftShift = 256 - TYPES_BITS_SIZE * (_index + 1); return (_binValue & ~(mask << leftShift) ) | (_amount << leftShift); } }
pragma solidity 0.5.2; import "./SafeMath.sol"; library ObjectLib32 { using SafeMath for uint256; enum Operations { ADD, SUB, REPLACE } // Constants regarding bin or chunk sizes for balance packing uint256 constant TYPES_BITS_SIZE = 32; // Max size of each object uint256 constant TYPES_PER_UINT256 = 256 / TYPES_BITS_SIZE; // Number of types per uint256 // // Objects and Tokens Functions // /** * @dev Return the bin number and index within that bin where ID is * @param _tokenId Object type * @return (Bin number, ID's index within that bin) */ function getTokenBinIndex(uint256 _tokenId) internal pure returns (uint256 bin, uint256 index) { bin = _tokenId * TYPES_BITS_SIZE / 256; index = _tokenId % TYPES_PER_UINT256; return (bin, index); } /** * @dev update the balance of a type provided in _binBalances * @param _binBalances Uint256 containing the balances of objects * @param _index Index of the object in the provided bin * @param _amount Value to update the type balance * @param _operation Which operation to conduct : * Operations.REPLACE : Replace type balance with _amount * Operations.ADD : ADD _amount to type balance * Operations.SUB : Substract _amount from type balance */ function updateTokenBalance( uint256 _binBalances, uint256 _index, uint256 _amount, Operations _operation) internal pure returns (uint256 newBinBalance) { uint256 objectBalance = 0; if (_operation == Operations.ADD) { objectBalance = getValueInBin(_binBalances, _index); newBinBalance = writeValueInBin(_binBalances, _index, objectBalance.add(_amount)); } else if (_operation == Operations.SUB) { objectBalance = getValueInBin(_binBalances, _index); newBinBalance = writeValueInBin(_binBalances, _index, objectBalance.sub(_amount)); } else if (_operation == Operations.REPLACE) { newBinBalance = writeValueInBin(_binBalances, _index, _amount); } else { revert("Invalid operation"); // Bad operation } return newBinBalance; } /* * @dev return value in _binValue at position _index * @param _binValue uint256 containing the balances of TYPES_PER_UINT256 types * @param _index index at which to retrieve value * @return Value at given _index in _bin */ function getValueInBin(uint256 _binValue, uint256 _index) internal pure returns (uint256) { // Mask to retrieve data for a given binData uint256 mask = (uint256(1) << TYPES_BITS_SIZE) - 1; // Shift amount uint256 rightShift = 256 - TYPES_BITS_SIZE * (_index + 1); return (_binValue >> rightShift) & mask; } /** * @dev return the updated _binValue after writing _amount at _index * @param _binValue uint256 containing the balances of TYPES_PER_UINT256 types * @param _index Index at which to retrieve value * @param _amount Value to store at _index in _bin * @return Value at given _index in _bin */ function writeValueInBin(uint256 _binValue, uint256 _index, uint256 _amount) internal pure returns (uint256) { require(_amount < 2**TYPES_BITS_SIZE, "Amount to write in bin is too large"); // Mask to retrieve data for a given binData uint256 mask = (uint256(1) << TYPES_BITS_SIZE) - 1; // Shift amount uint256 leftShift = 256 - TYPES_BITS_SIZE * (_index + 1); return (_binValue & ~(mask << leftShift) ) | (_amount << leftShift); } }
pragma solidity 0.5.2; /** * @title Ownable * @dev The Ownable contract has an owner address, and provides basic authorization control * functions, this simplifies the implementation of "user permissions". */ contract Ownable { address payable public owner; event OwnershipTransferred( address indexed previousOwner, address indexed newOwner ); /** * @dev The Ownable constructor sets the original `owner` of the contract to the sender * account. */ constructor() public { owner = msg.sender; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(msg.sender == owner); _; } // /** // * @dev Allows the current owner to relinquish control of the contract. // * @notice Renouncing to ownership will leave the contract without an owner. // * It will not be possible to call the functions with the `onlyOwner` // * modifier anymore. // */ // function renounceOwnership() public onlyOwner { // emit OwnershipRenounced(owner); // owner = address(0); // } /** * @dev Allows the current owner to transfer control of the contract to a newOwner. * @param _newOwner The address to transfer ownership to. */ function transferOwnership(address payable _newOwner) public onlyOwner { _transferOwnership(_newOwner); } /** * @dev Transfers control of the contract to a newOwner. * @param _newOwner The address to transfer ownership to. */ function _transferOwnership(address payable _newOwner) internal { require(_newOwner != address(0)); emit OwnershipTransferred(owner, _newOwner); owner = _newOwner; } }
pragma solidity 0.5.2; library PriceUtil { function calculateCurrentPrice(uint256 startingPrice, uint256 endingPrice, uint256 duration, uint256 secondsPassed) internal pure returns (uint256) { if(secondsPassed > duration) { return endingPrice; } int256 totalPriceChange = int256(endingPrice) - int256(startingPrice); int256 currentPriceChange = totalPriceChange * int256(secondsPassed) / int256(duration); return uint256(int256(startingPrice) + currentPriceChange); } function calculateTax(uint256 _price, uint256 _tax) internal pure returns (uint256) { // _tax < 10000, so the result will be <= price return _price * _tax / 10000; } }
pragma solidity 0.5.2; // works when no arguments required // contract BaseImplementation { // constructor() public { // init(); // } // function init() public {} // } // contract ProxyImplementation is BaseImplementation { // // allow sub class to initialse their specific phase: // mapping (string => bool) initialised; // modifier phase(string memory _phase) { // if(!initialised[_phase]) { // super.init(); // initialised[_phase] = true; // _; // } // } // } contract ProxyImplementation { mapping (string => bool) initialised; modifier phase(string memory _phase) { if(!initialised[_phase]) { initialised[_phase] = true; _; } } }
pragma solidity 0.5.2; /** * @title SafeMath * @dev Math operations with safety checks that throw on error */ library SafeMath { /** * @dev Multiplies two numbers, throws on overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256 c) { // Gas optimization: this is cheaper than asserting 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522 if (a == 0) { return 0; } c = a * b; assert(c / a == b); return c; } /** * @dev Integer division of two numbers, truncating the quotient. */ function div(uint256 a, uint256 b) internal pure 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 a / b; } /** * @dev Subtracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend). */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { assert(b <= a); return a - b; } /** * @dev Adds two numbers, throws on overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256 c) { c = a + b; assert(c >= a); return c; } }
pragma solidity 0.5.2; library SigUtil{ function recover(bytes32 hash, bytes memory sig) internal pure returns (address recovered) { require(sig.length == 65); bytes32 r; bytes32 s; uint8 v; assembly { r := mload(add(sig, 32)) s := mload(add(sig, 64)) v := byte(0, mload(add(sig, 96))) } // Version of signature should be 27 or 28, but 0 and 1 are also possible versions if (v < 27) { v += 27; } require(v == 27 || v == 28); recovered = ecrecover(hash, v, r, s); require(recovered != address(0)); } function recoverWithZeroOnFailure(bytes32 hash, bytes memory sig) internal pure returns (address) { if (sig.length != 65) { return (address(0)); } bytes32 r; bytes32 s; uint8 v; assembly { r := mload(add(sig, 32)) s := mload(add(sig, 64)) v := byte(0, mload(add(sig, 96))) } // Version of signature should be 27 or 28, but 0 and 1 are also possible versions if (v < 27) { v += 27; } if (v != 27 && v != 28) { return (address(0)); } else { return ecrecover(hash, v, r, s); } } // Builds a prefixed hash to mimic the behavior of eth_sign. function prefixed(bytes32 hash) internal pure returns (bytes memory) { return abi.encodePacked("\x19Ethereum Signed Message:\n32", hash); } }
pragma solidity 0.5.2; import "../Sand/Sand20.sol"; import "../Sand/Sand777.sol"; contract MetaProxy { address payable owner; address payable executor; address sandContract; uint256 recharge; uint256 alertThreshold; event RechargeAlert(uint256 balance); constructor(address payable _owner, address _sandContract, address payable _executor, uint256 _recharge, uint256 _alertThreshold) public { owner = _owner; sandContract = _sandContract; executor = _executor; recharge = _recharge; alertThreshold = _alertThreshold; } function processRecharge(address payable _executor) internal { require(_executor == executor, "only executor is able to execute"); if(_executor.balance < recharge) { if(recharge - _executor.balance < address(this).balance) { _executor.transfer(recharge - _executor.balance); } else { _executor.transfer(address(this).balance); } if(address(this).balance <= alertThreshold) { emit RechargeAlert(address(this).balance); } } } function executeERC20MetaTx( address _from, address _to, uint256 _amount, bytes calldata _data, uint256[4] calldata params, // _nonce, _gasPrice, _gasLimit, _tokenGasPrice address _relayer, bytes calldata _sig, bool signedOnBehalf ) external returns (bool, bytes memory) { processRecharge(tx.origin); return Sand20(sandContract).executeERC20MetaTx(_from, _to, _amount, _data, params, _relayer, _sig, address(this), signedOnBehalf); } function executeERC20MetaTxViaBasicSignature( address _from, address _to, uint256 _amount, bytes calldata _data, uint256[4] calldata params, // _nonce, _gasPrice, _gasLimit, _tokenGasPrice address _relayer, bytes calldata _sig, bool signedOnBehalf ) external returns (bool, bytes memory) { processRecharge(tx.origin); return Sand20(sandContract).executeERC20MetaTxViaBasicSignature(_from, _to, _amount, _data, params, _relayer, _sig, address(this), signedOnBehalf); } function executeERC777MetaTx( address _from, address _to, uint256 _amount, bytes calldata _data, uint256[4] calldata params, // _nonce, _gasPrice, _gasLimit, _tokenGasPrice address _relayer, bytes calldata _sig, bool signedOnBehalf ) external returns (bool, bytes memory) { processRecharge(tx.origin); return Sand777(sandContract).executeERC777MetaTx(_from, _to, _amount, _data, params, _relayer, _sig, address(this), signedOnBehalf); } function executeERC777MetaTxViaBasicSignature( address _from, address _to, uint256 _amount, bytes calldata _data, uint256[4] calldata params, // _nonce, _gasPrice, _gasLimit, _tokenGasPrice address _relayer, bytes calldata _sig, bool signedOnBehalf ) external returns (bool, bytes memory) { processRecharge(tx.origin); return Sand777(sandContract).executeERC777MetaTxViaBasicSignature(_from, _to, _amount, _data, params, _relayer, _sig, address(this), signedOnBehalf); } function() external payable {} function changeAlertThreshold(uint256 _newAlertThreshold) external { require(msg.sender == owner, "only owner able to change the alert threshold"); alertThreshold = _newAlertThreshold; } function changeRecharge(uint256 _newRecharge) external { require(msg.sender == owner, "only owner able to change recharge"); recharge = _newRecharge; } function changeOwner(address payable _newOwner) external { require(msg.sender == owner, "only owner able to change owner"); owner = _newOwner; } function changeExecutor(address payable _newExecutor) external { require(msg.sender == owner, "only owner able to change executor"); executor = _newExecutor; } function withdrawETH() external { require(msg.sender == owner, "only owner able to withdraw ETH"); owner.transfer(address(this).balance); } function withdrawETH(uint256 keep) external { require(msg.sender == owner, "only owner able to withdraw ETH"); if(keep < address(this).balance) { owner.transfer(address(this).balance - keep); } } function withdrawSand(uint256 keep) public { require(msg.sender == owner, "only owner able to withdrawn Sand"); uint256 currentBalance = Sand20(sandContract).balanceOf(address(this)); if(keep < currentBalance) { Sand20(sandContract).transfer(owner, currentBalance - keep); } } function withdrawSand() external { withdrawSand(1); // keep 1 Sand to keep the execute gas cost to not increase by having balance increase from zero } }
pragma solidity 0.5.2; import "../../Libraries/BytesUtil.sol"; import "../../Libraries/SigUtil.sol"; import "../../Interfaces/ERC1271.sol"; import "../../Interfaces/ERC1271Constants.sol"; contract ERC20ApproveExtension is ERC1271Constants{ mapping(address => mapping (uint256 => bool)) usedApprovalMessages; function approveAndCall(address _target, uint256 _amount, bytes memory _data) public payable returns (bytes memory) { _approveFor(msg.sender, _target, _amount); // ensure the first argument is equal to msg.sender // allowing function being called checking the actual sender (that approved the allowance) // this means target should not allow call from that contract if not expecting such behavior // user should be carefull as usual to not approve any contract without knowing what they'll do require(BytesUtil.doFirstParamEqualsAddress(_data, msg.sender), "first param != sender"); (bool success, bytes memory returnData) = _target.call.value(msg.value)(_data); require(success, "the call failed"); return returnData; } function approveUnlimitedAndCall(address _target, bytes calldata _data) external payable returns (bytes memory) { return approveAndCall(_target, 2**256-1, _data); // assume https://github.com/ethereum/EIPs/issues/717 } function approveViaBasicSignature(address _from, uint256 _messageId, address _target, uint256 _amount, bytes calldata _signature, bool signedOnBehalf) external returns (bool approved) { require(!usedApprovalMessages[_from][_messageId], "message already used or revoked"); bytes memory data = SigUtil.prefixed(keccak256(abi.encodePacked(address(this), APPROVE_TYPEHASH, _from, _messageId, _target,_amount))); if(signedOnBehalf) { require(ERC1271(_from).isValidSignature(data, _signature) == ERC1271_MAGICVALUE, "invalid signature"); } else { address signer = SigUtil.recover(keccak256(data), _signature); require(signer == _from, "signer != _from"); } usedApprovalMessages[_from][_messageId] = true; _approveFor(_from, _target, _amount); return true; } bytes32 constant APPROVE_TYPEHASH = keccak256("Approve(address from,uint256 messageId,address target,uint256 amount)"); function approveViaSignature(address _from, uint256 _messageId, address _target, uint256 _amount, bytes calldata _signature, bool signedOnBehalf) external returns (bool approved) { require(!usedApprovalMessages[_from][_messageId], "message already used or revoked"); bytes memory data = abi.encodePacked( "\x19\x01", domainSeparator(), keccak256(abi.encode( APPROVE_TYPEHASH, _from, _messageId, _target, _amount )) ); if(signedOnBehalf) { require(ERC1271(_from).isValidSignature(data, _signature) == ERC1271_MAGICVALUE, "invalid signature"); } else { address signer = SigUtil.recover(keccak256(data), _signature); require(signer == _from, "signer != _from"); } usedApprovalMessages[_from][_messageId] = true; _approveFor(_from, _target, _amount); return true; } function revokeApprovalMessage(uint256 _messageId) external { usedApprovalMessages[msg.sender][_messageId] = true; } function isApprovalMessageUsed(address account, uint256 _messageId) external view returns(bool revoked) { return usedApprovalMessages[account][_messageId]; } function _approveFor(address _owner, address _target, uint256 _amount) internal; function domainSeparator() internal view returns(bytes32); }
pragma solidity 0.5.2; import { ERC20 } from "../../Interfaces/ERC20.sol"; import { ERC20Events } from "../../Interfaces/ERC20Events.sol"; import "../../Libraries/SafeMath.sol"; contract ERC20BaseToken is ERC20Events /*is ERC20*/ { using SafeMath for uint256; ////////////////// Super Operators /////////////////////////////////////////////////////// // Allowing extension without redeploy mapping(address => bool) internal mSuperOperators; address public admin; event AdminChanged(address oldAdmin, address newAdmin); function changeAdmin(address _admin) external { require(msg.sender == admin, "only admin can change admin"); emit AdminChanged(admin, _admin); admin = _admin; } event SuperOperator(address superOperator, bool enabled); function setSuperOperator(address _superOperator, bool _enabled) external { require(msg.sender == admin, "only admin is allowed to add super operators"); mSuperOperators[_superOperator] = _enabled; emit SuperOperator(_superOperator, _enabled); } function isSuperOperator(address who) public view returns(bool) { return mSuperOperators[who]; } ///////////////////////////////////////////////////////////////////////////////////////////// uint256 internal mTotalSupply; mapping(address => uint256) internal mBalances; mapping(address => mapping(address => uint256)) internal mAllowed; function totalSupply() public view returns (uint256) { return mTotalSupply; } function balanceOf(address who) public view returns (uint256) { return mBalances[who]; } function decimals() public view returns (uint8) { return uint8(18); } function transfer(address _to, uint256 _amount) public returns (bool success) { _transfer(msg.sender, _to, _amount); return true; } function transferFrom(address _from, address _to, uint256 _amount) public returns (bool success) { if(msg.sender != _from && !mSuperOperators[msg.sender]) { uint256 allowance = mAllowed[_from][msg.sender]; if(allowance != (2**256)-1) { // save gas when allowance is maximal by not reducing it (see https://github.com/ethereum/EIPs/issues/717) require(allowance >= _amount, "Not enough funds allowed"); mAllowed[_from][msg.sender] = allowance.sub(_amount); } } _transfer(_from, _to, _amount); return true; } function approve(address _spender, uint256 _amount) public returns (bool success) { _approveFor(msg.sender, _spender, _amount); return true; } function approveFor(address from, address _spender, uint256 _amount) public returns (bool success) { require(msg.sender == from || mSuperOperators[msg.sender], "msg.sender != from || superOperator"); _approveFor(from, _spender, _amount); return true; } function _approveFor(address _owner, address _spender, uint256 _amount) internal { require(_owner != address(0) && _spender != address(0), "Cannot approve with 0x0"); mAllowed[_owner][_spender] = _amount; emit Approval(_owner, _spender, _amount); } function _approveForWithoutEvent(address _owner, address _spender, uint256 _amount) internal { require(_owner != address(0) && _spender != address(0), "Cannot approve with 0x0"); mAllowed[_owner][_spender] = _amount; } function allowance(address _owner, address _spender) public view returns (uint256 remaining) { return mAllowed[_owner][_spender]; } function _transfer(address _from, address _to, uint256 _amount) internal { _transferBalance(_from, _to, _amount); _emitTransferEvent(_from, _to, _amount); } function _transferBalance(address _from, address _to, uint256 _amount) internal { require(_to != address(0), "Cannot send to 0x0"); mBalances[_from] = mBalances[_from].sub(_amount); mBalances[_to] = mBalances[_to].add(_amount); } function _emitTransferEvent(address _from, address _to, uint256 _amount) internal { emit Transfer(_from, _to, _amount); } // extra functionalities ////////////////////////////////////////////////////////////////////////////// function _mint(address _to, uint256 _amount) internal { require(_to != address(0), "Cannot mint to 0x0"); mTotalSupply = mTotalSupply.add(_amount); mBalances[_to] = mBalances[_to].add(_amount); emit Transfer(address(0), _to, _amount); } function _burn(address _from, uint256 _amount) internal { if(msg.sender != _from && !mSuperOperators[msg.sender]) { require(mAllowed[_from][msg.sender] >= _amount, "Not enough funds allowed"); if(mAllowed[_from][msg.sender] != (2**256)-1) { // save gas when allowance is maximal by not reducing it (see https://github.com/ethereum/EIPs/issues/717) mAllowed[_from][msg.sender] = mAllowed[_from][msg.sender].sub(_amount); } } require(mBalances[_from] >= _amount, "Not enough funds"); mBalances[_from] = mBalances[_from].sub(_amount); mTotalSupply = mTotalSupply.sub(_amount); emit Transfer(_from, address(0), _amount); } }
pragma solidity 0.5.2; contract ERC20EscrowLessSellingExtension { mapping(address => mapping (uint256 => uint256)) sandClaimed; function claimSellerOffer( address _buyer, uint256 _offerId, address payable _seller, address _tokenContract, uint256 _buyAmount, bytes calldata _signature ) external payable { require(msg.sender == _buyer || msg.sender == address(_tokenContract), "invalid buyer"); //this assume tokenContract is safe require(sandClaimed[_seller][_offerId] >= _buyAmount, "not enough sand left"); // require(seller == recover(token, auctionData, ids, amounts, signature), "Signature mismatches"); // TODO ... } }
pragma solidity 0.5.2; import { ProxyImplementation } from "../../Libraries/ProxyImplementation.sol"; // from https://github.com/ricmoo/ethers-airdrop/blob/master/AirDropToken.sol // https://blog.ricmoo.com/merkle-air-drops-e6406945584d contract ERC20MerkleDropExtension is ProxyImplementation { bytes32 rootHash; mapping (uint256 => uint256) redeemed; function initMerkleDrop(bytes32 _rootHash) public phase("merkleDrop") { rootHash = _rootHash; } function isRedeemed(uint256 _index) public view returns (bool _redeemed) { uint256 redeemedBlock = redeemed[_index / 256]; uint256 redeemedMask = (uint256(1) << uint256(_index % 256)); return ((redeemedBlock & redeemedMask) != 0); } function redeemPackage(uint256 _index, address _recipient, uint256 _amount, bytes32[] calldata _merkleProof) external { // Make sure this package has not already been claimed (and claim it) uint256 redeemedBlock = redeemed[_index / 256]; uint256 redeemedMask = (uint256(1) << uint256(_index % 256)); require((redeemedBlock & redeemedMask) == 0); redeemed[_index / 256] = redeemedBlock | redeemedMask; // Compute the merkle root bytes32 node = keccak256(abi.encodePacked(_index, _recipient, _amount)); uint256 path = _index; for (uint16 i = 0; i < _merkleProof.length; i++) { if ((path & 0x01) == 1) { node = keccak256(abi.encodePacked(_merkleProof[i], node)); } else { node = keccak256(abi.encodePacked(node, _merkleProof[i])); } path /= 2; } // Check the merkle proof require(node == rootHash); // Redeem! _mint(_recipient, _amount); // this increase the totalSupply } function _mint(address _to, uint256 _amount) internal; }
pragma solidity 0.5.2; import "../../Libraries/BytesUtil.sol"; import "../../Libraries/SigUtil.sol"; import "../../Libraries/SafeMath.sol"; import "../../Interfaces/ERC1271.sol"; import "../../Interfaces/ERC1271Constants.sol"; contract ERC20MetaTxExtension is ERC1271Constants{ using SafeMath for uint256; bytes32 constant ERC20METATRANSACTION_TYPEHASH = keccak256("ERC20MetaTransaction(address from,address to,uint256 amount,bytes data,uint256 nonce,uint256 gasPrice,uint256 txGas,uint256 gasLimit,uint256 tokenGasPrice,address relayer)"); mapping(address => uint256) nonces; uint256 constant GAS_LIMIT_OFFSET = 112000; uint256 constant MIN_GAS = 23000 + 17500; // ~ 13000 (transfer with non-zero receiver balance) + ~ 4500 (Sent event) event MetaTx(address indexed from, uint256 indexed nonce, bool success, bytes returnData); function ensureParametersValidity( address _from, uint256 _amount, uint256[4] memory params, // _nonce, _gasPrice, _txGas, _tokenGasPrice address _relayer, uint256 initialGas ) internal view { require(_relayer == address(0) || _relayer == msg.sender, "wrong relayer"); require(nonces[_from]+1 == params[0], "nonce out of order"); require(balanceOf(_from) >= _amount.add((params[2].add(GAS_LIMIT_OFFSET)).mul(params[3])), "_from not enough balance"); require(tx.gasprice >= params[1], "gasPrice < signer gasPrice"); // need to provide at least as much gasPrice as requested by signer } function ensureCorrectSigner( address _from, address _to, uint256 _amount, bytes memory _data, uint256[4] memory params, // _nonce, _gasPrice, _txGas, _tokenGasPrice address _relayer, bytes memory _sig, bytes32 typeHash, bool signedOnBehalf ) internal view { bytes memory data = abi.encodePacked( "\x19\x01", domainSeparator(), keccak256(abi.encode( typeHash, _from, _to, _amount, keccak256(_data), params[0], params[1], params[2], GAS_LIMIT_OFFSET.add(params[2]), // expect signing gasLimit = txGas + GAS_LIMIT_OFFSET params[3], _relayer )) ); if(signedOnBehalf) { require(ERC1271(_from).isValidSignature(data, _sig) == ERC1271_MAGICVALUE, "invalid signature"); } else { address signer = SigUtil.recover(keccak256(data), _sig); require(signer == _from, "signer != _from"); } } function encodeBasicSignatureData( bytes32 typeHash, address _from, address _to, uint256 _amount, bytes memory _data, uint256[4] memory params, address _relayer ) internal view returns (bytes32) { return keccak256(abi.encodePacked( address(this), typeHash, _from, _to, _amount, keccak256(_data), params[0], params[1], params[2], GAS_LIMIT_OFFSET.add(params[2]), // expect signing gasLimit = txGas + GAS_LIMIT_OFFSET params[3], _relayer )); } function ensureCorrectSignerViaBasicSignature( address _from, address _to, uint256 _amount, bytes memory _data, uint256[4] memory params, // _nonce, _gasPrice, _txGas, _tokenGasPrice address _relayer, bytes memory _sig, bytes32 typeHash, bool signedOnBehalf ) internal view { bytes memory data = SigUtil.prefixed(encodeBasicSignatureData(typeHash, _from, _to, _amount, _data, params, _relayer)); if(signedOnBehalf) { require(ERC1271(_from).isValidSignature(data, _sig) == ERC1271_MAGICVALUE, "invalid signature"); } else { address signer = SigUtil.recover(keccak256(data), _sig); require(signer == _from, "signer != _from"); } } function executeERC20MetaTx( address _from, address _to, uint256 _amount, bytes calldata _data, uint256[4] calldata params, // _nonce, _gasPrice, _txGas, _tokenGasPrice address _relayer, bytes calldata _sig, address _tokenReceiver, bool signedOnBehalf ) external returns (bool, bytes memory) { uint256 initialGas = gasleft(); ensureParametersValidity(_from, _amount, params, _relayer, initialGas); ensureCorrectSigner(_from, _to, _amount, _data, params, _relayer, _sig, ERC20METATRANSACTION_TYPEHASH, signedOnBehalf); return performERC20MetaTx(_from, _to, _amount, _data, params, initialGas, _tokenReceiver); } function executeERC20MetaTxViaBasicSignature( address _from, address _to, uint256 _amount, bytes calldata _data, uint256[4] calldata params, // _nonce, _gasPrice, _txGas, _tokenGasPrice address _relayer, bytes calldata _sig, address _tokenReceiver, bool signedOnBehalf ) external returns (bool, bytes memory) { uint256 initialGas = gasleft(); ensureParametersValidity(_from, _amount, params, _relayer, initialGas); ensureCorrectSignerViaBasicSignature(_from, _to, _amount, _data, params, _relayer, _sig, ERC20METATRANSACTION_TYPEHASH, signedOnBehalf); return performERC20MetaTx(_from, _to, _amount, _data, params, initialGas, _tokenReceiver); } function performERC20MetaTx( address _from, address _to, uint256 _amount, bytes memory _data, uint256[4] memory params, uint256 initialGas, address _tokenReceiver ) internal returns(bool, bytes memory) { nonces[_from] = params[0]; bool success; bytes memory returnData; if(_data.length == 0){ _transfer(_from, _to, _amount); success = true; } else { require(BytesUtil.doFirstParamEqualsAddress(_data, _from), "first param != _from"); bool allowanceChanged = false; uint256 before = 0; if(_amount > 0 && !isSuperOperator(_to)){ before = allowance(_from, _to); if(before != 2**256-1) { allowanceChanged = true; _approveForWithoutEvent(_from, _to, _amount); } } (success, returnData) = _to.call.gas(params[2])(_data); require(gasleft() >= params[2].div(63), "not enough gas left"); if(allowanceChanged) { _approveForWithoutEvent(_from, _to, before); } } emit MetaTx(_from, params[0], success, returnData); if(params[3] > 0) { uint256 gasConsumed = (initialGas.add(MIN_GAS)).sub(gasleft()); uint256 maxGasCharge = GAS_LIMIT_OFFSET.add(params[2]); if(gasConsumed > maxGasCharge) { gasConsumed = maxGasCharge; // idealy we would like to charge only max(GAS_LIMIT_OFFSET, gas consumed outside the inner call) + gas consumed as part of the inner call } _transfer(_from, _tokenReceiver, gasConsumed.mul(params[3])); } return (success, returnData); } function meta_nonce(address _from) external view returns (uint256 nonce) { return nonces[_from]; } function isSuperOperator(address who) public view returns(bool); function allowance(address _owner, address _spender) public view returns (uint256 remaining); function domainSeparator() internal view returns(bytes32); function balanceOf(address who) public view returns (uint256); function _approveForWithoutEvent(address _owner, address _target, uint256 _amount) internal; function _transfer(address _from, address _to, uint256 _amount) internal; }
pragma solidity 0.5.2; import { ERC777TokenEvents } from "../../Interfaces/ERC777TokenEvents.sol"; import { ERC20BaseToken } from "../erc20/ERC20BaseToken.sol"; /* Allow ERC20 to be later upgraded to an ERC777 Since to be a valid ERC777 token, events of that standard need to be emitted for every balance transfer that ever happened we need to trigger them as part of ERC20 */ contract ERC20BaseTokenWithERC777Events is ERC20BaseToken, ERC777TokenEvents { function _transfer(address _from, address _to, uint256 _amount) internal { super._transfer(_from, _to, _amount); emit Sent(msg.sender, _from, _to, _amount, '', ''); } function _mint(address _to, uint256 _amount) internal { super._mint(_to, _amount); emit Minted(msg.sender, _to, _amount, ''); } function _burn(address _from, uint256 _amount) internal { super._burn(_from, _amount); emit Burned(msg.sender, _from, _amount, '', ''); } }
pragma solidity 0.5.2; import { ERC820Implementer } from "../../Libraries/ERC820Implementer.sol"; import { ERC777Token } from "../../Interfaces/ERC777Token.sol"; import { ERC777TokenEvents } from "../../Interfaces/ERC777TokenEvents.sol"; import { ERC777TokensSender } from "../../Interfaces/ERC777TokensSender.sol"; import { ERC777TokensRecipient } from "../../Interfaces/ERC777TokensRecipient.sol"; import { ProxyImplementation } from "../../Libraries/ProxyImplementation.sol"; import { ERC20BaseToken } from "../erc20/ERC20BaseToken.sol"; contract ERC777BaseToken is ProxyImplementation, ERC20BaseToken, /*ERC777Token,*/ ERC777TokenEvents, ERC820Implementer { mapping(address => mapping(address => bool)) internal mAuthorizedOperators; constructor() public { init777(); } function init777() public phase('777') { setInterfaceImplementation("ERC777Token", address(this)); setInterfaceImplementation("ERC20Token", address(this)); } /// @return the granularity of the token function granularity() public pure returns (uint256) { return 1; } /// @notice Return the list of default operators /// @return the list of all the default operators function defaultOperators() public pure returns (address[] memory) {} /// @notice Send `_amount` of tokens to address `_to` passing `_data` to the recipient /// @param _to The address of the recipient /// @param _amount The number of tokens to be sent function send(address _to, uint256 _amount, bytes memory _data) public { _send(msg.sender, msg.sender, _to, _amount, _data, "", true); } /// @notice Authorize a third party `_operator` to manage (send) `msg.sender`'s tokens. /// @param _operator The operator that wants to be Authorized function authorizeOperator(address _operator) public { require(_operator != msg.sender, "Cannot authorize yourself as an operator"); mAuthorizedOperators[_operator][msg.sender] = true; emit AuthorizedOperator(_operator, msg.sender); } /// @notice Revoke a third party `_operator`'s rights to manage (send) `msg.sender`'s tokens. /// @param _operator The operator that wants to be Revoked function revokeOperator(address _operator) public { require(_operator != msg.sender, "Cannot revoke yourself as an operator"); mAuthorizedOperators[_operator][msg.sender] = false; emit RevokedOperator(_operator, msg.sender); } /// @notice Check whether the `_operator` address is allowed to manage the tokens held by `_tokenHolder` address. /// @param _operator address to check if it has the right to manage the tokens /// @param _tokenHolder address which holds the tokens to be managed /// @return `true` if `_operator` is authorized for `_tokenHolder` function isOperatorFor(address _operator, address _tokenHolder) public view returns (bool) { return (_operator == _tokenHolder // solium-disable-line operator-whitespace || mAuthorizedOperators[_operator][_tokenHolder]); } /// @notice Send `_amount` of tokens on behalf of the address `from` to the address `to`. /// @param _from The address holding the tokens being sent /// @param _to The address of the recipient /// @param _amount The number of tokens to be sent /// @param _data Data generated by the user to be sent to the recipient /// @param _operatorData Data generated by the operator to be sent to the recipient function operatorSend(address _from, address _to, uint256 _amount, bytes memory _data, bytes memory _operatorData) public { require(isOperatorFor(msg.sender, _from), "Not an operator"); _send(msg.sender, _from, _to, _amount, _data, _operatorData, true); } /* -- Helper Functions -- */ /// @notice Check whether an address is a regular address or not. /// @param _addr Address of the contract that has to be checked /// @return `true` if `_addr` is a regular address (not a contract) function isRegularAddress(address _addr) internal view returns(bool) { if (_addr == address(0)) { return false; } uint size; assembly { size := extcodesize(_addr) } // solium-disable-line security/no-inline-assembly return size == 0; } /// @notice Helper function actually performing the sending of tokens. /// @param _operator The address performing the send /// @param _from The address holding the tokens being sent /// @param _to The address of the recipient /// @param _amount The number of tokens to be sent /// @param _data Data generated by the user to be passed to the recipient /// @param _operatorData Data generated by the operator to be passed to the recipient /// @param _preventLocking `true` if you want this function to throw when tokens are sent to a contract not /// implementing `ERC777tokensRecipient`. /// ERC777 native Send functions MUST set this parameter to `true`, and backwards compatible ERC20 transfer /// functions SHOULD set this parameter to `false`. function _send( address _operator, address _from, address _to, uint256 _amount, bytes memory _data, bytes memory _operatorData, bool _preventLocking ) internal { callSender(_operator, _from, _to, _amount, _data, _operatorData); super._transfer(_from, _to, _amount); // TODO test it does not call this._transfer (which would emit 2 Sent event) callRecipient(_operator, _from, _to, _amount, _data, _operatorData, _preventLocking); emit Sent(_operator, _from, _to, _amount, _data, _operatorData); } function _transfer(address _from, address _to, uint256 _amount) internal { _send(msg.sender, _from, _to, _amount, "", "", false); } /// @notice Helper function that checks for ERC777TokensRecipient on the recipient and calls it. /// May throw according to `_preventLocking` /// @param _operator The address performing the send or mint /// @param _from The address holding the tokens being sent /// @param _to The address of the recipient /// @param _amount The number of tokens to be sent /// @param _data Data generated by the user to be passed to the recipient /// @param _operatorData Data generated by the operator to be passed to the recipient /// @param _preventLocking `true` if you want this function to throw when tokens are sent to a contract not /// implementing `ERC777TokensRecipient`. /// ERC777 native Send functions MUST set this parameter to `true`, and backwards compatible ERC20 transfer /// functions SHOULD set this parameter to `false`. function callRecipient( address _operator, address _from, address _to, uint256 _amount, bytes memory _data, bytes memory _operatorData, bool _preventLocking ) internal { address recipientImplementation = interfaceAddr(_to, "ERC777TokensRecipient"); if (recipientImplementation != address(0)) { ERC777TokensRecipient(recipientImplementation).tokensReceived( _operator, _from, _to, _amount, _data, _operatorData); } else if (_preventLocking) { require(isRegularAddress(_to), "Cannot send to contract without ERC777TokensRecipient"); } } /// @notice Helper function that checks for ERC777TokensSender on the sender and calls it. /// May throw according to `_preventLocking` /// @param _from The address holding the tokens being sent /// @param _to The address of the recipient /// @param _amount The amount of tokens to be sent /// @param _data Data generated by the user to be passed to the recipient /// @param _operatorData Data generated by the operator to be passed to the recipient /// implementing `ERC777TokensSender`. /// ERC777 native Send functions MUST set this parameter to `true`, and backwards compatible ERC20 transfer /// functions SHOULD set this parameter to `false`. function callSender( address _operator, address _from, address _to, uint256 _amount, bytes memory _data, bytes memory _operatorData ) internal { address senderImplementation = interfaceAddr(_from, "ERC777TokensSender"); if (senderImplementation == address(0)) { return; } ERC777TokensSender(senderImplementation).tokensToSend( _operator, _from, _to, _amount, _data, _operatorData); } // extra functionalities ////////////////////////////////////////////////////////////////////////////// function _mint(address _to, uint256 _amount) internal { super._mint(_to, _amount); emit Minted(msg.sender, _to, _amount, ''); } function _burn(address _from, uint256 _amount) internal { super._burn(_from, _amount); emit Burned(msg.sender, _from, _amount, '', ''); } }
pragma solidity 0.5.2; import "../../Libraries/BytesUtil.sol"; import "../../Libraries/SigUtil.sol"; import "../../Libraries/SafeMath.sol"; import "../erc20/ERC20MetaTxExtension.sol"; // TODO WORK IN PROGRESS contract ERC777MetaTxExtension is ERC20MetaTxExtension { bytes32 constant ERC777METATRANSACTION_TYPEHASH = keccak256("ERC777MetaTransaction(address from,address to,uint256 amount,bytes data,uint256 nonce,uint256 gasPrice,uint256 gasLimit,uint256 tokenGasPrice,address relayer)"); // TODO could potentialy get ir fo this and use operatorSend instead (the token contract itself could be an defaultOperator) function sendFrom(address _from, address _to, uint256 _amount, bytes calldata _data) external { require(msg.sender == address(this), "only to be used by contract to support meta-tx"); // allow _from to allow gas estimatiom _send(_from, _from, _to, _amount, _data, "", true); } function executeERC777MetaTx( address _from, address _to, uint256 _amount, bytes calldata _data, uint256[4] calldata params, // _nonce, _gasPrice, _txGas, _tokenGasPrice address _relayer, bytes calldata _sig, address _tokenReceiver, bool signedOnBehalf ) external returns (bool, bytes memory) { uint256 initialGas = gasleft(); ensureParametersValidity(_from, _amount, params, _relayer, initialGas); ensureCorrectSigner(_from, _to, _amount, _data, params, _relayer, _sig, ERC777METATRANSACTION_TYPEHASH, signedOnBehalf); return performERC777MetaTx(_from, _to, _amount, _data, params, initialGas, _tokenReceiver); } function executeERC777MetaTxViaBasicSignature( address _from, address _to, uint256 _amount, bytes calldata _data, uint256[4] calldata params, // _nonce, _gasPrice, _txGas, _tokenGasPrice address _relayer, bytes calldata _sig, address _tokenReceiver, bool signedOnBehalf ) external returns (bool, bytes memory) { uint256 initialGas = gasleft(); ensureParametersValidity(_from, _amount, params, _relayer, initialGas); ensureCorrectSignerViaBasicSignature(_from, _to, _amount, _data, params, _relayer, _sig, ERC777METATRANSACTION_TYPEHASH, signedOnBehalf); return performERC777MetaTx(_from, _to, _amount, _data, params, initialGas, _tokenReceiver); } function performERC777MetaTx( address _from, address _to, uint256 _amount, bytes memory _data, uint256[4] memory params, // _nonce, _gasPrice, _txGas, _tokenGasPrice uint256 initialGas, address _tokenReceiver ) internal returns (bool, bytes memory) { nonces[_from] = params[0]; // TODO extract to not dupplicate ERC20MetaTxExtension code bool success; bytes memory returnData; if(_data.length == 0){ _transfer(_from, _to, _amount); success = true; } else { // should we support non-erc777 execution ? (success, returnData) = address(this).call.gas(params[2])(abi.encodeWithSignature("sendFrom(address,address,uint256,bytes)", _from, _to, _amount, _data)); require(gasleft() >= params[2].div(63), "not enough gas left"); } // TODO extract to not dupplicate ERC20MetaTxExtension code emit MetaTx(_from, params[0], success, returnData); if(params[3] > 0) { uint256 gasConsumed = (initialGas + MIN_GAS) - gasleft(); if(gasConsumed > GAS_LIMIT_OFFSET + params[2]) { gasConsumed = GAS_LIMIT_OFFSET + params[2]; // idealy we would like to charge only max(BASE_GAS, gas consumed outside the inner call) + gas consumed as part of the inner call } _transfer(_from, _tokenReceiver, gasConsumed * params[3]); } return (success, returnData); } function _send( address _operator, address _from, address _to, uint256 _amount, bytes memory _data, bytes memory _operatorData, bool _preventLocking )internal; }
pragma solidity 0.5.2; import { ERC777BaseToken } from "../ERC777BaseToken.sol"; import { Ownable } from "../../../Libraries/ownership/Ownable.sol"; contract ERC777WithOptionalERC20 is ERC777BaseToken, Ownable { bool internal mErc20compatible; event ERC20Disabled(); constructor() public { initOptionalERC20(); } function initOptionalERC20() public phase('OptionalERC20') { init777(); mErc20compatible = true; } /// @notice This modifier is applied to erc20 obsolete methods that are /// implemented only to maintain backwards compatibility. When the erc20 /// compatibility is disabled, this methods will fail. modifier erc20 () { require(mErc20compatible, "ERC20 is disabled"); _; } /// @notice Disables the ERC20 interface. This function can only be called /// by the owner. function disableERC20() public onlyOwner { mErc20compatible = false; setInterfaceImplementation("ERC20Token", address(0)); emit ERC20Disabled(); } function decimals() public erc20 view returns (uint8) { return super.decimals(); } function transfer(address _to, uint256 _amount) public erc20 returns (bool success) { return super.transfer(_to, _amount); } function transferFrom(address _from, address _to, uint256 _amount) public erc20 returns (bool success) { return super.transferFrom(_from, _to, _amount); } function approve(address _spender, uint256 _amount) public erc20 returns (bool success) { return super.approve(_spender, _amount); } function allowance(address _owner, address _spender) public erc20 view returns (uint256 remaining) { return super.allowance(_owner, _spender); } //override to block from emitting Transfer when not mErc20compatible function _send( address _operator, address _from, address _to, uint256 _amount, bytes memory _data, bytes memory _operatorData, bool _preventLocking ) internal { callSender(_operator, _from, _to, _amount, _data, _operatorData); // _transfer /////////////////////////////////////////////////////////////// require(_to != address(0), "Cannot send to 0x0"); require(mBalances[_from] >= _amount, "Not enough funds"); mBalances[_from] = mBalances[_from] -= _amount; mBalances[_to] = mBalances[_to] += _amount; if (mErc20compatible) { emit Transfer(_from, _to, _amount); } // //////////////////////////////////////////////////////////////////////// callRecipient(_operator, _from, _to, _amount, _data, _operatorData, _preventLocking); emit Sent(_operator, _from, _to, _amount, _data, _operatorData); } }
pragma solidity 0.5.2; import { ERC777BaseToken } from "../ERC777BaseToken.sol"; import { Ownable } from "../../../Libraries/ownership/Ownable.sol"; contract ERC777WitoutERC20 is ERC777BaseToken, Ownable { constructor() public { init777WithoutERC20(); } function init777WithoutERC20() public phase('777WithoutERC20') { setInterfaceImplementation("ERC20Token", address(0)); } /// overrite ERC20BaseToken ERC20 methods to revert function decimals() public view returns (uint8) { revert(); } function transfer(address, uint256) public returns (bool) { revert(); } function transferFrom(address, address, uint256) public returns (bool) { revert(); } function approve(address, uint256) public returns (bool) { revert(); } function allowance(address, address) public view returns (uint256) { revert(); } //override to block from emitting Transfer when not mErc20compatible function _send( address _operator, address _from, address _to, uint256 _amount, bytes memory _data, bytes memory _operatorData, bool _preventLocking ) internal { callSender(_operator, _from, _to, _amount, _data, _operatorData); require(_to != address(0), "Cannot send to 0x0"); require(mBalances[_from] >= _amount, "Not enough funds"); mBalances[_from] = mBalances[_from] -= _amount; mBalances[_to] = mBalances[_to] += _amount; callRecipient(_operator, _from, _to, _amount, _data, _operatorData, _preventLocking); emit Sent(_operator, _from, _to, _amount, _data, _operatorData); } }
pragma solidity 0.5.2; import "./erc20/ERC20ApproveExtension.sol"; import "./erc20/ERC20MetaTxExtension.sol"; import "./erc777/ERC20BaseTokenWithERC777Events.sol"; import "../TheSandbox712.sol"; import { ProxyImplementation } from "../Libraries/ProxyImplementation.sol"; contract Sand20 is ProxyImplementation, ERC20MetaTxExtension, ERC20ApproveExtension, TheSandbox712, ERC20BaseTokenWithERC777Events { constructor(address _admin, address _beneficiary) public { initSand(_admin, _beneficiary); } function initSand(address _admin, address _beneficiary) public phase('SAND_20') { init712(); admin = _admin; if(mTotalSupply == 0 ) { _mint(_beneficiary, 3000000000000000000000000000); } } function name() public view returns (string memory) { return "SAND"; } function symbol() public view returns (string memory) { return "SAND"; } function burn(uint256 _amount) external { _burn(msg.sender, _amount); } }
pragma solidity 0.5.2; import "./erc777/ERC20BaseTokenWithERC777Events.sol"; import { ProxyImplementation } from "../Libraries/ProxyImplementation.sol"; contract Sand20Basic is ProxyImplementation, ERC20BaseTokenWithERC777Events { constructor(address _admin, address _beneficiary) public { initSand(_admin, _beneficiary); } function initSand(address _admin, address _beneficiary) public phase('SAND_20') { admin = _admin; if(mTotalSupply == 0 ) { _mint(_beneficiary, 3000000000000000000000000000); } } function name() public pure returns (string memory) { return "SAND"; } function symbol() public pure returns (string memory) { return "SND"; } function burn(uint256 _amount) external { _burn(msg.sender, _amount); } }
pragma solidity 0.5.2; import "./erc20/ERC20ApproveExtension.sol"; import "./erc777/ERC777BaseToken.sol"; import "../TheSandbox712.sol"; import { ProxyImplementation } from "../Libraries/ProxyImplementation.sol"; import "./erc20/ERC20MetaTxExtension.sol"; import "./erc777/ERC777MetaTxExtension.sol"; contract Sand777 is ERC777MetaTxExtension, ProxyImplementation, ERC20ApproveExtension, TheSandbox712, ERC777BaseToken { // TODO add _owners constructor(address _beneficiary) public { initSand(_beneficiary); } // TODO need to be updated if updating inheritance // better pattern ? function initSand(address _beneficiary) public phase('SAND_777') { init712(); init777(); if(mTotalSupply == 0 ) { _mint(_beneficiary, 3000000000000000000000000000); } } function name() public pure returns (string memory) { return "SAND"; } function symbol() public pure returns (string memory) { return "SND"; } function burn(uint256 _amount) external { _burn(msg.sender, _amount); } }
pragma solidity 0.5.2; import "./Sand/Sand20.sol"; contract Sand is Sand20 { constructor(address _admin, address _beneficiary) public Sand20(_admin, _beneficiary) {} }
pragma solidity 0.5.2; // from : https://github.com/christianlundkvist/simple-multisig/blob/f63ef72e448ecef85dd61ad5a3727c7dba4e4377/contracts/SimpleMultiSig.sol // + specify 0.5.2 // + fixed indentation + add storage location contract SimpleMultiSig { // kekkac256("MultiSigTransaction(address destination,uint256 value,bytes data,uint256 nonce,address executor,uint256 gasLimit)") bytes32 constant TXTYPE_HASH = 0x3ee892349ae4bbe61dce18f95115b5dc02daf49204cc602458cd4c1f540d56d7; bytes32 constant SALT = 0x251543af6a222378665a76fe38dbceae4871a070b7fdaf5c6c30cf758dc33cc0; uint public nonce; // (only) mutable state uint public threshold; // immutable state mapping (address => bool) isOwner; // immutable state address[] public ownersArr; // immutable state // Note that owners_ must be strictly increasing, in order to prevent duplicates constructor(uint threshold_, address[] memory owners_) public { require(owners_.length <= 10 && threshold_ <= owners_.length && threshold_ > 0); address lastAdd = address(0); for (uint i = 0; i < owners_.length; i++) { require(owners_[i] > lastAdd); isOwner[owners_[i]] = true; lastAdd = owners_[i]; } ownersArr = owners_; threshold = threshold_; } // Note that address recovered from signatures must be strictly increasing, in order to prevent duplicates function execute(uint8[] memory sigV, bytes32[] memory sigR, bytes32[] memory sigS, address destination, uint value, bytes memory data, address executor, uint gasLimit) public { require(sigR.length == threshold); require(sigR.length == sigS.length && sigR.length == sigV.length); require(executor == msg.sender || executor == address(0)); bytes32 txInputHash = keccak256(abi.encodePacked( address(this), TXTYPE_HASH, SALT, destination, value, keccak256(data), nonce, executor, gasLimit )); bytes32 totalHash = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", txInputHash)); address lastAdd = address(0); // cannot have address(0) as an owner for (uint i = 0; i < threshold; i++) { address recovered = ecrecover(totalHash, sigV[i], sigR[i], sigS[i]); require(recovered > lastAdd && isOwner[recovered]); lastAdd = recovered; } // If we make it here all signatures are accounted for. // The address.call() syntax is no longer recommended, see: // https://github.com/ethereum/solidity/issues/2884 nonce = nonce + 1; bool success = false; assembly { success := call(gasLimit, destination, value, add(data, 0x20), mload(data), 0, 0) } require(success); } function () payable external {} }
pragma solidity 0.5.2; import "./SimpleMultiSig.sol"; contract SimpleMultiSigDeployer { event MultiSigDeployed(string indexed name, address indexed multiSigAddress, uint256 threshold, address[] owners); event MultiSigOwner(string indexed name, address indexed owner); mapping(string => SimpleMultiSig) deployed; address owner; constructor(address _owner) public { owner = _owner; } // TODO ? // function deploySimpleMultiSig(uint256 threshold_, address[] calldata owners_, uint256 chainId, string calldata name) external { // require(msg.sender == owner, "only owner can deploy"); // require(address(deployed[name]) == address(0), "same name already deployed"); // SimpleMultiSig simpleMultiSig = new SimpleMultiSig(threshold_, owners_, chainId); // deployed[name] = simpleMultiSig; // for(uint256 i = 0; i < owners_.length; i++) { // emit MultiSigOwner(name, owners_[i]); // } // emit MultiSigDeployed(name, address(simpleMultiSig), threshold_, owners_); // } function isDeployed(string calldata name) external view returns(bool) { return address(deployed[name]) != address(0); } function transferOwnership(address _newOwner) external { require(msg.sender == owner, "only owner can change owner"); owner = _newOwner; } }
pragma solidity 0.5.2; import "../Interfaces/ERC1271.sol"; import "../Interfaces/ERC1271Constants.sol"; import "../Libraries/SigUtil.sol"; contract ERC1271Wallet is ERC1271, ERC1271Constants{ address owner; mapping(address => bool) authorizedSigners; constructor(address _signer) public { owner = msg.sender; authorizedSigners[_signer] = true; } function isValidSignature( bytes memory _data, bytes memory _signature ) public view returns (bytes4 magicValue){ address signer = SigUtil.recoverWithZeroOnFailure(keccak256(_data), _signature); if(authorizedSigners[signer]) { return ERC1271_MAGICVALUE; } } }
pragma solidity 0.5.2; import "../Interfaces/ERC20.sol"; contract ERC20Fund { ERC20 token; address owner; constructor(ERC20 _token) public { token = _token; owner = msg.sender; } function take(address _from, uint256 _amount) public returns(bool) { return token.transferFrom(_from, address(this), _amount); } function give(address _to, uint256 _amount) public returns(bool) { require(msg.sender == owner, "only onwer can give"); return token.transfer(_to, _amount); } function fail() external pure { require(false, "fail"); } }
pragma solidity 0.5.2; import "../Interfaces/ERC20.sol"; contract ERC20MetaTxReceiver { ERC20 token; address owner; uint256 price; uint256 balance; event Received(address sender, uint256 value, string name, uint256 test); constructor(ERC20 _token, uint256 _price) public { token = _token; price = _price; owner = msg.sender; } function receiveMeta(address sender, uint256 value, string calldata name, uint256 test) external { require(msg.sender == sender || msg.sender == address(token), "sender != msg.sender || token"); require(value == price, "not enough value"); token.transferFrom(sender, address(this), value); balance += value; emit Received(sender, value, name, test); } function withdrawnAll() external { require(owner == msg.sender, "only owner can withdraw"); uint256 tmpBalance = balance; balance = 0; token.transfer(msg.sender, tmpBalance); } }
pragma solidity 0.5.2; contract GasDrain { mapping(uint256 => uint256) store; function receiveAnyToken(address sender, address token, uint256 id, uint256 value, uint256 amoutOfGas) external { uint256 start = gasleft() + 500; // TODO uint256 i = 1; while(start - gasleft() < amoutOfGas) { i++; } } function receiveSpecificERC20(address, uint256, uint256 amoutOfGas) external { uint256 start = gasleft() + 303; // 301 for amoutOfGas == 3000000 // 321 for amountOfGas == 2000000 // 303 for amountOfGas == 5000000 while(start - gasleft() < amoutOfGas) {} } function receiveSpecificERC20IfEnoughGas(address, uint256, uint256 amoutOfGas) external { assert(gasleft() > amoutOfGas - 231); // 231 for amoutOfGas == 5000000 } function receive(uint256 amoutOfGas) external view { uint256 start = gasleft() + 301; while(start - gasleft() < amoutOfGas) {} } function receiveWithData(uint256 amoutOfGas, bytes calldata) external view { uint256 start = gasleft() + 427; while(start - gasleft() < amoutOfGas) {} } }
pragma solidity 0.5.2; contract GasTest{ uint256 constant WORST_CASE_EPSILON = 1000; event Tx(bool success, bytes returnData, uint256 gasUsed); function test(uint256 epsilon, uint256 txGas, address _to, bytes calldata _data) external returns (bool success, bytes memory returnData) { uint256 gasAvailable = gasleft() - epsilon; require(gasAvailable - gasAvailable/64 > txGas, "not enough gas"); (success, returnData) = _to.call.gas(txGas)(_data); emit Tx(success, returnData, gasAvailable - gasleft()); } function test(uint256 txGas, address _to, bytes calldata _data) external returns (bool success, bytes memory returnData) { uint256 gasAvailable = gasleft() - WORST_CASE_EPSILON; require(gasAvailable - gasAvailable/64 > txGas, "not enough gas"); (success, returnData) = _to.call.gas(txGas)(_data); emit Tx(success, returnData, gasAvailable - gasleft()); } function raw(uint256 txGas, address _to, bytes calldata _data) external returns (bool success, bytes memory returnData) { uint256 gasAvailable = gasleft(); (success, returnData) = _to.call.gas(txGas)(_data); emit Tx(success, returnData, gasAvailable - gasleft()); } }
pragma solidity 0.5.2; import "../Interfaces/ERC20.sol"; contract GenericERC20MetaTxReceiver { address metaTxContract; ERC20 token; address owner; uint256 price; uint256 balance; event Received(address sender, uint256 value); constructor(address _metaTxContract, ERC20 _token, uint256 _price) public { token = _token; owner = msg.sender; price = _price; metaTxContract = _metaTxContract; } function erc20_tokensReceived(address from, address tokenContract, uint256 amount, bytes calldata data) external { // TODO check token being given require(msg.sender == address(metaTxContract) || msg.sender == tokenContract , "sender != metaTxContract && != tokenContract"); require(amount == price, "not enough value"); balance += amount; emit Received(from, amount); } function meta_transaction_received(address sender, bytes calldata data) external { (address addr, uint256 value) = abi.decode(data, (address, uint256)); require(sender == msg.sender || msg.sender == address(metaTxContract), "sender != sender && != metaTxContract"); emit Received(addr, value); } function withdrawnAll() external { require(owner == msg.sender, "only owner can withdraw"); uint256 tmpBalance = balance; balance = 0; token.transfer(msg.sender, tmpBalance); } }
pragma solidity 0.5.2; import "../Interfaces/ERC777TokensRecipient.sol"; import "../Interfaces/ERC777Token.sol"; import "../Interfaces/ERC20.sol"; import { ERC820Implementer } from "../Libraries/ERC820Implementer.sol"; contract Sand777Receiver is ERC777TokensRecipient, ERC820Implementer { bool private allowTokensReceived; address private owner; ERC777Token private tokenContract; uint256 private tokenBalance; constructor(ERC777Token _tokenContract, bool _allowTokensReceived) public { tokenContract = _tokenContract; allowTokensReceived = _allowTokensReceived; owner = msg.sender; setInterfaceImplementation("ERC777TokensRecipient", address(this)); } modifier onlyOwner() { require(msg.sender == owner); _; } function send(address _to, uint256 _amount) public { tokenContract.send(_to, _amount, ""); } function transfer(address _to, uint256 _amount) public { ERC20(address(tokenContract)).transfer(_to, _amount); } function tokensReceived( address,// operator, address,// from, address,// to, uint256 amount, bytes memory,// data, bytes memory // operatorData ) public { require(address(tokenContract) == msg.sender, "only accept tokenContract as sender"); require(allowTokensReceived, "Receive not allowed"); tokenBalance += amount; } function acceptTokens() public onlyOwner { allowTokensReceived = true; } function rejectTokens() public onlyOwner { allowTokensReceived = false; } function receiveMeta(address sender, string calldata name, uint256 value, uint256 test) external { // for test matching erc20Receiver } }
pragma solidity 0.5.2; import "../Interfaces/ERC777TokensRecipient.sol"; import "../Interfaces/ERC777Token.sol"; import "../Interfaces/ERC20.sol"; import { ERC820Implementer } from "../Libraries/ERC820Implementer.sol"; contract Sand777Sender is ERC777TokensRecipient, ERC820Implementer { bool private allowTokensSent; address private owner; ERC777Token private tokenContract; uint256 private tokenBalance; constructor(ERC777Token _tokenContract, bool _allowTokensSent) public { tokenContract = _tokenContract; allowTokensSent = _allowTokensSent; owner = msg.sender; setInterfaceImplementation("ERC777TokensSender", address(this)); setInterfaceImplementation("ERC777TokensRecipient", address(this)); } modifier onlyOwner() { require(msg.sender == owner); _; } function send(address _to, uint256 _amount) public { tokenContract.send(_to, _amount, ""); } function transfer(address _to, uint256 _amount) public { ERC20(address(tokenContract)).transfer(_to, _amount); } function tokensReceived( address,// operator, address,// from, address,// to, uint256 amount, bytes memory,// data, bytes memory // operatorData ) public { require(address(tokenContract) == msg.sender, "only accept tokenContract as sender"); tokenBalance += amount; } function tokensToSend( address,// operator, address,// from, address,// to, uint256 amount, bytes memory,// data, bytes memory // operatorData ) public { require(address(tokenContract) == msg.sender, "only accept tokenContract as sender"); require(allowTokensSent, "Sending not allowed"); tokenBalance -= amount; } function acceptTokens() public onlyOwner { allowTokensSent = true; } function rejectTokens() public onlyOwner { allowTokensSent = false; } }
pragma solidity 0.5.2; contract TestERC1155ERC721TokenReceiver { bool private allowTokensReceived; bool private returnCorrectBytes; bool private allowBatchTokensReceived; bool private returnCorrectBytesOnBatch; bool private doNotThrow; address private owner; address private tokenContract; mapping(uint256 => bool) private tokens; bytes4 constant private ERC1155_REJECTED = 0xafed434d; bytes4 constant private ERC1155_RECEIVED = 0xf23a6e61; bytes4 constant private ERC1155_BATCH_RECEIVED = 0xbc197c81; bytes4 private constant _ERC721_RECEIVED = 0x150b7a02; constructor( address _tokenContract, bool _allowTokensReceived, bool _returnCorrectBytes, bool _allowBatchTokensReceived, bool _returnCorrectBytesOnBatch, bool _doNotThrow ) public { tokenContract = _tokenContract; allowTokensReceived = _allowTokensReceived; returnCorrectBytes = _returnCorrectBytes; allowBatchTokensReceived = _allowBatchTokensReceived; returnCorrectBytesOnBatch = _returnCorrectBytesOnBatch; doNotThrow = _doNotThrow; owner = msg.sender; } modifier onlyOwner() { require(msg.sender == owner, "only owner allowed"); _; } function onERC1155Received( address _operator, address _from, uint256 _id, uint256 _value, bytes calldata _data ) external returns(bytes4){ require(address(tokenContract) == msg.sender, "only accept tokenContract as sender"); require(doNotThrow, "throw requested"); if(!allowTokensReceived) { if(returnCorrectBytes) { return ERC1155_REJECTED; } else { return 0x150b7a03; } } if(returnCorrectBytes) { (bool success, bytes memory returnData) = tokenContract.call(abi.encodeWithSignature("ownerOf(uint256)", _id)); uint256 value; assembly { value := mload(add(returnData, 32)) } if(success && value == uint256(address(this))) { onERC721Received(_operator, _from, _id, _data); } return ERC1155_RECEIVED; } else { return 0x150b7a03; } } function onERC1155BatchReceived( address _operator, address _from, uint256[] calldata _ids, uint256[] calldata _values, bytes calldata _data ) external returns(bytes4){ require(address(tokenContract) == msg.sender, "only accept tokenContract as sender"); require(allowBatchTokensReceived, "Receive not allowed"); if(returnCorrectBytesOnBatch) { return ERC1155_BATCH_RECEIVED; } else { return 0x150b7a03; } } function onERC721Received( address,// operator, address,// from, uint256 _tokenId, bytes memory // data ) public returns (bytes4) { require(address(tokenContract) == msg.sender, "only accept tokenContract as sender"); require(allowTokensReceived, "Receive not allowed"); if(returnCorrectBytes) { return _ERC721_RECEIVED; } else { return 0x150b7a03; } } function acceptTokens() public onlyOwner { allowTokensReceived = true; } function rejectTokens() public onlyOwner { allowTokensReceived = false; } function acceptBatchTokens() public onlyOwner { allowBatchTokensReceived = true; } function rejectBatchTokens() public onlyOwner { allowBatchTokensReceived = false; } }
pragma solidity 0.5.2; contract TestERC1155Receiver { bool private allowTokensReceived; bool private returnCorrectBytes; bool private allowBatchTokensReceived; bool private returnCorrectBytesOnBatch; address private owner; address private tokenContract; mapping(uint256 => bool) private tokens; bytes4 constant private ERC1155_REJECTED = 0xafed434d; // TODO use it bytes4 constant private ERC1155_RECEIVED = 0xf23a6e61; bytes4 constant private ERC1155_BATCH_RECEIVED = 0xbc197c81; constructor( address _tokenContract, bool _allowTokensReceived, bool _returnCorrectBytes, bool _allowBatchTokensReceived, bool _returnCorrectBytesOnBatch ) public { tokenContract = _tokenContract; allowTokensReceived = _allowTokensReceived; returnCorrectBytes = _returnCorrectBytes; allowBatchTokensReceived = _allowBatchTokensReceived; returnCorrectBytesOnBatch = _returnCorrectBytesOnBatch; owner = msg.sender; } modifier onlyOwner() { require(msg.sender == owner, "only owner allowed"); _; } function onERC1155Received( address _operator, address _from, uint256 _id, uint256 _value, bytes calldata _data ) external returns(bytes4){ require(address(tokenContract) == msg.sender, "only accept tokenContract as sender"); require(allowTokensReceived, "Receive not allowed"); if(returnCorrectBytes) { return ERC1155_RECEIVED; } else { return 0x150b7a03; } } function onERC1155BatchReceived( address _operator, address _from, uint256[] calldata _ids, uint256[] calldata _values, bytes calldata _data ) external returns(bytes4){ require(address(tokenContract) == msg.sender, "only accept tokenContract as sender"); require(allowBatchTokensReceived, "Receive not allowed"); if(returnCorrectBytesOnBatch) { return ERC1155_BATCH_RECEIVED; } else { return 0x150b7a03; } } function acceptTokens() public onlyOwner { allowTokensReceived = true; } function rejectTokens() public onlyOwner { allowTokensReceived = false; } function acceptBatchTokens() public onlyOwner { allowBatchTokensReceived = true; } function rejectBatchTokens() public onlyOwner { allowBatchTokensReceived = false; } }
pragma solidity 0.5.2; contract TestERC721TokenReceiver { bool private allowTokensReceived; bool private returnCorrectBytes; address private owner; address private tokenContract; mapping(uint256 => bool) private tokens; // Equals to `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))` // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector` bytes4 private constant _ERC721_RECEIVED = 0x150b7a02; constructor(address _tokenContract, bool _allowTokensReceived, bool _returnCorrectBytes) public { tokenContract = _tokenContract; allowTokensReceived = _allowTokensReceived; returnCorrectBytes = _returnCorrectBytes; owner = msg.sender; } modifier onlyOwner() { require(msg.sender == owner, "only owner allowed"); _; } function onERC721Received( address,// operator, address,// from, uint256 _tokenId, bytes memory // data ) public returns (bytes4) { require(address(tokenContract) == msg.sender, "only accept tokenContract as sender"); require(allowTokensReceived, "Receive not allowed"); if(returnCorrectBytes) { return _ERC721_RECEIVED; } else { return 0x150b7a03; } } function acceptTokens() public onlyOwner { allowTokensReceived = true; } function rejectTokens() public onlyOwner { allowTokensReceived = false; } }
pragma solidity 0.5.2; import "../Asset/Interfaces/MintingFeeCollector.sol"; import "../Asset.sol"; contract TestMintingFeeCollector is MintingFeeCollector { mapping(uint256 => uint256) stakes; Asset from; address owner; constructor(address _owner, Asset _from) public { from = _from; owner = _owner; } function multiple_minted(uint256[] calldata tokenIds, uint256 feePerToken) external { require(msg.sender == address(from), "only accepting from"); for(uint256 i = 0; i < tokenIds.length; i ++) { stakes[tokenIds[i]] = feePerToken; } } function single_minted(uint256 tokenId, uint256 fee) external { require(msg.sender == address(from), "only accepting from"); stakes[tokenId] = fee; } function setFeeCollection(address newCollector, uint256 newFee) external { require(msg.sender == owner); from.setFeeCollection(newCollector, newFee); } }
pragma solidity 0.5.2; import { ProxyImplementation } from "./Libraries/ProxyImplementation.sol"; contract TheSandbox712 is ProxyImplementation { bytes32 constant EIP712DOMAIN_TYPEHASH = keccak256("EIP712Domain(string name,string version,address verifyingContract)"); bytes32 DOMAIN_SEPARATOR; function init712() public phase("712") { DOMAIN_SEPARATOR = keccak256(abi.encode(EIP712DOMAIN_TYPEHASH, keccak256("The Sandbox 3D"), keccak256("1"), address(this))); } function domainSeparator() internal view returns(bytes32){ return DOMAIN_SEPARATOR; } }
pragma solidity 0.5.2; import "./AdminUpgradeabilityProxy.sol"; import "../Libraries/ownership/Ownable.sol"; contract ProxyAdmin is Ownable { AdminUpgradeabilityProxy proxy; constructor(AdminUpgradeabilityProxy _proxy, address payable _owner) public { proxy = _proxy; owner = _owner; } function proxyAddress() public view returns (address) { return address(proxy); } function admin() public returns (address) { return proxy.admin(); } function changeAdmin(address newAdmin) public onlyOwner { proxy.changeAdmin(newAdmin); } function upgradeTo(address implementation) public onlyOwner { proxy.upgradeTo(implementation); } function upgradeToAndCall(address implementation, bytes memory data) payable public onlyOwner { proxy.upgradeToAndCall.value(msg.value)(implementation, data); } }
// from https://github.com/zeppelinos/zos/blob/1cea266a672a1efc31915420af5eb5185173837c/packages/lib/contracts/upgradeability/Proxy.sol pragma solidity 0.5.2; /** * @title ProxyBase * @dev Implements delegation of calls to other contracts, with proper * forwarding of return values and bubbling of failures. * It defines a fallback function that delegates all calls to the address * returned by the abstract _implementation() internal function. */ contract ProxyBase { /** * @dev Fallback function. * Implemented entirely in `_fallback`. */ function () payable external { _fallback(); } /** * @return The Address of the implementation. */ function _implementation() internal view returns (address); /** * @dev Delegates execution to an implementation contract. * This is a low level function that doesn't return to its internal call site. * It will return to the external caller whatever the implementation returns. * @param implementation Address to delegate. */ function _delegate(address implementation) internal { assembly { // Copy msg.data. We take full control of memory in this inline assembly // block because it will not return to Solidity code. We overwrite the // Solidity scratch pad at memory position 0. calldatacopy(0, 0, calldatasize) // Call the implementation. // out and outsize are 0 because we don't know the size yet. let result := delegatecall(gas, implementation, 0, calldatasize, 0, 0) // Copy the returned data. returndatacopy(0, 0, returndatasize) switch result // delegatecall returns 0 on error. case 0 { revert(0, returndatasize) } default { return(0, returndatasize) } } } /** * @dev Function that is run as the first thing in the fallback function. * Can be redefined in derived contracts to add functionality. * Redefinitions must call super._willFallback(). */ function _willFallback() internal { } /** * @dev fallback implementation. * Extracted to enable manual triggering. */ function _fallback() internal { _willFallback(); _delegate(_implementation()); } }
// from https://github.com/zeppelinos/zos/blob/1cea266a672a1efc31915420af5eb5185173837c/packages/lib/contracts/upgradeability/UpgradeabilityProxy.sol pragma solidity 0.5.2; import "./ProxyBase.sol"; import "../Libraries/AddressUtils.sol"; /** * @title UpgradeabilityProxy * @dev This contract implements a proxy that allows to change the * implementation address to which it will delegate. * Such a change is called an implementation upgrade. */ contract UpgradeabilityProxy is ProxyBase { /** * @dev Emitted when the implementation is upgraded. * @param implementation Address of the new implementation. */ event Upgraded(address indexed implementation); /** * @dev Storage slot with the address of the current implementation. * This is the keccak-256 hash of "org.zeppelinos.proxy.implementation", and is * validated in the constructor. */ bytes32 private constant IMPLEMENTATION_SLOT = 0x7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c3; /** * @dev Contract constructor. * @param _implementation Address of the initial implementation. * @param _data Data to send as msg.data to the implementation to initialize the proxied contract. * It should include the signature and the parameters of the function to be called, as described in * https://solidity.readthedocs.io/en/v0.4.24/abi-spec.html#function-selector-and-argument-encoding. * This parameter is optional, if no data is given the initialization call to proxied contract will be skipped. */ constructor(address _implementation, bytes memory _data) public payable { assert(IMPLEMENTATION_SLOT == keccak256("org.zeppelinos.proxy.implementation")); _setImplementation(_implementation); if(_data.length > 0) { (bool success, bytes memory _) = _implementation.delegatecall(_data); require(success, "could not call the contract"); } } /** * @dev Returns the current implementation. * @return Address of the current implementation */ function _implementation() internal view returns (address impl) { bytes32 slot = IMPLEMENTATION_SLOT; assembly { impl := sload(slot) } } /** * @dev Upgrades the proxy to a new implementation. * @param newImplementation Address of the new implementation. */ function _upgradeTo(address newImplementation) internal { _setImplementation(newImplementation); emit Upgraded(newImplementation); } /** * @dev Sets the implementation address of the proxy. * @param newImplementation Address of the new implementation. */ function _setImplementation(address newImplementation) private { require(AddressUtils.isContract(newImplementation), "Cannot set a proxy implementation to a non-contract address"); bytes32 slot = IMPLEMENTATION_SLOT; assembly { sstore(slot, newImplementation) } } }
{ "optimizer": { "enabled": true, "runs": 2000 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"constant":false,"inputs":[{"name":"newImplementation","type":"address"}],"name":"upgradeTo","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"newImplementation","type":"address"},{"name":"data","type":"bytes"}],"name":"upgradeToAndCall","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[],"name":"implementation","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"newAdmin","type":"address"}],"name":"changeAdmin","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"admin","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_owner","type":"address"},{"name":"_implementation","type":"address"},{"name":"_data","type":"bytes"}],"payable":true,"stateMutability":"payable","type":"constructor"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"anonymous":false,"inputs":[{"indexed":false,"name":"previousAdmin","type":"address"},{"indexed":false,"name":"newAdmin","type":"address"}],"name":"AdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"implementation","type":"address"}],"name":"Upgraded","type":"event"}]
Contract Creation Code
60806040526040516113573803806113578339810180604052606081101561002657600080fd5b815160208301516040840180519294919382019264010000000081111561004c57600080fd5b8201602081018481111561005f57600080fd5b815164010000000081118282018710171561007957600080fd5b5050929190505050818160405180806112f9602391396040519081900360230190206000805160206112d98339815191521490506100b357fe5b6100c5826401000000006102d4810204565b6000815111156101e8576000606083600160a060020a0316836040518082805190602001908083835b6020831061010d5780518252601f1990920191602091820191016100ee565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855af49150503d806000811461016d576040519150601f19603f3d011682016040523d82523d6000602084013e610172565b606091505b50915091508115156101e557604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f636f756c64206e6f742063616c6c2074686520636f6e74726163740000000000604482015290519081900360640190fd5b50505b5050604080517f6f72672e7a657070656c696e6f732e70726f78792e61646d696e0000000000008152905190819003601a0190206000805160206112b98339815191521461023257fe5b6000308461023e61036d565b600160a060020a03928316815291166020820152604080519182900301906000f080158015610271573d6000803e3d6000fd5b506040805160008152600160a060020a038316602082015281519293507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f929081900390910190a16102cb81640100000000610353810204565b5050505061037d565b6102ea8164010000000061071261036582021704565b1515610341576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603b81526020018061131c603b913960400191505060405180910390fd5b6000805160206112d983398151915255565b6000805160206112b983398151915255565b6000903b1190565b60405161074480610b7583390190565b6107e98061038c6000396000f3fe608060405260043610610077576000357c0100000000000000000000000000000000000000000000000000000000900480635c60da1b116100605780635c60da1b1461014e5780638f2839701461018c578063f851a440146101cc57610077565b80633659cfe6146100815780634f1ef286146100c1575b61007f6101e1565b005b34801561008d57600080fd5b5061007f600480360360208110156100a457600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166101fb565b61007f600480360360408110156100d757600080fd5b73ffffffffffffffffffffffffffffffffffffffff823516919081019060408101602082013564010000000081111561010f57600080fd5b82018360208201111561012157600080fd5b8035906020019184600183028401116401000000008311171561014357600080fd5b50909250905061024f565b34801561015a57600080fd5b5061016361038b565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b34801561019857600080fd5b5061007f600480360360208110156101af57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166103e2565b3480156101d857600080fd5b506101636104ec565b6101e9610531565b6101f96101f46105af565b6105d4565b565b6102036105f8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156102445761023f8161061d565b61024c565b61024c6101e1565b50565b6102576105f8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561037e576102938361061d565b600060608473ffffffffffffffffffffffffffffffffffffffff1684846040518083838082843760405192019450600093509091505080830381855af49150503d80600081146102ff576040519150601f19603f3d011682016040523d82523d6000602084013e610304565b606091505b509150915081151561037757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f6661696c656420746f2063616c6c206e6577496d706c656d656e746174696f6e604482015290519081900360640190fd5b5050610386565b6103866101e1565b505050565b60006103956105f8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156103d7576103d06105af565b90506103df565b6103df6101e1565b90565b6103ea6105f8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156102445773ffffffffffffffffffffffffffffffffffffffff8116151561048b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603681526020018061074d6036913960400191505060405180910390fd5b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6104b46105f8565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301528051918290030190a161023f8161066a565b60006104f66105f8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156103d7576103d06105f8565b6105396105f8565b73ffffffffffffffffffffffffffffffffffffffff163314156105a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603281526020018061071b6032913960400191505060405180910390fd5b6101f96101f9565b7f7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c35490565b3660008037600080366000845af43d6000803e8080156105f3573d6000f35b3d6000fd5b7f10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b5490565b6106268161068e565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b7f10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b55565b61069781610712565b15156106ee576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603b815260200180610783603b913960400191505060405180910390fd5b7f7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c355565b6000903b119056fe43616e6e6f742063616c6c2066616c6c6261636b2066756e6374696f6e2066726f6d207468652070726f78792061646d696e43616e6e6f74206368616e6765207468652061646d696e206f6620612070726f787920746f20746865207a65726f206164647265737343616e6e6f742073657420612070726f787920696d706c656d656e746174696f6e20746f2061206e6f6e2d636f6e74726163742061646472657373a165627a7a7230582030e42712490ef9adf597100ceb1a7211e469ec70a14341aa7ad9b319a05bf7a40029608060405234801561001057600080fd5b506040516040806107448339810180604052604081101561003057600080fd5b5080516020909101516000805460018054600160a060020a03958616600160a060020a0319918216179091559390921691831633179092161790556106ca8061007a6000396000f3fe60806040526004361061008d576000357c0100000000000000000000000000000000000000000000000000000000900480638da5cb5b1161006b5780638da5cb5b146101d55780638f283970146101ea578063f2fde38b1461022a578063f851a4401461026a5761008d565b806323f5c02d146100925780633659cfe6146100d05780634f1ef28614610112575b600080fd5b34801561009e57600080fd5b506100a761027f565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b3480156100dc57600080fd5b50610110600480360360208110156100f357600080fd5b503573ffffffffffffffffffffffffffffffffffffffff1661029b565b005b6101106004803603604081101561012857600080fd5b73ffffffffffffffffffffffffffffffffffffffff823516919081019060408101602082013564010000000081111561016057600080fd5b82018360208201111561017257600080fd5b8035906020019184600183028401116401000000008311171561019457600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955061034e945050505050565b3480156101e157600080fd5b506100a761046e565b3480156101f657600080fd5b506101106004803603602081101561020d57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff1661048a565b34801561023657600080fd5b506101106004803603602081101561024d57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610522565b34801561027657600080fd5b506100a7610552565b60015473ffffffffffffffffffffffffffffffffffffffff1690565b60005473ffffffffffffffffffffffffffffffffffffffff1633146102bf57600080fd5b600154604080517f3659cfe600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff848116600483015291519190921691633659cfe691602480830192600092919082900301818387803b15801561033357600080fd5b505af1158015610347573d6000803e3d6000fd5b5050505050565b60005473ffffffffffffffffffffffffffffffffffffffff16331461037257600080fd5b600154604080517f4f1ef28600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85811660048301908152602483019384528551604484015285519190941693634f1ef28693349388938893929160640190602085019080838360005b838110156104055781810151838201526020016103ed565b50505050905090810190601f1680156104325780820380516001836020036101000a031916815260200191505b5093505050506000604051808303818588803b15801561045157600080fd5b505af1158015610465573d6000803e3d6000fd5b50505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff1681565b60005473ffffffffffffffffffffffffffffffffffffffff1633146104ae57600080fd5b600154604080517f8f28397000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff848116600483015291519190921691638f28397091602480830192600092919082900301818387803b15801561033357600080fd5b60005473ffffffffffffffffffffffffffffffffffffffff16331461054657600080fd5b61054f816105ef565b50565b600154604080517ff851a440000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff169163f851a44091600480830192602092919082900301818787803b1580156105be57600080fd5b505af11580156105d2573d6000803e3d6000fd5b505050506040513d60208110156105e857600080fd5b5051905090565b73ffffffffffffffffffffffffffffffffffffffff8116151561061157600080fd5b6000805460405173ffffffffffffffffffffffffffffffffffffffff808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905556fea165627a7a7230582010b864f6572a6c25c23160ae2546b64b97a93ebe8ae9183e344a7f5be10ad9f5002910d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c36f72672e7a657070656c696e6f732e70726f78792e696d706c656d656e746174696f6e43616e6e6f742073657420612070726f787920696d706c656d656e746174696f6e20746f2061206e6f6e2d636f6e74726163742061646472657373000000000000000000000000eaa0993e1d21c2103e4f172a20d29371fbaf6d06000000000000000000000000db3d91dcb27547d82a09556d1028beedb04a590200000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000044fdcc8d8c000000000000000000000000741db825bcdbbbb3f91cb257a8d3dd356a7f8e9f000000000000000000000000eaa0993e1d21c2103e4f172a20d29371fbaf6d0600000000000000000000000000000000000000000000000000000000
Deployed Bytecode
0x608060405260043610610077576000357c0100000000000000000000000000000000000000000000000000000000900480635c60da1b116100605780635c60da1b1461014e5780638f2839701461018c578063f851a440146101cc57610077565b80633659cfe6146100815780634f1ef286146100c1575b61007f6101e1565b005b34801561008d57600080fd5b5061007f600480360360208110156100a457600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166101fb565b61007f600480360360408110156100d757600080fd5b73ffffffffffffffffffffffffffffffffffffffff823516919081019060408101602082013564010000000081111561010f57600080fd5b82018360208201111561012157600080fd5b8035906020019184600183028401116401000000008311171561014357600080fd5b50909250905061024f565b34801561015a57600080fd5b5061016361038b565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b34801561019857600080fd5b5061007f600480360360208110156101af57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166103e2565b3480156101d857600080fd5b506101636104ec565b6101e9610531565b6101f96101f46105af565b6105d4565b565b6102036105f8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156102445761023f8161061d565b61024c565b61024c6101e1565b50565b6102576105f8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561037e576102938361061d565b600060608473ffffffffffffffffffffffffffffffffffffffff1684846040518083838082843760405192019450600093509091505080830381855af49150503d80600081146102ff576040519150601f19603f3d011682016040523d82523d6000602084013e610304565b606091505b509150915081151561037757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f6661696c656420746f2063616c6c206e6577496d706c656d656e746174696f6e604482015290519081900360640190fd5b5050610386565b6103866101e1565b505050565b60006103956105f8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156103d7576103d06105af565b90506103df565b6103df6101e1565b90565b6103ea6105f8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156102445773ffffffffffffffffffffffffffffffffffffffff8116151561048b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603681526020018061074d6036913960400191505060405180910390fd5b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6104b46105f8565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301528051918290030190a161023f8161066a565b60006104f66105f8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156103d7576103d06105f8565b6105396105f8565b73ffffffffffffffffffffffffffffffffffffffff163314156105a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603281526020018061071b6032913960400191505060405180910390fd5b6101f96101f9565b7f7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c35490565b3660008037600080366000845af43d6000803e8080156105f3573d6000f35b3d6000fd5b7f10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b5490565b6106268161068e565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b7f10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b55565b61069781610712565b15156106ee576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603b815260200180610783603b913960400191505060405180910390fd5b7f7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c355565b6000903b119056fe43616e6e6f742063616c6c2066616c6c6261636b2066756e6374696f6e2066726f6d207468652070726f78792061646d696e43616e6e6f74206368616e6765207468652061646d696e206f6620612070726f787920746f20746865207a65726f206164647265737343616e6e6f742073657420612070726f787920696d706c656d656e746174696f6e20746f2061206e6f6e2d636f6e74726163742061646472657373a165627a7a7230582030e42712490ef9adf597100ceb1a7211e469ec70a14341aa7ad9b319a05bf7a40029
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000eaa0993e1d21c2103e4f172a20d29371fbaf6d06000000000000000000000000db3d91dcb27547d82a09556d1028beedb04a590200000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000044fdcc8d8c000000000000000000000000741db825bcdbbbb3f91cb257a8d3dd356a7f8e9f000000000000000000000000eaa0993e1d21c2103e4f172a20d29371fbaf6d0600000000000000000000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : _owner (address): 0xEAA0993E1d21c2103e4f172a20D29371FbAF6D06
Arg [1] : _implementation (address): 0xdb3D91Dcb27547d82A09556D1028beEdB04A5902
Arg [2] : _data (bytes): 0xfdcc8d8c000000000000000000000000741db825bcdbbbb3f91cb257a8d3dd356a7f8e9f000000000000000000000000eaa0993e1d21c2103e4f172a20d29371fbaf6d06
-----Encoded View---------------
7 Constructor Arguments found :
Arg [0] : 000000000000000000000000eaa0993e1d21c2103e4f172a20d29371fbaf6d06
Arg [1] : 000000000000000000000000db3d91dcb27547d82a09556d1028beedb04a5902
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000060
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000044
Arg [4] : fdcc8d8c000000000000000000000000741db825bcdbbbb3f91cb257a8d3dd35
Arg [5] : 6a7f8e9f000000000000000000000000eaa0993e1d21c2103e4f172a20d29371
Arg [6] : fbaf6d0600000000000000000000000000000000000000000000000000000000
Deployed Bytecode Sourcemap
602:4336:65:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;596:11:67;:9;:11::i;:::-;602:4336:65;3382:103;;8:9:-1;5:2;;;30:1;27;20:12;5:2;3382:103:65;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;3382:103:65;;;;:::i;4002:272::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;4002:272:65;;;;;;;;;;;;;;;;21:11:-1;5:28;;2:2;;;46:1;43;36:12;2:2;4002:272:65;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;4002:272:65;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;39:11;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;-1:-1;4002:272:65;;-1:-1:-1;4002:272:65;-1:-1:-1;4002:272:65;:::i;2702:96::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;2702:96:65;;;:::i;:::-;;;;;;;;;;;;;;;;;;;2974:224;;8:9:-1;5:2;;;30:1;27;20:12;5:2;2974:224:65;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;2974:224:65;;;;:::i;2560:78::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;2560:78:65;;;:::i;2095:90:67:-;2131:15;:13;:15::i;:::-;2152:28;2162:17;:15;:17::i;:::-;2152:9;:28::i;:::-;2095:90::o;3382:103:65:-;1419:8;:6;:8::i;:::-;1405:22;;:10;:22;;;1401:76;;;3451:29;3462:17;3451:10;:29::i;:::-;1401:76;;;1459:11;:9;:11::i;:::-;3382:103;:::o;4002:272::-;1419:8;:6;:8::i;:::-;1405:22;;:10;:22;;;1401:76;;;4107:29;4118:17;4107:10;:29::i;:::-;4143:12;4157:14;4175:17;:30;;4206:4;;4175:36;;;;;30:3:-1;22:6;14;1:33;4175:36:65;;45:16:-1;;;-1:-1;4175:36:65;;-1:-1:-1;4175:36:65;;-1:-1:-1;;4175:36:65;;;;;;;;;;;14:1:-1;21;16:31;;;;75:4;69:11;64:16;;144:4;140:9;133:4;115:16;111:27;107:43;104:1;100:51;94:4;87:65;169:16;166:1;159:27;225:16;222:1;215:4;212:1;208:12;193:49;7:242;;16:31;36:4;31:9;;7:242;;4142:69:65;;;;4225:7;4217:52;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1437:1;;1401:76;;;1459:11;:9;:11::i;:::-;4002:272;;;:::o;2702:96::-;2754:7;1419:8;:6;:8::i;:::-;1405:22;;:10;:22;;;1401:76;;;2776:17;:15;:17::i;:::-;2769:24;;1401:76;;;1459:11;:9;:11::i;:::-;2702:96;:::o;2974:224::-;1419:8;:6;:8::i;:::-;1405:22;;:10;:22;;;1401:76;;;3044:22;;;;;3036:89;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3136:32;3149:8;:6;:8::i;:::-;3136:32;;;;;;;;;;;;;;;;;;;;;;;;;3174:19;3184:8;3174:9;:19::i;2560:78::-;2603:7;1419:8;:6;:8::i;:::-;1405:22;;:10;:22;;;1401:76;;;2625:8;:6;:8::i;4779:157::-;4841:8;:6;:8::i;:::-;4827:22;;:10;:22;;4819:85;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4910:21;:19;:21::i;2008:156:68:-;926:66;2143:11;;2127:33::o;1021:731:67:-;1323:12;1320:1;1317;1304:32;1513:1;1510;1496:12;1493:1;1477:14;1472:3;1459:56;1577:14;1574:1;1571;1556:36;1607:6;1662:36;;;;1725:14;1722:1;1715:25;1662:36;1681:14;1678:1;1671:25;4319:136:65;1120:66;4434:11;;4419:32::o;2299:142:68:-;2361:37;2380:17;2361:18;:37::i;:::-;2409:27;;;;;;;;;;;2299:142;:::o;4571:133:65:-;1120:66;4672:22;4664:36::o;2578:289:68:-;2655:42;2679:17;2655:23;:42::i;:::-;2647:114;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;926:66;2826:31;2818:45::o;435:576:24:-;492:4;967:17;;998:8;;435:576::o
Swarm Source
bzzr://10b864f6572a6c25c23160ae2546b64b97a93ebe8ae9183e344a7f5be10ad9f5
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.