编译器
0.8.17+commit.8df45f5f
文件 1 的 13:ContractState.sol
pragma solidity 0.8.17;
import "../interfaces/IContractState.sol";
abstract contract ContractState is IContractState {
uint8 public constant PAUSED = 0;
uint8 private _contractState;
modifier isState(uint8 expectedState_) {
if (_contractState != expectedState_) {
revert ContractState_INCORRECT_STATE(_contractState);
}
_;
}
modifier isNotState(uint8 unexpectedState_) {
if (_contractState == unexpectedState_) {
revert ContractState_INCORRECT_STATE(_contractState);
}
_;
}
function _setContractState(uint8 newState_) internal virtual {
uint8 _previousState_ = _contractState;
_contractState = newState_;
emit ContractStateChanged(_previousState_, newState_);
}
function getContractState() public virtual view override returns (uint8) {
return _contractState;
}
}
文件 2 的 13:ERC173.sol
pragma solidity 0.8.17;
import "../interfaces/IERC173.sol";
import "../interfaces/IERC173Errors.sol";
abstract contract ERC173 is IERC173, IERC173Errors {
address private _owner;
modifier onlyOwner() {
if (owner() != msg.sender) {
revert IERC173_NOT_OWNER(msg.sender);
}
_;
}
function _setOwner(address owner_) internal {
_owner = owner_;
}
function transferOwnership(address newOwner_) public virtual onlyOwner {
address _oldOwner_ = _owner;
_owner = newOwner_;
emit OwnershipTransferred(_oldOwner_, newOwner_);
}
function owner() public view virtual returns (address) {
return _owner;
}
}
文件 3 的 13:ExitPayloadReader.sol
pragma solidity ^0.8.0;
import { RLPReader } from "./RLPReader.sol";
library ExitPayloadReader {
using RLPReader for bytes;
using RLPReader for RLPReader.RLPItem;
uint8 constant WORD_SIZE = 32;
struct ExitPayload {
RLPReader.RLPItem[] data;
}
struct Receipt {
RLPReader.RLPItem[] data;
bytes raw;
uint256 logIndex;
}
struct Log {
RLPReader.RLPItem data;
RLPReader.RLPItem[] list;
}
struct LogTopics {
RLPReader.RLPItem[] data;
}
function copy(uint src, uint dest, uint len) private pure {
if (len == 0) return;
for (; len >= WORD_SIZE; len -= WORD_SIZE) {
assembly {
mstore(dest, mload(src))
}
src += WORD_SIZE;
dest += WORD_SIZE;
}
uint mask = 256 ** (WORD_SIZE - len) - 1;
assembly {
let srcpart := and(mload(src), not(mask))
let destpart := and(mload(dest), mask)
mstore(dest, or(destpart, srcpart))
}
}
function toExitPayload(bytes memory data)
internal
pure
returns (ExitPayload memory)
{
RLPReader.RLPItem[] memory payloadData = data
.toRlpItem()
.toList();
return ExitPayload(payloadData);
}
function getHeaderNumber(ExitPayload memory payload) internal pure returns(uint256) {
return payload.data[0].toUint();
}
function getBlockProof(ExitPayload memory payload) internal pure returns(bytes memory) {
return payload.data[1].toBytes();
}
function getBlockNumber(ExitPayload memory payload) internal pure returns(uint256) {
return payload.data[2].toUint();
}
function getBlockTime(ExitPayload memory payload) internal pure returns(uint256) {
return payload.data[3].toUint();
}
function getTxRoot(ExitPayload memory payload) internal pure returns(bytes32) {
return bytes32(payload.data[4].toUint());
}
function getReceiptRoot(ExitPayload memory payload) internal pure returns(bytes32) {
return bytes32(payload.data[5].toUint());
}
function getReceipt(ExitPayload memory payload) internal pure returns(Receipt memory receipt) {
receipt.raw = payload.data[6].toBytes();
RLPReader.RLPItem memory receiptItem = receipt.raw.toRlpItem();
if (receiptItem.isList()) {
receipt.data = receiptItem.toList();
} else {
bytes memory typedBytes = receipt.raw;
bytes memory result = new bytes(typedBytes.length - 1);
uint256 srcPtr;
uint256 destPtr;
assembly {
srcPtr := add(33, typedBytes)
destPtr := add(0x20, result)
}
copy(srcPtr, destPtr, result.length);
receipt.data = result.toRlpItem().toList();
}
receipt.logIndex = getReceiptLogIndex(payload);
return receipt;
}
function getReceiptProof(ExitPayload memory payload) internal pure returns(bytes memory) {
return payload.data[7].toBytes();
}
function getBranchMaskAsBytes(ExitPayload memory payload) internal pure returns(bytes memory) {
return payload.data[8].toBytes();
}
function getBranchMaskAsUint(ExitPayload memory payload) internal pure returns(uint256) {
return payload.data[8].toUint();
}
function getReceiptLogIndex(ExitPayload memory payload) internal pure returns(uint256) {
return payload.data[9].toUint();
}
function toBytes(Receipt memory receipt) internal pure returns(bytes memory) {
return receipt.raw;
}
function getLog(Receipt memory receipt) internal pure returns(Log memory) {
RLPReader.RLPItem memory logData = receipt.data[3].toList()[receipt.logIndex];
return Log(logData, logData.toList());
}
function getEmitter(Log memory log) internal pure returns(address) {
return RLPReader.toAddress(log.list[0]);
}
function getTopics(Log memory log) internal pure returns(LogTopics memory) {
return LogTopics(log.list[1].toList());
}
function getData(Log memory log) internal pure returns(bytes memory) {
return log.list[2].toBytes();
}
function toRlpBytes(Log memory log) internal pure returns(bytes memory) {
return log.data.toRlpBytes();
}
function getField(LogTopics memory topics, uint256 index) internal pure returns(RLPReader.RLPItem memory) {
return topics.data[index];
}
}
文件 4 的 13:FxBaseRootTunnel.sol
pragma solidity ^0.8.0;
import {RLPReader} from "../lib/RLPReader.sol";
import {MerklePatriciaProof} from "../lib/MerklePatriciaProof.sol";
import {Merkle} from "../lib/Merkle.sol";
import "../lib/ExitPayloadReader.sol";
interface IFxStateSender {
function sendMessageToChild(address _receiver, bytes calldata _data) external;
}
contract ICheckpointManager {
struct HeaderBlock {
bytes32 root;
uint256 start;
uint256 end;
uint256 createdAt;
address proposer;
}
mapping(uint256 => HeaderBlock) public headerBlocks;
}
abstract contract FxBaseRootTunnel {
using RLPReader for RLPReader.RLPItem;
using Merkle for bytes32;
using ExitPayloadReader for bytes;
using ExitPayloadReader for ExitPayloadReader.ExitPayload;
using ExitPayloadReader for ExitPayloadReader.Log;
using ExitPayloadReader for ExitPayloadReader.LogTopics;
using ExitPayloadReader for ExitPayloadReader.Receipt;
bytes32 public constant SEND_MESSAGE_EVENT_SIG = 0x8c5261668696ce22758910d05bab8f186d6eb247ceac2af2e82c7dc17669b036;
IFxStateSender public fxRoot;
ICheckpointManager public checkpointManager;
address public fxChildTunnel;
mapping(bytes32 => bool) public processedExits;
constructor(address _checkpointManager, address _fxRoot) {
checkpointManager = ICheckpointManager(_checkpointManager);
fxRoot = IFxStateSender(_fxRoot);
}
function setFxChildTunnel(address _fxChildTunnel) public {
require(fxChildTunnel == address(0x0), "FxBaseRootTunnel: CHILD_TUNNEL_ALREADY_SET");
fxChildTunnel = _fxChildTunnel;
}
function _sendMessageToChild(bytes memory message) internal {
fxRoot.sendMessageToChild(fxChildTunnel, message);
}
function _validateAndExtractMessage(bytes memory inputData) internal returns (bytes memory) {
ExitPayloadReader.ExitPayload memory payload = inputData.toExitPayload();
bytes memory branchMaskBytes = payload.getBranchMaskAsBytes();
uint256 blockNumber = payload.getBlockNumber();
bytes32 exitHash = keccak256(
abi.encodePacked(
blockNumber,
MerklePatriciaProof._getNibbleArray(branchMaskBytes),
payload.getReceiptLogIndex()
)
);
require(
processedExits[exitHash] == false,
"FxRootTunnel: EXIT_ALREADY_PROCESSED"
);
processedExits[exitHash] = true;
ExitPayloadReader.Receipt memory receipt = payload.getReceipt();
ExitPayloadReader.Log memory log = receipt.getLog();
require(fxChildTunnel == log.getEmitter(), "FxRootTunnel: INVALID_FX_CHILD_TUNNEL");
bytes32 receiptRoot = payload.getReceiptRoot();
require(
MerklePatriciaProof.verify(
receipt.toBytes(),
branchMaskBytes,
payload.getReceiptProof(),
receiptRoot
),
"FxRootTunnel: INVALID_RECEIPT_PROOF"
);
_checkBlockMembershipInCheckpoint(
blockNumber,
payload.getBlockTime(),
payload.getTxRoot(),
receiptRoot,
payload.getHeaderNumber(),
payload.getBlockProof()
);
ExitPayloadReader.LogTopics memory topics = log.getTopics();
require(
bytes32(topics.getField(0).toUint()) == SEND_MESSAGE_EVENT_SIG,
"FxRootTunnel: INVALID_SIGNATURE"
);
(bytes memory message) = abi.decode(log.getData(), (bytes));
return message;
}
function _checkBlockMembershipInCheckpoint(
uint256 blockNumber,
uint256 blockTime,
bytes32 txRoot,
bytes32 receiptRoot,
uint256 headerNumber,
bytes memory blockProof
) private view returns (uint256) {
(
bytes32 headerRoot,
uint256 startBlock,
,
uint256 createdAt,
) = checkpointManager.headerBlocks(headerNumber);
require(
keccak256(
abi.encodePacked(blockNumber, blockTime, txRoot, receiptRoot)
)
.checkMembership(
blockNumber-startBlock,
headerRoot,
blockProof
),
"FxRootTunnel: INVALID_HEADER"
);
return createdAt;
}
function receiveMessage(bytes memory inputData) public virtual {
bytes memory message = _validateAndExtractMessage(inputData);
_processMessageFromChild(message);
}
function _processMessageFromChild(bytes memory message) virtual internal;
}
文件 5 的 13:IArrayErrors.sol
pragma solidity 0.8.17;
interface IArrayErrors {
error ARRAY_LENGTH_MISMATCH();
}
文件 6 的 13:IContractState.sol
pragma solidity 0.8.17;
interface IContractState {
error ContractState_INCORRECT_STATE(uint8 currentState);
error ContractState_INVALID_STATE(uint8 invalidState);
event ContractStateChanged(uint8 indexed previousState, uint8 indexed newState);
function getContractState() external view returns (uint8);
}
文件 7 的 13:IERC173.sol
pragma solidity 0.8.17;
interface IERC173 {
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
function transferOwnership(address newOwner_) external;
function owner() external view returns(address);
}
文件 8 的 13:IERC173Errors.sol
pragma solidity 0.8.17;
interface IERC173Errors {
error IERC173_NOT_OWNER(address operator);
}
文件 9 的 13:IERC721.sol
pragma solidity 0.8.17;
interface IERC721 {
event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
function approve(address approved_, uint256 tokenId_) external;
function safeTransferFrom(address from_, address to_, uint256 tokenId_, bytes calldata data_) external;
function safeTransferFrom(address from_, address to_, uint256 tokenId_) external;
function setApprovalForAll(address operator_, bool approved_) external;
function transferFrom(address from_, address to_, uint256 tokenId_) external;
function balanceOf(address owner_) external view returns (uint256);
function getApproved(uint256 tokenId_) external view returns (address);
function isApprovedForAll(address owner_, address operator_) external view returns (bool);
function ownerOf(uint256 tokenId_) external view returns (address);
}
文件 10 的 13:Merkle.sol
pragma solidity ^0.8.0;
library Merkle {
function checkMembership(
bytes32 leaf,
uint256 index,
bytes32 rootHash,
bytes memory proof
) internal pure returns (bool) {
require(proof.length % 32 == 0, "Invalid proof length");
uint256 proofHeight = proof.length / 32;
require(index < 2 ** proofHeight, "Leaf index is too big");
bytes32 proofElement;
bytes32 computedHash = leaf;
for (uint256 i = 32; i <= proof.length; i += 32) {
assembly {
proofElement := mload(add(proof, i))
}
if (index % 2 == 0) {
computedHash = keccak256(
abi.encodePacked(computedHash, proofElement)
);
} else {
computedHash = keccak256(
abi.encodePacked(proofElement, computedHash)
);
}
index = index / 2;
}
return computedHash == rootHash;
}
}
文件 11 的 13:MerklePatriciaProof.sol
pragma solidity ^0.8.0;
import {RLPReader} from "./RLPReader.sol";
library MerklePatriciaProof {
function verify(
bytes memory value,
bytes memory encodedPath,
bytes memory rlpParentNodes,
bytes32 root
) internal pure returns (bool) {
RLPReader.RLPItem memory item = RLPReader.toRlpItem(rlpParentNodes);
RLPReader.RLPItem[] memory parentNodes = RLPReader.toList(item);
bytes memory currentNode;
RLPReader.RLPItem[] memory currentNodeList;
bytes32 nodeKey = root;
uint256 pathPtr = 0;
bytes memory path = _getNibbleArray(encodedPath);
if (path.length == 0) {
return false;
}
for (uint256 i = 0; i < parentNodes.length; i++) {
if (pathPtr > path.length) {
return false;
}
currentNode = RLPReader.toRlpBytes(parentNodes[i]);
if (nodeKey != keccak256(currentNode)) {
return false;
}
currentNodeList = RLPReader.toList(parentNodes[i]);
if (currentNodeList.length == 17) {
if (pathPtr == path.length) {
if (
keccak256(RLPReader.toBytes(currentNodeList[16])) ==
keccak256(value)
) {
return true;
} else {
return false;
}
}
uint8 nextPathNibble = uint8(path[pathPtr]);
if (nextPathNibble > 16) {
return false;
}
nodeKey = bytes32(
RLPReader.toUintStrict(currentNodeList[nextPathNibble])
);
pathPtr += 1;
} else if (currentNodeList.length == 2) {
uint256 traversed = _nibblesToTraverse(
RLPReader.toBytes(currentNodeList[0]),
path,
pathPtr
);
if (pathPtr + traversed == path.length) {
if (
keccak256(RLPReader.toBytes(currentNodeList[1])) ==
keccak256(value)
) {
return true;
} else {
return false;
}
}
if (traversed == 0) {
return false;
}
pathPtr += traversed;
nodeKey = bytes32(RLPReader.toUintStrict(currentNodeList[1]));
} else {
return false;
}
}
}
function _nibblesToTraverse(
bytes memory encodedPartialPath,
bytes memory path,
uint256 pathPtr
) private pure returns (uint256) {
uint256 len = 0;
bytes memory partialPath = _getNibbleArray(encodedPartialPath);
bytes memory slicedPath = new bytes(partialPath.length);
for (uint256 i = pathPtr; i < pathPtr + partialPath.length; i++) {
bytes1 pathNibble = path[i];
slicedPath[i - pathPtr] = pathNibble;
}
if (keccak256(partialPath) == keccak256(slicedPath)) {
len = partialPath.length;
} else {
len = 0;
}
return len;
}
function _getNibbleArray(bytes memory b)
internal
pure
returns (bytes memory)
{
bytes memory nibbles = "";
if (b.length > 0) {
uint8 offset;
uint8 hpNibble = uint8(_getNthNibbleOfBytes(0, b));
if (hpNibble == 1 || hpNibble == 3) {
nibbles = new bytes(b.length * 2 - 1);
bytes1 oddNibble = _getNthNibbleOfBytes(1, b);
nibbles[0] = oddNibble;
offset = 1;
} else {
nibbles = new bytes(b.length * 2 - 2);
offset = 0;
}
for (uint256 i = offset; i < nibbles.length; i++) {
nibbles[i] = _getNthNibbleOfBytes(i - offset + 2, b);
}
}
return nibbles;
}
function _getNthNibbleOfBytes(uint256 n, bytes memory str)
private
pure
returns (bytes1)
{
return
bytes1(
n % 2 == 0 ? uint8(str[n / 2]) / 0x10 : uint8(str[n / 2]) % 0x10
);
}
}
文件 12 的 13:NuCyberStaking.sol
pragma solidity 0.8.17;
import "@lambdalf-dev/ethereum-contracts/contracts/interfaces/IArrayErrors.sol";
import "@lambdalf-dev/ethereum-contracts/contracts/utils/ContractState.sol";
import "@lambdalf-dev/ethereum-contracts/contracts/utils/ERC173.sol";
import "@lambdalf-dev/ethereum-contracts/contracts/interfaces/IERC721.sol";
import { FxBaseRootTunnel } from "fx-portal/contracts/tunnel/FxBaseRootTunnel.sol";
contract NuCyberStaking is IArrayErrors, ContractState, ERC173, FxBaseRootTunnel {
struct StakedToken {
uint64 tokenId;
address beneficiary;
}
error NCS_TOKEN_NOT_OWNED(uint256 tokenId);
error NCS_REWARDS_NOT_SET();
event BenefitStarted(uint256 indexed tokenId, address indexed beneficiary);
event BenefitEnded(uint256 indexed tokenId, address indexed beneficiary);
uint8 public constant ACTIVE = 1;
IERC721 public nuCyber;
mapping(address => StakedToken[]) private _stakedTokens;
mapping(address => uint256[]) private _benefitTokens;
constructor(address nucyberContractAddress_, address cpManager_, address fxRoot_)
FxBaseRootTunnel(cpManager_, fxRoot_) {
nuCyber = IERC721(nucyberContractAddress_);
_setOwner(msg.sender);
}
function _balanceOfBenefit(address account_) internal view returns (uint256) {
return _benefitTokens[account_].length;
}
function _balanceOfStaked(address account_) internal view returns (uint256) {
return _stakedTokens[account_].length;
}
function _endBenefit(address beneficiary_, uint256 tokenId_) internal {
uint256 _last_ = _benefitTokens[beneficiary_].length;
uint256 _count_ = _last_;
bool _deleted_;
while(_count_ > 0) {
unchecked {
--_count_;
}
if (_benefitTokens[beneficiary_][_count_] == tokenId_) {
if (_count_ != _last_ - 1) {
_benefitTokens[beneficiary_][_count_] = _benefitTokens[beneficiary_][_last_ - 1];
}
_benefitTokens[beneficiary_].pop();
_deleted_ = true;
}
}
if(! _deleted_) {
revert NCS_TOKEN_NOT_OWNED(tokenId_);
}
emit BenefitEnded(tokenId_, beneficiary_);
}
function _findToken(address tokenOwner_, uint256 tokenId_) internal view returns (StakedToken memory, uint256) {
uint256 _count_ = _stakedTokens[tokenOwner_].length;
while(_count_ > 0) {
unchecked {
--_count_;
}
if (_stakedTokens[tokenOwner_][_count_].tokenId == tokenId_) {
return (_stakedTokens[tokenOwner_][_count_], _count_);
}
}
revert NCS_TOKEN_NOT_OWNED(tokenId_);
}
function _processMessageFromChild(bytes memory message) internal override {
}
function _sendMessage(address sender_, uint16 amount_, bool isStake_) internal {
if (amount_ > 0) {
_sendMessageToChild(
abi.encode(sender_, uint8(1), amount_, isStake_)
);
}
}
function _stakeToken(address tokenOwner_, uint256 tokenId_, address beneficiary_) internal {
_stakedTokens[tokenOwner_].push(StakedToken(uint64(tokenId_),beneficiary_));
if (beneficiary_ != address(0)) {
_benefitTokens[beneficiary_].push(tokenId_);
emit BenefitStarted(tokenId_, beneficiary_);
}
try nuCyber.transferFrom(tokenOwner_, address(this), tokenId_) {}
catch Error(string memory reason) {
revert(reason);
}
}
function _unstakeToken(address tokenOwner_, uint256 tokenId_) internal {
uint256 _last_ = _stakedTokens[tokenOwner_].length;
uint256 _count_ = _last_;
bool _deleted_;
while(_count_ > 0) {
unchecked {
--_count_;
}
if (_stakedTokens[tokenOwner_][_count_].tokenId == tokenId_) {
address _beneficiary_ = _stakedTokens[tokenOwner_][_count_].beneficiary;
if(_beneficiary_ != address(0)) {
_endBenefit(_beneficiary_, tokenId_);
}
if (_count_ != _last_ - 1) {
_stakedTokens[tokenOwner_][_count_] = _stakedTokens[tokenOwner_][_last_ - 1];
}
_stakedTokens[tokenOwner_].pop();
_deleted_ = true;
}
}
if(! _deleted_) {
revert NCS_TOKEN_NOT_OWNED(tokenId_);
}
try nuCyber.transferFrom(address(this), tokenOwner_, tokenId_) {}
catch Error(string memory reason) {
revert(reason);
}
}
function bulkStake(uint256[] memory tokenIds_, address[] memory beneficiaries_) public isState(ACTIVE) {
if (fxChildTunnel == address(0)) {
revert NCS_REWARDS_NOT_SET();
}
uint256 _len_ = tokenIds_.length;
if ( beneficiaries_.length != _len_ ) {
revert ARRAY_LENGTH_MISMATCH();
}
while (_len_ > 0) {
unchecked {
--_len_;
}
_stakeToken(msg.sender, tokenIds_[_len_], beneficiaries_[_len_]);
}
_sendMessage(msg.sender, uint16(tokenIds_.length), true);
}
function bulkUnstake(uint256[] memory tokenIds_) public {
uint256 _len_ = tokenIds_.length;
while (_len_ > 0) {
unchecked {
--_len_;
}
_unstakeToken(msg.sender, tokenIds_[_len_]);
}
_sendMessage(msg.sender, uint16(tokenIds_.length), false);
}
function stake(uint256 tokenId_, address beneficiary_) public isState(ACTIVE) {
if (fxChildTunnel == address(0)) {
revert NCS_REWARDS_NOT_SET();
}
_stakeToken(msg.sender, tokenId_, beneficiary_);
_sendMessage(msg.sender, 1, true);
}
function unstake(uint256 tokenId_) public {
_unstakeToken(msg.sender, tokenId_);
_sendMessage(msg.sender, 1, false);
}
function updateBeneficiary(uint256 tokenId_, address newBeneficiary_) public {
(StakedToken memory _stakedToken_, uint256 _index_) = _findToken(msg.sender, tokenId_);
_stakedTokens[msg.sender][_index_].beneficiary = newBeneficiary_;
if (_stakedToken_.beneficiary != address(0)) {
_endBenefit(_stakedToken_.beneficiary, tokenId_);
}
if (newBeneficiary_ != address(0)) {
_benefitTokens[newBeneficiary_].push(tokenId_);
emit BenefitStarted(tokenId_, newBeneficiary_);
}
}
function setNuCyberContract(address contractAddress_) external onlyOwner {
nuCyber = IERC721(contractAddress_);
}
function setContractState(uint8 newState_) external onlyOwner {
if (newState_ > ACTIVE) {
revert ContractState_INVALID_STATE(newState_);
}
_setContractState(newState_);
}
function updateFxChildTunnel(address fxChildTunnel_) external onlyOwner {
fxChildTunnel = fxChildTunnel_;
}
function balanceOf(address tokenOwner_) public view returns (uint256) {
return nuCyber.balanceOf(tokenOwner_) + _balanceOfStaked(tokenOwner_) + _balanceOfBenefit(tokenOwner_);
}
function balanceOfBenefit(address account_) external view returns (uint256) {
return _balanceOfBenefit(account_);
}
function balanceOfStaked(address account_) external view returns (uint256) {
return _balanceOfStaked(account_);
}
function stakedTokens(address tokenOwner_) public view returns (StakedToken[] memory) {
return _stakedTokens[tokenOwner_];
}
}
文件 13 的 13:RLPReader.sol
pragma solidity ^0.8.0;
library RLPReader {
uint8 constant STRING_SHORT_START = 0x80;
uint8 constant STRING_LONG_START = 0xb8;
uint8 constant LIST_SHORT_START = 0xc0;
uint8 constant LIST_LONG_START = 0xf8;
uint8 constant WORD_SIZE = 32;
struct RLPItem {
uint len;
uint memPtr;
}
struct Iterator {
RLPItem item;
uint nextPtr;
}
function next(Iterator memory self) internal pure returns (RLPItem memory) {
require(hasNext(self));
uint ptr = self.nextPtr;
uint itemLength = _itemLength(ptr);
self.nextPtr = ptr + itemLength;
return RLPItem(itemLength, ptr);
}
function hasNext(Iterator memory self) internal pure returns (bool) {
RLPItem memory item = self.item;
return self.nextPtr < item.memPtr + item.len;
}
function toRlpItem(bytes memory item) internal pure returns (RLPItem memory) {
uint memPtr;
assembly {
memPtr := add(item, 0x20)
}
return RLPItem(item.length, memPtr);
}
function iterator(RLPItem memory self) internal pure returns (Iterator memory) {
require(isList(self));
uint ptr = self.memPtr + _payloadOffset(self.memPtr);
return Iterator(self, ptr);
}
function rlpLen(RLPItem memory item) internal pure returns (uint) {
return item.len;
}
function payloadLen(RLPItem memory item) internal pure returns (uint) {
return item.len - _payloadOffset(item.memPtr);
}
function toList(RLPItem memory item) internal pure returns (RLPItem[] memory) {
require(isList(item));
uint items = numItems(item);
RLPItem[] memory result = new RLPItem[](items);
uint memPtr = item.memPtr + _payloadOffset(item.memPtr);
uint dataLen;
for (uint i = 0; i < items; i++) {
dataLen = _itemLength(memPtr);
result[i] = RLPItem(dataLen, memPtr);
memPtr = memPtr + dataLen;
}
return result;
}
function isList(RLPItem memory item) internal pure returns (bool) {
if (item.len == 0) return false;
uint8 byte0;
uint memPtr = item.memPtr;
assembly {
byte0 := byte(0, mload(memPtr))
}
if (byte0 < LIST_SHORT_START)
return false;
return true;
}
function rlpBytesKeccak256(RLPItem memory item) internal pure returns (bytes32) {
uint256 ptr = item.memPtr;
uint256 len = item.len;
bytes32 result;
assembly {
result := keccak256(ptr, len)
}
return result;
}
function payloadLocation(RLPItem memory item) internal pure returns (uint, uint) {
uint offset = _payloadOffset(item.memPtr);
uint memPtr = item.memPtr + offset;
uint len = item.len - offset;
return (memPtr, len);
}
function payloadKeccak256(RLPItem memory item) internal pure returns (bytes32) {
(uint memPtr, uint len) = payloadLocation(item);
bytes32 result;
assembly {
result := keccak256(memPtr, len)
}
return result;
}
function toRlpBytes(RLPItem memory item) internal pure returns (bytes memory) {
bytes memory result = new bytes(item.len);
if (result.length == 0) return result;
uint ptr;
assembly {
ptr := add(0x20, result)
}
copy(item.memPtr, ptr, item.len);
return result;
}
function toBoolean(RLPItem memory item) internal pure returns (bool) {
require(item.len == 1);
uint result;
uint memPtr = item.memPtr;
assembly {
result := byte(0, mload(memPtr))
}
return result == 0 ? false : true;
}
function toAddress(RLPItem memory item) internal pure returns (address) {
require(item.len == 21);
return address(uint160(toUint(item)));
}
function toUint(RLPItem memory item) internal pure returns (uint) {
require(item.len > 0 && item.len <= 33);
uint offset = _payloadOffset(item.memPtr);
uint len = item.len - offset;
uint result;
uint memPtr = item.memPtr + offset;
assembly {
result := mload(memPtr)
if lt(len, 32) {
result := div(result, exp(256, sub(32, len)))
}
}
return result;
}
function toUintStrict(RLPItem memory item) internal pure returns (uint) {
require(item.len == 33);
uint result;
uint memPtr = item.memPtr + 1;
assembly {
result := mload(memPtr)
}
return result;
}
function toBytes(RLPItem memory item) internal pure returns (bytes memory) {
require(item.len > 0);
uint offset = _payloadOffset(item.memPtr);
uint len = item.len - offset;
bytes memory result = new bytes(len);
uint destPtr;
assembly {
destPtr := add(0x20, result)
}
copy(item.memPtr + offset, destPtr, len);
return result;
}
function numItems(RLPItem memory item) private pure returns (uint) {
if (item.len == 0) return 0;
uint count = 0;
uint currPtr = item.memPtr + _payloadOffset(item.memPtr);
uint endPtr = item.memPtr + item.len;
while (currPtr < endPtr) {
currPtr = currPtr + _itemLength(currPtr);
count++;
}
return count;
}
function _itemLength(uint memPtr) private pure returns (uint) {
uint itemLen;
uint byte0;
assembly {
byte0 := byte(0, mload(memPtr))
}
if (byte0 < STRING_SHORT_START)
itemLen = 1;
else if (byte0 < STRING_LONG_START)
itemLen = byte0 - STRING_SHORT_START + 1;
else if (byte0 < LIST_SHORT_START) {
assembly {
let byteLen := sub(byte0, 0xb7)
memPtr := add(memPtr, 1)
let dataLen := div(mload(memPtr), exp(256, sub(32, byteLen)))
itemLen := add(dataLen, add(byteLen, 1))
}
}
else if (byte0 < LIST_LONG_START) {
itemLen = byte0 - LIST_SHORT_START + 1;
}
else {
assembly {
let byteLen := sub(byte0, 0xf7)
memPtr := add(memPtr, 1)
let dataLen := div(mload(memPtr), exp(256, sub(32, byteLen)))
itemLen := add(dataLen, add(byteLen, 1))
}
}
return itemLen;
}
function _payloadOffset(uint memPtr) private pure returns (uint) {
uint byte0;
assembly {
byte0 := byte(0, mload(memPtr))
}
if (byte0 < STRING_SHORT_START)
return 0;
else if (byte0 < STRING_LONG_START || (byte0 >= LIST_SHORT_START && byte0 < LIST_LONG_START))
return 1;
else if (byte0 < LIST_SHORT_START)
return byte0 - (STRING_LONG_START - 1) + 1;
else
return byte0 - (LIST_LONG_START - 1) + 1;
}
function copy(uint src, uint dest, uint len) private pure {
if (len == 0) return;
for (; len >= WORD_SIZE; len -= WORD_SIZE) {
assembly {
mstore(dest, mload(src))
}
src += WORD_SIZE;
dest += WORD_SIZE;
}
if (len == 0) return;
uint mask = 256 ** (WORD_SIZE - len) - 1;
assembly {
let srcpart := and(mload(src), not(mask))
let destpart := and(mload(dest), mask)
mstore(dest, or(destpart, srcpart))
}
}
}
{
"compilationTarget": {
"contracts/NuCyberStaking.sol": "NuCyberStaking"
},
"evmVersion": "london",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 10000
},
"remappings": []
}
[{"inputs":[{"internalType":"address","name":"nucyberContractAddress_","type":"address"},{"internalType":"address","name":"cpManager_","type":"address"},{"internalType":"address","name":"fxRoot_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ARRAY_LENGTH_MISMATCH","type":"error"},{"inputs":[{"internalType":"uint8","name":"currentState","type":"uint8"}],"name":"ContractState_INCORRECT_STATE","type":"error"},{"inputs":[{"internalType":"uint8","name":"invalidState","type":"uint8"}],"name":"ContractState_INVALID_STATE","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"IERC173_NOT_OWNER","type":"error"},{"inputs":[],"name":"NCS_REWARDS_NOT_SET","type":"error"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"NCS_TOKEN_NOT_OWNED","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"beneficiary","type":"address"}],"name":"BenefitEnded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"beneficiary","type":"address"}],"name":"BenefitStarted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint8","name":"previousState","type":"uint8"},{"indexed":true,"internalType":"uint8","name":"newState","type":"uint8"}],"name":"ContractStateChanged","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":"ACTIVE","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PAUSED","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SEND_MESSAGE_EVENT_SIG","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenOwner_","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account_","type":"address"}],"name":"balanceOfBenefit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account_","type":"address"}],"name":"balanceOfStaked","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds_","type":"uint256[]"},{"internalType":"address[]","name":"beneficiaries_","type":"address[]"}],"name":"bulkStake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds_","type":"uint256[]"}],"name":"bulkUnstake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"checkpointManager","outputs":[{"internalType":"contract ICheckpointManager","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"fxChildTunnel","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"fxRoot","outputs":[{"internalType":"contract IFxStateSender","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getContractState","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nuCyber","outputs":[{"internalType":"contract IERC721","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"processedExits","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"inputData","type":"bytes"}],"name":"receiveMessage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"newState_","type":"uint8"}],"name":"setContractState","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_fxChildTunnel","type":"address"}],"name":"setFxChildTunnel","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"contractAddress_","type":"address"}],"name":"setNuCyberContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId_","type":"uint256"},{"internalType":"address","name":"beneficiary_","type":"address"}],"name":"stake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenOwner_","type":"address"}],"name":"stakedTokens","outputs":[{"components":[{"internalType":"uint64","name":"tokenId","type":"uint64"},{"internalType":"address","name":"beneficiary","type":"address"}],"internalType":"struct NuCyberStaking.StakedToken[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner_","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId_","type":"uint256"}],"name":"unstake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId_","type":"uint256"},{"internalType":"address","name":"newBeneficiary_","type":"address"}],"name":"updateBeneficiary","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"fxChildTunnel_","type":"address"}],"name":"updateFxChildTunnel","outputs":[],"stateMutability":"nonpayable","type":"function"}]