编译器
0.8.24+commit.e11b9ed9
文件 1 的 20:Address.sol
pragma solidity ^0.8.20;
library Address {
error AddressInsufficientBalance(address account);
error AddressEmptyCode(address target);
error FailedInnerCall();
function sendValue(address payable recipient, uint256 amount) internal {
if (address(this).balance < amount) {
revert AddressInsufficientBalance(address(this));
}
(bool success, ) = recipient.call{value: amount}("");
if (!success) {
revert FailedInnerCall();
}
}
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0);
}
function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
if (address(this).balance < value) {
revert AddressInsufficientBalance(address(this));
}
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResultFromTarget(target, success, returndata);
}
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResultFromTarget(target, success, returndata);
}
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResultFromTarget(target, success, returndata);
}
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata
) internal view returns (bytes memory) {
if (!success) {
_revert(returndata);
} else {
if (returndata.length == 0 && target.code.length == 0) {
revert AddressEmptyCode(target);
}
return returndata;
}
}
function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) {
if (!success) {
_revert(returndata);
} else {
return returndata;
}
}
function _revert(bytes memory returndata) private pure {
if (returndata.length > 0) {
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert FailedInnerCall();
}
}
}
文件 2 的 20:Arrays.sol
pragma solidity ^0.8.20;
import {StorageSlot} from "./StorageSlot.sol";
import {Math} from "./math/Math.sol";
library Arrays {
using StorageSlot for bytes32;
function findUpperBound(uint256[] storage array, uint256 element) internal view returns (uint256) {
uint256 low = 0;
uint256 high = array.length;
if (high == 0) {
return 0;
}
while (low < high) {
uint256 mid = Math.average(low, high);
if (unsafeAccess(array, mid).value > element) {
high = mid;
} else {
low = mid + 1;
}
}
if (low > 0 && unsafeAccess(array, low - 1).value == element) {
return low - 1;
} else {
return low;
}
}
function unsafeAccess(address[] storage arr, uint256 pos) internal pure returns (StorageSlot.AddressSlot storage) {
bytes32 slot;
assembly {
mstore(0, arr.slot)
slot := add(keccak256(0, 0x20), pos)
}
return slot.getAddressSlot();
}
function unsafeAccess(bytes32[] storage arr, uint256 pos) internal pure returns (StorageSlot.Bytes32Slot storage) {
bytes32 slot;
assembly {
mstore(0, arr.slot)
slot := add(keccak256(0, 0x20), pos)
}
return slot.getBytes32Slot();
}
function unsafeAccess(uint256[] storage arr, uint256 pos) internal pure returns (StorageSlot.Uint256Slot storage) {
bytes32 slot;
assembly {
mstore(0, arr.slot)
slot := add(keccak256(0, 0x20), pos)
}
return slot.getUint256Slot();
}
function unsafeMemoryAccess(uint256[] memory arr, uint256 pos) internal pure returns (uint256 res) {
assembly {
res := mload(add(add(arr, 0x20), mul(pos, 0x20)))
}
}
function unsafeMemoryAccess(address[] memory arr, uint256 pos) internal pure returns (address res) {
assembly {
res := mload(add(add(arr, 0x20), mul(pos, 0x20)))
}
}
}
文件 3 的 20:Context.sol
pragma solidity ^0.8.20;
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}
文件 4 的 20:ERC1155.sol
pragma solidity ^0.8.20;
import {IERC1155} from "./IERC1155.sol";
import {IERC1155Receiver} from "./IERC1155Receiver.sol";
import {IERC1155MetadataURI} from "./extensions/IERC1155MetadataURI.sol";
import {Context} from "../../utils/Context.sol";
import {IERC165, ERC165} from "../../utils/introspection/ERC165.sol";
import {Arrays} from "../../utils/Arrays.sol";
import {IERC1155Errors} from "../../interfaces/draft-IERC6093.sol";
abstract contract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI, IERC1155Errors {
using Arrays for uint256[];
using Arrays for address[];
mapping(uint256 id => mapping(address account => uint256)) private _balances;
mapping(address account => mapping(address operator => bool)) private _operatorApprovals;
string private _uri;
constructor(string memory uri_) {
_setURI(uri_);
}
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
return
interfaceId == type(IERC1155).interfaceId ||
interfaceId == type(IERC1155MetadataURI).interfaceId ||
super.supportsInterface(interfaceId);
}
function uri(uint256 ) public view virtual returns (string memory) {
return _uri;
}
function balanceOf(address account, uint256 id) public view virtual returns (uint256) {
return _balances[id][account];
}
function balanceOfBatch(
address[] memory accounts,
uint256[] memory ids
) public view virtual returns (uint256[] memory) {
if (accounts.length != ids.length) {
revert ERC1155InvalidArrayLength(ids.length, accounts.length);
}
uint256[] memory batchBalances = new uint256[](accounts.length);
for (uint256 i = 0; i < accounts.length; ++i) {
batchBalances[i] = balanceOf(accounts.unsafeMemoryAccess(i), ids.unsafeMemoryAccess(i));
}
return batchBalances;
}
function setApprovalForAll(address operator, bool approved) public virtual {
_setApprovalForAll(_msgSender(), operator, approved);
}
function isApprovedForAll(address account, address operator) public view virtual returns (bool) {
return _operatorApprovals[account][operator];
}
function safeTransferFrom(address from, address to, uint256 id, uint256 value, bytes memory data) public virtual {
address sender = _msgSender();
if (from != sender && !isApprovedForAll(from, sender)) {
revert ERC1155MissingApprovalForAll(sender, from);
}
_safeTransferFrom(from, to, id, value, data);
}
function safeBatchTransferFrom(
address from,
address to,
uint256[] memory ids,
uint256[] memory values,
bytes memory data
) public virtual {
address sender = _msgSender();
if (from != sender && !isApprovedForAll(from, sender)) {
revert ERC1155MissingApprovalForAll(sender, from);
}
_safeBatchTransferFrom(from, to, ids, values, data);
}
function _update(address from, address to, uint256[] memory ids, uint256[] memory values) internal virtual {
if (ids.length != values.length) {
revert ERC1155InvalidArrayLength(ids.length, values.length);
}
address operator = _msgSender();
for (uint256 i = 0; i < ids.length; ++i) {
uint256 id = ids.unsafeMemoryAccess(i);
uint256 value = values.unsafeMemoryAccess(i);
if (from != address(0)) {
uint256 fromBalance = _balances[id][from];
if (fromBalance < value) {
revert ERC1155InsufficientBalance(from, fromBalance, value, id);
}
unchecked {
_balances[id][from] = fromBalance - value;
}
}
if (to != address(0)) {
_balances[id][to] += value;
}
}
if (ids.length == 1) {
uint256 id = ids.unsafeMemoryAccess(0);
uint256 value = values.unsafeMemoryAccess(0);
emit TransferSingle(operator, from, to, id, value);
} else {
emit TransferBatch(operator, from, to, ids, values);
}
}
function _updateWithAcceptanceCheck(
address from,
address to,
uint256[] memory ids,
uint256[] memory values,
bytes memory data
) internal virtual {
_update(from, to, ids, values);
if (to != address(0)) {
address operator = _msgSender();
if (ids.length == 1) {
uint256 id = ids.unsafeMemoryAccess(0);
uint256 value = values.unsafeMemoryAccess(0);
_doSafeTransferAcceptanceCheck(operator, from, to, id, value, data);
} else {
_doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, values, data);
}
}
}
function _safeTransferFrom(address from, address to, uint256 id, uint256 value, bytes memory data) internal {
if (to == address(0)) {
revert ERC1155InvalidReceiver(address(0));
}
if (from == address(0)) {
revert ERC1155InvalidSender(address(0));
}
(uint256[] memory ids, uint256[] memory values) = _asSingletonArrays(id, value);
_updateWithAcceptanceCheck(from, to, ids, values, data);
}
function _safeBatchTransferFrom(
address from,
address to,
uint256[] memory ids,
uint256[] memory values,
bytes memory data
) internal {
if (to == address(0)) {
revert ERC1155InvalidReceiver(address(0));
}
if (from == address(0)) {
revert ERC1155InvalidSender(address(0));
}
_updateWithAcceptanceCheck(from, to, ids, values, data);
}
function _setURI(string memory newuri) internal virtual {
_uri = newuri;
}
function _mint(address to, uint256 id, uint256 value, bytes memory data) internal {
if (to == address(0)) {
revert ERC1155InvalidReceiver(address(0));
}
(uint256[] memory ids, uint256[] memory values) = _asSingletonArrays(id, value);
_updateWithAcceptanceCheck(address(0), to, ids, values, data);
}
function _mintBatch(address to, uint256[] memory ids, uint256[] memory values, bytes memory data) internal {
if (to == address(0)) {
revert ERC1155InvalidReceiver(address(0));
}
_updateWithAcceptanceCheck(address(0), to, ids, values, data);
}
function _burn(address from, uint256 id, uint256 value) internal {
if (from == address(0)) {
revert ERC1155InvalidSender(address(0));
}
(uint256[] memory ids, uint256[] memory values) = _asSingletonArrays(id, value);
_updateWithAcceptanceCheck(from, address(0), ids, values, "");
}
function _burnBatch(address from, uint256[] memory ids, uint256[] memory values) internal {
if (from == address(0)) {
revert ERC1155InvalidSender(address(0));
}
_updateWithAcceptanceCheck(from, address(0), ids, values, "");
}
function _setApprovalForAll(address owner, address operator, bool approved) internal virtual {
if (operator == address(0)) {
revert ERC1155InvalidOperator(address(0));
}
_operatorApprovals[owner][operator] = approved;
emit ApprovalForAll(owner, operator, approved);
}
function _doSafeTransferAcceptanceCheck(
address operator,
address from,
address to,
uint256 id,
uint256 value,
bytes memory data
) private {
if (to.code.length > 0) {
try IERC1155Receiver(to).onERC1155Received(operator, from, id, value, data) returns (bytes4 response) {
if (response != IERC1155Receiver.onERC1155Received.selector) {
revert ERC1155InvalidReceiver(to);
}
} catch (bytes memory reason) {
if (reason.length == 0) {
revert ERC1155InvalidReceiver(to);
} else {
assembly {
revert(add(32, reason), mload(reason))
}
}
}
}
}
function _doSafeBatchTransferAcceptanceCheck(
address operator,
address from,
address to,
uint256[] memory ids,
uint256[] memory values,
bytes memory data
) private {
if (to.code.length > 0) {
try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, values, data) returns (
bytes4 response
) {
if (response != IERC1155Receiver.onERC1155BatchReceived.selector) {
revert ERC1155InvalidReceiver(to);
}
} catch (bytes memory reason) {
if (reason.length == 0) {
revert ERC1155InvalidReceiver(to);
} else {
assembly {
revert(add(32, reason), mload(reason))
}
}
}
}
}
function _asSingletonArrays(
uint256 element1,
uint256 element2
) private pure returns (uint256[] memory array1, uint256[] memory array2) {
assembly {
array1 := mload(0x40)
mstore(array1, 1)
mstore(add(array1, 0x20), element1)
array2 := add(array1, 0x40)
mstore(array2, 1)
mstore(add(array2, 0x20), element2)
mstore(0x40, add(array2, 0x40))
}
}
}
文件 5 的 20:ERC165.sol
pragma solidity ^0.8.20;
import {IERC165} from "./IERC165.sol";
abstract contract ERC165 is IERC165 {
function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}
文件 6 的 20:IERC1155.sol
pragma solidity ^0.8.20;
import {IERC165} from "../../utils/introspection/IERC165.sol";
interface IERC1155 is IERC165 {
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 account, address indexed operator, bool approved);
event URI(string value, uint256 indexed id);
function balanceOf(address account, uint256 id) external view returns (uint256);
function balanceOfBatch(
address[] calldata accounts,
uint256[] calldata ids
) external view returns (uint256[] memory);
function setApprovalForAll(address operator, bool approved) external;
function isApprovedForAll(address account, address operator) external view returns (bool);
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;
}
文件 7 的 20:IERC1155MetadataURI.sol
pragma solidity ^0.8.20;
import {IERC1155} from "../IERC1155.sol";
interface IERC1155MetadataURI is IERC1155 {
function uri(uint256 id) external view returns (string memory);
}
文件 8 的 20:IERC1155Receiver.sol
pragma solidity ^0.8.20;
import {IERC165} from "../../utils/introspection/IERC165.sol";
interface IERC1155Receiver is IERC165 {
function onERC1155Received(
address operator,
address from,
uint256 id,
uint256 value,
bytes calldata data
) external returns (bytes4);
function onERC1155BatchReceived(
address operator,
address from,
uint256[] calldata ids,
uint256[] calldata values,
bytes calldata data
) external returns (bytes4);
}
文件 9 的 20:IERC165.sol
pragma solidity ^0.8.20;
interface IERC165 {
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
文件 10 的 20:IERC20.sol
pragma solidity ^0.8.20;
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 value) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 value) external returns (bool);
function transferFrom(address from, address to, uint256 value) external returns (bool);
}
文件 11 的 20:IERC20Permit.sol
pragma solidity ^0.8.20;
interface IERC20Permit {
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
function nonces(address owner) external view returns (uint256);
function DOMAIN_SEPARATOR() external view returns (bytes32);
}
文件 12 的 20:Math.sol
pragma solidity ^0.8.20;
library Math {
error MathOverflowedMulDiv();
enum Rounding {
Floor,
Ceil,
Trunc,
Expand
}
function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
uint256 c = a + b;
if (c < a) return (false, 0);
return (true, c);
}
}
function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b > a) return (false, 0);
return (true, a - b);
}
}
function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (a == 0) return (true, 0);
uint256 c = a * b;
if (c / a != b) return (false, 0);
return (true, c);
}
}
function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a / b);
}
}
function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a % b);
}
}
function max(uint256 a, uint256 b) internal pure returns (uint256) {
return a > b ? a : b;
}
function min(uint256 a, uint256 b) internal pure returns (uint256) {
return a < b ? a : b;
}
function average(uint256 a, uint256 b) internal pure returns (uint256) {
return (a & b) + (a ^ b) / 2;
}
function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
if (b == 0) {
return a / b;
}
return a == 0 ? 0 : (a - 1) / b + 1;
}
function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {
unchecked {
uint256 prod0 = x * y;
uint256 prod1;
assembly {
let mm := mulmod(x, y, not(0))
prod1 := sub(sub(mm, prod0), lt(mm, prod0))
}
if (prod1 == 0) {
return prod0 / denominator;
}
if (denominator <= prod1) {
revert MathOverflowedMulDiv();
}
uint256 remainder;
assembly {
remainder := mulmod(x, y, denominator)
prod1 := sub(prod1, gt(remainder, prod0))
prod0 := sub(prod0, remainder)
}
uint256 twos = denominator & (0 - denominator);
assembly {
denominator := div(denominator, twos)
prod0 := div(prod0, twos)
twos := add(div(sub(0, twos), twos), 1)
}
prod0 |= prod1 * twos;
uint256 inverse = (3 * denominator) ^ 2;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
result = prod0 * inverse;
return result;
}
}
function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {
uint256 result = mulDiv(x, y, denominator);
if (unsignedRoundsUp(rounding) && mulmod(x, y, denominator) > 0) {
result += 1;
}
return result;
}
function sqrt(uint256 a) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
uint256 result = 1 << (log2(a) >> 1);
unchecked {
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
return min(result, a / result);
}
}
function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = sqrt(a);
return result + (unsignedRoundsUp(rounding) && result * result < a ? 1 : 0);
}
}
function log2(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 128;
}
if (value >> 64 > 0) {
value >>= 64;
result += 64;
}
if (value >> 32 > 0) {
value >>= 32;
result += 32;
}
if (value >> 16 > 0) {
value >>= 16;
result += 16;
}
if (value >> 8 > 0) {
value >>= 8;
result += 8;
}
if (value >> 4 > 0) {
value >>= 4;
result += 4;
}
if (value >> 2 > 0) {
value >>= 2;
result += 2;
}
if (value >> 1 > 0) {
result += 1;
}
}
return result;
}
function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log2(value);
return result + (unsignedRoundsUp(rounding) && 1 << result < value ? 1 : 0);
}
}
function log10(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >= 10 ** 64) {
value /= 10 ** 64;
result += 64;
}
if (value >= 10 ** 32) {
value /= 10 ** 32;
result += 32;
}
if (value >= 10 ** 16) {
value /= 10 ** 16;
result += 16;
}
if (value >= 10 ** 8) {
value /= 10 ** 8;
result += 8;
}
if (value >= 10 ** 4) {
value /= 10 ** 4;
result += 4;
}
if (value >= 10 ** 2) {
value /= 10 ** 2;
result += 2;
}
if (value >= 10 ** 1) {
result += 1;
}
}
return result;
}
function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log10(value);
return result + (unsignedRoundsUp(rounding) && 10 ** result < value ? 1 : 0);
}
}
function log256(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 16;
}
if (value >> 64 > 0) {
value >>= 64;
result += 8;
}
if (value >> 32 > 0) {
value >>= 32;
result += 4;
}
if (value >> 16 > 0) {
value >>= 16;
result += 2;
}
if (value >> 8 > 0) {
result += 1;
}
}
return result;
}
function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log256(value);
return result + (unsignedRoundsUp(rounding) && 1 << (result << 3) < value ? 1 : 0);
}
}
function unsignedRoundsUp(Rounding rounding) internal pure returns (bool) {
return uint8(rounding) % 2 == 1;
}
}
文件 13 的 20:Ownable.sol
pragma solidity ^0.8.20;
import {Context} from "../utils/Context.sol";
abstract contract Ownable is Context {
address private _owner;
error OwnableUnauthorizedAccount(address account);
error OwnableInvalidOwner(address owner);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor(address initialOwner) {
if (initialOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(initialOwner);
}
modifier onlyOwner() {
_checkOwner();
_;
}
function owner() public view virtual returns (address) {
return _owner;
}
function _checkOwner() internal view virtual {
if (owner() != _msgSender()) {
revert OwnableUnauthorizedAccount(_msgSender());
}
}
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
function transferOwnership(address newOwner) public virtual onlyOwner {
if (newOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(newOwner);
}
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
文件 14 的 20:Ownable2Step.sol
pragma solidity ^0.8.20;
import {Ownable} from "./Ownable.sol";
abstract contract Ownable2Step is Ownable {
address private _pendingOwner;
event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);
function pendingOwner() public view virtual returns (address) {
return _pendingOwner;
}
function transferOwnership(address newOwner) public virtual override onlyOwner {
_pendingOwner = newOwner;
emit OwnershipTransferStarted(owner(), newOwner);
}
function _transferOwnership(address newOwner) internal virtual override {
delete _pendingOwner;
super._transferOwnership(newOwner);
}
function acceptOwnership() public virtual {
address sender = _msgSender();
if (pendingOwner() != sender) {
revert OwnableUnauthorizedAccount(sender);
}
_transferOwnership(sender);
}
}
文件 15 的 20:SafeERC20.sol
pragma solidity ^0.8.20;
import {IERC20} from "../IERC20.sol";
import {IERC20Permit} from "../extensions/IERC20Permit.sol";
import {Address} from "../../../utils/Address.sol";
library SafeERC20 {
using Address for address;
error SafeERC20FailedOperation(address token);
error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease);
function safeTransfer(IERC20 token, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeCall(token.transfer, (to, value)));
}
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeCall(token.transferFrom, (from, to, value)));
}
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 oldAllowance = token.allowance(address(this), spender);
forceApprove(token, spender, oldAllowance + value);
}
function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal {
unchecked {
uint256 currentAllowance = token.allowance(address(this), spender);
if (currentAllowance < requestedDecrease) {
revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease);
}
forceApprove(token, spender, currentAllowance - requestedDecrease);
}
}
function forceApprove(IERC20 token, address spender, uint256 value) internal {
bytes memory approvalCall = abi.encodeCall(token.approve, (spender, value));
if (!_callOptionalReturnBool(token, approvalCall)) {
_callOptionalReturn(token, abi.encodeCall(token.approve, (spender, 0)));
_callOptionalReturn(token, approvalCall);
}
}
function _callOptionalReturn(IERC20 token, bytes memory data) private {
bytes memory returndata = address(token).functionCall(data);
if (returndata.length != 0 && !abi.decode(returndata, (bool))) {
revert SafeERC20FailedOperation(address(token));
}
}
function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {
(bool success, bytes memory returndata) = address(token).call(data);
return success && (returndata.length == 0 || abi.decode(returndata, (bool))) && address(token).code.length > 0;
}
}
文件 16 的 20:SignedMath.sol
pragma solidity ^0.8.20;
library SignedMath {
function max(int256 a, int256 b) internal pure returns (int256) {
return a > b ? a : b;
}
function min(int256 a, int256 b) internal pure returns (int256) {
return a < b ? a : b;
}
function average(int256 a, int256 b) internal pure returns (int256) {
int256 x = (a & b) + ((a ^ b) >> 1);
return x + (int256(uint256(x) >> 255) & (a ^ b));
}
function abs(int256 n) internal pure returns (uint256) {
unchecked {
return uint256(n >= 0 ? n : -n);
}
}
}
文件 17 的 20:StorageSlot.sol
pragma solidity ^0.8.20;
library StorageSlot {
struct AddressSlot {
address value;
}
struct BooleanSlot {
bool value;
}
struct Bytes32Slot {
bytes32 value;
}
struct Uint256Slot {
uint256 value;
}
struct StringSlot {
string value;
}
struct BytesSlot {
bytes value;
}
function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {
assembly {
r.slot := slot
}
}
function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {
assembly {
r.slot := slot
}
}
function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {
assembly {
r.slot := slot
}
}
function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {
assembly {
r.slot := slot
}
}
function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) {
assembly {
r.slot := slot
}
}
function getStringSlot(string storage store) internal pure returns (StringSlot storage r) {
assembly {
r.slot := store.slot
}
}
function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) {
assembly {
r.slot := slot
}
}
function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) {
assembly {
r.slot := store.slot
}
}
}
文件 18 的 20:Strings.sol
pragma solidity ^0.8.20;
import {Math} from "./math/Math.sol";
import {SignedMath} from "./math/SignedMath.sol";
library Strings {
bytes16 private constant HEX_DIGITS = "0123456789abcdef";
uint8 private constant ADDRESS_LENGTH = 20;
error StringsInsufficientHexLength(uint256 value, uint256 length);
function toString(uint256 value) internal pure returns (string memory) {
unchecked {
uint256 length = Math.log10(value) + 1;
string memory buffer = new string(length);
uint256 ptr;
assembly {
ptr := add(buffer, add(32, length))
}
while (true) {
ptr--;
assembly {
mstore8(ptr, byte(mod(value, 10), HEX_DIGITS))
}
value /= 10;
if (value == 0) break;
}
return buffer;
}
}
function toStringSigned(int256 value) internal pure returns (string memory) {
return string.concat(value < 0 ? "-" : "", toString(SignedMath.abs(value)));
}
function toHexString(uint256 value) internal pure returns (string memory) {
unchecked {
return toHexString(value, Math.log256(value) + 1);
}
}
function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
uint256 localValue = value;
bytes memory buffer = new bytes(2 * length + 2);
buffer[0] = "0";
buffer[1] = "x";
for (uint256 i = 2 * length + 1; i > 1; --i) {
buffer[i] = HEX_DIGITS[localValue & 0xf];
localValue >>= 4;
}
if (localValue != 0) {
revert StringsInsufficientHexLength(value, length);
}
return string(buffer);
}
function toHexString(address addr) internal pure returns (string memory) {
return toHexString(uint256(uint160(addr)), ADDRESS_LENGTH);
}
function equal(string memory a, string memory b) internal pure returns (bool) {
return bytes(a).length == bytes(b).length && keccak256(bytes(a)) == keccak256(bytes(b));
}
}
文件 19 的 20:Wildcard.sol
pragma solidity ^0.8.24;
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "@openzeppelin/contracts/token/ERC1155/ERC1155.sol";
import "@openzeppelin/contracts/utils/Strings.sol";
import "@openzeppelin/contracts/utils/Context.sol";
import "@openzeppelin/contracts/access/Ownable2Step.sol";
import "@openzeppelin/contracts/utils/math/Math.sol";
import "@openzeppelin/contracts/utils/introspection/IERC165.sol";
contract Wildcard is ERC1155, Ownable2Step {
using Strings for uint256;
using SafeERC20 for IERC20;
string public name = "Wildcard";
string public symbol = "WC";
uint256 public constant TICKET_DECIMALS = 3;
uint256 public constant SINGLE_TICKET_CHUNKS = 10 ** TICKET_DECIMALS;
uint256 public constant PRICE_DENOMINATOR = 10000 * SINGLE_TICKET_CHUNKS * 1000;
uint32 public constant ONE_PERCENT_PRECISION_MULTIPLIER = 1000000;
uint256 private _tokenIdCount;
mapping(uint256 => uint256) private _totalSupply;
mapping(uint256 => uint256) private _mintableToSocialIdOwner;
mapping(uint256 => uint256) private _ethForSocialIdOwner;
mapping(uint32 => string) private _platformNameById;
mapping(uint32 => mapping(uint256 => uint256)) private _tokenIdBySocialId;
mapping(uint256 => address) private _socialIdOwners;
string metadataBaseUrlPrefix;
string metadataBaseUrlSuffix;
string contractMetadataUrl;
uint32 public protocolFeePercent = ONE_PERCENT_PRECISION_MULTIPLIER;
uint32 public socialIdFeePercent = ONE_PERCENT_PRECISION_MULTIPLIER;
address public protocolFeeDestination = msg.sender;
address private _admin = msg.sender;
bool public isPaused;
event SocialUserAddress(
uint32 indexed platformId,
uint256 indexed platformUserId,
address indexed socialIdOwnerAddr
);
event Release(
uint32 indexed platformId,
uint256 indexed platformUserId,
uint256 indexed tokenId
);
event Mint(
uint256 indexed tokenId,
uint256 amount,
address indexed destination
);
event Buy(
address indexed txnFromAddr,
address indexed destinationAddr,
uint256 indexed tokenId,
uint256 amount,
uint256 price,
uint256 protocolFeePaid,
uint256 socialIdFeePaid,
uint256 newTotalSupply
);
event Sell(
address indexed txnFromAddr,
address indexed destinationAddr,
uint256 indexed tokenId,
uint256 amount,
uint256 price,
uint256 protocolFeePaid,
uint256 socialIdFeePaid,
uint256 newTotalSupply
);
event ProtocolFeePercentChanged(uint32 oldValue, uint32 newValue);
event SocialIdFeePercentChanged(uint32 oldValue, uint32 newValue);
event ToggledPause(bool oldPauseState, bool newPauseState, address caller);
event BatchMetadataUpdate(uint256 _fromTokenId, uint256 _toTokenId);
error WildCard__ContractIsPaused();
error WildCard_OnlyAdmin();
modifier whenNotPaused() {
if (isPaused) revert WildCard__ContractIsPaused();
_;
}
modifier onlyAdmin() {
if (msg.sender != _admin) revert WildCard_OnlyAdmin();
_;
}
constructor(
address _owner,
string memory _name,
string memory _symbol,
string memory _metadataBaseUrlPrefix,
string memory _metadataBaseUrlSuffix,
string memory _contractMetadataUrl,
address _protocolFeeDestination
) Ownable(_owner) ERC1155(contractMetadataUrl) {
name = _name;
symbol = _symbol;
metadataBaseUrlPrefix = _metadataBaseUrlPrefix;
metadataBaseUrlSuffix = _metadataBaseUrlSuffix;
contractMetadataUrl = _contractMetadataUrl;
protocolFeeDestination = _protocolFeeDestination;
}
function uri(uint256 tokenId) public view override returns (string memory) {
if (tokenId > _tokenIdCount || tokenId == 0) {
return "";
}
return
string(
abi.encodePacked(
metadataBaseUrlPrefix,
Strings.toString(tokenId),
metadataBaseUrlSuffix
)
);
}
function contractURI() public view returns (string memory) {
return contractMetadataUrl;
}
function setAdmin(address newAddress) public onlyOwner {
require(newAddress != address(0), "Invalid address");
_admin = newAddress;
}
function admin() public view returns (address) {
return _admin;
}
function setMetadataBaseUrlPrefix(string memory newValue) public onlyOwner {
metadataBaseUrlPrefix = newValue;
emit BatchMetadataUpdate(0, _tokenIdCount);
}
function setMetadataBaseUrlSuffix(string memory newValue) public onlyOwner {
metadataBaseUrlSuffix = newValue;
emit BatchMetadataUpdate(0, _tokenIdCount);
}
function setContractMetadataUrl(string memory newValue) public onlyOwner {
contractMetadataUrl = newValue;
}
function setProtocolFeePercent(uint32 newValue) public onlyOwner {
require(newValue <= 10 * ONE_PERCENT_PRECISION_MULTIPLIER, "Value must be between 0 and 10%");
emit ProtocolFeePercentChanged(protocolFeePercent, newValue);
protocolFeePercent = newValue;
}
function setSocialIdFeePercent(uint32 newValue) public onlyOwner {
require(newValue <= 10 * ONE_PERCENT_PRECISION_MULTIPLIER, "Value must be between 0 and 10%");
emit SocialIdFeePercentChanged(socialIdFeePercent, newValue);
socialIdFeePercent = newValue;
}
function setProtocolFeeDestination(
address newAddress
) public onlyOwner returns (address) {
require(newAddress != address(0), "Invalid address");
protocolFeeDestination = newAddress;
return protocolFeeDestination;
}
function setPause(bool state) public onlyOwner {
emit ToggledPause(isPaused, state, msg.sender);
isPaused = state;
}
function calculatePrice(uint256 supply, uint256 amount) public pure returns (uint256) {
uint256 price;
uint256 currentN = Math.ceilDiv(supply + 1, SINGLE_TICKET_CHUNKS);
uint256 leftAtThisPrice = SINGLE_TICKET_CHUNKS - supply % SINGLE_TICKET_CHUNKS;
uint256 takenAtThisPrice = Math.min(leftAtThisPrice, amount);
price += takenAtThisPrice * singleTicketPrice(currentN);
amount -= takenAtThisPrice;
if (amount == 0) return price;
currentN += 1;
if (amount > SINGLE_TICKET_CHUNKS) {
uint256 numPerfectMultiples = (amount / SINGLE_TICKET_CHUNKS);
if (numPerfectMultiples == 1) {
price += singleTicketPrice(currentN) * SINGLE_TICKET_CHUNKS;
} else {
price += ticketPrice(currentN, currentN + numPerfectMultiples - 1) * SINGLE_TICKET_CHUNKS;
}
amount -= numPerfectMultiples * SINGLE_TICKET_CHUNKS;
currentN += numPerfectMultiples;
}
if (amount > 0) {
price += amount * singleTicketPrice(currentN);
}
return price;
}
function getBuyPrice(
uint256 tokenId,
uint256 amount
) public view returns (uint256) {
return calculatePrice(_totalSupply[tokenId], amount);
}
function getTicketBuyPriceBySocialId(
uint32 platformId,
uint256 platformUserId,
uint256 amount
) public view returns (uint256) {
uint256 tokenId = _tokenIdBySocialId[platformId][platformUserId];
if(tokenId == 0) {
return calculatePrice(0, amount);
}
return getBuyPrice(tokenId, amount);
}
function getSellPrice(
uint256 tokenId,
uint256 amount
) public view returns (uint256) {
return calculatePrice(_totalSupply[tokenId] - amount, amount);
}
function getTicketSellPriceBySocialId(
uint32 platformId,
uint256 platformUserId,
uint256 amount
) public view returns (uint256) {
uint256 tokenId = _tokenIdBySocialId[platformId][platformUserId];
if(tokenId==0){
return 0;
}
return getSellPrice(tokenId, amount);
}
function getBuyPriceAfterFee(
uint256 tokenId,
uint256 amount
) public view returns (uint256) {
uint256 price = getBuyPrice(tokenId, amount);
return price + _getFee(price);
}
function getTicketBuyPriceAfterTaxBySocialId(
uint32 platformId,
uint256 platformUserId,
uint256 amount
) public view returns (uint256) {
uint256 price = getTicketBuyPriceBySocialId(platformId, platformUserId, amount);
return price + _getFee(price);
}
function getSellPriceAfterFee(
uint256 tokenId,
uint256 amount
) public view returns (uint256) {
uint256 price = getSellPrice(tokenId, amount);
return price - _getFee(price);
}
function getTicketSellPriceAfterTaxBySocialId(
uint32 platformId,
uint256 platformUserId,
uint256 amount
) public view returns (uint256) {
uint256 tokenId = _tokenIdBySocialId[platformId][platformUserId];
if(tokenId==0){
return 0;
}
return getSellPriceAfterFee(tokenId, amount);
}
function getSocialIdOwner(uint256 tokenId) public view returns (address) {
return _socialIdOwners[tokenId];
}
function getSocialIdOwnerBySocialId(
uint32 platformId,
uint256 platformUserId
) public view returns (address) {
return _socialIdOwners[_tokenIdBySocialId[platformId][platformUserId]];
}
function getTokenIdBySocialId(
uint32 platformId,
uint256 platformUserId
) public view returns (uint256) {
return _tokenIdBySocialId[platformId][platformUserId];
}
function getReleaseSupply(uint256 tokenId) public view returns (uint256) {
return _totalSupply[tokenId];
}
function getReleaseSupplyBySocialId(
uint32 platformId,
uint256 platformUserId
) public view returns (uint256) {
uint256 tokenId = _tokenIdBySocialId[platformId][platformUserId];
return _totalSupply[tokenId];
}
function getSocialPlatform(uint32 platformId) public view returns (string memory) {
return _platformNameById[platformId];
}
function getSocialIdPurchaseDetailsMulti(
uint32 platformId,
uint256 platformUserId,
uint256[] memory amounts
) public view returns (
uint256[] memory tokenIds,
uint256[] memory buyPrices,
uint256[] memory sellPrices,
uint256[] memory buyPricesWithFee,
uint256[] memory sellPricesWithFee,
uint256[] memory supplies
) {
tokenIds = new uint256[](amounts.length);
buyPrices = new uint256[](amounts.length);
sellPrices = new uint256[](amounts.length);
buyPricesWithFee = new uint256[](amounts.length);
sellPricesWithFee = new uint256[](amounts.length);
supplies = new uint256[](amounts.length);
for (uint256 i = 0; i < amounts.length; i++) {
(
tokenIds[i],
buyPrices[i],
sellPrices[i],
buyPricesWithFee[i],
sellPricesWithFee[i],
supplies[i]
) = getSocialIdPurchaseDetails(platformId, platformUserId, amounts[i]);
}
return (
tokenIds,
buyPrices,
sellPrices,
buyPricesWithFee,
sellPricesWithFee,
supplies
);
}
function getSocialIdPurchaseDetailsBulk(
uint32[] memory platformIds,
uint256[] memory platformUserIds,
uint256[] memory amounts
) public view returns (
uint256[] memory tokenIds,
uint256[] memory buyPrices,
uint256[] memory sellPrices,
uint256[] memory buyPricesWithFee,
uint256[] memory sellPricesWithFee,
uint256[] memory supplies
) {
tokenIds = new uint256[](amounts.length);
buyPrices = new uint256[](amounts.length);
sellPrices = new uint256[](amounts.length);
buyPricesWithFee = new uint256[](amounts.length);
sellPricesWithFee = new uint256[](amounts.length);
supplies = new uint256[](amounts.length);
for (uint256 i = 0; i < amounts.length; i++) {
(
tokenIds[i],
buyPrices[i],
sellPrices[i],
buyPricesWithFee[i],
sellPricesWithFee[i],
supplies[i]
) = getSocialIdPurchaseDetails(platformIds[i], platformUserIds[i], amounts[i]);
}
return (
tokenIds,
buyPrices,
sellPrices,
buyPricesWithFee,
sellPricesWithFee,
supplies
);
}
function getSocialIdPurchaseDetails(
uint32 platformId,
uint256 platformUserId,
uint256 amount
) public view returns (
uint256 tokenId,
uint256 buyPrice,
uint256 sellPrice,
uint256 buyPriceWithFee,
uint256 sellPriceWithFee,
uint256 supply
) {
tokenId = _tokenIdBySocialId[platformId][platformUserId];
supply = _totalSupply[tokenId];
if (tokenId == 0) {
buyPrice = calculatePrice(SINGLE_TICKET_CHUNKS, amount);
sellPrice = 0;
} else {
buyPrice = getBuyPrice(tokenId, amount);
if (amount > supply){
sellPrice = getSellPrice(tokenId, supply);
}else{
sellPrice = getSellPrice(tokenId, amount);
}
}
uint256 feePercent = protocolFeePercent + socialIdFeePercent;
buyPriceWithFee = buyPrice * (ONE_PERCENT_PRECISION_MULTIPLIER * 100 + feePercent) / (ONE_PERCENT_PRECISION_MULTIPLIER * 100);
sellPriceWithFee = sellPrice * (ONE_PERCENT_PRECISION_MULTIPLIER * 100 - feePercent) / (ONE_PERCENT_PRECISION_MULTIPLIER * 100);
return (
tokenId,
buyPrice,
sellPrice,
buyPriceWithFee,
sellPriceWithFee,
supply
);
}
function addSocialPlatform(
uint32 platformId,
string calldata platformName
) public onlyOwner {
require(bytes(_platformNameById[platformId]).length == 0, "Social platform already set");
require(bytes(platformName).length > 0, "Platform name cannot be empty");
_platformNameById[platformId] = platformName;
}
function updateSocialOwnerAddressAndDisperse(
uint32 platformId,
uint256 platformUserId,
address socialIdOwnerAddr
) public onlyAdmin returns (uint256) {
uint256 tokenId = _getOrReleaseTokenId(platformId, platformUserId);
_socialIdOwners[tokenId] = socialIdOwnerAddr;
uint256 tokensToDisperse = _mintableToSocialIdOwner[tokenId];
uint256 ethToDisperse = _ethForSocialIdOwner[tokenId];
if (ethToDisperse > 0){
delete _ethForSocialIdOwner[tokenId];
}
if (tokensToDisperse > 0){
delete _mintableToSocialIdOwner[tokenId];
}
if (ethToDisperse > 0){
(bool success, ) = socialIdOwnerAddr.call{value: ethToDisperse}("");
require(success, "Unable to send funds");
}
if (tokensToDisperse > 0){
_mint(socialIdOwnerAddr, tokenId, tokensToDisperse, "");
}
emit SocialUserAddress(platformId, platformUserId, socialIdOwnerAddr);
return tokenId;
}
function DisperseEthToSocialIdOwner(
uint32 platformId,
uint256 platformUserId
) public onlyAdmin {
uint256 tokenId = _tokenIdBySocialId[platformId][platformUserId];
require (tokenId != 0, "Invalid social");
address socialIdOwnerAddr = _socialIdOwners[tokenId];
require(socialIdOwnerAddr != address(0), "Social id owner not set");
uint256 ethToDisperse = _ethForSocialIdOwner[tokenId];
if (ethToDisperse > 0){
delete _ethForSocialIdOwner[tokenId];
}
if (ethToDisperse > 0){
(bool success, ) = socialIdOwnerAddr.call{value: ethToDisperse}("");
require(success, "Unable to send funds");
}
}
function buySocialId(
address _to,
uint32 platformId,
uint256 platformUserId,
uint256 amount
)
public
payable
whenNotPaused
returns (
uint256 price,
uint256 protocolFeePaid,
uint256 socialIdFeePaid
)
{
uint256 tokenId = _getOrReleaseTokenId(platformId, platformUserId);
return buy(_to, tokenId, amount);
}
function sellSocialId(
address refundRecipient,
uint32 platformId,
uint256 platformUserId,
uint256 amount,
uint256 minExpectedPrice
)
public
whenNotPaused
returns (
uint256 price,
uint256 protocolFee,
uint256 subjectFee
)
{
uint256 tokenId = _tokenIdBySocialId[platformId][platformUserId];
require(tokenId > 0, "SocialId invalid or not released");
return sell(refundRecipient, tokenId, amount, minExpectedPrice);
}
function buy(
address _to,
uint256 tokenId,
uint256 amountToBuy
)
public
payable
whenNotPaused
returns (
uint256 price,
uint256 protocolFee,
uint256 socialIdFee
)
{
uint256 supply = _totalSupply[tokenId];
require(supply > 0, "Ticket not released");
require(amountToBuy > 0, "Minimum amount is 1");
price = getBuyPrice(tokenId, amountToBuy);
protocolFee = ((price * protocolFeePercent) / (ONE_PERCENT_PRECISION_MULTIPLIER * 100));
socialIdFee = ((price * socialIdFeePercent) / (ONE_PERCENT_PRECISION_MULTIPLIER * 100));
uint256 ethConsumed = price + protocolFee + socialIdFee;
require(
msg.value >= ethConsumed,
string.concat("Insufficient payment, need ", Strings.toString(ethConsumed), " wei")
);
uint256 ethLeft = msg.value - ethConsumed;
uint256 newSupply = _totalSupply[tokenId] += amountToBuy;
address _socialIdOwner = _socialIdOwners[tokenId];
if (_socialIdOwner == address(0)){
_ethForSocialIdOwner[tokenId] += socialIdFee;
}else{
(bool success2, ) = _socialIdOwner.call{value: socialIdFee}("");
if (!success2) {
_ethForSocialIdOwner[tokenId] += socialIdFee;
}
}
(bool success1, ) = protocolFeeDestination.call{value: protocolFee}("");
require(success1, "Unable to send funds (protocolFee)");
_mint(_to, tokenId, amountToBuy, "");
emit Buy(
msg.sender,
_to,
tokenId,
amountToBuy,
price,
protocolFee,
socialIdFee,
newSupply
);
if (ethLeft > 0) {
(bool success, ) = payable(msg.sender).call{value: ethLeft}("");
require(success, "Failed to refund excess Ether");
}
}
function sell(
address refundRecipient,
uint256 tokenId,
uint256 amount,
uint256 minExpectedPrice
)
public
whenNotPaused
returns (
uint256 price,
uint256 protocolFee,
uint256 socialIdFee
)
{
_canSellOrTransferPre(tokenId, amount);
price = getSellPrice(tokenId, amount);
protocolFee = ((price * protocolFeePercent) / (ONE_PERCENT_PRECISION_MULTIPLIER * 100));
socialIdFee = ((price * socialIdFeePercent) / (ONE_PERCENT_PRECISION_MULTIPLIER * 100));
price = price - protocolFee - socialIdFee;
require(price >= minExpectedPrice, "Slippage too high");
uint256 supply = _totalSupply[tokenId] -= amount;
_burn(msg.sender, tokenId, amount);
address _socialIdOwner = _socialIdOwners[tokenId];
if (_socialIdOwner == address(0)){
_ethForSocialIdOwner[tokenId] += socialIdFee;
}else{
(bool success2, ) = _socialIdOwner.call{value: socialIdFee}("");
if (!success2) {
_ethForSocialIdOwner[tokenId] += socialIdFee;
}
}
(bool success1, ) = refundRecipient.call{value: price }("");
require(success1, "Unable to send funds (feeRefund)");
(bool success3, ) = protocolFeeDestination.call{value: protocolFee}("");
require(success3, "Unable to send funds (protocolFee)");
emit Sell(
msg.sender,
refundRecipient,
tokenId,
amount,
price,
protocolFee,
socialIdFee,
supply
);
_canSellOrTransferPost(msg.sender, tokenId);
}
function safeTransferFrom(
address from,
address to,
uint256 id,
uint256 value,
bytes memory data
) public override whenNotPaused {
_canSellOrTransferPre(id, value);
super.safeTransferFrom(from, to, id, value, data);
_canSellOrTransferPost(from, id);
}
function safeBatchTransferFrom(
address from,
address to,
uint256[] memory ids,
uint256[] memory values,
bytes memory data
) public override whenNotPaused {
_canSellOrTransferPreBulk(ids, values);
super.safeBatchTransferFrom(from, to, ids, values, data);
for (uint256 i = 0; i < ids.length; i++) {
_canSellOrTransferPost(from, ids[i]);
}
}
function setApprovalForAll(address operator, bool approved) public override whenNotPaused {
super.setApprovalForAll(operator, approved);
}
function renounceOwnership() public view override onlyOwner {
revert("disabled");
}
function firstNTicketPrice(uint256 n) private pure returns (uint256) {
if (n <= 1) return 0;
n -= 1;
uint256 sumOfN = (n * (n + 1)) / 2;
uint256 sumOfNSquared = sumOfN * sumOfN;
return ((10000 * sumOfN + sumOfNSquared) * 1 ether) / PRICE_DENOMINATOR;
}
function ticketPrice(
uint256 startTicketNum,
uint256 endTicketNum
) private pure returns (uint256) {
if (endTicketNum < startTicketNum) return 0;
uint256 startTicketPriceBefore = startTicketNum == 0 ? 0 : firstNTicketPrice(startTicketNum - 1);
return firstNTicketPrice(endTicketNum) - startTicketPriceBefore;
}
function singleTicketPrice(
uint256 n
) private pure returns (uint256) {
if (n <= 1) return 0;
n -= 1;
return ((n * (10000 + n * n)) * 1 ether) / PRICE_DENOMINATOR;
}
function _getFee(uint256 price) internal view returns (uint256) {
return (price * (protocolFeePercent + socialIdFeePercent)) / (ONE_PERCENT_PRECISION_MULTIPLIER * 100);
}
function _getOrReleaseTokenId(uint32 platformId, uint256 platformUserId) internal returns (uint256) {
uint256 tokenId = _tokenIdBySocialId[platformId][platformUserId];
if (tokenId == 0){
tokenId = _release(platformId, platformUserId);
}
return tokenId;
}
function _canSellOrTransferPre(uint256 tokenId, uint256 amount) internal view {
require(_totalSupply[tokenId] > 0, "Ticket not released");
require(amount > 0, "Minimum amount is 1");
}
function _canSellOrTransferPreBulk(uint256[] memory tokenIds, uint256[] memory amounts) internal view {
for (uint256 i = 0; i < tokenIds.length; i++) {
require(_totalSupply[tokenIds[i]] > 0, "Ticket not released");
}
for(uint256 i = 0; i < amounts.length; i++) {
require(amounts[i] > 0, "Minimum amount is 1");
}
}
function _canSellOrTransferPost(address from, uint256 tokenId) internal view {
address socialIdOwner = _socialIdOwners[tokenId];
if (from == socialIdOwner) {
uint256 balance = balanceOf(from, tokenId);
require(balance >= SINGLE_TICKET_CHUNKS, "Cannot sell or transfer last ticket");
}
}
function _release(
uint32 platformId,
uint256 platformUserId
) internal returns (uint256) {
require(bytes(_platformNameById[platformId]).length > 0, "Invalid Social Platform");
require(_tokenIdBySocialId[platformId][platformUserId] == 0, "socialId has already been released");
uint256 count = _tokenIdCount += 1;
_tokenIdBySocialId[platformId][platformUserId] = count;
_totalSupply[count] += SINGLE_TICKET_CHUNKS;
_mintableToSocialIdOwner[count] = SINGLE_TICKET_CHUNKS;
emit Release(
platformId,
platformUserId,
count
);
return count;
}
}
文件 20 的 20:draft-IERC6093.sol
pragma solidity ^0.8.20;
interface IERC20Errors {
error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed);
error ERC20InvalidSender(address sender);
error ERC20InvalidReceiver(address receiver);
error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed);
error ERC20InvalidApprover(address approver);
error ERC20InvalidSpender(address spender);
}
interface IERC721Errors {
error ERC721InvalidOwner(address owner);
error ERC721NonexistentToken(uint256 tokenId);
error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner);
error ERC721InvalidSender(address sender);
error ERC721InvalidReceiver(address receiver);
error ERC721InsufficientApproval(address operator, uint256 tokenId);
error ERC721InvalidApprover(address approver);
error ERC721InvalidOperator(address operator);
}
interface IERC1155Errors {
error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId);
error ERC1155InvalidSender(address sender);
error ERC1155InvalidReceiver(address receiver);
error ERC1155MissingApprovalForAll(address operator, address owner);
error ERC1155InvalidApprover(address approver);
error ERC1155InvalidOperator(address operator);
error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength);
}
{
"compilationTarget": {
"contracts/Wildcard.sol": "Wildcard"
},
"evmVersion": "paris",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"string","name":"_metadataBaseUrlPrefix","type":"string"},{"internalType":"string","name":"_metadataBaseUrlSuffix","type":"string"},{"internalType":"string","name":"_contractMetadataUrl","type":"string"},{"internalType":"address","name":"_protocolFeeDestination","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ERC1155InsufficientBalance","type":"error"},{"inputs":[{"internalType":"address","name":"approver","type":"address"}],"name":"ERC1155InvalidApprover","type":"error"},{"inputs":[{"internalType":"uint256","name":"idsLength","type":"uint256"},{"internalType":"uint256","name":"valuesLength","type":"uint256"}],"name":"ERC1155InvalidArrayLength","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"ERC1155InvalidOperator","type":"error"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"ERC1155InvalidReceiver","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"ERC1155InvalidSender","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"address","name":"owner","type":"address"}],"name":"ERC1155MissingApprovalForAll","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[],"name":"WildCard_OnlyAdmin","type":"error"},{"inputs":[],"name":"WildCard__ContractIsPaused","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_fromTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_toTokenId","type":"uint256"}],"name":"BatchMetadataUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"txnFromAddr","type":"address"},{"indexed":true,"internalType":"address","name":"destinationAddr","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"price","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"protocolFeePaid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"socialIdFeePaid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newTotalSupply","type":"uint256"}],"name":"Buy","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":true,"internalType":"address","name":"destination","type":"address"}],"name":"Mint","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferStarted","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"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"oldValue","type":"uint32"},{"indexed":false,"internalType":"uint32","name":"newValue","type":"uint32"}],"name":"ProtocolFeePercentChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint32","name":"platformId","type":"uint32"},{"indexed":true,"internalType":"uint256","name":"platformUserId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Release","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"txnFromAddr","type":"address"},{"indexed":true,"internalType":"address","name":"destinationAddr","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"price","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"protocolFeePaid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"socialIdFeePaid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newTotalSupply","type":"uint256"}],"name":"Sell","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"oldValue","type":"uint32"},{"indexed":false,"internalType":"uint32","name":"newValue","type":"uint32"}],"name":"SocialIdFeePercentChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint32","name":"platformId","type":"uint32"},{"indexed":true,"internalType":"uint256","name":"platformUserId","type":"uint256"},{"indexed":true,"internalType":"address","name":"socialIdOwnerAddr","type":"address"}],"name":"SocialUserAddress","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"oldPauseState","type":"bool"},{"indexed":false,"internalType":"bool","name":"newPauseState","type":"bool"},{"indexed":false,"internalType":"address","name":"caller","type":"address"}],"name":"ToggledPause","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"values","type":"uint256[]"}],"name":"TransferBatch","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"TransferSingle","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"value","type":"string"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"URI","type":"event"},{"inputs":[{"internalType":"uint32","name":"platformId","type":"uint32"},{"internalType":"uint256","name":"platformUserId","type":"uint256"}],"name":"DisperseEthToSocialIdOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"ONE_PERCENT_PRECISION_MULTIPLIER","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PRICE_DENOMINATOR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SINGLE_TICKET_CHUNKS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TICKET_DECIMALS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"platformId","type":"uint32"},{"internalType":"string","name":"platformName","type":"string"}],"name":"addSocialPlatform","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"admin","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"accounts","type":"address[]"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"}],"name":"balanceOfBatch","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"amountToBuy","type":"uint256"}],"name":"buy","outputs":[{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"protocolFee","type":"uint256"},{"internalType":"uint256","name":"socialIdFee","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint32","name":"platformId","type":"uint32"},{"internalType":"uint256","name":"platformUserId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"buySocialId","outputs":[{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"protocolFeePaid","type":"uint256"},{"internalType":"uint256","name":"socialIdFeePaid","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"supply","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"calculatePrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"contractURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"getBuyPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"getBuyPriceAfterFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getReleaseSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"platformId","type":"uint32"},{"internalType":"uint256","name":"platformUserId","type":"uint256"}],"name":"getReleaseSupplyBySocialId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"getSellPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"getSellPriceAfterFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getSocialIdOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"platformId","type":"uint32"},{"internalType":"uint256","name":"platformUserId","type":"uint256"}],"name":"getSocialIdOwnerBySocialId","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"platformId","type":"uint32"},{"internalType":"uint256","name":"platformUserId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"getSocialIdPurchaseDetails","outputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"buyPrice","type":"uint256"},{"internalType":"uint256","name":"sellPrice","type":"uint256"},{"internalType":"uint256","name":"buyPriceWithFee","type":"uint256"},{"internalType":"uint256","name":"sellPriceWithFee","type":"uint256"},{"internalType":"uint256","name":"supply","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32[]","name":"platformIds","type":"uint32[]"},{"internalType":"uint256[]","name":"platformUserIds","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"name":"getSocialIdPurchaseDetailsBulk","outputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"},{"internalType":"uint256[]","name":"buyPrices","type":"uint256[]"},{"internalType":"uint256[]","name":"sellPrices","type":"uint256[]"},{"internalType":"uint256[]","name":"buyPricesWithFee","type":"uint256[]"},{"internalType":"uint256[]","name":"sellPricesWithFee","type":"uint256[]"},{"internalType":"uint256[]","name":"supplies","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"platformId","type":"uint32"},{"internalType":"uint256","name":"platformUserId","type":"uint256"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"name":"getSocialIdPurchaseDetailsMulti","outputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"},{"internalType":"uint256[]","name":"buyPrices","type":"uint256[]"},{"internalType":"uint256[]","name":"sellPrices","type":"uint256[]"},{"internalType":"uint256[]","name":"buyPricesWithFee","type":"uint256[]"},{"internalType":"uint256[]","name":"sellPricesWithFee","type":"uint256[]"},{"internalType":"uint256[]","name":"supplies","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"platformId","type":"uint32"}],"name":"getSocialPlatform","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"platformId","type":"uint32"},{"internalType":"uint256","name":"platformUserId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"getTicketBuyPriceAfterTaxBySocialId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"platformId","type":"uint32"},{"internalType":"uint256","name":"platformUserId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"getTicketBuyPriceBySocialId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"platformId","type":"uint32"},{"internalType":"uint256","name":"platformUserId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"getTicketSellPriceAfterTaxBySocialId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"platformId","type":"uint32"},{"internalType":"uint256","name":"platformUserId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"getTicketSellPriceBySocialId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"platformId","type":"uint32"},{"internalType":"uint256","name":"platformUserId","type":"uint256"}],"name":"getTokenIdBySocialId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"protocolFeeDestination","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"protocolFeePercent","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"values","type":"uint256[]"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeBatchTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"refundRecipient","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"minExpectedPrice","type":"uint256"}],"name":"sell","outputs":[{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"protocolFee","type":"uint256"},{"internalType":"uint256","name":"socialIdFee","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"refundRecipient","type":"address"},{"internalType":"uint32","name":"platformId","type":"uint32"},{"internalType":"uint256","name":"platformUserId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"minExpectedPrice","type":"uint256"}],"name":"sellSocialId","outputs":[{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"protocolFee","type":"uint256"},{"internalType":"uint256","name":"subjectFee","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newAddress","type":"address"}],"name":"setAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"newValue","type":"string"}],"name":"setContractMetadataUrl","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"newValue","type":"string"}],"name":"setMetadataBaseUrlPrefix","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"newValue","type":"string"}],"name":"setMetadataBaseUrlSuffix","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"state","type":"bool"}],"name":"setPause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newAddress","type":"address"}],"name":"setProtocolFeeDestination","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"newValue","type":"uint32"}],"name":"setProtocolFeePercent","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"newValue","type":"uint32"}],"name":"setSocialIdFeePercent","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"socialIdFeePercent","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"platformId","type":"uint32"},{"internalType":"uint256","name":"platformUserId","type":"uint256"},{"internalType":"address","name":"socialIdOwnerAddr","type":"address"}],"name":"updateSocialOwnerAddressAndDisperse","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"uri","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"}]