文件 1 的 8:ERC721Structs.sol
pragma solidity ^0.8.7;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
struct CreateParams {
string name;
string symbol;
string uri;
string tokensURI;
uint24 maxSupply;
bool isZeroIndexed;
uint24 royaltyAmount;
uint256 endTime;
bool isEdition;
bool isSBT;
uint256 premintQuantity;
}
struct MintParams {
address to;
address collection;
uint24 quantity;
bytes32[] merkleProof;
uint8 phaseId;
bytes payloadForCall;
}
struct OmnichainMintParams {
address collection;
uint24 quantity;
uint256 paid;
uint8 phaseId;
address minter;
}
struct Phase {
uint256 from;
uint256 to;
uint24 maxPerAddress;
uint256 price;
bytes32 merkleRoot;
address token;
uint256 minToken;
}
struct BasicCollectionParams {
uint tokenId;
string name;
string symbol;
string uri;
string tokenURI;
address owner;
}
struct LzParams {
uint16 dstChainId;
address zroPaymentAddress;
bytes adapterParams;
address payable refundAddress;
}
struct SendParams {
bytes toAddress;
address sender;
address from;
bytes payloadForCall;
}
struct EncodedSendParams {
bytes toAddress;
bytes sender;
bytes from;
bytes payloadForCall;
}
文件 2 的 8:IERC165.sol
pragma solidity ^0.8.0;
interface IERC165 {
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
文件 3 的 8:IERC20.sol
pragma solidity ^0.8.0;
interface IERC20 {
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address to, uint256 amount) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(
address from,
address to,
uint256 amount
) external returns (bool);
}
文件 4 的 8:IOmniseaDropsFactory.sol
pragma solidity ^0.8.7;
import {CreateParams} from "../structs/erc721/ERC721Structs.sol";
interface IOmniseaDropsFactory {
function create(CreateParams calldata params) external;
function drops(address) external returns (bool);
}
文件 5 的 8:IOmniseaERC721Psi.sol
pragma solidity >=0.5.0;
import "@openzeppelin/contracts/utils/introspection/IERC165.sol";
import { CreateParams } from "../structs/erc721/ERC721Structs.sol";
interface IOmniseaERC721Psi is IERC165 {
function initialize(CreateParams memory params, address _owner, address _dropsManagerAddress, address _scheduler) external;
function mint(address _minter, uint24 _quantity, bytes32[] memory _merkleProof, uint8 _phaseId) external returns (uint256);
function mintPrice(uint8 _phaseId) external view returns (uint256);
function owner() external view returns (address);
function dropsManager() external view returns (address);
function endTime() external view returns (uint256);
}
文件 6 的 8:IOmniseaReceiver.sol
pragma solidity ^0.8.7;
interface IOmniseaReceiver {
function omReceive(address collection, uint256 mintQuantity, uint256 nextTokenId, bytes memory payloadForCall) external;
}
文件 7 的 8:OmniseaDropsManager.sol
pragma solidity ^0.8.7;
pragma abicoder v2;
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {MintParams} from "../structs/erc721/ERC721Structs.sol";
import "../interfaces/IOmniseaERC721Psi.sol";
import "../interfaces/IOmniseaDropsFactory.sol";
import "../interfaces/IOmniseaReceiver.sol";
contract OmniseaDropsManager is ReentrancyGuard {
event Minted(address collection, address minter, uint256 quantity, uint256 value);
uint256 public fixedFee;
uint256 public dynamicFee;
IERC20 public osea;
mapping (address => uint256) public collectionsOsea;
mapping (address => uint256) public collectionsOseaPerToken;
uint256 public minOseaPerCollection;
bool public isOseaEnabled;
address private _revenueManager;
address private _owner;
bool private _isPaused;
IOmniseaDropsFactory private _factory;
modifier onlyOwner() {
require(msg.sender == _owner);
_;
}
constructor(address factory_) {
_owner = msg.sender;
_revenueManager = address(0x61104fBe07ecc735D8d84422c7f045f8d29DBf15);
_factory = IOmniseaDropsFactory(factory_);
dynamicFee = 4;
fixedFee = 250000000000000;
}
function setOSEA(address _osea, uint256 _minOseaPerCollection, bool _isEnabled) external onlyOwner {
if (address(osea) == address(0)) {
osea = IERC20(_osea);
}
minOseaPerCollection = _minOseaPerCollection;
isOseaEnabled = _isEnabled;
}
function setFee(uint256 fee_) external onlyOwner {
require(fee_ <= 20);
dynamicFee = fee_;
}
function setFixedFee(uint256 fee_) external onlyOwner {
fixedFee = fee_;
}
function setRevenueManager(address _manager) external onlyOwner {
_revenueManager = _manager;
}
function addOseaToCollection(address _collection, uint256 _oseaAmount, uint256 _oseaAmountPerToken) external {
require(isOseaEnabled && _factory.drops(_collection));
require(_oseaAmount > 0 && _oseaAmountPerToken > 0);
uint256 collectionOsea = collectionsOsea[_collection];
require(collectionOsea + _oseaAmount >= minOseaPerCollection);
if (collectionOsea > 0 && collectionsOseaPerToken[_collection] != _oseaAmountPerToken) {
IOmniseaERC721Psi collection = IOmniseaERC721Psi(_collection);
require(msg.sender == collection.owner());
}
uint256 addAmount = _oseaAmount * 95 / 100;
uint256 burnAmount = _oseaAmount - addAmount;
require(osea.transferFrom(msg.sender, address(this), addAmount));
require(osea.transferFrom(msg.sender, address(0x000000000000000000000000000000000000dEaD), burnAmount));
collectionsOsea[_collection] += addAmount;
require(_oseaAmountPerToken <= collectionsOsea[_collection], ">oseaAmountPerToken");
collectionsOseaPerToken[_collection] = _oseaAmountPerToken;
}
function mint(MintParams calldata _params) external payable nonReentrant {
require(!_isPaused);
require(_factory.drops(_params.collection));
IOmniseaERC721Psi collection = IOmniseaERC721Psi(_params.collection);
address recipient = _params.to;
uint256 price = collection.mintPrice(_params.phaseId);
uint256 quantityPrice = price * _params.quantity;
require(msg.value == quantityPrice + fixedFee, "!=price");
uint256 collectionOsea = collectionsOsea[_params.collection];
uint256 dynamicFee_ = dynamicFee;
if (isOseaEnabled && collectionOsea > 0) {
dynamicFee_ = 0;
uint256 totalOsea = collectionsOseaPerToken[_params.collection] * _params.quantity;
uint256 oseaAmount = collectionOsea > totalOsea ? totalOsea : collectionOsea;
osea.transfer(recipient, oseaAmount);
collectionsOsea[_params.collection] -= oseaAmount;
}
if (quantityPrice > 0) {
uint256 paidToOwner = quantityPrice * (100 - dynamicFee_) / 100;
(bool p1,) = payable(collection.owner()).call{value: paidToOwner}("");
require(p1, "!p1");
(bool p2,) = payable(_revenueManager).call{value: msg.value - paidToOwner}("");
require(p2, "!p2");
} else {
(bool p3,) = payable(_revenueManager).call{value: msg.value}("");
require(p3, "!p3");
}
uint256 nextTokenId = collection.mint(recipient, _params.quantity, _params.merkleProof, _params.phaseId);
if (_params.payloadForCall.length > 0) {
IOmniseaReceiver(recipient).omReceive(_params.collection, _params.quantity, nextTokenId, _params.payloadForCall);
}
}
function setPause(bool isPaused_) external onlyOwner {
_isPaused = isPaused_;
}
function withdraw() external onlyOwner {
(bool p,) = payable(_owner).call{value: address(this).balance}("");
require(p, "!p");
}
receive() external payable {}
}
文件 8 的 8:ReentrancyGuard.sol
pragma solidity ^0.8.0;
abstract contract ReentrancyGuard {
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
constructor() {
_status = _NOT_ENTERED;
}
modifier nonReentrant() {
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
_status = _ENTERED;
_;
_status = _NOT_ENTERED;
}
}
{
"compilationTarget": {
"src/contracts/v3/OmniseaDropsManager.sol": "OmniseaDropsManager"
},
"evmVersion": "london",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 1
},
"remappings": []
}
[{"inputs":[{"internalType":"address","name":"factory_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"collection","type":"address"},{"indexed":false,"internalType":"address","name":"minter","type":"address"},{"indexed":false,"internalType":"uint256","name":"quantity","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Minted","type":"event"},{"inputs":[{"internalType":"address","name":"_collection","type":"address"},{"internalType":"uint256","name":"_oseaAmount","type":"uint256"},{"internalType":"uint256","name":"_oseaAmountPerToken","type":"uint256"}],"name":"addOseaToCollection","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"collectionsOsea","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"collectionsOseaPerToken","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"dynamicFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"fixedFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isOseaEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minOseaPerCollection","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"to","type":"address"},{"internalType":"address","name":"collection","type":"address"},{"internalType":"uint24","name":"quantity","type":"uint24"},{"internalType":"bytes32[]","name":"merkleProof","type":"bytes32[]"},{"internalType":"uint8","name":"phaseId","type":"uint8"},{"internalType":"bytes","name":"payloadForCall","type":"bytes"}],"internalType":"struct MintParams","name":"_params","type":"tuple"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"osea","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"fee_","type":"uint256"}],"name":"setFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"fee_","type":"uint256"}],"name":"setFixedFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_osea","type":"address"},{"internalType":"uint256","name":"_minOseaPerCollection","type":"uint256"},{"internalType":"bool","name":"_isEnabled","type":"bool"}],"name":"setOSEA","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"isPaused_","type":"bool"}],"name":"setPause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_manager","type":"address"}],"name":"setRevenueManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]