编译器
0.8.12+commit.f00d7308
文件 1 的 50:ARBID.sol
pragma solidity >=0.8.4;
interface ARBID {
event NewOwner(bytes32 indexed node, bytes32 indexed label, address owner);
event Transfer(bytes32 indexed node, address owner);
event NewResolver(bytes32 indexed node, address resolver);
event NewTTL(bytes32 indexed node, uint64 ttl);
event ApprovalForAll(
address indexed owner,
address indexed operator,
bool approved
);
function setRecord(
bytes32 node,
address owner,
address resolver,
uint64 ttl
) external;
function setSubnodeRecord(
bytes32 node,
bytes32 label,
address owner,
address resolver,
uint64 ttl
) external;
function setSubnodeOwner(
bytes32 node,
bytes32 label,
address owner
) external returns (bytes32);
function setResolver(bytes32 node, address resolver) external;
function setOwner(bytes32 node, address owner) external;
function setTTL(bytes32 node, uint64 ttl) external;
function setApprovalForAll(address operator, bool approved) external;
function owner(bytes32 node) external view returns (address);
function resolver(bytes32 node) external view returns (address);
function ttl(bytes32 node) external view returns (uint64);
function recordExists(bytes32 node) external view returns (bool);
function isApprovedForAll(address owner, address operator)
external
view
returns (bool);
}
文件 2 的 50:ARBRegistrarControllerV6.sol
pragma solidity >=0.8.4;
import "../price-oracle/ISidPriceOracle.sol";
import "../giftcard/SidGiftCardLedger.sol";
import {BaseRegistrarImplementation} from "./BaseRegistrarImplementation.sol";
import {StringUtils} from "../common/StringUtils.sol";
import {Resolver} from "../resolvers/Resolver.sol";
import {IARBRegistrarControllerV3, ISidPriceOracle} from "./IARBRegistrarControllerV3.sol";
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
import {Address} from "@openzeppelin/contracts/utils/Address.sol";
import {ReentrancyGuard} from "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import {ReferralInfo} from "../struct/SidStruct.sol";
import {RegInfo} from "../struct/SidStruct.sol";
import {ReferralHub} from "../referral/ReferralHub.sol";
import {ReferralVerifier} from "../referral/ReferralVerifier.sol";
error CommitmentTooNew(bytes32 commitment);
error CommitmentTooOld(bytes32 commitment);
error NameNotAvailable(string name);
error DurationTooShort(uint256 duration);
error ResolverRequiredWhenDataSupplied();
error UnexpiredCommitmentExists(bytes32 commitment);
error InsufficientValue();
error Unauthorised(bytes32 node);
error MaxCommitmentAgeTooLow();
error MaxCommitmentAgeTooHigh();
error InvalidOwner(address owner);
contract ARBRegistrarControllerV6 is Ownable, IERC165, ReentrancyGuard {
using StringUtils for *;
using Address for address;
uint256 public constant MIN_REGISTRATION_DURATION = 365 days;
uint256 private constant COIN_TYPE_ARB1 = 2147525809;
uint256 private constant COIN_TYPE_ARB_NOVA = 2147525818;
BaseRegistrarImplementation immutable base;
ISidPriceOracle public immutable prices;
uint256 public immutable minCommitmentAge;
uint256 public immutable maxCommitmentAge;
SidGiftCardLedger public immutable giftCardLedger;
ReferralHub public immutable referralHub;
ReferralVerifier public immutable referralVerifier;
address public beneficiary;
mapping(bytes32 => uint256) public commitments;
event NameRegistered(
string name,
bytes32 indexed label,
address indexed owner,
uint256 baseCost,
uint256 premium,
uint256 expires
);
event NameRenewed(
string name,
bytes32 indexed label,
uint256 cost,
uint256 expires
);
constructor(
BaseRegistrarImplementation _base,
ISidPriceOracle _prices,
SidGiftCardLedger _giftCardLedger,
ReferralHub _referralHub,
ReferralVerifier _referralVerifier,
address _beneficiary,
uint256 _minCommitmentAge,
uint256 _maxCommitmentAge
) {
if (_maxCommitmentAge <= _minCommitmentAge) {
revert MaxCommitmentAgeTooLow();
}
if (_maxCommitmentAge > block.timestamp) {
revert MaxCommitmentAgeTooHigh();
}
require(_beneficiary != address(0));
base = _base;
prices = _prices;
giftCardLedger = _giftCardLedger;
beneficiary = _beneficiary;
minCommitmentAge = _minCommitmentAge;
maxCommitmentAge = _maxCommitmentAge;
referralHub = _referralHub;
referralVerifier = _referralVerifier;
}
function rentPrice(
string calldata name,
uint256 duration
) public view returns (ISidPriceOracle.Price memory price) {
bytes32 label = keccak256(bytes(name));
price = prices.domain(name, base.nameExpires(uint256(label)), duration);
}
function rentPrice(
string calldata name,
uint256 duration,
address registerAddress
) public view returns (ISidPriceOracle.Price memory price) {
bytes32 label = keccak256(bytes(name));
price = prices.domainWithPoint(
name,
base.nameExpires(uint256(label)),
duration,
registerAddress
);
}
function valid(string calldata name) public pure returns (bool) {
if (name.strlen() < 3) {
return false;
}
bytes memory nb = bytes(name);
for (uint256 i; i < nb.length - 2; i++) {
if (bytes1(nb[i]) == 0xe2 && bytes1(nb[i + 1]) == 0x80) {
if (
bytes1(nb[i + 2]) == 0x8b ||
bytes1(nb[i + 2]) == 0x8c ||
bytes1(nb[i + 2]) == 0x8d
) {
return false;
}
} else if (bytes1(nb[i]) == 0xef) {
if (bytes1(nb[i + 1]) == 0xbb && bytes1(nb[i + 2]) == 0xbf)
return false;
}
}
return true;
}
function available(string calldata name) public view returns (bool) {
bytes32 label = keccak256(bytes(name));
return valid(name) && base.available(uint256(label));
}
function makeCommitment(
string calldata name,
address owner,
bytes32 secret
) public pure returns (bytes32) {
bytes32 label = keccak256(bytes(name));
return keccak256(abi.encodePacked(label, owner, secret));
}
function commit(bytes32 commitment) public {
if (commitments[commitment] + maxCommitmentAge >= block.timestamp) {
revert UnexpiredCommitmentExists(commitment);
}
commitments[commitment] = block.timestamp;
}
function registerWithConfigAndPoint(
string calldata name,
address owner,
uint duration,
bytes32 secret,
address resolver,
bool isUsePoints,
ReferralInfo memory referralInfo
) external payable {
uint256 cost = _registerWithConfigAndPoint(
name,
RegInfo(owner, duration, secret, resolver, isUsePoints, msg.value),
referralInfo
);
if (msg.value > cost) {
(bool sent, ) = msg.sender.call{value: msg.value - cost}("");
require(sent, "Failed to send Ether");
}
}
function _registerWithConfigAndPoint(
string calldata name,
RegInfo memory regInfo,
ReferralInfo memory referralInfo
) internal nonReentrant returns (uint256 cost) {
ISidPriceOracle.Price memory price;
if (regInfo.isUsePoints) {
price = rentPrice(name, regInfo.duration, msg.sender);
giftCardLedger.deduct(msg.sender, price.usedPoint);
} else {
price = rentPrice(name, regInfo.duration);
}
if (regInfo.paidFee < price.base + price.premium) {
revert InsufficientValue();
}
if (regInfo.owner == address(0)) {
revert InvalidOwner(regInfo.owner);
}
_consumeCommitment(
name,
regInfo.duration,
makeCommitment(name, regInfo.owner, regInfo.secret)
);
bytes32 label = keccak256(bytes(name));
uint256 tokenId = uint256(label);
uint256 expires = base.register(
tokenId,
address(this),
regInfo.duration
);
bytes32 nodehash = keccak256(abi.encodePacked(base.baseNode(), label));
base.arbid().setResolver(nodehash, regInfo.resolver);
if (regInfo.owner != address(0)) {
Resolver(regInfo.resolver).setAddr(
nodehash,
COIN_TYPE_ARB1,
regInfo.owner
);
Resolver(regInfo.resolver).setAddr(
nodehash,
COIN_TYPE_ARB_NOVA,
regInfo.owner
);
}
base.reclaim(tokenId, regInfo.owner);
base.transferFrom(address(this), regInfo.owner, tokenId);
emit NameRegistered(
name,
keccak256(bytes(name)),
regInfo.owner,
price.base,
price.premium,
expires
);
cost = price.base + price.premium;
if (referralInfo.referrerAddress != address(0)) {
cost = _handleReferral(
cost,
referralInfo.referrerAddress,
referralInfo.referrerNodehash,
referralInfo.referralAmount,
referralInfo.signedAt,
referralInfo.signature
);
}
return cost;
}
function registerWithConfig(
string calldata name,
address owner,
uint256 duration,
bytes32 secret,
address resolver
) public payable {
uint256 cost = _registerWithConfigAndPoint(
name,
RegInfo(owner, duration, secret, resolver, false, msg.value),
ReferralInfo(address(0), bytes32(0), 0, 0, bytes(""))
);
if (msg.value > cost) {
(bool sent, ) = msg.sender.call{value: msg.value - cost}("");
require(sent, "Failed to send Ether");
}
}
function renew(string calldata name, uint duration) external payable {
uint256 cost = _renewWithPoint(name, duration, false, msg.value);
if (msg.value > cost) {
(bool sent, ) = msg.sender.call{value: msg.value - cost}("");
require(sent, "Failed to send Ether");
}
}
function renewWithPoint(
string calldata name,
uint duration,
bool isUsePoints
) external payable {
uint256 cost = _renewWithPoint(name, duration, isUsePoints, msg.value);
if (msg.value > cost) {
(bool sent, ) = msg.sender.call{value: msg.value - cost}("");
require(sent, "Failed to send Ether");
}
}
function _renewWithPoint(
string calldata name,
uint duration,
bool isUsePoints,
uint256 paid
) internal nonReentrant returns (uint256 cost) {
ISidPriceOracle.Price memory price;
if (isUsePoints) {
price = rentPrice(name, duration, msg.sender);
giftCardLedger.deduct(msg.sender, price.usedPoint);
} else {
price = rentPrice(name, duration);
}
cost = (price.base + price.premium);
require(paid >= cost);
bytes32 label = keccak256(bytes(name));
uint expires = base.renew(uint256(label), duration);
emit NameRenewed(name, label, cost, expires);
return cost;
}
function withdraw() public onlyOwner nonReentrant {
(bool sent, ) = beneficiary.call{value: address(this).balance}("");
require(sent, "Failed to send Ether");
}
function supportsInterface(
bytes4 interfaceID
) external pure returns (bool) {
return
interfaceID == type(IERC165).interfaceId ||
interfaceID == type(IARBRegistrarControllerV3).interfaceId;
}
function _consumeCommitment(
string calldata name,
uint256 duration,
bytes32 commitment
) internal {
if (commitments[commitment] + minCommitmentAge > block.timestamp) {
revert CommitmentTooNew(commitment);
}
if (commitments[commitment] + maxCommitmentAge <= block.timestamp) {
revert CommitmentTooOld(commitment);
}
if (!available(name)) {
revert NameNotAvailable(name);
}
delete (commitments[commitment]);
if (duration < MIN_REGISTRATION_DURATION) {
revert DurationTooShort(duration);
}
}
function bulkMakeCommitmentWithConfig(
string[] calldata name,
address owner,
bytes32 secret
) public pure returns (bytes32[] memory newCommitments) {
newCommitments = new bytes32[](name.length);
for (uint256 i = 0; i < name.length; i++) {
newCommitments[i] = makeCommitment(name[i], owner, secret);
}
return newCommitments;
}
function bulkCommit(bytes32[] calldata newCommitments) external {
for (uint256 i = 0; i < newCommitments.length; i++) {
commit(newCommitments[i]);
}
}
function bulkRentPrice(
string[] calldata names,
uint256 duration
) public view returns (uint256 total) {
for (uint256 i = 0; i < names.length; i++) {
ISidPriceOracle.Price memory price = rentPrice(names[i], duration);
total += (price.base + price.premium);
}
}
function bulkRegister(
string[] calldata names,
address owner,
uint duration,
bytes32 secret,
address resolver,
bool isUseGiftCard,
ReferralInfo memory referralInfo
) external payable {
uint256 unspent = msg.value;
for (uint256 i = 0; i < names.length; i++) {
uint256 cost = _registerWithConfigAndPoint(
names[i],
RegInfo(
owner,
duration,
secret,
resolver,
isUseGiftCard,
unspent
),
referralInfo
);
unspent -= cost;
}
if (unspent > 0) {
(bool sent, ) = msg.sender.call{value: unspent}("");
require(sent, "Failed to send Ether");
}
}
function _handleReferral(
uint cost,
address referrerAddress,
bytes32 referrerNodehash,
uint256 referralAmount,
uint256 signedAt,
bytes memory signature
) internal returns (uint) {
require(
referralVerifier.verifyReferral(
referrerAddress,
referrerNodehash,
referralAmount,
signedAt,
signature
),
"Invalid referral signature"
);
uint256 referrerFee = 0;
uint256 refereeFee = 0;
if (referralHub.isPartner(referrerNodehash)) {
(referrerFee, refereeFee) = referralHub.getReferralCommisionFee(
cost,
referrerNodehash
);
} else {
(referrerFee, refereeFee) = referralVerifier
.getReferralCommisionFee(cost, referralAmount);
}
referralHub.addNewReferralRecord(referrerNodehash);
if (referrerFee > 0) {
referralHub.deposit{value: referrerFee}(referrerAddress);
}
return cost - refereeFee;
}
}
文件 3 的 50:AddrResolver.sol
pragma solidity >=0.8.4;
import "../ResolverBase.sol";
import "./IAddrResolver.sol";
import "./IAddressResolver.sol";
abstract contract AddrResolver is IAddrResolver, IAddressResolver, ResolverBase {
uint256 constant private COIN_TYPE_ARB1 = 2147525809;
uint256 constant private COIN_TYPE_ARB_NOVA = 2147525809;
mapping(bytes32=>mapping(uint=>bytes)) _addresses;
function setAddr(bytes32 node, address a) virtual external authorised(node) {
setAddr(node, COIN_TYPE_ARB1, addressToBytes(a));
}
function setAddr(bytes32 node, uint coinType, address a) virtual external authorised(node) {
setAddr(node, coinType, addressToBytes(a));
}
function addr(bytes32 node) virtual override public view returns (address payable) {
bytes memory a = addr(node, COIN_TYPE_ARB1);
if(a.length == 0) {
return payable(0);
}
return bytesToAddress(a);
}
function setAddr(bytes32 node, uint coinType, bytes memory a) virtual public authorised(node) {
emit AddressChanged(node, coinType, a);
_addresses[node][coinType] = a;
}
function addr(bytes32 node, uint coinType) virtual override public view returns(bytes memory) {
return _addresses[node][coinType];
}
function supportsInterface(bytes4 interfaceID) virtual override public pure returns(bool) {
return interfaceID == type(IAddrResolver).interfaceId || interfaceID == type(IAddressResolver).interfaceId || super.supportsInterface(interfaceID);
}
function bytesToAddress(bytes memory b) internal pure returns(address payable a) {
require(b.length == 20);
assembly {
a := div(mload(add(b, 32)), exp(256, 12))
}
}
function addressToBytes(address a) internal pure returns(bytes memory b) {
b = new bytes(20);
assembly {
mstore(add(b, 32), mul(a, exp(256, 12)))
}
}
}
文件 4 的 50:Address.sol
pragma solidity ^0.8.0;
library Address {
function isContract(address account) internal view returns (bool) {
uint256 size;
assembly {
size := extcodesize(account)
}
return size > 0;
}
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCall(target, data, "Address: low-level call failed");
}
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
function functionCallWithValue(
address target,
bytes memory data,
uint256 value
) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
require(isContract(target), "Address: call to non-contract");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResult(success, returndata, errorMessage);
}
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
require(isContract(target), "Address: static call to non-contract");
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResult(success, returndata, errorMessage);
}
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
require(isContract(target), "Address: delegate call to non-contract");
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResult(success, returndata, errorMessage);
}
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
if (returndata.length > 0) {
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}
文件 5 的 50:BaseRegistrarImplementation.sol
pragma solidity >=0.8.4;
import "../registry/ARBID.sol";
import "./IBaseRegistrar.sol";
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/Strings.sol";
contract BaseRegistrarImplementation is ERC721, IBaseRegistrar, Ownable {
mapping(uint256 => uint) expiries;
ARBID public arbid;
bytes32 public baseNode;
mapping(address => bool) public controllers;
uint256 public constant GRACE_PERIOD = 90 days;
bytes4 private constant INTERFACE_META_ID = bytes4(keccak256("supportsInterface(bytes4)"));
bytes4 private constant ERC721_ID =
bytes4(
keccak256("balanceOf(address)") ^
keccak256("ownerOf(uint256)") ^
keccak256("approve(address,uint256)") ^
keccak256("getApproved(uint256)") ^
keccak256("setApprovalForAll(address,bool)") ^
keccak256("isApprovedForAll(address,address)") ^
keccak256("transferFrom(address,address,uint256)") ^
keccak256("safeTransferFrom(address,address,uint256)") ^
keccak256("safeTransferFrom(address,address,uint256,bytes)")
);
bytes4 private constant RECLAIM_ID = bytes4(keccak256("reclaim(uint256,address)"));
string public baseUri;
uint256 supplyAmount = 0;
function _isApprovedOrOwner(address spender, uint256 tokenId) internal view override returns (bool) {
address owner = ownerOf(tokenId);
return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender));
}
constructor(ARBID _arbid, bytes32 _baseNode) ERC721("SPACE ID .arb Name", "SIDARB ") {
arbid = _arbid;
baseNode = _baseNode;
}
modifier live() {
require(arbid.owner(baseNode) == address(this));
_;
}
modifier onlyController() {
require(controllers[msg.sender]);
_;
}
function totalSupply() external view returns (uint256) {
return supplyAmount;
}
function _mint(address _to, uint256 _tokenId) internal virtual override {
super._mint(_to, _tokenId);
supplyAmount = supplyAmount + 1;
}
function _burn(uint256 _tokenId) internal virtual override {
super._burn(_tokenId);
supplyAmount = supplyAmount - 1;
}
function transferFrom(
address from,
address to,
uint256 tokenId
) public override(ERC721, IERC721) {
require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not approved or owner");
_transfer(from, to, tokenId);
arbid.setSubnodeOwner(baseNode, bytes32(tokenId), to);
}
function safeTransferFrom(
address from,
address to,
uint256 tokenId,
bytes memory _data
) public override(ERC721, IERC721) {
require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not approved or owner");
_safeTransfer(from, to, tokenId, _data);
arbid.setSubnodeOwner(baseNode, bytes32(tokenId), to);
}
function ownerOf(uint256 tokenId) public view override(IERC721, ERC721) returns (address) {
require(expiries[tokenId] > block.timestamp);
return super.ownerOf(tokenId);
}
function addController(address controller) external override onlyOwner {
require(controller != address(0), "address can not be zero!");
controllers[controller] = true;
emit ControllerAdded(controller);
}
function removeController(address controller) external override onlyOwner {
require(controller != address(0), "address can not be zero!");
controllers[controller] = false;
emit ControllerRemoved(controller);
}
function setResolver(address resolver) external override onlyOwner {
arbid.setResolver(baseNode, resolver);
}
function nameExpires(uint256 id) public view override returns (uint) {
return expiries[id];
}
function available(uint256 id) public view override returns (bool) {
return expiries[id] + GRACE_PERIOD < block.timestamp;
}
function register(
uint256 id,
address owner,
uint duration
) external override returns (uint) {
return _register(id, owner, duration, true);
}
function registerOnly(
uint256 id,
address owner,
uint duration
) external returns (uint) {
return _register(id, owner, duration, false);
}
function _register(
uint256 id,
address owner,
uint duration,
bool updateRegistry
) internal live onlyController returns (uint) {
require(available(id));
require(block.timestamp + duration + GRACE_PERIOD > block.timestamp + GRACE_PERIOD);
expiries[id] = block.timestamp + duration;
if (_exists(id)) {
_burn(id);
}
_mint(owner, id);
if (updateRegistry) {
arbid.setSubnodeOwner(baseNode, bytes32(id), owner);
}
emit NameRegistered(id, owner, block.timestamp + duration);
return block.timestamp + duration;
}
function renew(uint256 id, uint duration) external override live onlyController returns (uint) {
require(expiries[id] + GRACE_PERIOD >= block.timestamp);
require(expiries[id] + duration + GRACE_PERIOD > duration + GRACE_PERIOD);
expiries[id] += duration;
emit NameRenewed(id, expiries[id]);
return expiries[id];
}
function reclaim(uint256 id, address owner) external override live {
require(_isApprovedOrOwner(msg.sender, id));
arbid.setSubnodeOwner(baseNode, bytes32(id), owner);
}
function supportsInterface(bytes4 interfaceID) public view override(ERC721, IERC165) returns (bool) {
return interfaceID == INTERFACE_META_ID || interfaceID == ERC721_ID || interfaceID == RECLAIM_ID;
}
function setURI(string memory newURI) external onlyOwner {
baseUri = newURI;
}
function tokenURI(uint256 tokenId) public view override returns (string memory) {
require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");
string memory baseURI = baseUri;
return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, Strings.toString(tokenId))) : "";
}
}
文件 6 的 50: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;
}
}
文件 7 的 50:ECDSA.sol
pragma solidity ^0.8.0;
import "../Strings.sol";
library ECDSA {
enum RecoverError {
NoError,
InvalidSignature,
InvalidSignatureLength,
InvalidSignatureS,
InvalidSignatureV
}
function _throwError(RecoverError error) private pure {
if (error == RecoverError.NoError) {
return;
} else if (error == RecoverError.InvalidSignature) {
revert("ECDSA: invalid signature");
} else if (error == RecoverError.InvalidSignatureLength) {
revert("ECDSA: invalid signature length");
} else if (error == RecoverError.InvalidSignatureS) {
revert("ECDSA: invalid signature 's' value");
} else if (error == RecoverError.InvalidSignatureV) {
revert("ECDSA: invalid signature 'v' value");
}
}
function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {
if (signature.length == 65) {
bytes32 r;
bytes32 s;
uint8 v;
assembly {
r := mload(add(signature, 0x20))
s := mload(add(signature, 0x40))
v := byte(0, mload(add(signature, 0x60)))
}
return tryRecover(hash, v, r, s);
} else if (signature.length == 64) {
bytes32 r;
bytes32 vs;
assembly {
r := mload(add(signature, 0x20))
vs := mload(add(signature, 0x40))
}
return tryRecover(hash, r, vs);
} else {
return (address(0), RecoverError.InvalidSignatureLength);
}
}
function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {
(address recovered, RecoverError error) = tryRecover(hash, signature);
_throwError(error);
return recovered;
}
function tryRecover(
bytes32 hash,
bytes32 r,
bytes32 vs
) internal pure returns (address, RecoverError) {
bytes32 s;
uint8 v;
assembly {
s := and(vs, 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
v := add(shr(255, vs), 27)
}
return tryRecover(hash, v, r, s);
}
function recover(
bytes32 hash,
bytes32 r,
bytes32 vs
) internal pure returns (address) {
(address recovered, RecoverError error) = tryRecover(hash, r, vs);
_throwError(error);
return recovered;
}
function tryRecover(
bytes32 hash,
uint8 v,
bytes32 r,
bytes32 s
) internal pure returns (address, RecoverError) {
if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {
return (address(0), RecoverError.InvalidSignatureS);
}
if (v != 27 && v != 28) {
return (address(0), RecoverError.InvalidSignatureV);
}
address signer = ecrecover(hash, v, r, s);
if (signer == address(0)) {
return (address(0), RecoverError.InvalidSignature);
}
return (signer, RecoverError.NoError);
}
function recover(
bytes32 hash,
uint8 v,
bytes32 r,
bytes32 s
) internal pure returns (address) {
(address recovered, RecoverError error) = tryRecover(hash, v, r, s);
_throwError(error);
return recovered;
}
function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {
return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash));
}
function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {
return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", Strings.toString(s.length), s));
}
function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {
return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash));
}
}
文件 8 的 50:ERC1155.sol
pragma solidity ^0.8.0;
import "./IERC1155.sol";
import "./IERC1155Receiver.sol";
import "./extensions/IERC1155MetadataURI.sol";
import "../../utils/Address.sol";
import "../../utils/Context.sol";
import "../../utils/introspection/ERC165.sol";
contract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {
using Address for address;
mapping(uint256 => mapping(address => uint256)) private _balances;
mapping(address => mapping(address => 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 override returns (string memory) {
return _uri;
}
function balanceOf(address account, uint256 id) public view virtual override returns (uint256) {
require(account != address(0), "ERC1155: balance query for the zero address");
return _balances[id][account];
}
function balanceOfBatch(address[] memory accounts, uint256[] memory ids)
public
view
virtual
override
returns (uint256[] memory)
{
require(accounts.length == ids.length, "ERC1155: accounts and ids length mismatch");
uint256[] memory batchBalances = new uint256[](accounts.length);
for (uint256 i = 0; i < accounts.length; ++i) {
batchBalances[i] = balanceOf(accounts[i], ids[i]);
}
return batchBalances;
}
function setApprovalForAll(address operator, bool approved) public virtual override {
_setApprovalForAll(_msgSender(), operator, approved);
}
function isApprovedForAll(address account, address operator) public view virtual override returns (bool) {
return _operatorApprovals[account][operator];
}
function safeTransferFrom(
address from,
address to,
uint256 id,
uint256 amount,
bytes memory data
) public virtual override {
require(
from == _msgSender() || isApprovedForAll(from, _msgSender()),
"ERC1155: caller is not owner nor approved"
);
_safeTransferFrom(from, to, id, amount, data);
}
function safeBatchTransferFrom(
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) public virtual override {
require(
from == _msgSender() || isApprovedForAll(from, _msgSender()),
"ERC1155: transfer caller is not owner nor approved"
);
_safeBatchTransferFrom(from, to, ids, amounts, data);
}
function _safeTransferFrom(
address from,
address to,
uint256 id,
uint256 amount,
bytes memory data
) internal virtual {
require(to != address(0), "ERC1155: transfer to the zero address");
address operator = _msgSender();
_beforeTokenTransfer(operator, from, to, _asSingletonArray(id), _asSingletonArray(amount), data);
uint256 fromBalance = _balances[id][from];
require(fromBalance >= amount, "ERC1155: insufficient balance for transfer");
unchecked {
_balances[id][from] = fromBalance - amount;
}
_balances[id][to] += amount;
emit TransferSingle(operator, from, to, id, amount);
_doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);
}
function _safeBatchTransferFrom(
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) internal virtual {
require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");
require(to != address(0), "ERC1155: transfer to the zero address");
address operator = _msgSender();
_beforeTokenTransfer(operator, from, to, ids, amounts, data);
for (uint256 i = 0; i < ids.length; ++i) {
uint256 id = ids[i];
uint256 amount = amounts[i];
uint256 fromBalance = _balances[id][from];
require(fromBalance >= amount, "ERC1155: insufficient balance for transfer");
unchecked {
_balances[id][from] = fromBalance - amount;
}
_balances[id][to] += amount;
}
emit TransferBatch(operator, from, to, ids, amounts);
_doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data);
}
function _setURI(string memory newuri) internal virtual {
_uri = newuri;
}
function _mint(
address to,
uint256 id,
uint256 amount,
bytes memory data
) internal virtual {
require(to != address(0), "ERC1155: mint to the zero address");
address operator = _msgSender();
_beforeTokenTransfer(operator, address(0), to, _asSingletonArray(id), _asSingletonArray(amount), data);
_balances[id][to] += amount;
emit TransferSingle(operator, address(0), to, id, amount);
_doSafeTransferAcceptanceCheck(operator, address(0), to, id, amount, data);
}
function _mintBatch(
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) internal virtual {
require(to != address(0), "ERC1155: mint to the zero address");
require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");
address operator = _msgSender();
_beforeTokenTransfer(operator, address(0), to, ids, amounts, data);
for (uint256 i = 0; i < ids.length; i++) {
_balances[ids[i]][to] += amounts[i];
}
emit TransferBatch(operator, address(0), to, ids, amounts);
_doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);
}
function _burn(
address from,
uint256 id,
uint256 amount
) internal virtual {
require(from != address(0), "ERC1155: burn from the zero address");
address operator = _msgSender();
_beforeTokenTransfer(operator, from, address(0), _asSingletonArray(id), _asSingletonArray(amount), "");
uint256 fromBalance = _balances[id][from];
require(fromBalance >= amount, "ERC1155: burn amount exceeds balance");
unchecked {
_balances[id][from] = fromBalance - amount;
}
emit TransferSingle(operator, from, address(0), id, amount);
}
function _burnBatch(
address from,
uint256[] memory ids,
uint256[] memory amounts
) internal virtual {
require(from != address(0), "ERC1155: burn from the zero address");
require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");
address operator = _msgSender();
_beforeTokenTransfer(operator, from, address(0), ids, amounts, "");
for (uint256 i = 0; i < ids.length; i++) {
uint256 id = ids[i];
uint256 amount = amounts[i];
uint256 fromBalance = _balances[id][from];
require(fromBalance >= amount, "ERC1155: burn amount exceeds balance");
unchecked {
_balances[id][from] = fromBalance - amount;
}
}
emit TransferBatch(operator, from, address(0), ids, amounts);
}
function _setApprovalForAll(
address owner,
address operator,
bool approved
) internal virtual {
require(owner != operator, "ERC1155: setting approval status for self");
_operatorApprovals[owner][operator] = approved;
emit ApprovalForAll(owner, operator, approved);
}
function _beforeTokenTransfer(
address operator,
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) internal virtual {}
function _doSafeTransferAcceptanceCheck(
address operator,
address from,
address to,
uint256 id,
uint256 amount,
bytes memory data
) private {
if (to.isContract()) {
try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {
if (response != IERC1155Receiver.onERC1155Received.selector) {
revert("ERC1155: ERC1155Receiver rejected tokens");
}
} catch Error(string memory reason) {
revert(reason);
} catch {
revert("ERC1155: transfer to non ERC1155Receiver implementer");
}
}
}
function _doSafeBatchTransferAcceptanceCheck(
address operator,
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) private {
if (to.isContract()) {
try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (
bytes4 response
) {
if (response != IERC1155Receiver.onERC1155BatchReceived.selector) {
revert("ERC1155: ERC1155Receiver rejected tokens");
}
} catch Error(string memory reason) {
revert(reason);
} catch {
revert("ERC1155: transfer to non ERC1155Receiver implementer");
}
}
}
function _asSingletonArray(uint256 element) private pure returns (uint256[] memory) {
uint256[] memory array = new uint256[](1);
array[0] = element;
return array;
}
}
文件 9 的 50:ERC165.sol
pragma solidity ^0.8.0;
import "./IERC165.sol";
abstract contract ERC165 is IERC165 {
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}
文件 10 的 50:ERC721.sol
pragma solidity ^0.8.0;
import "./IERC721.sol";
import "./IERC721Receiver.sol";
import "./extensions/IERC721Metadata.sol";
import "../../utils/Address.sol";
import "../../utils/Context.sol";
import "../../utils/Strings.sol";
import "../../utils/introspection/ERC165.sol";
contract ERC721 is Context, ERC165, IERC721, IERC721Metadata {
using Address for address;
using Strings for uint256;
string private _name;
string private _symbol;
mapping(uint256 => address) private _owners;
mapping(address => uint256) private _balances;
mapping(uint256 => address) private _tokenApprovals;
mapping(address => mapping(address => bool)) private _operatorApprovals;
constructor(string memory name_, string memory symbol_) {
_name = name_;
_symbol = symbol_;
}
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
return
interfaceId == type(IERC721).interfaceId ||
interfaceId == type(IERC721Metadata).interfaceId ||
super.supportsInterface(interfaceId);
}
function balanceOf(address owner) public view virtual override returns (uint256) {
require(owner != address(0), "ERC721: balance query for the zero address");
return _balances[owner];
}
function ownerOf(uint256 tokenId) public view virtual override returns (address) {
address owner = _owners[tokenId];
require(owner != address(0), "ERC721: owner query for nonexistent token");
return owner;
}
function name() public view virtual override returns (string memory) {
return _name;
}
function symbol() public view virtual override returns (string memory) {
return _symbol;
}
function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");
string memory baseURI = _baseURI();
return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : "";
}
function _baseURI() internal view virtual returns (string memory) {
return "";
}
function approve(address to, uint256 tokenId) public virtual override {
address owner = ERC721.ownerOf(tokenId);
require(to != owner, "ERC721: approval to current owner");
require(
_msgSender() == owner || isApprovedForAll(owner, _msgSender()),
"ERC721: approve caller is not owner nor approved for all"
);
_approve(to, tokenId);
}
function getApproved(uint256 tokenId) public view virtual override returns (address) {
require(_exists(tokenId), "ERC721: approved query for nonexistent token");
return _tokenApprovals[tokenId];
}
function setApprovalForAll(address operator, bool approved) public virtual override {
_setApprovalForAll(_msgSender(), operator, approved);
}
function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {
return _operatorApprovals[owner][operator];
}
function transferFrom(
address from,
address to,
uint256 tokenId
) public virtual override {
require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");
_transfer(from, to, tokenId);
}
function safeTransferFrom(
address from,
address to,
uint256 tokenId
) public virtual override {
safeTransferFrom(from, to, tokenId, "");
}
function safeTransferFrom(
address from,
address to,
uint256 tokenId,
bytes memory _data
) public virtual override {
require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");
_safeTransfer(from, to, tokenId, _data);
}
function _safeTransfer(
address from,
address to,
uint256 tokenId,
bytes memory _data
) internal virtual {
_transfer(from, to, tokenId);
require(_checkOnERC721Received(from, to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer");
}
function _exists(uint256 tokenId) internal view virtual returns (bool) {
return _owners[tokenId] != address(0);
}
function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {
require(_exists(tokenId), "ERC721: operator query for nonexistent token");
address owner = ERC721.ownerOf(tokenId);
return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender));
}
function _safeMint(address to, uint256 tokenId) internal virtual {
_safeMint(to, tokenId, "");
}
function _safeMint(
address to,
uint256 tokenId,
bytes memory _data
) internal virtual {
_mint(to, tokenId);
require(
_checkOnERC721Received(address(0), to, tokenId, _data),
"ERC721: transfer to non ERC721Receiver implementer"
);
}
function _mint(address to, uint256 tokenId) internal virtual {
require(to != address(0), "ERC721: mint to the zero address");
require(!_exists(tokenId), "ERC721: token already minted");
_beforeTokenTransfer(address(0), to, tokenId);
_balances[to] += 1;
_owners[tokenId] = to;
emit Transfer(address(0), to, tokenId);
}
function _burn(uint256 tokenId) internal virtual {
address owner = ERC721.ownerOf(tokenId);
_beforeTokenTransfer(owner, address(0), tokenId);
_approve(address(0), tokenId);
_balances[owner] -= 1;
delete _owners[tokenId];
emit Transfer(owner, address(0), tokenId);
}
function _transfer(
address from,
address to,
uint256 tokenId
) internal virtual {
require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer of token that is not own");
require(to != address(0), "ERC721: transfer to the zero address");
_beforeTokenTransfer(from, to, tokenId);
_approve(address(0), tokenId);
_balances[from] -= 1;
_balances[to] += 1;
_owners[tokenId] = to;
emit Transfer(from, to, tokenId);
}
function _approve(address to, uint256 tokenId) internal virtual {
_tokenApprovals[tokenId] = to;
emit Approval(ERC721.ownerOf(tokenId), to, tokenId);
}
function _setApprovalForAll(
address owner,
address operator,
bool approved
) internal virtual {
require(owner != operator, "ERC721: approve to caller");
_operatorApprovals[owner][operator] = approved;
emit ApprovalForAll(owner, operator, approved);
}
function _checkOnERC721Received(
address from,
address to,
uint256 tokenId,
bytes memory _data
) private returns (bool) {
if (to.isContract()) {
try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, _data) returns (bytes4 retval) {
return retval == IERC721Receiver.onERC721Received.selector;
} catch (bytes memory reason) {
if (reason.length == 0) {
revert("ERC721: transfer to non ERC721Receiver implementer");
} else {
assembly {
revert(add(32, reason), mload(reason))
}
}
}
} else {
return true;
}
}
function _beforeTokenTransfer(
address from,
address to,
uint256 tokenId
) internal virtual {}
}
文件 11 的 50:IABIResolver.sol
pragma solidity >=0.8.4;
import "./IABIResolver.sol";
import "../ResolverBase.sol";
interface IABIResolver {
event ABIChanged(bytes32 indexed node, uint256 indexed contentType);
function ABI(bytes32 node, uint256 contentTypes) external view returns (uint256, bytes memory);
}
文件 12 的 50:IARBRegistrarControllerV3.sol
pragma solidity >=0.8.4;
import "../price-oracle/ISidPriceOracle.sol";
import {ReferralInfo} from "../struct/SidStruct.sol";
interface IARBRegistrarControllerV3 {
function rentPrice(string memory, uint256)
external
view
returns (ISidPriceOracle.Price memory);
function available(string memory) external returns (bool);
function rentPrice(string memory, uint256, address)
external
view
returns (ISidPriceOracle.Price memory);
function makeCommitment(
string memory,
address,
bytes32
) external pure returns (bytes32);
function commit(bytes32) external;
function registerWithConfig(
string calldata,
address,
uint256,
bytes32,
address,
bool
) external payable;
function registerWithConfigAndPoint(
string calldata,
address,
uint256,
bytes32,
address,
bool,
ReferralInfo memory
) external payable;
function renew(string calldata, uint256) external payable;
function renewWithPoint(string calldata, uint256, bool)
external
payable;
}
文件 13 的 50:IAddrResolver.sol
pragma solidity >=0.8.4;
interface IAddrResolver {
event AddrChanged(bytes32 indexed node, address a);
function addr(bytes32 node) external view returns (address payable);
}
文件 14 的 50:IAddressResolver.sol
pragma solidity >=0.8.4;
interface IAddressResolver {
event AddressChanged(bytes32 indexed node, uint coinType, bytes newAddress);
function addr(bytes32 node, uint coinType) external view returns(bytes memory);
}
文件 15 的 50:IBaseRegistrar.sol
import "../registry/ARBID.sol";
import "./IBaseRegistrar.sol";
import "@openzeppelin/contracts/token/ERC721/IERC721.sol";
interface IBaseRegistrar is IERC721 {
event ControllerAdded(address indexed controller);
event ControllerRemoved(address indexed controller);
event NameMigrated(
uint256 indexed id,
address indexed owner,
uint256 expires
);
event NameRegistered(
uint256 indexed id,
address indexed owner,
uint256 expires
);
event NameRenewed(uint256 indexed id, uint256 expires);
function addController(address controller) external;
function removeController(address controller) external;
function setResolver(address resolver) external;
function nameExpires(uint256 id) external view returns (uint256);
function available(uint256 id) external view returns (bool);
function register(
uint256 id,
address owner,
uint256 duration
) external returns (uint256);
function renew(uint256 id, uint256 duration) external returns (uint256);
function reclaim(uint256 id, address owner) external;
}
文件 16 的 50:IContentHashResolver.sol
pragma solidity >=0.8.4;
interface IContentHashResolver {
event ContenthashChanged(bytes32 indexed node, bytes hash);
function contenthash(bytes32 node) external view returns (bytes memory);
}
文件 17 的 50:IDNSRecordResolver.sol
pragma solidity >=0.8.4;
interface IDNSRecordResolver {
event DNSRecordChanged(bytes32 indexed node, bytes name, uint16 resource, bytes record);
event DNSRecordDeleted(bytes32 indexed node, bytes name, uint16 resource);
event DNSZoneCleared(bytes32 indexed node);
function dnsRecord(bytes32 node, bytes32 name, uint16 resource) external view returns (bytes memory);
}
文件 18 的 50:IDNSZoneResolver.sol
pragma solidity >=0.8.4;
interface IDNSZoneResolver {
event DNSZonehashChanged(bytes32 indexed node, bytes lastzonehash, bytes zonehash);
function zonehash(bytes32 node) external view returns (bytes memory);
}
文件 19 的 50:IERC1155.sol
pragma solidity ^0.8.0;
import "../../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 amount,
bytes calldata data
) external;
function safeBatchTransferFrom(
address from,
address to,
uint256[] calldata ids,
uint256[] calldata amounts,
bytes calldata data
) external;
}
文件 20 的 50:IERC1155MetadataURI.sol
pragma solidity ^0.8.0;
import "../IERC1155.sol";
interface IERC1155MetadataURI is IERC1155 {
function uri(uint256 id) external view returns (string memory);
}
文件 21 的 50:IERC1155Receiver.sol
pragma solidity ^0.8.0;
import "../../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);
}
文件 22 的 50:IERC165.sol
pragma solidity ^0.8.0;
interface IERC165 {
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
文件 23 的 50:IERC721.sol
pragma solidity ^0.8.0;
import "../../utils/introspection/IERC165.sol";
interface IERC721 is IERC165 {
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
function balanceOf(address owner) external view returns (uint256 balance);
function ownerOf(uint256 tokenId) external view returns (address owner);
function safeTransferFrom(
address from,
address to,
uint256 tokenId
) external;
function transferFrom(
address from,
address to,
uint256 tokenId
) external;
function approve(address to, uint256 tokenId) external;
function getApproved(uint256 tokenId) external view returns (address operator);
function setApprovalForAll(address operator, bool _approved) external;
function isApprovedForAll(address owner, address operator) external view returns (bool);
function safeTransferFrom(
address from,
address to,
uint256 tokenId,
bytes calldata data
) external;
}
文件 24 的 50:IERC721Metadata.sol
pragma solidity ^0.8.0;
import "../IERC721.sol";
interface IERC721Metadata is IERC721 {
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function tokenURI(uint256 tokenId) external view returns (string memory);
}
文件 25 的 50:IERC721Receiver.sol
pragma solidity ^0.8.0;
interface IERC721Receiver {
function onERC721Received(
address operator,
address from,
uint256 tokenId,
bytes calldata data
) external returns (bytes4);
}
文件 26 的 50:IInterfaceResolver.sol
pragma solidity >=0.8.4;
interface IInterfaceResolver {
event InterfaceChanged(bytes32 indexed node, bytes4 indexed interfaceID, address implementer);
function interfaceImplementer(bytes32 node, bytes4 interfaceID) external view returns (address);
}
文件 27 的 50:INameResolver.sol
pragma solidity >=0.8.4;
interface INameResolver {
event NameChanged(bytes32 indexed node, string name);
function name(bytes32 node) external view returns (string memory);
}
文件 28 的 50:IPubkeyResolver.sol
pragma solidity >=0.8.4;
interface IPubkeyResolver {
event PubkeyChanged(bytes32 indexed node, bytes32 x, bytes32 y);
function pubkey(bytes32 node) external view returns (bytes32 x, bytes32 y);
}
文件 29 的 50:IReferralHub.sol
pragma solidity >=0.8.4;
interface IReferralHub {
event ControllerAdded(address indexed controller);
event ControllerRemoved(address indexed controller);
event NewReferralRecord(bytes32 indexed referralNodeHash);
event depositRecord(address indexed addr, uint256 amount);
event withdrawRecord(address indexed addr, uint256 amount);
function addController(address controller) external;
function removeController(address controller) external;
function isReferralEligible(
bytes32 nodeHash
) external view returns (bool, address);
function addNewReferralRecord(bytes32 referrerNodeHash) external;
function getReferralDetails(bytes32 referrerNodeHash)
external
view
returns (
uint256,
uint256,
uint256,
uint256
);
function setPartnerComissionChart(
string calldata name,
string calldata tld,
uint256 minimumReferralCount,
uint256 referrerComission,
uint256 refereeComission
) external;
function getReferralCommisionFee(uint256 price, bytes32 nodeHash) external view returns (uint256, uint256);
function deposit(address _referrer) external payable;
function withdraw() external;
}
文件 30 的 50:IReverseRegistrar.sol
pragma solidity >=0.8.4;
interface IReverseRegistrar {
function setDefaultResolver(address resolver) external;
function claim(address owner) external returns (bytes32);
function claimForAddr(
address addr,
address owner,
address resolver
) external returns (bytes32);
function claimWithResolver(address owner, address resolver)
external
returns (bytes32);
function setName(string memory name) external returns (bytes32);
function setNameForAddr(
address addr,
address owner,
address resolver,
string memory name
) external returns (bytes32);
function node(address addr) external pure returns (bytes32);
}
文件 31 的 50:ISidGiftCardRegistrar.sol
pragma solidity >=0.8.4;
import "@openzeppelin/contracts/token/ERC1155/IERC1155.sol";
interface ISidGiftCardRegistrar is IERC1155 {
event ControllerAdded(address indexed controller);
event ControllerRemoved(address indexed controller);
function addController(address controller) external;
function removeController(address controller) external;
function register(
address to,
uint256 id,
uint256 amount
) external returns (uint256, uint256);
function batchRegister(
address to,
uint256[] calldata ids,
uint256[] calldata amounts
) external;
}
文件 32 的 50:ISidPriceOracle.sol
pragma solidity >=0.8.4;
interface ISidPriceOracle {
struct Price {
uint256 base;
uint256 premium;
uint256 usedPoint;
}
function giftcard(
uint256[] memory ids,
uint256[] memory amounts
) external view returns (Price calldata);
function domain(
string memory name,
uint256 expires,
uint256 duration
) external view returns (Price calldata);
function domainWithPoint(
string memory name,
uint256 expires,
uint256 duration,
address owner
) external view returns (Price calldata);
}
文件 33 的 50:ISupportsInterface.sol
pragma solidity ^0.8.4;
interface ISupportsInterface {
function supportsInterface(bytes4 interfaceID) external pure returns(bool);
}
文件 34 的 50:ITextResolver.sol
pragma solidity >=0.8.4;
interface ITextResolver {
event TextChanged(bytes32 indexed node, string indexed indexedKey, string key);
function text(bytes32 node, string calldata key) external view returns (string memory);
}
文件 35 的 50:NameResolver.sol
pragma solidity >=0.8.4;
import "../ResolverBase.sol";
import "./INameResolver.sol";
abstract contract NameResolver is INameResolver, ResolverBase {
mapping(bytes32=>string) names;
function setName(bytes32 node, string calldata newName) virtual external authorised(node) {
names[node] = newName;
emit NameChanged(node, newName);
}
function name(bytes32 node) virtual override external view returns (string memory) {
return names[node];
}
function supportsInterface(bytes4 interfaceID) virtual override public pure returns(bool) {
return interfaceID == type(INameResolver).interfaceId || super.supportsInterface(interfaceID);
}
}
文件 36 的 50: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);
}
}
文件 37 的 50:Pausable.sol
pragma solidity ^0.8.0;
import "../utils/Context.sol";
abstract contract Pausable is Context {
event Paused(address account);
event Unpaused(address account);
bool private _paused;
constructor() {
_paused = false;
}
function paused() public view virtual returns (bool) {
return _paused;
}
modifier whenNotPaused() {
require(!paused(), "Pausable: paused");
_;
}
modifier whenPaused() {
require(paused(), "Pausable: not paused");
_;
}
function _pause() internal virtual whenNotPaused {
_paused = true;
emit Paused(_msgSender());
}
function _unpause() internal virtual whenPaused {
_paused = false;
emit Unpaused(_msgSender());
}
}
文件 38 的 50: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;
}
}
文件 39 的 50:ReferralHub.sol
pragma solidity >=0.8.4;
import "./IReferralHub.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import "../registry/ARBID.sol";
import "../resolvers/profiles/AddrResolver.sol";
import "../resolvers/profiles/NameResolver.sol";
import "../registry/IReverseRegistrar.sol";
contract ReferralHub is IReferralHub, Ownable, ReentrancyGuard {
mapping(address => bool) public controllers;
struct Comission {
uint256 minimumReferralCount;
uint256 referrer;
uint256 referee;
}
mapping(uint256 => Comission) public comissionCharts;
mapping(bytes32 => uint256) public referralCount;
mapping(address => uint256) public referralBalance;
mapping(bytes32 => Comission) public partnerComissionCharts;
bytes32 constant ADDR_REVERSE_NODE = 0x91d1777781884d03a6757a803996e38de2a42967fb37eeaca72729271025a9e2;
bytes32 constant lookup = 0x3031323334353637383961626364656600000000000000000000000000000000;
ARBID immutable arbid;
constructor(ARBID _arbid) {
arbid = _arbid;
comissionCharts[1] = Comission(0, 5, 0);
comissionCharts[2] = Comission(30, 8, 0);
comissionCharts[3] = Comission(100, 11, 0);
comissionCharts[4] = Comission(600, 15, 0);
comissionCharts[5] = Comission(100000000, 15, 0);
comissionCharts[6] = Comission(100000000, 15, 0);
comissionCharts[7] = Comission(100000000, 15, 0);
comissionCharts[8] = Comission(100000000, 15, 0);
comissionCharts[9] = Comission(100000000, 15, 0);
comissionCharts[10] = Comission(100000000, 15, 0);
}
modifier onlyController() {
require(controllers[msg.sender], "Not a authorized controller");
_;
}
modifier validLevel(uint256 _level) {
require(_level >= 1 && _level <= 10, "Invalid level");
_;
}
function getNodehash(string calldata name, string calldata tld) public pure returns (bytes32) {
bytes32 nameHash = keccak256(bytes(name));
bytes32 tldHash = keccak256(abi.encodePacked(bytes32(0), keccak256(bytes(tld))));
return keccak256(abi.encodePacked(tldHash, nameHash));
}
function getReverseNodehash(address addr) public pure returns (bytes32) {
return keccak256(abi.encodePacked(ADDR_REVERSE_NODE, sha3HexAddress(addr)));
}
function sha3HexAddress(address addr) private pure returns (bytes32 ret) {
assembly {
for {
let i := 40
} gt(i, 0) {
} {
i := sub(i, 1)
mstore8(i, byte(and(addr, 0xf), lookup))
addr := div(addr, 0x10)
i := sub(i, 1)
mstore8(i, byte(and(addr, 0xf), lookup))
addr := div(addr, 0x10)
}
ret := keccak256(0, 40)
}
}
function isReferralEligible(bytes32 nodeHash) external view override returns (bool, address) {
address resolverAddress = arbid.resolver(nodeHash);
if (resolverAddress == address(0)) {
return (false, address(0));
}
AddrResolver resolver = AddrResolver(resolverAddress);
address resolvedAddress = resolver.addr(nodeHash);
bytes32 reverseNodeHash = getReverseNodehash(resolvedAddress);
address reverseResolverAddress = arbid.resolver(reverseNodeHash);
if (reverseResolverAddress == address(0)) {
return (false, address(0));
}
return (true, resolvedAddress);
}
function isPartner(bytes32 nodeHash) public view returns (bool) {
return partnerComissionCharts[nodeHash].referrer > 0 || partnerComissionCharts[nodeHash].referee > 0;
}
function getReferralCommisionFee(uint256 price, bytes32 nodeHash) public view returns (uint256, uint256) {
uint256 referrerRate = 0;
uint256 refereeRate = 0;
uint256 level = 1;
if (isPartner(nodeHash)) {
referrerRate = partnerComissionCharts[nodeHash].referrer;
refereeRate = partnerComissionCharts[nodeHash].referee;
} else {
(level, referrerRate, refereeRate) = _getComissionChart(referralCount[nodeHash]);
}
uint256 referrerFee = (price * referrerRate) / 100;
uint256 refereeFee = (price * refereeRate) / 100;
return (referrerFee, refereeFee);
}
function setPartnerComissionChart(
string calldata name,
string calldata tld,
uint256 minimumReferralCount,
uint256 referrerRate,
uint256 refereeRate
) external onlyOwner {
bytes32 nodeHash = getNodehash(name, tld);
partnerComissionCharts[nodeHash] = Comission(minimumReferralCount, referrerRate, refereeRate);
}
function addNewReferralRecord(bytes32 referrerNodeHash) external override onlyController {
referralCount[referrerNodeHash] += 1;
emit NewReferralRecord(referrerNodeHash);
}
function _getReferralCount(bytes32 referrerNodeHash) internal view returns (uint256) {
return referralCount[referrerNodeHash];
}
function _getComissionChart(uint256 referralAmount)
internal
view
returns (
uint256,
uint256,
uint256
)
{
uint256 curLevel = 1;
uint256 referrerRate;
uint256 refereeRate;
uint256 level;
while (referralAmount >= comissionCharts[curLevel].minimumReferralCount && curLevel <= 10) {
referrerRate = comissionCharts[curLevel].referrer;
refereeRate = comissionCharts[curLevel].referee;
level = curLevel;
curLevel += 1;
}
return (level, referrerRate, refereeRate);
}
function getReferralDetails(bytes32 referrerNodeHash)
external
view
override
returns (
uint256,
uint256,
uint256,
uint256
)
{
uint256 referralNum = _getReferralCount(referrerNodeHash);
(uint256 level, uint256 referrerRate, uint256 refereeRate) = _getComissionChart(referralNum);
return (referralNum, level, referrerRate, refereeRate);
}
function setComissionChart(
uint256 level,
uint256 minimumAmount,
uint256 referrerRate,
uint256 refereeRate
) external onlyOwner validLevel(level) {
comissionCharts[level] = Comission(minimumAmount, referrerRate, refereeRate);
}
function deposit(address _referrer) external payable onlyController{
require(msg.value > 0, "Invalid amount");
referralBalance[_referrer] += msg.value;
emit depositRecord(_referrer, msg.value);
}
function withdraw() external nonReentrant{
uint256 amount = referralBalance[msg.sender];
require(amount > 0, "Insufficient balance");
referralBalance[msg.sender] = 0;
payable(msg.sender).transfer(amount);
emit withdrawRecord(msg.sender, amount);
}
function addController(address controller) external override onlyOwner {
controllers[controller] = true;
emit ControllerAdded(controller);
}
function removeController(address controller) external override onlyOwner {
controllers[controller] = false;
emit ControllerRemoved(controller);
}
}
文件 40 的 50:ReferralVerifier.sol
pragma solidity >=0.8.4;
import "./ReferralVerifier.sol";
import {EIP712} from "@openzeppelin/contracts/utils/cryptography/draft-EIP712.sol";
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {Pausable} from "@openzeppelin/contracts/security/Pausable.sol";
import {ECDSA} from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
import {ReferralHub} from "./ReferralHub.sol";
contract ReferralVerifier is EIP712, Ownable, Pausable {
address public spaceid_signer;
uint256 public sigValidDuration;
ReferralHub immutable referralHub;
bytes32 private constant _REFERRAL_TYPEHASH = keccak256("Referral(address referrerAddress,bytes32 nodehash,uint256 referralCount,uint256 signedAt)");
constructor(address _spaceid_signer, ReferralHub _referral_hub) EIP712("ReferralVerifier", "1.0.0") {
spaceid_signer = _spaceid_signer;
referralHub = _referral_hub;
sigValidDuration = 5 minutes;
}
function setSpaceIdSigner(address _spaceid_signer) external onlyOwner {
spaceid_signer = _spaceid_signer;
}
function setSigValidDuration(uint256 duration) external onlyOwner {
sigValidDuration = duration;
}
function pause() external onlyOwner {
_pause();
}
function unpause() external onlyOwner {
_unpause();
}
function _hash(address referrerAddress, bytes32 nodehash, uint256 referralCount, uint256 signedAt) public view returns (bytes32) {
return _hashTypedDataV4(keccak256(abi.encode(_REFERRAL_TYPEHASH, referrerAddress, nodehash, referralCount, signedAt)));
}
function verifyReferral(address referrerAddress, bytes32 nodehash, uint256 referralCount, uint256 signedAt, bytes calldata signature) external view whenNotPaused returns (bool) {
return block.timestamp < signedAt + sigValidDuration && _verifySignature(_hash(referrerAddress, nodehash, referralCount, signedAt), signature);
}
function getReferralCommisionFee(uint256 price, uint256 referralCount) external view returns (uint256, uint256) {
uint256 curLevel = 1;
(uint256 minimumReferralCount, uint256 referrerRate, uint256 refereeRate) = referralHub.comissionCharts(curLevel);
while (referralCount > minimumReferralCount && curLevel <= 10) {
(, referrerRate, refereeRate) = referralHub.comissionCharts(curLevel);
(minimumReferralCount, , ) = referralHub.comissionCharts(++curLevel);
}
uint256 referrerFee = (price * referrerRate) / 100;
uint256 refereeFee = (price * refereeRate) / 100;
return (referrerFee, refereeFee);
}
function _verifySignature(bytes32 hash, bytes calldata signature) private view returns (bool) {
return ECDSA.recover(hash, signature) == spaceid_signer;
}
}
文件 41 的 50:Resolver.sol
pragma solidity >=0.8.4;
import "./profiles/IABIResolver.sol";
import "./profiles/IAddressResolver.sol";
import "./profiles/IAddrResolver.sol";
import "./profiles/IContentHashResolver.sol";
import "./profiles/IDNSRecordResolver.sol";
import "./profiles/IDNSZoneResolver.sol";
import "./profiles/IInterfaceResolver.sol";
import "./profiles/INameResolver.sol";
import "./profiles/IPubkeyResolver.sol";
import "./profiles/ITextResolver.sol";
import "./ISupportsInterface.sol";
interface Resolver is
ISupportsInterface,
IABIResolver,
IAddressResolver,
IAddrResolver,
IContentHashResolver,
IDNSRecordResolver,
IDNSZoneResolver,
IInterfaceResolver,
INameResolver,
IPubkeyResolver,
ITextResolver
{
event ContentChanged(bytes32 indexed node, bytes32 hash);
function setABI(
bytes32 node,
uint256 contentType,
bytes calldata data
) external;
function setAddr(bytes32 node, address addr) external;
function setAddr(
bytes32 node,
uint256 coinType,
bytes calldata a
) external;
function setAddr(
bytes32 node,
uint256 coinType,
address a
) external;
function setContenthash(bytes32 node, bytes calldata hash) external;
function setDnsrr(bytes32 node, bytes calldata data) external;
function setName(bytes32 node, string calldata _name) external;
function setPubkey(
bytes32 node,
bytes32 x,
bytes32 y
) external;
function setText(
bytes32 node,
string calldata key,
string calldata value
) external;
function setInterface(
bytes32 node,
bytes4 interfaceID,
address implementer
) external;
function multicall(bytes[] calldata data)
external
returns (bytes[] memory results);
function content(bytes32 node) external view returns (bytes32);
function multihash(bytes32 node) external view returns (bytes memory);
function setContent(bytes32 node, bytes32 hash) external;
function setMultihash(bytes32 node, bytes calldata hash) external;
}
文件 42 的 50:ResolverBase.sol
pragma solidity >=0.8.4;
import "./SupportsInterface.sol";
abstract contract ResolverBase is SupportsInterface {
function isAuthorised(bytes32 node) internal virtual view returns(bool);
modifier authorised(bytes32 node) {
require(isAuthorised(node));
_;
}
}
文件 43 的 50:SidGiftCardLedger.sol
pragma solidity >=0.8.4;
import "./SidGiftCardRegistrar.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "./SidGiftCardVoucher.sol";
contract SidGiftCardLedger is Ownable {
SidGiftCardRegistrar public registrar;
SidGiftCardVoucher public voucher;
mapping(address => uint256) public balances;
mapping(address => bool) public controllers;
event ControllerAdded(address indexed controller);
event ControllerRemoved(address indexed controller);
constructor(SidGiftCardRegistrar _registrar, SidGiftCardVoucher _voucher) {
registrar = _registrar;
voucher = _voucher;
}
modifier onlyController() {
require(controllers[msg.sender], "Not a authorized controller");
_;
}
function balanceOf(address account) public view returns (uint256) {
return balances[account];
}
function redeem(uint256[] calldata ids, uint256[] calldata amounts) external {
registrar.batchBurn(msg.sender, ids, amounts);
uint256 totalValue = voucher.totalValue(ids, amounts);
balances[msg.sender] += totalValue;
}
function deduct(address account, uint256 amount) public onlyController {
uint256 fromBalance = balances[account];
require(fromBalance >= amount, "Insufficient balance");
balances[account] = fromBalance - amount;
}
function addController(address controller) external onlyOwner {
require(controller != address(0), "address can not be zero!");
controllers[controller] = true;
emit ControllerAdded(controller);
}
function removeController(address controller) external onlyOwner {
require(controller != address(0), "address can not be zero!");
controllers[controller] = false;
emit ControllerRemoved(controller);
}
}
文件 44 的 50:SidGiftCardRegistrar.sol
pragma solidity >=0.8.4;
import "@openzeppelin/contracts/token/ERC1155/ERC1155.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "./ISidGiftCardRegistrar.sol";
import "@openzeppelin/contracts/utils/Strings.sol";
import "@openzeppelin/contracts/security/Pausable.sol";
contract SidGiftCardRegistrar is ERC1155, ISidGiftCardRegistrar, Ownable, Pausable {
mapping(address => bool) public controllers;
constructor() ERC1155("") {}
modifier onlyController() {
require(controllers[msg.sender], "Not a authorized controller");
_;
}
function setURI(string calldata newURI) external onlyOwner {
_setURI(newURI);
}
function uri(uint256 _id) public view virtual override(ERC1155) returns (string memory) {
return string(abi.encodePacked(ERC1155.uri(_id), Strings.toString(_id)));
}
function name() public view virtual returns (string memory) {
return "SPACE ID Gift Card";
}
function symbol() public view virtual returns (string memory) {
return "SIDGC";
}
function register(
address to,
uint256 id,
uint256 amount
) external onlyController whenNotPaused returns (uint256, uint256) {
super._mint(to, id, amount, "");
return (id, amount);
}
function batchRegister(
address to,
uint256[] calldata ids,
uint256[] calldata amounts
) external onlyController whenNotPaused {
require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");
for (uint256 i = 0; i < ids.length; i++) {
if (amounts[i] > 0) {
super._mint(to, ids[i], amounts[i], "");
}
}
}
function batchBurn(
address account,
uint256[] calldata ids,
uint256[] calldata amounts
) external onlyController whenNotPaused {
require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");
for (uint256 i = 0; i < ids.length; i++) {
if (amounts[i] > 0) {
super._burn(account, ids[i], amounts[i]);
}
}
}
function addController(address controller) external override onlyOwner {
require(controller != address(0), "address can not be zero!");
controllers[controller] = true;
emit ControllerAdded(controller);
}
function removeController(address controller) external override onlyOwner {
require(controller != address(0), "address can not be zero!");
controllers[controller] = false;
emit ControllerRemoved(controller);
}
function pause() external onlyOwner {
_pause();
}
function unpause() external onlyOwner {
_unpause();
}
function safeBatchTransferFrom(
address from,
address to,
uint256[] calldata ids,
uint256[] calldata amounts,
bytes calldata data
) public virtual whenNotPaused override(ERC1155, IERC1155) {
require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");
for (uint256 i = 0; i < ids.length; i++) {
if (amounts[i] > 0) {
super.safeTransferFrom(from, to, ids[i], amounts[i], data);
}
}
}
}
文件 45 的 50:SidGiftCardVoucher.sol
pragma solidity >=0.8.4;
import "@openzeppelin/contracts/access/Ownable.sol";
contract SidGiftCardVoucher is Ownable {
uint256 public constant THREE_DIGIT_VOUCHER = 0;
uint256 public constant FOUR_DIGIT_VOUCHER = 1;
uint256 public constant FIVE_DIGIT_VOUCHER = 2;
uint256 public constant THREE_DIGIT_VOUCHER_VALUE = 500 * (10**18);
uint256 public constant FOUR_DIGIT_VOUCHER_VALUE = 100 * (10**18);
uint256 public constant FIVE_DIGIT_VOUCHER_VALUE = 5 * (10**18);
mapping(uint256 => uint256) public voucherValues;
constructor() {
voucherValues[THREE_DIGIT_VOUCHER] = THREE_DIGIT_VOUCHER_VALUE;
voucherValues[FOUR_DIGIT_VOUCHER] = FOUR_DIGIT_VOUCHER_VALUE;
voucherValues[FIVE_DIGIT_VOUCHER] = FIVE_DIGIT_VOUCHER_VALUE;
}
function addCustomizedVoucher(uint256 tokenId, uint256 price) external onlyOwner {
require(voucherValues[tokenId] == 0, "voucher already exsits");
voucherValues[tokenId] = price;
}
function totalValue(uint256[] calldata ids, uint256[] calldata amounts) external view returns (uint256) {
uint256 total = 0;
for (uint256 i = 0; i < ids.length; i++) {
total += voucherValues[ids[i]] * amounts[i];
}
return total;
}
function isValidVoucherIds(uint256[] calldata id) external view returns (bool) {
for (uint256 i = 0; i < id.length; i++) {
if (voucherValues[id[i]] == 0) {
return false;
}
}
return true;
}
}
文件 46 的 50:SidStruct.sol
pragma solidity >=0.8.4;
struct ReferralInfo {
address referrerAddress;
bytes32 referrerNodehash;
uint256 referralAmount;
uint256 signedAt;
bytes signature;
}
struct RegInfo {
address owner;
uint duration;
bytes32 secret;
address resolver;
bool isUsePoints;
uint256 paidFee;
}
文件 47 的 50:StringUtils.sol
pragma solidity >=0.8.4;
library StringUtils {
function strlen(string memory s) internal pure returns (uint) {
uint len;
uint i = 0;
uint bytelength = bytes(s).length;
for(len = 0; i < bytelength; len++) {
bytes1 b = bytes(s)[i];
if(b < 0x80) {
i += 1;
} else if (b < 0xE0) {
i += 2;
} else if (b < 0xF0) {
i += 3;
} else if (b < 0xF8) {
i += 4;
} else if (b < 0xFC) {
i += 5;
} else {
i += 6;
}
}
return len;
}
}
文件 48 的 50:Strings.sol
pragma solidity ^0.8.0;
library Strings {
bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef";
function toString(uint256 value) internal pure returns (string memory) {
if (value == 0) {
return "0";
}
uint256 temp = value;
uint256 digits;
while (temp != 0) {
digits++;
temp /= 10;
}
bytes memory buffer = new bytes(digits);
while (value != 0) {
digits -= 1;
buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
value /= 10;
}
return string(buffer);
}
function toHexString(uint256 value) internal pure returns (string memory) {
if (value == 0) {
return "0x00";
}
uint256 temp = value;
uint256 length = 0;
while (temp != 0) {
length++;
temp >>= 8;
}
return toHexString(value, length);
}
function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
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_SYMBOLS[value & 0xf];
value >>= 4;
}
require(value == 0, "Strings: hex length insufficient");
return string(buffer);
}
}
文件 49 的 50:SupportsInterface.sol
pragma solidity ^0.8.4;
import "./ISupportsInterface.sol";
abstract contract SupportsInterface is ISupportsInterface {
function supportsInterface(bytes4 interfaceID) virtual override public pure returns(bool) {
return interfaceID == type(ISupportsInterface).interfaceId;
}
}
文件 50 的 50:draft-EIP712.sol
pragma solidity ^0.8.0;
import "./ECDSA.sol";
abstract contract EIP712 {
bytes32 private immutable _CACHED_DOMAIN_SEPARATOR;
uint256 private immutable _CACHED_CHAIN_ID;
address private immutable _CACHED_THIS;
bytes32 private immutable _HASHED_NAME;
bytes32 private immutable _HASHED_VERSION;
bytes32 private immutable _TYPE_HASH;
constructor(string memory name, string memory version) {
bytes32 hashedName = keccak256(bytes(name));
bytes32 hashedVersion = keccak256(bytes(version));
bytes32 typeHash = keccak256(
"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"
);
_HASHED_NAME = hashedName;
_HASHED_VERSION = hashedVersion;
_CACHED_CHAIN_ID = block.chainid;
_CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(typeHash, hashedName, hashedVersion);
_CACHED_THIS = address(this);
_TYPE_HASH = typeHash;
}
function _domainSeparatorV4() internal view returns (bytes32) {
if (address(this) == _CACHED_THIS && block.chainid == _CACHED_CHAIN_ID) {
return _CACHED_DOMAIN_SEPARATOR;
} else {
return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION);
}
}
function _buildDomainSeparator(
bytes32 typeHash,
bytes32 nameHash,
bytes32 versionHash
) private view returns (bytes32) {
return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));
}
function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {
return ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash);
}
}
{
"compilationTarget": {
"contracts/arbregistrar/ARBRegistrarControllerV6.sol": "ARBRegistrarControllerV6"
},
"evmVersion": "london",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs",
"useLiteralContent": true
},
"optimizer": {
"enabled": true,
"runs": 10000
},
"remappings": []
}
[{"inputs":[{"internalType":"contract BaseRegistrarImplementation","name":"_base","type":"address"},{"internalType":"contract ISidPriceOracle","name":"_prices","type":"address"},{"internalType":"contract SidGiftCardLedger","name":"_giftCardLedger","type":"address"},{"internalType":"contract ReferralHub","name":"_referralHub","type":"address"},{"internalType":"contract ReferralVerifier","name":"_referralVerifier","type":"address"},{"internalType":"address","name":"_beneficiary","type":"address"},{"internalType":"uint256","name":"_minCommitmentAge","type":"uint256"},{"internalType":"uint256","name":"_maxCommitmentAge","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"bytes32","name":"commitment","type":"bytes32"}],"name":"CommitmentTooNew","type":"error"},{"inputs":[{"internalType":"bytes32","name":"commitment","type":"bytes32"}],"name":"CommitmentTooOld","type":"error"},{"inputs":[{"internalType":"uint256","name":"duration","type":"uint256"}],"name":"DurationTooShort","type":"error"},{"inputs":[],"name":"InsufficientValue","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"InvalidOwner","type":"error"},{"inputs":[],"name":"MaxCommitmentAgeTooHigh","type":"error"},{"inputs":[],"name":"MaxCommitmentAgeTooLow","type":"error"},{"inputs":[{"internalType":"string","name":"name","type":"string"}],"name":"NameNotAvailable","type":"error"},{"inputs":[{"internalType":"bytes32","name":"commitment","type":"bytes32"}],"name":"UnexpiredCommitmentExists","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"name","type":"string"},{"indexed":true,"internalType":"bytes32","name":"label","type":"bytes32"},{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"baseCost","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"premium","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"expires","type":"uint256"}],"name":"NameRegistered","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"name","type":"string"},{"indexed":true,"internalType":"bytes32","name":"label","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"cost","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"expires","type":"uint256"}],"name":"NameRenewed","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":[],"name":"MIN_REGISTRATION_DURATION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"name","type":"string"}],"name":"available","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"beneficiary","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"newCommitments","type":"bytes32[]"}],"name":"bulkCommit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string[]","name":"name","type":"string[]"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"bytes32","name":"secret","type":"bytes32"}],"name":"bulkMakeCommitmentWithConfig","outputs":[{"internalType":"bytes32[]","name":"newCommitments","type":"bytes32[]"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"string[]","name":"names","type":"string[]"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"duration","type":"uint256"},{"internalType":"bytes32","name":"secret","type":"bytes32"},{"internalType":"address","name":"resolver","type":"address"},{"internalType":"bool","name":"isUseGiftCard","type":"bool"},{"components":[{"internalType":"address","name":"referrerAddress","type":"address"},{"internalType":"bytes32","name":"referrerNodehash","type":"bytes32"},{"internalType":"uint256","name":"referralAmount","type":"uint256"},{"internalType":"uint256","name":"signedAt","type":"uint256"},{"internalType":"bytes","name":"signature","type":"bytes"}],"internalType":"struct ReferralInfo","name":"referralInfo","type":"tuple"}],"name":"bulkRegister","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"string[]","name":"names","type":"string[]"},{"internalType":"uint256","name":"duration","type":"uint256"}],"name":"bulkRentPrice","outputs":[{"internalType":"uint256","name":"total","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"commitment","type":"bytes32"}],"name":"commit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"commitments","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"giftCardLedger","outputs":[{"internalType":"contract SidGiftCardLedger","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"bytes32","name":"secret","type":"bytes32"}],"name":"makeCommitment","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"maxCommitmentAge","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minCommitmentAge","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"prices","outputs":[{"internalType":"contract ISidPriceOracle","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"referralHub","outputs":[{"internalType":"contract ReferralHub","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"referralVerifier","outputs":[{"internalType":"contract ReferralVerifier","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"duration","type":"uint256"},{"internalType":"bytes32","name":"secret","type":"bytes32"},{"internalType":"address","name":"resolver","type":"address"}],"name":"registerWithConfig","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"duration","type":"uint256"},{"internalType":"bytes32","name":"secret","type":"bytes32"},{"internalType":"address","name":"resolver","type":"address"},{"internalType":"bool","name":"isUsePoints","type":"bool"},{"components":[{"internalType":"address","name":"referrerAddress","type":"address"},{"internalType":"bytes32","name":"referrerNodehash","type":"bytes32"},{"internalType":"uint256","name":"referralAmount","type":"uint256"},{"internalType":"uint256","name":"signedAt","type":"uint256"},{"internalType":"bytes","name":"signature","type":"bytes"}],"internalType":"struct ReferralInfo","name":"referralInfo","type":"tuple"}],"name":"registerWithConfigAndPoint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"uint256","name":"duration","type":"uint256"}],"name":"renew","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"uint256","name":"duration","type":"uint256"},{"internalType":"bool","name":"isUsePoints","type":"bool"}],"name":"renewWithPoint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"uint256","name":"duration","type":"uint256"},{"internalType":"address","name":"registerAddress","type":"address"}],"name":"rentPrice","outputs":[{"components":[{"internalType":"uint256","name":"base","type":"uint256"},{"internalType":"uint256","name":"premium","type":"uint256"},{"internalType":"uint256","name":"usedPoint","type":"uint256"}],"internalType":"struct ISidPriceOracle.Price","name":"price","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"uint256","name":"duration","type":"uint256"}],"name":"rentPrice","outputs":[{"components":[{"internalType":"uint256","name":"base","type":"uint256"},{"internalType":"uint256","name":"premium","type":"uint256"},{"internalType":"uint256","name":"usedPoint","type":"uint256"}],"internalType":"struct ISidPriceOracle.Price","name":"price","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceID","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"name","type":"string"}],"name":"valid","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]