文件 1 的 6: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 的 6:GenArtAccess.sol
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/access/Ownable.sol";
abstract contract GenArtAccess is Ownable {
mapping(address => bool) public admins;
address public genartAdmin;
constructor() Ownable() {
genartAdmin = _msgSender();
}
modifier onlyAdmin() {
address sender = _msgSender();
require(
owner() == sender || admins[sender],
"GenArtAccess: caller is not the owner nor admin"
);
_;
}
modifier onlyGenArtAdmin() {
address sender = _msgSender();
require(
genartAdmin == sender,
"GenArtAccess: caller is not genart admin"
);
_;
}
function setGenArtAdmin(address admin) public onlyGenArtAdmin {
genartAdmin = admin;
}
function setAdminAccess(address admin, bool access) public onlyGenArtAdmin {
admins[admin] = access;
}
}
文件 3 的 6:GenArtPaymentSplitterV2.sol
pragma solidity ^0.8.0;
import "./GenArtAccess.sol";
import "./IGenArtPaymentSplitterV2.sol";
import "@openzeppelin/contracts/interfaces/IERC20.sol";
contract GenArtPaymentSplitterV2 is GenArtAccess, IGenArtPaymentSplitterV2 {
struct Payment {
address[] payees;
uint256[] shares;
}
event IncomingPayment(
address collection,
uint256 paymentType,
address payee,
uint256 amount
);
mapping(address => uint256) public _balances;
mapping(address => uint256) public _wethBalances;
mapping(address => Payment) private _payments;
mapping(address => Payment) private _paymentsRoyalties;
address public _wethAddress;
bool public _destoryed = false;
constructor(address wethAddress_) GenArtAccess() {
_wethAddress = wethAddress_;
}
modifier onlyCollectionContractOrAdmin(bool isCollection) {
address sender = _msgSender();
require(
isCollection || (owner() == sender) || admins[sender],
"GenArtAccess: caller is not the owner nor admin"
);
_;
}
function addCollectionPayment(
address collection,
address[] memory payees,
uint256[] memory shares
) public override onlyAdmin {
require(!_destoryed, "GenArtPaymentSplitterV2: contract is destroyed");
require(
shares.length > 0 && shares.length == payees.length,
"GenArtPaymentSplitterV2: invalid arguments"
);
_payments[collection] = Payment(payees, shares);
}
function addCollectionPaymentRoyalty(
address collection,
address[] memory payees,
uint256[] memory shares
) public override onlyAdmin {
require(!_destoryed, "GenArtPaymentSplitterV2: contract is destroyed");
require(
shares.length > 0 && shares.length == payees.length,
"GenArtPaymentSplitterV2: invalid arguments"
);
_paymentsRoyalties[collection] = Payment(payees, shares);
}
function sanityCheck(address collection, uint8 paymentType) internal view {
require(!_destoryed, "GenArtPaymentSplitterV2: contract is destroyed");
Payment memory payment = paymentType == 0
? _payments[collection]
: _paymentsRoyalties[collection];
require(
payment.payees.length > 0,
"GenArtPaymentSplitterV2: payment not found for collection"
);
}
function splitPayment(address collection)
public
payable
override
onlyCollectionContractOrAdmin(_payments[msg.sender].payees.length > 0)
{
uint256 totalShares = getTotalSharesOfCollection(collection, 0);
for (uint8 i; i < _payments[collection].payees.length; i++) {
address payee = _payments[collection].payees[i];
uint256 ethAmount = (msg.value * _payments[collection].shares[i]) /
totalShares;
unchecked {
_balances[payee] += ethAmount;
}
emit IncomingPayment(collection, 0, payee, ethAmount);
}
}
function splitPaymentRoyalty(address collection)
public
payable
override
onlyCollectionContractOrAdmin(
_paymentsRoyalties[msg.sender].payees.length > 0
)
{
uint256 totalShares = getTotalSharesOfCollection(collection, 1);
for (uint8 i; i < _paymentsRoyalties[collection].payees.length; i++) {
address payee = _paymentsRoyalties[collection].payees[i];
uint256 ethAmount = (msg.value *
_paymentsRoyalties[collection].shares[i]) / totalShares;
unchecked {
_balances[payee] += ethAmount;
}
emit IncomingPayment(collection, 1, payee, ethAmount);
}
}
function splitPaymentRoyaltyWETH(address collection, uint256 wethAmount)
public
payable
override
onlyCollectionContractOrAdmin(
_paymentsRoyalties[msg.sender].payees.length > 0
)
{
uint256 totalShares = getTotalSharesOfCollection(collection, 1);
for (uint8 i; i < _paymentsRoyalties[collection].payees.length; i++) {
address payee = _paymentsRoyalties[collection].payees[i];
uint256 wethAmountShare = (wethAmount *
_paymentsRoyalties[collection].shares[i]) / totalShares;
unchecked {
_wethBalances[payee] += wethAmountShare;
}
emit IncomingPayment(collection, 1, payee, wethAmountShare);
}
}
function getTotalSharesOfCollection(address collection, uint8 paymentType)
public
view
override
returns (uint256)
{
sanityCheck(collection, paymentType);
Payment memory payment = paymentType == 0
? _payments[collection]
: _paymentsRoyalties[collection];
uint256 totalShares;
for (uint8 i; i < payment.shares.length; i++) {
unchecked {
totalShares += payment.shares[i];
}
}
return totalShares;
}
function release(address account) public override {
require(!_destoryed, "GenArtPaymentSplitterV2: contract is destroyed");
uint256 amount = _balances[account];
uint256 wethAmount = _wethBalances[account];
require(
amount > 0 || wethAmount > 0,
"GenArtPaymentSplitterV2: no funds to release"
);
if (amount > 0) {
_balances[account] = 0;
payable(account).transfer(amount);
}
if (wethAmount > 0) {
_wethBalances[account] = 0;
IERC20(_wethAddress).transfer(account, wethAmount);
}
}
function updatePayee(
address collection,
uint8 paymentType,
uint256 payeeIndex,
address newPayee
) public override {
sanityCheck(collection, paymentType);
Payment storage payment = paymentType == 0
? _payments[collection]
: _paymentsRoyalties[collection];
address oldPayee = payment.payees[payeeIndex];
require(
oldPayee == _msgSender(),
"GenArtPaymentSplitterV2: sender is not current payee"
);
payment.payees[payeeIndex] = newPayee;
}
function getBalanceForAccount(address account)
public
view
returns (uint256)
{
require(!_destoryed, "GenArtPaymentSplitterV2: contract is destroyed");
return _balances[account];
}
function emergencyWithdraw() public onlyOwner {
_destoryed = true;
payable(owner()).transfer(address(this).balance);
}
receive() external payable {
payable(owner()).transfer(msg.value);
}
}
文件 4 的 6:IERC20.sol
pragma solidity ^0.8.0;
import "../token/ERC20/IERC20.sol";
文件 5 的 6:IGenArtPaymentSplitterV2.sol
pragma solidity ^0.8.0;
interface IGenArtPaymentSplitterV2 {
function addCollectionPayment(
address collection,
address[] memory payees,
uint256[] memory shares
) external;
function addCollectionPaymentRoyalty(
address collection,
address[] memory payees,
uint256[] memory shares
) external;
function splitPayment(address collection) external payable;
function splitPaymentRoyalty(address collection) external payable;
function splitPaymentRoyaltyWETH(address collection, uint256 wethAmount)
external
payable;
function getTotalSharesOfCollection(address collection, uint8 _payment)
external
view
returns (uint256);
function release(address account) external;
function updatePayee(
address collection,
uint8 paymentType,
uint256 payeeIndex,
address newPayee
) external;
}
文件 6 的 6: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());
}
function owner() public view virtual returns (address) {
return _owner;
}
modifier onlyOwner() {
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);
}
}
{
"compilationTarget": {
"contracts/GenArtPaymentSplitterV2.sol": "GenArtPaymentSplitterV2"
},
"evmVersion": "istanbul",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": false,
"runs": 200
},
"remappings": []
}
[{"inputs":[{"internalType":"address","name":"wethAddress_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"collection","type":"address"},{"indexed":false,"internalType":"uint256","name":"paymentType","type":"uint256"},{"indexed":false,"internalType":"address","name":"payee","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"IncomingPayment","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"_balances","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_destoryed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_wethAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"_wethBalances","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"collection","type":"address"},{"internalType":"address[]","name":"payees","type":"address[]"},{"internalType":"uint256[]","name":"shares","type":"uint256[]"}],"name":"addCollectionPayment","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"collection","type":"address"},{"internalType":"address[]","name":"payees","type":"address[]"},{"internalType":"uint256[]","name":"shares","type":"uint256[]"}],"name":"addCollectionPaymentRoyalty","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"admins","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"emergencyWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"genartAdmin","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getBalanceForAccount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"collection","type":"address"},{"internalType":"uint8","name":"paymentType","type":"uint8"}],"name":"getTotalSharesOfCollection","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"release","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"admin","type":"address"},{"internalType":"bool","name":"access","type":"bool"}],"name":"setAdminAccess","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"admin","type":"address"}],"name":"setGenArtAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"collection","type":"address"}],"name":"splitPayment","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"collection","type":"address"}],"name":"splitPaymentRoyalty","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"collection","type":"address"},{"internalType":"uint256","name":"wethAmount","type":"uint256"}],"name":"splitPaymentRoyaltyWETH","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"collection","type":"address"},{"internalType":"uint8","name":"paymentType","type":"uint8"},{"internalType":"uint256","name":"payeeIndex","type":"uint256"},{"internalType":"address","name":"newPayee","type":"address"}],"name":"updatePayee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]