编译器
0.8.19+commit.7dd6d404
文件 1 的 9:Context.sol
pragma solidity ^0.8.0;
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
文件 2 的 9:IAdminACLV0.sol
pragma solidity ^0.8.0;
interface IAdminACLV0 {
event SuperAdminTransferred(
address indexed previousSuperAdmin,
address indexed newSuperAdmin,
address[] genArt721CoreAddressesToUpdate
);
function AdminACLType() external view returns (string memory);
function superAdmin() external view returns (address);
function transferOwnershipOn(
address _contract,
address _newAdminACL
) external;
function renounceOwnershipOn(address _contract) external;
function allowed(
address _sender,
address _contract,
bytes4 _selector
) external returns (bool);
}
文件 3 的 9:IERC165.sol
pragma solidity ^0.8.0;
interface IERC165 {
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
文件 4 的 9:IERC721.sol
pragma solidity ^0.8.0;
import "../../utils/introspection/IERC165.sol";
interface IERC721 is IERC165 {
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);
function balanceOf(address owner) external view returns (uint256 balance);
function ownerOf(uint256 tokenId) external view returns (address owner);
function safeTransferFrom(
address from,
address to,
uint256 tokenId,
bytes calldata data
) external;
function safeTransferFrom(
address from,
address to,
uint256 tokenId
) external;
function transferFrom(
address from,
address to,
uint256 tokenId
) external;
function approve(address to, uint256 tokenId) external;
function setApprovalForAll(address operator, bool _approved) external;
function getApproved(uint256 tokenId) external view returns (address operator);
function isApprovedForAll(address owner, address operator) external view returns (bool);
}
文件 5 的 9:IGenArt721CoreContractV3_Base.sol
pragma solidity ^0.8.0;
import "./IAdminACLV0.sol";
import "./IManifold.sol";
interface IGenArt721CoreContractV3_Base is IManifold {
event Mint(address indexed _to, uint256 indexed _tokenId);
event MinterUpdated(address indexed _currentMinter);
event PlatformUpdated(bytes32 indexed _field);
event ProjectUpdated(uint256 indexed _projectId, bytes32 indexed _update);
event ProposedArtistAddressesAndSplits(
uint256 indexed _projectId,
address _artistAddress,
address _additionalPayeePrimarySales,
uint256 _additionalPayeePrimarySalesPercentage,
address _additionalPayeeSecondarySales,
uint256 _additionalPayeeSecondarySalesPercentage
);
event AcceptedArtistAddressesAndSplits(uint256 indexed _projectId);
function coreVersion() external view returns (string memory);
function coreType() external view returns (string memory);
function owner() external view returns (address);
function adminACLContract() external returns (IAdminACLV0);
function admin() external view returns (address);
function adminACLAllowed(
address _sender,
address _contract,
bytes4 _selector
) external returns (bool);
function startingProjectId() external view returns (uint256);
function nextProjectId() external view returns (uint256);
function tokenIdToProjectId(
uint256 tokenId
) external view returns (uint256 projectId);
function isMintWhitelisted(address minter) external view returns (bool);
function projectIdToArtistAddress(
uint256 _projectId
) external view returns (address payable);
function projectIdToAdditionalPayeePrimarySales(
uint256 _projectId
) external view returns (address payable);
function projectIdToAdditionalPayeePrimarySalesPercentage(
uint256 _projectId
) external view returns (uint256);
function projectIdToSecondaryMarketRoyaltyPercentage(
uint256 _projectId
) external view returns (uint256);
function projectURIInfo(
uint256 _projectId
) external view returns (string memory projectBaseURI);
function projectStateData(
uint256 _projectId
)
external
view
returns (
uint256 invocations,
uint256 maxInvocations,
bool active,
bool paused,
uint256 completedTimestamp,
bool locked
);
function projectDetails(
uint256 _projectId
)
external
view
returns (
string memory projectName,
string memory artist,
string memory description,
string memory website,
string memory license
);
function projectScriptDetails(
uint256 _projectId
)
external
view
returns (
string memory scriptTypeAndVersion,
string memory aspectRatio,
uint256 scriptCount
);
function projectScriptByIndex(
uint256 _projectId,
uint256 _index
) external view returns (string memory);
function tokenIdToHash(uint256 _tokenId) external view returns (bytes32);
function setTokenHash_8PT(uint256 _tokenId, bytes32 _hash) external;
function mint_Ecf(
address _to,
uint256 _projectId,
address _by
) external returns (uint256 tokenId);
}
文件 6 的 9:IGenArt721CoreContractV3_Engine.sol
pragma solidity ^0.8.0;
import "./IAdminACLV0.sol";
import "./IGenArt721CoreContractV3_Base.sol";
interface IGenArt721CoreContractV3_Engine is IGenArt721CoreContractV3_Base {
function getPrimaryRevenueSplits(
uint256 _projectId,
uint256 _price
)
external
view
returns (
uint256 renderProviderRevenue_,
address payable renderProviderAddress_,
uint256 platformProviderRevenue_,
address payable platformProviderAddress_,
uint256 artistRevenue_,
address payable artistAddress_,
uint256 additionalPayeePrimaryRevenue_,
address payable additionalPayeePrimaryAddress_
);
function renderProviderPrimarySalesAddress()
external
view
returns (address payable);
function platformProviderPrimarySalesAddress()
external
view
returns (address payable);
function renderProviderPrimarySalesPercentage()
external
view
returns (uint256);
function platformProviderPrimarySalesPercentage()
external
view
returns (uint256);
function renderProviderSecondarySalesAddress()
external
view
returns (address payable);
function platformProviderSecondarySalesAddress()
external
view
returns (address payable);
function renderProviderSecondarySalesBPS() external view returns (uint256);
function platformProviderSecondarySalesBPS()
external
view
returns (uint256);
}
文件 7 的 9:IManifold.sol
pragma solidity ^0.8.0;
interface IManifold {
function getRoyalties(
uint256 tokenId
) external view returns (address payable[] memory, uint256[] memory);
}
文件 8 的 9:Ownable.sol
pragma solidity ^0.8.0;
import "../utils/Context.sol";
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor() {
_transferOwnership(_msgSender());
}
modifier onlyOwner() {
_checkOwner();
_;
}
function owner() public view virtual returns (address) {
return _owner;
}
function _checkOwner() internal view virtual {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
}
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
文件 9 的 9:ScribbleTogetherPaletteSelections.sol
pragma solidity ^0.8.9;
import "@openzeppelin-4.7/contracts/access/Ownable.sol";
import "@openzeppelin-4.7/contracts/token/ERC721/IERC721.sol";
import '@artblocks/contracts/contracts/interfaces/v0.8.x/IGenArt721CoreContractV3_Engine.sol';
contract ScribbleTogetherPaletteSelections is Ownable {
string public constant CONFIRMATION_FOR_STOPPING_PALETTE_SELECTION = 'yes conclude palette selection';
string public constant CONFIRMATION_FOR_DISTRIBUTING_PAYOUTS = 'yes distribute payouts';
IGenArt721CoreContractV3_Engine public plottablesContract;
uint256 public projectId;
address payable[] public paletteCreators;
bool public paletteSelectionConcluded;
bool public payoutsDistributed;
uint256 private numberOfTokensWithChangedPalettesTotal;
uint256[] private numberOfTokensWithChangedPalettesPerPalette;
mapping(uint => uint) private tokenToOverriddenPalette;
struct PaletteSelection {
uint256 tokenId;
uint256 defaultPalette;
uint256 selectedPalette;
}
constructor(IGenArt721CoreContractV3_Engine _plottablesContract, uint256 _projectId, address payable[] memory _paletteCreators)
Ownable()
{
plottablesContract = _plottablesContract;
projectId = _projectId;
paletteCreators = _paletteCreators;
paletteSelectionConcluded = false;
payoutsDistributed = false;
numberOfTokensWithChangedPalettesPerPalette = new uint256[](paletteCreators.length);
require(plottablesContract.projectIdToArtistAddress(projectId) == msg.sender, 'Deployer must be project artist');
require(numInvocations() == 0, 'Project cannot have any mints yet');
require(paletteCreators.length > 0, 'Need at least one palette');
}
receive() external payable requirePayoutsNotDistributed {}
function plottablesTokenIdFor(uint256 _tokenId) private view returns (uint256) {
return projectId * 1e6 + _tokenId;
}
function numPalettes() public view returns (uint256) {
return paletteCreators.length;
}
function numInvocations() public view returns (uint256) {
(uint256 invocations, , , , , ) = plottablesContract.projectStateData(projectId);
return invocations;
}
function hashForTokenId(uint256 _tokenId) public view returns (bytes32) {
require(_tokenId < numInvocations(), 'Invalid token');
return plottablesContract.tokenIdToHash(plottablesTokenIdFor(_tokenId));
}
function defaultPaletteForTokenId(uint256 _tokenId) public view returns (uint256) {
return calculateDefaultPaletteForHash(hashForTokenId(_tokenId), paletteCreators.length);
}
function selectedPaletteForTokenId(uint256 _tokenId) public view returns (uint256) {
return paletteSelectionForTokenId(_tokenId).selectedPalette;
}
function paletteSelectionForTokenId(uint256 _tokenId) private view returns (PaletteSelection memory selection) {
selection.tokenId = _tokenId;
selection.defaultPalette = defaultPaletteForTokenId(_tokenId);
uint256 paletteSelection = tokenToOverriddenPalette[_tokenId];
if(paletteSelection == 0) {
selection.selectedPalette = selection.defaultPalette;
}
else {
selection.selectedPalette = paletteSelection-1;
}
}
function paletteSelectionsInRange(uint256 _firstTokenId, uint256 _numTokens) public view returns (PaletteSelection[] memory selections) {
selections = new PaletteSelection[](_numTokens);
for(uint i = 0; i < _numTokens; i++) {
selections[i] = paletteSelectionForTokenId(i + _firstTokenId);
}
}
function allPaletteSelections() public view returns (PaletteSelection[] memory selections) {
return paletteSelectionsInRange(0, numInvocations());
}
function numTokensOverridingByPalette() public view returns (uint256[] memory result) {
return numberOfTokensWithChangedPalettesPerPalette;
}
function selectPaletteForTokenId(uint256 _tokenId, uint256 _newPalette) public {
require(IERC721(address(plottablesContract)).ownerOf(plottablesTokenIdFor(_tokenId)) == msg.sender, 'Not owner of token');
uint256 defaultPalette = defaultPaletteForTokenId(_tokenId);
uint256 currentPalette = selectedPaletteForTokenId(_tokenId);
if(_newPalette != currentPalette) {
if(currentPalette != defaultPalette) {
numberOfTokensWithChangedPalettesPerPalette[currentPalette]--;
numberOfTokensWithChangedPalettesTotal--;
}
if(_newPalette != defaultPalette) {
tokenToOverriddenPalette[_tokenId] = _newPalette+1;
numberOfTokensWithChangedPalettesPerPalette[_newPalette]++;
numberOfTokensWithChangedPalettesTotal++;
}
else {
tokenToOverriddenPalette[_tokenId] = 0;
}
}
}
function numDefaultInvocations() public view returns (uint256) {
return numInvocations() - numberOfTokensWithChangedPalettesTotal;
}
function numChangedInvocations() public view returns (uint256) {
return numberOfTokensWithChangedPalettesTotal;
}
function calculatePayouts() public view returns (uint256[] memory payouts) {
uint256 tokensCount = numInvocations();
require(tokensCount > 0, 'No tokens');
uint256 palettesCount = paletteCreators.length;
uint256 totalDistribution = address(this).balance;
uint256 cumulativeDistribution = 0;
uint256 proRataDistributionPerPalette = totalDistribution * numDefaultInvocations() / tokensCount / palettesCount;
payouts = new uint256[](palettesCount);
for(uint256 thisPalette = 0; thisPalette < palettesCount - 1; thisPalette++) {
uint256 thisDistributionForTokensSelectingThisPalette = totalDistribution * numberOfTokensWithChangedPalettesPerPalette[thisPalette] / tokensCount;
uint256 thisDistribution = proRataDistributionPerPalette + thisDistributionForTokensSelectingThisPalette;
payouts[thisPalette] = thisDistribution;
cumulativeDistribution += thisDistribution;
}
payouts[payouts.length-1] = totalDistribution - cumulativeDistribution;
}
function concludePaletteSelection(string memory _confirmation) public
onlyOwner
requireValidConfirmation(CONFIRMATION_FOR_STOPPING_PALETTE_SELECTION, _confirmation) {
(,,,bool paused,,) = plottablesContract.projectStateData(projectId);
require(paused == true, 'Project is not paused');
paletteSelectionConcluded = true;
}
function distributePayouts(string memory _confirmation) public
onlyOwner
requireValidConfirmation(CONFIRMATION_FOR_DISTRIBUTING_PAYOUTS, _confirmation)
requirePayoutsNotDistributed {
require(paletteSelectionConcluded, 'Palette selection not concluded');
uint256[] memory payouts = calculatePayouts();
for(uint256 i=0; i<payouts.length; i++) {
(bool sent, ) = payable(paletteCreators[i]).call{value: payouts[i]}("");
require(sent, "Failed to send");
}
payoutsDistributed = true;
}
function calculateDefaultPaletteForHash(bytes32 _hash, uint256 _numPalettes) public pure returns (uint256) {
uint256 intOfHash = uint256(uint32(uint256(_hash)));
return intOfHash % _numPalettes;
}
modifier requireValidConfirmation(string memory expectedConfirmation, string memory actualConfirmation) {
require(
keccak256(abi.encodePacked(expectedConfirmation)) == keccak256(abi.encodePacked(actualConfirmation)),
"Invalid confirmation string provided"
);
_;
}
modifier requirePayoutsNotDistributed() {
require(!payoutsDistributed, 'Payouts already distributed');
_;
}
}
{
"compilationTarget": {
"contracts/ScribbleTogetherPaletteSelections.sol": "ScribbleTogetherPaletteSelections"
},
"evmVersion": "paris",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": false,
"runs": 200
},
"remappings": []
}
[{"inputs":[{"internalType":"contract IGenArt721CoreContractV3_Engine","name":"_plottablesContract","type":"address"},{"internalType":"uint256","name":"_projectId","type":"uint256"},{"internalType":"address payable[]","name":"_paletteCreators","type":"address[]"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[],"name":"CONFIRMATION_FOR_DISTRIBUTING_PAYOUTS","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"CONFIRMATION_FOR_STOPPING_PALETTE_SELECTION","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"allPaletteSelections","outputs":[{"components":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"defaultPalette","type":"uint256"},{"internalType":"uint256","name":"selectedPalette","type":"uint256"}],"internalType":"struct ScribbleTogetherPaletteSelections.PaletteSelection[]","name":"selections","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_hash","type":"bytes32"},{"internalType":"uint256","name":"_numPalettes","type":"uint256"}],"name":"calculateDefaultPaletteForHash","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"calculatePayouts","outputs":[{"internalType":"uint256[]","name":"payouts","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"_confirmation","type":"string"}],"name":"concludePaletteSelection","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"defaultPaletteForTokenId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"_confirmation","type":"string"}],"name":"distributePayouts","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"hashForTokenId","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"numChangedInvocations","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"numDefaultInvocations","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"numInvocations","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"numPalettes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"numTokensOverridingByPalette","outputs":[{"internalType":"uint256[]","name":"result","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"paletteCreators","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"paletteSelectionConcluded","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_firstTokenId","type":"uint256"},{"internalType":"uint256","name":"_numTokens","type":"uint256"}],"name":"paletteSelectionsInRange","outputs":[{"components":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"defaultPalette","type":"uint256"},{"internalType":"uint256","name":"selectedPalette","type":"uint256"}],"internalType":"struct ScribbleTogetherPaletteSelections.PaletteSelection[]","name":"selections","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"payoutsDistributed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"plottablesContract","outputs":[{"internalType":"contract IGenArt721CoreContractV3_Engine","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"projectId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"_newPalette","type":"uint256"}],"name":"selectPaletteForTokenId","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"selectedPaletteForTokenId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]