quartz/wallet/node_modules/@3rdweb/contracts/contracts/Splits.sol
2022-03-04 20:05:23 +08:00

89 lines
3.2 KiB
Solidity

// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.0;
// Base
import "./openzeppelin-presets/finance/PaymentSplitter.sol";
// Meta transactions
import "@openzeppelin/contracts/metatx/ERC2771Context.sol";
import "@openzeppelin/contracts/utils/Multicall.sol";
import "@openzeppelin/contracts/access/AccessControlEnumerable.sol";
import { Registry } from "./Registry.sol";
import { ProtocolControl } from "./ProtocolControl.sol";
/**
* Splits automatically adds protocol provider (the registry) of protocol control to the payees
* and shares that represent the fees.
*/
contract Splits is PaymentSplitter, AccessControlEnumerable, ERC2771Context, Multicall {
/// @dev The protocol control center.
ProtocolControl private controlCenter;
/// @dev Contract level metadata.
string public contractURI;
modifier onlyModuleAdmin() {
require(hasRole(DEFAULT_ADMIN_ROLE, _msgSender()), "only module admin role");
_;
}
/// @dev shares_ are scaled by 10,000 to prevent precision loss when including fees
constructor(
address payable _controlCenter,
address _trustedForwarder,
string memory _uri,
address[] memory payees,
uint256[] memory shares_
) PaymentSplitter() ERC2771Context(_trustedForwarder) {
require(payees.length == shares_.length, "Royalty: unequal number of payees and shares provided.");
require(payees.length > 0, "Royalty: no payees provided.");
// Set contract metadata
contractURI = _uri;
// Set the protocol's control center.
controlCenter = ProtocolControl(_controlCenter);
Registry registry = Registry(controlCenter.registry());
// 0.3% fee
uint256 feeBps = 30;
uint256 totalScaledShares = 0;
uint256 totalScaledSharesMinusFee = 0;
// Scaling the share, so we don't lose precision on division
for (uint256 i = 0; i < payees.length; i++) {
uint256 scaledShares = shares_[i] * 10000;
totalScaledShares += scaledShares;
uint256 feeFromScaledShares = (scaledShares * feeBps) / 10000;
uint256 scaledSharesMinusFee = scaledShares - feeFromScaledShares;
totalScaledSharesMinusFee += scaledSharesMinusFee;
// WARNING: Do not call _addPayee outside of this constructor.
_addPayee(payees[i], scaledSharesMinusFee);
}
// WARNING: Do not call _addPayee outside of this constructor.
uint256 totalFeeShares = totalScaledShares - totalScaledSharesMinusFee;
_addPayee(registry.treasury(), totalFeeShares);
_setupRole(DEFAULT_ADMIN_ROLE, _msgSender());
}
/// @dev See ERC2771
function _msgSender() internal view virtual override(Context, ERC2771Context) returns (address sender) {
return ERC2771Context._msgSender();
}
/// @dev See ERC2771
function _msgData() internal view virtual override(Context, ERC2771Context) returns (bytes calldata) {
return ERC2771Context._msgData();
}
/// @dev Sets contract URI for the contract-level metadata of the contract.
function setContractURI(string calldata _URI) external onlyModuleAdmin {
contractURI = _URI;
}
}