diff --git a/audits/README.md b/audits/README.md index f5b7cd5f..b7055854 100644 --- a/audits/README.md +++ b/audits/README.md @@ -10,6 +10,8 @@ contracts is located in this folder: [internal audit 2](https://github.com/valor An internal audit with a focus on one-shot upgrade and operating services with signatures contracts is located in this folder: [internal audit 3](https://github.com/valory-xyz/autonolas-registries/blob/main/audits/internal3). +An internal audit with a focus on Service Staking +contracts is located in this folder: [internal audit 4](https://github.com/valory-xyz/autonolas-registries/blob/main/audits/internal4). ### External audit diff --git a/audits/internal4/README.md b/audits/internal4/README.md new file mode 100644 index 00000000..f73740f9 --- /dev/null +++ b/audits/internal4/README.md @@ -0,0 +1,135 @@ +# Internal audit of autonolas-registries +The review has been performed based on the contract code in the following repository:
+`https://github.com/valory-xyz/autonolas-registries`
+commit: `v1.1.7.pre-internal-audit`
+ +## Objectives +The audit focused on `staking a service` contracts in this repo. + +### Flatten version +Flatten version of contracts. [contracts](https://github.com/valory-xyz/autonolas-registries/blob/main/audits/internal4/analysis/contracts) + +### ERC20/ERC721 checks +N/A + +### Security issues. Updated 04-10-23 +#### Problems found instrumentally +Several checks are obtained automatically. They are commented. Some issues found need to be fixed.
+All automatic warnings are listed in the following file, concerns of which we address in more detail below:
+[slither-full](https://github.com/valory-xyz/autonolas-registries/blob/main/audits/internal4/analysis/slither_full.txt) + +Bad pattern (ref: reentrancy):
+```solidity +unstake: +Doesn't match the pattern Checks, Effects, and Interactions (CEI): +_withdraw(sInfo.multisig, sInfo.reward); in middle +``` + +Reentrancy critical issue:
+```solidity +ServiceStaking.unstake -> _withdraw -> to.call{value: amount}("") -> ServiceStaking.unstake (sInfo.reward > 0 ??) -> _withdraw -> to.call{value: amount}("") +``` + +Reentrancy medium issue:
+```solidity +ServiceStakingToken.unstake -> _withdraw -> SafeTransferLib.safeTransfer(stakingToken, to, amount); -> ServiceStaking.unstake +via custom stakingToken +``` + +Reentrancy low issue:
+```solidity +ServiceStakingToken.deposit -> SafeTransferLib.safeTransfer(stakingToken, to, amount); -> ServiceStaking.deposit +via custom stakingToken +``` + +Pointer bug (thanks Aleksandr Kuperman)
+``` +ServiceInfo memory sInfo = mapServiceInfo[serviceId]; +(uint256[] memory serviceIds, , , , , ) = checkpoint(); // mapServiceInfo[curServiceId].reward += updatedReward; +sInfo.reward; +Incorrect state when updating in checkpoint() +``` + +Low problem:
+```solidity +function checkpoint() public returns () +uint256 curServiceId; +vs +// Get the current service Id +uint256 curServiceId = serviceIds[i]; +Details: https://github.com/crytic/slither/wiki/Detector-Documentation#variable-names-too-similar +Reusing a same variable name in different scopes. +``` + + +```solidity + if (state != 4) { + revert WrongServiceState(state, serviceId); + } +It's better to use the original type enum. +Details: https://github.com/pessimistic-io/slitherin/blob/master/docs/magic_number.md +``` + +# Low optimization +``` +if (size > 0) { + for (uint256 i = 0; i < size; ++i) { + // Agent Ids must be unique and in ascending order + if (_stakingParams.agentIds[i] <= agentId) { + revert WrongAgentId(_stakingParams.agentIds[i]); + } + agentId = _stakingParams.agentIds[i]; + agentIds.push(agentId); + } + } +if size == 0 then for(i = 0; i < 0; i++) -> no loop +``` +``` + // Transfer the service for staking + IService(serviceRegistry).safeTransferFrom(msg.sender, address(this), serviceId); + Last operation? +``` + +### General considerations +Measuring the number of live transactions through a smart contract has fundamental limitations:
+Ethereum smart contracts only have access to the current state - not to historical states at previous blocks.
+Also, there's currently no EVM opcode (hence no Solidity function) to look up the amount of transactions by an address.
+Therefore, we have to rely on the internal counter "nonce" to measure tps (tx per sec).
+https://github.com/safe-global/safe-contracts/blob/1cfa95710057e33832600e6b9ad5ececca8f7839/contracts/Safe.sol#L167
+ +In this contract, we assume that the services are mostly honest and are not trying to tamper with this counter.
+ref: IService(serviceRegistry).safeTransferFrom(msg.sender, address(this), serviceId);
+ +There are two ways to fake it:
+1. Fake multisig. Open question +```solidity + (uint96 stakingDeposit, address multisig, bytes32 hash, uint256 agentThreshold, uint256 maxNumInstances, , uint8 state) = + IService(serviceRegistry).mapServices(serviceId); +sInfo.multisig = multisig; +sInfo.owner = msg.sender; +uint256 nonce = IMultisig(multisig).nonce(); +Thus, it is trivial to tweak nonce it now if there is some trivial contract with the method setNonce(uint256); + +If you wish, you can fight, for example, using this method +hash(multisig.code) vs well-know hash +``` +Is it possible to replace the multisig with some kind of fake one without losing the opportunity to receive rewards?
+Notes: re-checking logic in contracts\multisigs\GnosisSafeSameAddressMultisig.sol (!) and update logic if necessary. + +2. "Normal" multisig. Open question +``` +https://github.com/safe-global/safe-contracts/blob/main/contracts/Safe.sol#L139 +We can call execTransaction from another contract as owner in loop. + txHash = getTransactionHash( // Transaction info + ... + nonce++ + ); + checkSignatures(txHash, "", signatures); + +I don't see a way to deal with this. Moreover, it is practically indistinguishable from normal use. +Estimating gas consumption will not give us anything either. Only by off-chain measurement can we understand what is happening. +``` +Suggestion: Do nothing.
+ + + diff --git a/audits/internal4/analysis/contracts/ServiceStakingBase-flatten.sol b/audits/internal4/analysis/contracts/ServiceStakingBase-flatten.sol new file mode 100644 index 00000000..86449f87 --- /dev/null +++ b/audits/internal4/analysis/contracts/ServiceStakingBase-flatten.sol @@ -0,0 +1,876 @@ +// Sources flattened with hardhat v2.17.1 https://hardhat.org + +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.21; + +/// @dev Errors. +interface IErrorsRegistries { + /// @dev Only `manager` has a privilege, but the `sender` was provided. + /// @param sender Sender address. + /// @param manager Required sender address as a manager. + error ManagerOnly(address sender, address manager); + + /// @dev Only `owner` has a privilege, but the `sender` was provided. + /// @param sender Sender address. + /// @param owner Required sender address as an owner. + error OwnerOnly(address sender, address owner); + + /// @dev Hash already exists in the records. + error HashExists(); + + /// @dev Provided zero address. + error ZeroAddress(); + + /// @dev Agent Id is not correctly provided for the current routine. + /// @param agentId Component Id. + error WrongAgentId(uint256 agentId); + + /// @dev Wrong length of two arrays. + /// @param numValues1 Number of values in a first array. + /// @param numValues2 Numberf of values in a second array. + error WrongArrayLength(uint256 numValues1, uint256 numValues2); + + /// @dev Canonical agent Id is not found. + /// @param agentId Canonical agent Id. + error AgentNotFound(uint256 agentId); + + /// @dev Component Id is not found. + /// @param componentId Component Id. + error ComponentNotFound(uint256 componentId); + + /// @dev Multisig threshold is out of bounds. + /// @param currentThreshold Current threshold value. + /// @param minThreshold Minimum possible threshold value. + /// @param maxThreshold Maximum possible threshold value. + error WrongThreshold(uint256 currentThreshold, uint256 minThreshold, uint256 maxThreshold); + + /// @dev Agent instance is already registered with a specified `operator`. + /// @param operator Operator that registered an instance. + error AgentInstanceRegistered(address operator); + + /// @dev Wrong operator is specified when interacting with a specified `serviceId`. + /// @param serviceId Service Id. + error WrongOperator(uint256 serviceId); + + /// @dev Operator has no registered instances in the service. + /// @param operator Operator address. + /// @param serviceId Service Id. + error OperatorHasNoInstances(address operator, uint256 serviceId); + + /// @dev Canonical `agentId` is not found as a part of `serviceId`. + /// @param agentId Canonical agent Id. + /// @param serviceId Service Id. + error AgentNotInService(uint256 agentId, uint256 serviceId); + + /// @dev The contract is paused. + error Paused(); + + /// @dev Zero value when it has to be different from zero. + error ZeroValue(); + + /// @dev Value overflow. + /// @param provided Overflow value. + /// @param max Maximum possible value. + error Overflow(uint256 provided, uint256 max); + + /// @dev Service must be inactive. + /// @param serviceId Service Id. + error ServiceMustBeInactive(uint256 serviceId); + + /// @dev All the agent instance slots for a specific `serviceId` are filled. + /// @param serviceId Service Id. + error AgentInstancesSlotsFilled(uint256 serviceId); + + /// @dev Wrong state of a service. + /// @param state Service state. + /// @param serviceId Service Id. + error WrongServiceState(uint256 state, uint256 serviceId); + + /// @dev Only own service multisig is allowed. + /// @param provided Provided address. + /// @param expected Expected multisig address. + /// @param serviceId Service Id. + error OnlyOwnServiceMultisig(address provided, address expected, uint256 serviceId); + + /// @dev Multisig is not whitelisted. + /// @param multisig Address of a multisig implementation. + error UnauthorizedMultisig(address multisig); + + /// @dev Incorrect deposit provided for the registration activation. + /// @param sent Sent amount. + /// @param expected Expected amount. + /// @param serviceId Service Id. + error IncorrectRegistrationDepositValue(uint256 sent, uint256 expected, uint256 serviceId); + + /// @dev Insufficient value provided for the agent instance bonding. + /// @param sent Sent amount. + /// @param expected Expected amount. + /// @param serviceId Service Id. + error IncorrectAgentBondingValue(uint256 sent, uint256 expected, uint256 serviceId); + + /// @dev Failure of a transfer. + /// @param token Address of a token. + /// @param from Address `from`. + /// @param to Address `to`. + /// @param value Value. + error TransferFailed(address token, address from, address to, uint256 value); + + /// @dev Caught reentrancy violation. + error ReentrancyGuard(); +} + + +// File lib/solmate/src/tokens/ERC721.sol +/// @notice Modern, minimalist, and gas efficient ERC-721 implementation. +/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC721.sol) +abstract contract ERC721 { + /*////////////////////////////////////////////////////////////// + EVENTS + //////////////////////////////////////////////////////////////*/ + + event Transfer(address indexed from, address indexed to, uint256 indexed id); + + event Approval(address indexed owner, address indexed spender, uint256 indexed id); + + event ApprovalForAll(address indexed owner, address indexed operator, bool approved); + + /*////////////////////////////////////////////////////////////// + METADATA STORAGE/LOGIC + //////////////////////////////////////////////////////////////*/ + + string public name; + + string public symbol; + + function tokenURI(uint256 id) public view virtual returns (string memory); + + /*////////////////////////////////////////////////////////////// + ERC721 BALANCE/OWNER STORAGE + //////////////////////////////////////////////////////////////*/ + + mapping(uint256 => address) internal _ownerOf; + + mapping(address => uint256) internal _balanceOf; + + function ownerOf(uint256 id) public view virtual returns (address owner) { + require((owner = _ownerOf[id]) != address(0), "NOT_MINTED"); + } + + function balanceOf(address owner) public view virtual returns (uint256) { + require(owner != address(0), "ZERO_ADDRESS"); + + return _balanceOf[owner]; + } + + /*////////////////////////////////////////////////////////////// + ERC721 APPROVAL STORAGE + //////////////////////////////////////////////////////////////*/ + + mapping(uint256 => address) public getApproved; + + mapping(address => mapping(address => bool)) public isApprovedForAll; + + /*////////////////////////////////////////////////////////////// + CONSTRUCTOR + //////////////////////////////////////////////////////////////*/ + + constructor(string memory _name, string memory _symbol) { + name = _name; + symbol = _symbol; + } + + /*////////////////////////////////////////////////////////////// + ERC721 LOGIC + //////////////////////////////////////////////////////////////*/ + + function approve(address spender, uint256 id) public virtual { + address owner = _ownerOf[id]; + + require(msg.sender == owner || isApprovedForAll[owner][msg.sender], "NOT_AUTHORIZED"); + + getApproved[id] = spender; + + emit Approval(owner, spender, id); + } + + function setApprovalForAll(address operator, bool approved) public virtual { + isApprovedForAll[msg.sender][operator] = approved; + + emit ApprovalForAll(msg.sender, operator, approved); + } + + function transferFrom( + address from, + address to, + uint256 id + ) public virtual { + require(from == _ownerOf[id], "WRONG_FROM"); + + require(to != address(0), "INVALID_RECIPIENT"); + + require( + msg.sender == from || isApprovedForAll[from][msg.sender] || msg.sender == getApproved[id], + "NOT_AUTHORIZED" + ); + + // Underflow of the sender's balance is impossible because we check for + // ownership above and the recipient's balance can't realistically overflow. + unchecked { + _balanceOf[from]--; + + _balanceOf[to]++; + } + + _ownerOf[id] = to; + + delete getApproved[id]; + + emit Transfer(from, to, id); + } + + function safeTransferFrom( + address from, + address to, + uint256 id + ) public virtual { + transferFrom(from, to, id); + + if (to.code.length != 0) + require( + ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, "") == + ERC721TokenReceiver.onERC721Received.selector, + "UNSAFE_RECIPIENT" + ); + } + + function safeTransferFrom( + address from, + address to, + uint256 id, + bytes calldata data + ) public virtual { + transferFrom(from, to, id); + + if (to.code.length != 0) + require( + ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, data) == + ERC721TokenReceiver.onERC721Received.selector, + "UNSAFE_RECIPIENT" + ); + } + + /*////////////////////////////////////////////////////////////// + ERC165 LOGIC + //////////////////////////////////////////////////////////////*/ + + function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) { + return + interfaceId == 0x01ffc9a7 || // ERC165 Interface ID for ERC165 + interfaceId == 0x80ac58cd || // ERC165 Interface ID for ERC721 + interfaceId == 0x5b5e139f; // ERC165 Interface ID for ERC721Metadata + } + + /*////////////////////////////////////////////////////////////// + INTERNAL MINT/BURN LOGIC + //////////////////////////////////////////////////////////////*/ + + function _mint(address to, uint256 id) internal virtual { + require(to != address(0), "INVALID_RECIPIENT"); + + require(_ownerOf[id] == address(0), "ALREADY_MINTED"); + + // Counter overflow is incredibly unrealistic. + unchecked { + _balanceOf[to]++; + } + + _ownerOf[id] = to; + + emit Transfer(address(0), to, id); + } + + function _burn(uint256 id) internal virtual { + address owner = _ownerOf[id]; + + require(owner != address(0), "NOT_MINTED"); + + // Ownership check above ensures no underflow. + unchecked { + _balanceOf[owner]--; + } + + delete _ownerOf[id]; + + delete getApproved[id]; + + emit Transfer(owner, address(0), id); + } + + /*////////////////////////////////////////////////////////////// + INTERNAL SAFE MINT LOGIC + //////////////////////////////////////////////////////////////*/ + + function _safeMint(address to, uint256 id) internal virtual { + _mint(to, id); + + if (to.code.length != 0) + require( + ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, "") == + ERC721TokenReceiver.onERC721Received.selector, + "UNSAFE_RECIPIENT" + ); + } + + function _safeMint( + address to, + uint256 id, + bytes memory data + ) internal virtual { + _mint(to, id); + + if (to.code.length != 0) + require( + ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, data) == + ERC721TokenReceiver.onERC721Received.selector, + "UNSAFE_RECIPIENT" + ); + } +} + +/// @notice A generic interface for a contract which properly accepts ERC721 tokens. +/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC721.sol) +abstract contract ERC721TokenReceiver { + function onERC721Received( + address, + address, + uint256, + bytes calldata + ) external virtual returns (bytes4) { + return ERC721TokenReceiver.onERC721Received.selector; + } +} + + +// File contracts/staking/ServiceStakingBase.sol +// Multisig interface +interface IMultisig { + /// @dev Gets the multisig nonce. + /// @return Multisig nonce. + function nonce() external view returns (uint256); +} + +// Service Registry interface +interface IService { + enum UnitType { + Component, + Agent + } + + /// @dev Transfers the service that was previously approved to this contract address. + /// @param from Account address to transfer from. + /// @param to Account address to transfer to. + /// @param id Service Id. + function safeTransferFrom(address from, address to, uint256 id) external; + + /// @dev Gets service parameters from the map of services. + /// @param serviceId Service Id. + /// @return securityDeposit Registration activation deposit. + /// @return multisig Service multisig address. + /// @return configHash IPFS hashes pointing to the config metadata. + /// @return threshold Agent instance signers threshold. + /// @return maxNumAgentInstances Total number of agent instances. + /// @return numAgentInstances Actual number of agent instances. + /// @return state Service state. + function mapServices(uint256 serviceId) external view returns ( + uint96 securityDeposit, + address multisig, + bytes32 configHash, + uint32 threshold, + uint32 maxNumAgentInstances, + uint32 numAgentInstances, + uint8 state + ); + + /// @dev Gets the full set of linearized components / canonical agent Ids for a specified service. + /// @notice The service must be / have been deployed in order to get the actual data. + /// @param serviceId Service Id. + /// @return numUnitIds Number of component / agent Ids. + /// @return unitIds Set of component / agent Ids. + function getUnitIdsOfService(UnitType unitType, uint256 serviceId) external view + returns (uint256 numUnitIds, uint32[] memory unitIds); +} + +/// @dev No rewards are available in the contract. +error NoRewardsAvailable(); + +/// @dev Maximum number of staking services is reached. +/// @param maxNumServices Maximum number of staking services. +error MaxNumServicesReached(uint256 maxNumServices); + +/// @dev Received lower value than the expected one. +/// @param provided Provided value is lower. +/// @param expected Expected value. +error LowerThan(uint256 provided, uint256 expected); + +/// @dev Required service configuration is wrong. +/// @param serviceId Service Id. +error WrongServiceConfiguration(uint256 serviceId); + +/// @dev Service is not staked. +/// @param serviceId Service Id. +error ServiceNotStaked(uint256 serviceId); + +// Service Info struct +struct ServiceInfo { + // Service multisig address + address multisig; + // Service owner + address owner; + // Service multisig nonce + uint256 nonce; + // Staking start time + uint256 tsStart; + // Accumulated service staking reward + uint256 reward; +} + +/// @title ServiceStakingBase - Base abstract smart contract for staking a service by its owner +/// @author Aleksandr Kuperman - +/// @author Andrey Lebedev - +/// @author Mariapia Moscatiello - +abstract contract ServiceStakingBase is ERC721TokenReceiver, IErrorsRegistries { + struct StakingParams { + // Maximum number of staking services + uint256 maxNumServices; + // Rewards per second + uint256 rewardsPerSecond; + // Minimum service staking deposit value required for staking + uint256 minStakingDeposit; + // Liveness period + uint256 livenessPeriod; + // Liveness ratio in the format of 1e18 + uint256 livenessRatio; + // Number of agent instances in the service + uint256 numAgentInstances; + // Optional agent Ids requirement + uint256[] agentIds; + // Optional service multisig threshold requirement + uint256 threshold; + // Optional service configuration hash requirement + bytes32 configHash; + } + + event ServiceStaked(uint256 indexed serviceId, address indexed owner, address indexed multisig, uint256 nonce); + event Checkpoint(uint256 availableRewards, uint256 numServices); + event ServiceUnstaked(uint256 indexed serviceId, address indexed owner, address indexed multisig, uint256 nonce, + uint256 reward, uint256 tsStart); + event Deposit(address indexed sender, uint256 amount, uint256 balance, uint256 availableRewards); + event Withdraw(address indexed to, uint256 amount); + + // Contract version + string public constant VERSION = "0.1.0"; + // Maximum number of staking services + uint256 public immutable maxNumServices; + // Rewards per second + uint256 public immutable rewardsPerSecond; + // Minimum service staking deposit value required for staking + uint256 public immutable minStakingDeposit; + // Liveness period + uint256 public immutable livenessPeriod; + // Liveness ratio in the format of 1e18 + uint256 public immutable livenessRatio; + // Number of agent instances in the service + uint256 public immutable numAgentInstances; + // Optional service multisig threshold requirement + uint256 public immutable threshold; + // Optional service configuration hash requirement + bytes32 public immutable configHash; + // ServiceRegistry contract address + address public immutable serviceRegistry; + + // Token / ETH balance + uint256 public balance; + // Token / ETH available rewards + uint256 public availableRewards; + // Timestamp of the last checkpoint + uint256 public tsCheckpoint; + // Optional agent Ids requirement + uint256[] public agentIds; + // Mapping of serviceId => staking service info + mapping (uint256 => ServiceInfo) public mapServiceInfo; + // Set of currently staking serviceIds + uint256[] public setServiceIds; + + /// @dev ServiceStakingBase constructor. + /// @param _stakingParams Service staking parameters. + /// @param _serviceRegistry ServiceRegistry contract address. + constructor(StakingParams memory _stakingParams, address _serviceRegistry) { + // Initial checks + if (_stakingParams.maxNumServices == 0 || _stakingParams.rewardsPerSecond == 0 || + _stakingParams.minStakingDeposit == 0 || _stakingParams.livenessPeriod == 0 || + _stakingParams.livenessRatio == 0 || _stakingParams.numAgentInstances == 0) { + revert ZeroValue(); + } + if (_serviceRegistry == address(0)) { + revert ZeroAddress(); + } + + // Assign all the required parameters + maxNumServices = _stakingParams.maxNumServices; + rewardsPerSecond = _stakingParams.rewardsPerSecond; + minStakingDeposit = _stakingParams.minStakingDeposit; + livenessPeriod = _stakingParams.livenessPeriod; + livenessRatio = _stakingParams.livenessRatio; + numAgentInstances = _stakingParams.numAgentInstances; + serviceRegistry = _serviceRegistry; + + // Assign optional parameters + threshold = _stakingParams.threshold; + configHash = _stakingParams.configHash; + + // Assign agent Ids, if applicable + uint256 size = _stakingParams.agentIds.length; + uint256 agentId; + if (size > 0) { + for (uint256 i = 0; i < size; ++i) { + // Agent Ids must be unique and in ascending order + if (_stakingParams.agentIds[i] <= agentId) { + revert WrongAgentId(_stakingParams.agentIds[i]); + } + agentId = _stakingParams.agentIds[i]; + agentIds.push(agentId); + } + } + + // Set the checkpoint timestamp to be the deployment one + tsCheckpoint = block.timestamp; + } + + /// @dev Checks token / ETH staking deposit. + /// @param stakingDeposit Staking deposit. + function _checkTokenStakingDeposit(uint256, uint256 stakingDeposit) internal view virtual { + // The staking deposit derived from a security deposit value must be greater or equal to the minimum defined one + if (stakingDeposit < minStakingDeposit) { + revert LowerThan(stakingDeposit, minStakingDeposit); + } + } + + /// @dev Withdraws the reward amount to a service owner. + /// @param to Address to. + /// @param amount Amount to withdraw. + function _withdraw(address to, uint256 amount) internal virtual; + + /// @dev Stakes the service. + /// @param serviceId Service Id. + function stake(uint256 serviceId) external { + // Check if there available rewards + if (availableRewards == 0) { + revert NoRewardsAvailable(); + } + + // Check for the maximum number of staking services + uint256 numStakingServices = setServiceIds.length; + if (numStakingServices == maxNumServices) { + revert MaxNumServicesReached(maxNumServices); + } + + // Check the service conditions for staking + (uint96 stakingDeposit, address multisig, bytes32 hash, uint256 agentThreshold, uint256 maxNumInstances, , uint8 state) = + IService(serviceRegistry).mapServices(serviceId); + + // Check the number of agent instances + if (numAgentInstances != maxNumInstances) { + revert WrongServiceConfiguration(serviceId); + } + + // Check the configuration hash, if applicable + if (configHash != bytes32(0) && configHash != hash) { + revert WrongServiceConfiguration(serviceId); + } + // Check the threshold, if applicable + if (threshold > 0 && threshold != agentThreshold) { + revert WrongServiceConfiguration(serviceId); + } + // The service must be deployed + if (state != 4) { + revert WrongServiceState(state, serviceId); + } + // Check the agent Ids requirement, if applicable + uint256 size = agentIds.length; + if (size > 0) { + (uint256 numAgents, uint32[] memory agents) = + IService(serviceRegistry).getUnitIdsOfService(IService.UnitType.Agent, serviceId); + + if (size != numAgents) { + revert WrongServiceConfiguration(serviceId); + } + for (uint256 i = 0; i < numAgents; ++i) { + if (agentIds[i] != agents[i]) { + revert WrongAgentId(agentIds[i]); + } + } + } + + // Check service staking deposit and token, if applicable + _checkTokenStakingDeposit(serviceId, stakingDeposit); + + // Transfer the service for staking + IService(serviceRegistry).safeTransferFrom(msg.sender, address(this), serviceId); + + // ServiceInfo struct will be an empty one since otherwise the safeTransferFrom above would fail + ServiceInfo storage sInfo = mapServiceInfo[serviceId]; + sInfo.multisig = multisig; + sInfo.owner = msg.sender; + uint256 nonce = IMultisig(multisig).nonce(); + sInfo.nonce = nonce; + sInfo.tsStart = block.timestamp; + + // Add the service Id to the set of staked services + setServiceIds.push(serviceId); + + emit ServiceStaked(serviceId, msg.sender, multisig, nonce); + } + + /// @dev Calculates staking rewards for all services at current timestamp. + /// @param lastAvailableRewards Available amount of rewards. + /// @param numServices Number of services eligible for the reward that passed the liveness check. + /// @param totalRewards Total calculated rewards. + /// @param eligibleServiceIds Service Ids eligible for rewards. + /// @param eligibleServiceRewards Corresponding rewards for eligible service Ids. + /// @param serviceIds All the staking service Ids. + /// @param serviceNonces Current service nonces. + function _calculateStakingRewards() internal view returns ( + uint256 lastAvailableRewards, + uint256 numServices, + uint256 totalRewards, + uint256[] memory eligibleServiceIds, + uint256[] memory eligibleServiceRewards, + uint256[] memory serviceIds, + uint256[] memory serviceNonces + ) + { + // Get the service Ids set length + uint256 size = setServiceIds.length; + serviceIds = new uint256[](size); + + // Record service Ids + for (uint256 i = 0; i < size; ++i) { + // Get current service Id + serviceIds[i] = setServiceIds[i]; + } + + // Check the last checkpoint timestamp and the liveness period + uint256 tsCheckpointLast = tsCheckpoint; + if (block.timestamp - tsCheckpointLast >= livenessPeriod) { + // Get available rewards and last checkpoint timestamp + lastAvailableRewards = availableRewards; + + // If available rewards are not zero, proceed with staking calculation + if (lastAvailableRewards > 0) { + // Get necessary arrays + eligibleServiceIds = new uint256[](size); + eligibleServiceRewards = new uint256[](size); + serviceNonces = new uint256[](size); + + // Calculate each staked service reward eligibility + for (uint256 i = 0; i < size; ++i) { + // Get the service info + ServiceInfo storage curInfo = mapServiceInfo[serviceIds[i]]; + + // Get current service multisig nonce + serviceNonces[i] = IMultisig(curInfo.multisig).nonce(); + + // Calculate the liveness nonce ratio + // Get the last service checkpoint: staking start time or the global checkpoint timestamp + uint256 serviceCheckpoint = tsCheckpointLast; + uint256 ts = curInfo.tsStart; + // Adjust the service checkpoint time if the service was staking less than the current staking period + if (ts > serviceCheckpoint) { + serviceCheckpoint = ts; + } + + // Calculate the liveness ratio in 1e18 value + // This subtraction is always positive or zero, as the last checkpoint can be at most block.timestamp + ts = block.timestamp - serviceCheckpoint; + uint256 ratio; + // If the checkpoint was called in the exact same block, the ratio is zero + if (ts > 0) { + ratio = ((serviceNonces[i] - curInfo.nonce) * 1e18) / ts; + } + + // Record the reward for the service if it has provided enough transactions + if (ratio >= livenessRatio) { + // Calculate the reward up until now and record its value for the corresponding service + uint256 reward = rewardsPerSecond * ts; + totalRewards += reward; + eligibleServiceRewards[numServices] = reward; + eligibleServiceIds[numServices] = serviceIds[i]; + ++numServices; + } + } + } + } + } + + /// @dev Checkpoint to allocate rewards up until a current time. + /// @return All staking service Ids. + /// @return All staking updated nonces. + /// @return Number of reward-eligible staking services during current checkpoint period. + /// @return Eligible service Ids. + /// @return Eligible service rewards. + /// @return success True, if the checkpoint was successful. + function checkpoint() public returns ( + uint256[] memory, + uint256[] memory, + uint256, + uint256[] memory, + uint256[] memory, + bool success + ) + { + // Calculate staking rewards + (uint256 lastAvailableRewards, uint256 numServices, uint256 totalRewards, + uint256[] memory eligibleServiceIds, uint256[] memory eligibleServiceRewards, + uint256[] memory serviceIds, uint256[] memory serviceNonces) = _calculateStakingRewards(); + + // If there are eligible services, proceed with staking calculation and update rewards + if (numServices > 0) { + // If total allocated rewards are not enough, adjust the reward value + if (totalRewards > lastAvailableRewards) { + // Traverse all the eligible services and adjust their rewards proportional to leftovers + uint256 updatedReward; + uint256 updatedTotalRewards; + uint256 curServiceId; + for (uint256 i = 1; i < numServices; ++i) { + // Calculate the updated reward + updatedReward = (eligibleServiceRewards[i] * lastAvailableRewards) / totalRewards; + // Add to the total updated reward + updatedTotalRewards += updatedReward; + // Add reward to the overall service reward + curServiceId = eligibleServiceIds[i]; + mapServiceInfo[curServiceId].reward += updatedReward; + } + + // Process the first service in the set + updatedReward = (eligibleServiceRewards[0] * lastAvailableRewards) / totalRewards; + updatedTotalRewards += updatedReward; + curServiceId = eligibleServiceIds[0]; + // If the reward adjustment happened to have small leftovers, add it to the first service + if (lastAvailableRewards > updatedTotalRewards) { + updatedReward += lastAvailableRewards - updatedTotalRewards; + } + // Add reward to the overall service reward + mapServiceInfo[curServiceId].reward += updatedReward; + // Set available rewards to zero + lastAvailableRewards = 0; + } else { + // Traverse all the eligible services and add to their rewards + for (uint256 i = 0; i < numServices; ++i) { + // Add reward to the service overall reward + uint256 curServiceId = eligibleServiceIds[i]; + mapServiceInfo[curServiceId].reward += eligibleServiceRewards[i]; + } + + // Adjust available rewards + // TODO: Fuzz this such that totalRewards is never bigger than lastAvailableRewards + lastAvailableRewards -= totalRewards; + } + + // Update the storage value of available rewards + availableRewards = lastAvailableRewards; + } + + // If service nonces were updated, then the checkpoint takes place, otherwise only service Ids are returned + if (serviceNonces.length > 0) { + // Updated current service nonces + for (uint256 i = 0; i < serviceIds.length; ++i) { + // Get the current service Id + uint256 curServiceId = serviceIds[i]; + mapServiceInfo[curServiceId].nonce = serviceNonces[i]; + } + + // Record the current timestamp such that next calculations start from this point of time + tsCheckpoint = block.timestamp; + + success = true; + + emit Checkpoint(lastAvailableRewards, numServices); + } + + return (serviceIds, serviceNonces, numServices, eligibleServiceIds, eligibleServiceRewards, success); + } + + /// @dev Unstakes the service. + /// @param serviceId Service Id. + function unstake(uint256 serviceId) external { + ServiceInfo memory sInfo = mapServiceInfo[serviceId]; + // Check for the service ownership + if (msg.sender != sInfo.owner) { + revert OwnerOnly(msg.sender, sInfo.owner); + } + + // Call the checkpoint + (uint256[] memory serviceIds, , , , , ) = checkpoint(); + + // Get the service index in the set of services + // The index must always exist as the service is currently staked, otherwise it has no record in the map + uint256 idx; + for (; idx < serviceIds.length; ++idx) { + if (serviceIds[idx] == serviceId) { + break; + } + } + + // Transfer the service back to the owner + IService(serviceRegistry).safeTransferFrom(address(this), msg.sender, serviceId); + + // Transfer accumulated rewards to the service multisig + if (sInfo.reward > 0) { + _withdraw(sInfo.multisig, sInfo.reward); + } + + // Clear all the data about the unstaked service + // Delete the service info struct + delete mapServiceInfo[serviceId]; + + // Update the set of staked service Ids + setServiceIds[idx] = setServiceIds[setServiceIds.length - 1]; + setServiceIds.pop(); + + emit ServiceUnstaked(serviceId, msg.sender, sInfo.multisig, sInfo.nonce, sInfo.reward, sInfo.tsStart); + } + + /// @dev Calculates service staking reward at current timestamp. + /// @param serviceId Service Id. + /// @return reward Service reward. + function calculateServiceStakingReward(uint256 serviceId) external view returns (uint256 reward) { + // Get current service reward + ServiceInfo memory sInfo = mapServiceInfo[serviceId]; + reward = sInfo.reward; + + // Check if the service is staked + if (sInfo.tsStart == 0) { + revert ServiceNotStaked(serviceId); + } + + // Calculate overall staking rewards + (uint256 lastAvailableRewards, uint256 numServices, uint256 totalRewards, uint256[] memory eligibleServiceIds, + uint256[] memory eligibleServiceRewards, , ) = _calculateStakingRewards(); + + // If there are eligible services, proceed with staking calculation and update rewards for the service Id + if (numServices > 0) { + // Get the service index in the eligible service set and calculate its latest reward + for (uint256 i = 0; i < eligibleServiceIds.length; ++i) { + if (eligibleServiceIds[i] == serviceId) { + // If total allocated rewards are not enough, adjust the reward value + if (totalRewards > lastAvailableRewards) { + reward += (eligibleServiceRewards[i] * lastAvailableRewards) / totalRewards; + } else { + reward += eligibleServiceRewards[i]; + } + break; + } + } + } + } +} diff --git a/audits/internal4/analysis/contracts/ServiceStakingNativeToken-flatten.sol b/audits/internal4/analysis/contracts/ServiceStakingNativeToken-flatten.sol new file mode 100644 index 00000000..1ce18170 --- /dev/null +++ b/audits/internal4/analysis/contracts/ServiceStakingNativeToken-flatten.sol @@ -0,0 +1,922 @@ +// Sources flattened with hardhat v2.17.1 https://hardhat.org + +// SPDX-License-Identifier: MIT + +// File contracts/interfaces/IErrorsRegistries.sol + +// Original license: SPDX_License_Identifier: MIT +pragma solidity ^0.8.21; + +/// @dev Errors. +interface IErrorsRegistries { + /// @dev Only `manager` has a privilege, but the `sender` was provided. + /// @param sender Sender address. + /// @param manager Required sender address as a manager. + error ManagerOnly(address sender, address manager); + + /// @dev Only `owner` has a privilege, but the `sender` was provided. + /// @param sender Sender address. + /// @param owner Required sender address as an owner. + error OwnerOnly(address sender, address owner); + + /// @dev Hash already exists in the records. + error HashExists(); + + /// @dev Provided zero address. + error ZeroAddress(); + + /// @dev Agent Id is not correctly provided for the current routine. + /// @param agentId Component Id. + error WrongAgentId(uint256 agentId); + + /// @dev Wrong length of two arrays. + /// @param numValues1 Number of values in a first array. + /// @param numValues2 Numberf of values in a second array. + error WrongArrayLength(uint256 numValues1, uint256 numValues2); + + /// @dev Canonical agent Id is not found. + /// @param agentId Canonical agent Id. + error AgentNotFound(uint256 agentId); + + /// @dev Component Id is not found. + /// @param componentId Component Id. + error ComponentNotFound(uint256 componentId); + + /// @dev Multisig threshold is out of bounds. + /// @param currentThreshold Current threshold value. + /// @param minThreshold Minimum possible threshold value. + /// @param maxThreshold Maximum possible threshold value. + error WrongThreshold(uint256 currentThreshold, uint256 minThreshold, uint256 maxThreshold); + + /// @dev Agent instance is already registered with a specified `operator`. + /// @param operator Operator that registered an instance. + error AgentInstanceRegistered(address operator); + + /// @dev Wrong operator is specified when interacting with a specified `serviceId`. + /// @param serviceId Service Id. + error WrongOperator(uint256 serviceId); + + /// @dev Operator has no registered instances in the service. + /// @param operator Operator address. + /// @param serviceId Service Id. + error OperatorHasNoInstances(address operator, uint256 serviceId); + + /// @dev Canonical `agentId` is not found as a part of `serviceId`. + /// @param agentId Canonical agent Id. + /// @param serviceId Service Id. + error AgentNotInService(uint256 agentId, uint256 serviceId); + + /// @dev The contract is paused. + error Paused(); + + /// @dev Zero value when it has to be different from zero. + error ZeroValue(); + + /// @dev Value overflow. + /// @param provided Overflow value. + /// @param max Maximum possible value. + error Overflow(uint256 provided, uint256 max); + + /// @dev Service must be inactive. + /// @param serviceId Service Id. + error ServiceMustBeInactive(uint256 serviceId); + + /// @dev All the agent instance slots for a specific `serviceId` are filled. + /// @param serviceId Service Id. + error AgentInstancesSlotsFilled(uint256 serviceId); + + /// @dev Wrong state of a service. + /// @param state Service state. + /// @param serviceId Service Id. + error WrongServiceState(uint256 state, uint256 serviceId); + + /// @dev Only own service multisig is allowed. + /// @param provided Provided address. + /// @param expected Expected multisig address. + /// @param serviceId Service Id. + error OnlyOwnServiceMultisig(address provided, address expected, uint256 serviceId); + + /// @dev Multisig is not whitelisted. + /// @param multisig Address of a multisig implementation. + error UnauthorizedMultisig(address multisig); + + /// @dev Incorrect deposit provided for the registration activation. + /// @param sent Sent amount. + /// @param expected Expected amount. + /// @param serviceId Service Id. + error IncorrectRegistrationDepositValue(uint256 sent, uint256 expected, uint256 serviceId); + + /// @dev Insufficient value provided for the agent instance bonding. + /// @param sent Sent amount. + /// @param expected Expected amount. + /// @param serviceId Service Id. + error IncorrectAgentBondingValue(uint256 sent, uint256 expected, uint256 serviceId); + + /// @dev Failure of a transfer. + /// @param token Address of a token. + /// @param from Address `from`. + /// @param to Address `to`. + /// @param value Value. + error TransferFailed(address token, address from, address to, uint256 value); + + /// @dev Caught reentrancy violation. + error ReentrancyGuard(); +} + + +// File lib/solmate/src/tokens/ERC721.sol +/// @notice Modern, minimalist, and gas efficient ERC-721 implementation. +/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC721.sol) +abstract contract ERC721 { + /*////////////////////////////////////////////////////////////// + EVENTS + //////////////////////////////////////////////////////////////*/ + + event Transfer(address indexed from, address indexed to, uint256 indexed id); + + event Approval(address indexed owner, address indexed spender, uint256 indexed id); + + event ApprovalForAll(address indexed owner, address indexed operator, bool approved); + + /*////////////////////////////////////////////////////////////// + METADATA STORAGE/LOGIC + //////////////////////////////////////////////////////////////*/ + + string public name; + + string public symbol; + + function tokenURI(uint256 id) public view virtual returns (string memory); + + /*////////////////////////////////////////////////////////////// + ERC721 BALANCE/OWNER STORAGE + //////////////////////////////////////////////////////////////*/ + + mapping(uint256 => address) internal _ownerOf; + + mapping(address => uint256) internal _balanceOf; + + function ownerOf(uint256 id) public view virtual returns (address owner) { + require((owner = _ownerOf[id]) != address(0), "NOT_MINTED"); + } + + function balanceOf(address owner) public view virtual returns (uint256) { + require(owner != address(0), "ZERO_ADDRESS"); + + return _balanceOf[owner]; + } + + /*////////////////////////////////////////////////////////////// + ERC721 APPROVAL STORAGE + //////////////////////////////////////////////////////////////*/ + + mapping(uint256 => address) public getApproved; + + mapping(address => mapping(address => bool)) public isApprovedForAll; + + /*////////////////////////////////////////////////////////////// + CONSTRUCTOR + //////////////////////////////////////////////////////////////*/ + + constructor(string memory _name, string memory _symbol) { + name = _name; + symbol = _symbol; + } + + /*////////////////////////////////////////////////////////////// + ERC721 LOGIC + //////////////////////////////////////////////////////////////*/ + + function approve(address spender, uint256 id) public virtual { + address owner = _ownerOf[id]; + + require(msg.sender == owner || isApprovedForAll[owner][msg.sender], "NOT_AUTHORIZED"); + + getApproved[id] = spender; + + emit Approval(owner, spender, id); + } + + function setApprovalForAll(address operator, bool approved) public virtual { + isApprovedForAll[msg.sender][operator] = approved; + + emit ApprovalForAll(msg.sender, operator, approved); + } + + function transferFrom( + address from, + address to, + uint256 id + ) public virtual { + require(from == _ownerOf[id], "WRONG_FROM"); + + require(to != address(0), "INVALID_RECIPIENT"); + + require( + msg.sender == from || isApprovedForAll[from][msg.sender] || msg.sender == getApproved[id], + "NOT_AUTHORIZED" + ); + + // Underflow of the sender's balance is impossible because we check for + // ownership above and the recipient's balance can't realistically overflow. + unchecked { + _balanceOf[from]--; + + _balanceOf[to]++; + } + + _ownerOf[id] = to; + + delete getApproved[id]; + + emit Transfer(from, to, id); + } + + function safeTransferFrom( + address from, + address to, + uint256 id + ) public virtual { + transferFrom(from, to, id); + + if (to.code.length != 0) + require( + ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, "") == + ERC721TokenReceiver.onERC721Received.selector, + "UNSAFE_RECIPIENT" + ); + } + + function safeTransferFrom( + address from, + address to, + uint256 id, + bytes calldata data + ) public virtual { + transferFrom(from, to, id); + + if (to.code.length != 0) + require( + ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, data) == + ERC721TokenReceiver.onERC721Received.selector, + "UNSAFE_RECIPIENT" + ); + } + + /*////////////////////////////////////////////////////////////// + ERC165 LOGIC + //////////////////////////////////////////////////////////////*/ + + function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) { + return + interfaceId == 0x01ffc9a7 || // ERC165 Interface ID for ERC165 + interfaceId == 0x80ac58cd || // ERC165 Interface ID for ERC721 + interfaceId == 0x5b5e139f; // ERC165 Interface ID for ERC721Metadata + } + + /*////////////////////////////////////////////////////////////// + INTERNAL MINT/BURN LOGIC + //////////////////////////////////////////////////////////////*/ + + function _mint(address to, uint256 id) internal virtual { + require(to != address(0), "INVALID_RECIPIENT"); + + require(_ownerOf[id] == address(0), "ALREADY_MINTED"); + + // Counter overflow is incredibly unrealistic. + unchecked { + _balanceOf[to]++; + } + + _ownerOf[id] = to; + + emit Transfer(address(0), to, id); + } + + function _burn(uint256 id) internal virtual { + address owner = _ownerOf[id]; + + require(owner != address(0), "NOT_MINTED"); + + // Ownership check above ensures no underflow. + unchecked { + _balanceOf[owner]--; + } + + delete _ownerOf[id]; + + delete getApproved[id]; + + emit Transfer(owner, address(0), id); + } + + /*////////////////////////////////////////////////////////////// + INTERNAL SAFE MINT LOGIC + //////////////////////////////////////////////////////////////*/ + + function _safeMint(address to, uint256 id) internal virtual { + _mint(to, id); + + if (to.code.length != 0) + require( + ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, "") == + ERC721TokenReceiver.onERC721Received.selector, + "UNSAFE_RECIPIENT" + ); + } + + function _safeMint( + address to, + uint256 id, + bytes memory data + ) internal virtual { + _mint(to, id); + + if (to.code.length != 0) + require( + ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, data) == + ERC721TokenReceiver.onERC721Received.selector, + "UNSAFE_RECIPIENT" + ); + } +} + +/// @notice A generic interface for a contract which properly accepts ERC721 tokens. +/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC721.sol) +abstract contract ERC721TokenReceiver { + function onERC721Received( + address, + address, + uint256, + bytes calldata + ) external virtual returns (bytes4) { + return ERC721TokenReceiver.onERC721Received.selector; + } +} + + +// File contracts/staking/ServiceStakingBase.sol +// Multisig interface +interface IMultisig { + /// @dev Gets the multisig nonce. + /// @return Multisig nonce. + function nonce() external view returns (uint256); +} + +// Service Registry interface +interface IService { + enum UnitType { + Component, + Agent + } + + /// @dev Transfers the service that was previously approved to this contract address. + /// @param from Account address to transfer from. + /// @param to Account address to transfer to. + /// @param id Service Id. + function safeTransferFrom(address from, address to, uint256 id) external; + + /// @dev Gets service parameters from the map of services. + /// @param serviceId Service Id. + /// @return securityDeposit Registration activation deposit. + /// @return multisig Service multisig address. + /// @return configHash IPFS hashes pointing to the config metadata. + /// @return threshold Agent instance signers threshold. + /// @return maxNumAgentInstances Total number of agent instances. + /// @return numAgentInstances Actual number of agent instances. + /// @return state Service state. + function mapServices(uint256 serviceId) external view returns ( + uint96 securityDeposit, + address multisig, + bytes32 configHash, + uint32 threshold, + uint32 maxNumAgentInstances, + uint32 numAgentInstances, + uint8 state + ); + + /// @dev Gets the full set of linearized components / canonical agent Ids for a specified service. + /// @notice The service must be / have been deployed in order to get the actual data. + /// @param serviceId Service Id. + /// @return numUnitIds Number of component / agent Ids. + /// @return unitIds Set of component / agent Ids. + function getUnitIdsOfService(UnitType unitType, uint256 serviceId) external view + returns (uint256 numUnitIds, uint32[] memory unitIds); +} + +/// @dev No rewards are available in the contract. +error NoRewardsAvailable(); + +/// @dev Maximum number of staking services is reached. +/// @param maxNumServices Maximum number of staking services. +error MaxNumServicesReached(uint256 maxNumServices); + +/// @dev Received lower value than the expected one. +/// @param provided Provided value is lower. +/// @param expected Expected value. +error LowerThan(uint256 provided, uint256 expected); + +/// @dev Required service configuration is wrong. +/// @param serviceId Service Id. +error WrongServiceConfiguration(uint256 serviceId); + +/// @dev Service is not staked. +/// @param serviceId Service Id. +error ServiceNotStaked(uint256 serviceId); + +// Service Info struct +struct ServiceInfo { + // Service multisig address + address multisig; + // Service owner + address owner; + // Service multisig nonce + uint256 nonce; + // Staking start time + uint256 tsStart; + // Accumulated service staking reward + uint256 reward; +} + +/// @title ServiceStakingBase - Base abstract smart contract for staking a service by its owner +/// @author Aleksandr Kuperman - +/// @author Andrey Lebedev - +/// @author Mariapia Moscatiello - +abstract contract ServiceStakingBase is ERC721TokenReceiver, IErrorsRegistries { + struct StakingParams { + // Maximum number of staking services + uint256 maxNumServices; + // Rewards per second + uint256 rewardsPerSecond; + // Minimum service staking deposit value required for staking + uint256 minStakingDeposit; + // Liveness period + uint256 livenessPeriod; + // Liveness ratio in the format of 1e18 + uint256 livenessRatio; + // Number of agent instances in the service + uint256 numAgentInstances; + // Optional agent Ids requirement + uint256[] agentIds; + // Optional service multisig threshold requirement + uint256 threshold; + // Optional service configuration hash requirement + bytes32 configHash; + } + + event ServiceStaked(uint256 indexed serviceId, address indexed owner, address indexed multisig, uint256 nonce); + event Checkpoint(uint256 availableRewards, uint256 numServices); + event ServiceUnstaked(uint256 indexed serviceId, address indexed owner, address indexed multisig, uint256 nonce, + uint256 reward, uint256 tsStart); + event Deposit(address indexed sender, uint256 amount, uint256 balance, uint256 availableRewards); + event Withdraw(address indexed to, uint256 amount); + + // Contract version + string public constant VERSION = "0.1.0"; + // Maximum number of staking services + uint256 public immutable maxNumServices; + // Rewards per second + uint256 public immutable rewardsPerSecond; + // Minimum service staking deposit value required for staking + uint256 public immutable minStakingDeposit; + // Liveness period + uint256 public immutable livenessPeriod; + // Liveness ratio in the format of 1e18 + uint256 public immutable livenessRatio; + // Number of agent instances in the service + uint256 public immutable numAgentInstances; + // Optional service multisig threshold requirement + uint256 public immutable threshold; + // Optional service configuration hash requirement + bytes32 public immutable configHash; + // ServiceRegistry contract address + address public immutable serviceRegistry; + + // Token / ETH balance + uint256 public balance; + // Token / ETH available rewards + uint256 public availableRewards; + // Timestamp of the last checkpoint + uint256 public tsCheckpoint; + // Optional agent Ids requirement + uint256[] public agentIds; + // Mapping of serviceId => staking service info + mapping (uint256 => ServiceInfo) public mapServiceInfo; + // Set of currently staking serviceIds + uint256[] public setServiceIds; + + /// @dev ServiceStakingBase constructor. + /// @param _stakingParams Service staking parameters. + /// @param _serviceRegistry ServiceRegistry contract address. + constructor(StakingParams memory _stakingParams, address _serviceRegistry) { + // Initial checks + if (_stakingParams.maxNumServices == 0 || _stakingParams.rewardsPerSecond == 0 || + _stakingParams.minStakingDeposit == 0 || _stakingParams.livenessPeriod == 0 || + _stakingParams.livenessRatio == 0 || _stakingParams.numAgentInstances == 0) { + revert ZeroValue(); + } + if (_serviceRegistry == address(0)) { + revert ZeroAddress(); + } + + // Assign all the required parameters + maxNumServices = _stakingParams.maxNumServices; + rewardsPerSecond = _stakingParams.rewardsPerSecond; + minStakingDeposit = _stakingParams.minStakingDeposit; + livenessPeriod = _stakingParams.livenessPeriod; + livenessRatio = _stakingParams.livenessRatio; + numAgentInstances = _stakingParams.numAgentInstances; + serviceRegistry = _serviceRegistry; + + // Assign optional parameters + threshold = _stakingParams.threshold; + configHash = _stakingParams.configHash; + + // Assign agent Ids, if applicable + uint256 size = _stakingParams.agentIds.length; + uint256 agentId; + if (size > 0) { + for (uint256 i = 0; i < size; ++i) { + // Agent Ids must be unique and in ascending order + if (_stakingParams.agentIds[i] <= agentId) { + revert WrongAgentId(_stakingParams.agentIds[i]); + } + agentId = _stakingParams.agentIds[i]; + agentIds.push(agentId); + } + } + + // Set the checkpoint timestamp to be the deployment one + tsCheckpoint = block.timestamp; + } + + /// @dev Checks token / ETH staking deposit. + /// @param stakingDeposit Staking deposit. + function _checkTokenStakingDeposit(uint256, uint256 stakingDeposit) internal view virtual { + // The staking deposit derived from a security deposit value must be greater or equal to the minimum defined one + if (stakingDeposit < minStakingDeposit) { + revert LowerThan(stakingDeposit, minStakingDeposit); + } + } + + /// @dev Withdraws the reward amount to a service owner. + /// @param to Address to. + /// @param amount Amount to withdraw. + function _withdraw(address to, uint256 amount) internal virtual; + + /// @dev Stakes the service. + /// @param serviceId Service Id. + function stake(uint256 serviceId) external { + // Check if there available rewards + if (availableRewards == 0) { + revert NoRewardsAvailable(); + } + + // Check for the maximum number of staking services + uint256 numStakingServices = setServiceIds.length; + if (numStakingServices == maxNumServices) { + revert MaxNumServicesReached(maxNumServices); + } + + // Check the service conditions for staking + (uint96 stakingDeposit, address multisig, bytes32 hash, uint256 agentThreshold, uint256 maxNumInstances, , uint8 state) = + IService(serviceRegistry).mapServices(serviceId); + + // Check the number of agent instances + if (numAgentInstances != maxNumInstances) { + revert WrongServiceConfiguration(serviceId); + } + + // Check the configuration hash, if applicable + if (configHash != bytes32(0) && configHash != hash) { + revert WrongServiceConfiguration(serviceId); + } + // Check the threshold, if applicable + if (threshold > 0 && threshold != agentThreshold) { + revert WrongServiceConfiguration(serviceId); + } + // The service must be deployed + if (state != 4) { + revert WrongServiceState(state, serviceId); + } + // Check the agent Ids requirement, if applicable + uint256 size = agentIds.length; + if (size > 0) { + (uint256 numAgents, uint32[] memory agents) = + IService(serviceRegistry).getUnitIdsOfService(IService.UnitType.Agent, serviceId); + + if (size != numAgents) { + revert WrongServiceConfiguration(serviceId); + } + for (uint256 i = 0; i < numAgents; ++i) { + if (agentIds[i] != agents[i]) { + revert WrongAgentId(agentIds[i]); + } + } + } + + // Check service staking deposit and token, if applicable + _checkTokenStakingDeposit(serviceId, stakingDeposit); + + // Transfer the service for staking + IService(serviceRegistry).safeTransferFrom(msg.sender, address(this), serviceId); + + // ServiceInfo struct will be an empty one since otherwise the safeTransferFrom above would fail + ServiceInfo storage sInfo = mapServiceInfo[serviceId]; + sInfo.multisig = multisig; + sInfo.owner = msg.sender; + uint256 nonce = IMultisig(multisig).nonce(); + sInfo.nonce = nonce; + sInfo.tsStart = block.timestamp; + + // Add the service Id to the set of staked services + setServiceIds.push(serviceId); + + emit ServiceStaked(serviceId, msg.sender, multisig, nonce); + } + + /// @dev Calculates staking rewards for all services at current timestamp. + /// @param lastAvailableRewards Available amount of rewards. + /// @param numServices Number of services eligible for the reward that passed the liveness check. + /// @param totalRewards Total calculated rewards. + /// @param eligibleServiceIds Service Ids eligible for rewards. + /// @param eligibleServiceRewards Corresponding rewards for eligible service Ids. + /// @param serviceIds All the staking service Ids. + /// @param serviceNonces Current service nonces. + function _calculateStakingRewards() internal view returns ( + uint256 lastAvailableRewards, + uint256 numServices, + uint256 totalRewards, + uint256[] memory eligibleServiceIds, + uint256[] memory eligibleServiceRewards, + uint256[] memory serviceIds, + uint256[] memory serviceNonces + ) + { + // Get the service Ids set length + uint256 size = setServiceIds.length; + serviceIds = new uint256[](size); + + // Record service Ids + for (uint256 i = 0; i < size; ++i) { + // Get current service Id + serviceIds[i] = setServiceIds[i]; + } + + // Check the last checkpoint timestamp and the liveness period + uint256 tsCheckpointLast = tsCheckpoint; + if (block.timestamp - tsCheckpointLast >= livenessPeriod) { + // Get available rewards and last checkpoint timestamp + lastAvailableRewards = availableRewards; + + // If available rewards are not zero, proceed with staking calculation + if (lastAvailableRewards > 0) { + // Get necessary arrays + eligibleServiceIds = new uint256[](size); + eligibleServiceRewards = new uint256[](size); + serviceNonces = new uint256[](size); + + // Calculate each staked service reward eligibility + for (uint256 i = 0; i < size; ++i) { + // Get the service info + ServiceInfo storage curInfo = mapServiceInfo[serviceIds[i]]; + + // Get current service multisig nonce + serviceNonces[i] = IMultisig(curInfo.multisig).nonce(); + + // Calculate the liveness nonce ratio + // Get the last service checkpoint: staking start time or the global checkpoint timestamp + uint256 serviceCheckpoint = tsCheckpointLast; + uint256 ts = curInfo.tsStart; + // Adjust the service checkpoint time if the service was staking less than the current staking period + if (ts > serviceCheckpoint) { + serviceCheckpoint = ts; + } + + // Calculate the liveness ratio in 1e18 value + // This subtraction is always positive or zero, as the last checkpoint can be at most block.timestamp + ts = block.timestamp - serviceCheckpoint; + uint256 ratio; + // If the checkpoint was called in the exact same block, the ratio is zero + if (ts > 0) { + ratio = ((serviceNonces[i] - curInfo.nonce) * 1e18) / ts; + } + + // Record the reward for the service if it has provided enough transactions + if (ratio >= livenessRatio) { + // Calculate the reward up until now and record its value for the corresponding service + uint256 reward = rewardsPerSecond * ts; + totalRewards += reward; + eligibleServiceRewards[numServices] = reward; + eligibleServiceIds[numServices] = serviceIds[i]; + ++numServices; + } + } + } + } + } + + /// @dev Checkpoint to allocate rewards up until a current time. + /// @return All staking service Ids. + /// @return All staking updated nonces. + /// @return Number of reward-eligible staking services during current checkpoint period. + /// @return Eligible service Ids. + /// @return Eligible service rewards. + /// @return success True, if the checkpoint was successful. + function checkpoint() public returns ( + uint256[] memory, + uint256[] memory, + uint256, + uint256[] memory, + uint256[] memory, + bool success + ) + { + // Calculate staking rewards + (uint256 lastAvailableRewards, uint256 numServices, uint256 totalRewards, + uint256[] memory eligibleServiceIds, uint256[] memory eligibleServiceRewards, + uint256[] memory serviceIds, uint256[] memory serviceNonces) = _calculateStakingRewards(); + + // If there are eligible services, proceed with staking calculation and update rewards + if (numServices > 0) { + // If total allocated rewards are not enough, adjust the reward value + if (totalRewards > lastAvailableRewards) { + // Traverse all the eligible services and adjust their rewards proportional to leftovers + uint256 updatedReward; + uint256 updatedTotalRewards; + uint256 curServiceId; + for (uint256 i = 1; i < numServices; ++i) { + // Calculate the updated reward + updatedReward = (eligibleServiceRewards[i] * lastAvailableRewards) / totalRewards; + // Add to the total updated reward + updatedTotalRewards += updatedReward; + // Add reward to the overall service reward + curServiceId = eligibleServiceIds[i]; + mapServiceInfo[curServiceId].reward += updatedReward; + } + + // Process the first service in the set + updatedReward = (eligibleServiceRewards[0] * lastAvailableRewards) / totalRewards; + updatedTotalRewards += updatedReward; + curServiceId = eligibleServiceIds[0]; + // If the reward adjustment happened to have small leftovers, add it to the first service + if (lastAvailableRewards > updatedTotalRewards) { + updatedReward += lastAvailableRewards - updatedTotalRewards; + } + // Add reward to the overall service reward + mapServiceInfo[curServiceId].reward += updatedReward; + // Set available rewards to zero + lastAvailableRewards = 0; + } else { + // Traverse all the eligible services and add to their rewards + for (uint256 i = 0; i < numServices; ++i) { + // Add reward to the service overall reward + uint256 curServiceId = eligibleServiceIds[i]; + mapServiceInfo[curServiceId].reward += eligibleServiceRewards[i]; + } + + // Adjust available rewards + // TODO: Fuzz this such that totalRewards is never bigger than lastAvailableRewards + lastAvailableRewards -= totalRewards; + } + + // Update the storage value of available rewards + availableRewards = lastAvailableRewards; + } + + // If service nonces were updated, then the checkpoint takes place, otherwise only service Ids are returned + if (serviceNonces.length > 0) { + // Updated current service nonces + for (uint256 i = 0; i < serviceIds.length; ++i) { + // Get the current service Id + uint256 curServiceId = serviceIds[i]; + mapServiceInfo[curServiceId].nonce = serviceNonces[i]; + } + + // Record the current timestamp such that next calculations start from this point of time + tsCheckpoint = block.timestamp; + + success = true; + + emit Checkpoint(lastAvailableRewards, numServices); + } + + return (serviceIds, serviceNonces, numServices, eligibleServiceIds, eligibleServiceRewards, success); + } + + /// @dev Unstakes the service. + /// @param serviceId Service Id. + function unstake(uint256 serviceId) external { + ServiceInfo memory sInfo = mapServiceInfo[serviceId]; + // Check for the service ownership + if (msg.sender != sInfo.owner) { + revert OwnerOnly(msg.sender, sInfo.owner); + } + + // Call the checkpoint + (uint256[] memory serviceIds, , , , , ) = checkpoint(); + + // Get the service index in the set of services + // The index must always exist as the service is currently staked, otherwise it has no record in the map + uint256 idx; + for (; idx < serviceIds.length; ++idx) { + if (serviceIds[idx] == serviceId) { + break; + } + } + + // Transfer the service back to the owner + IService(serviceRegistry).safeTransferFrom(address(this), msg.sender, serviceId); + + // Transfer accumulated rewards to the service multisig + if (sInfo.reward > 0) { + _withdraw(sInfo.multisig, sInfo.reward); + } + + // Clear all the data about the unstaked service + // Delete the service info struct + delete mapServiceInfo[serviceId]; + + // Update the set of staked service Ids + setServiceIds[idx] = setServiceIds[setServiceIds.length - 1]; + setServiceIds.pop(); + + emit ServiceUnstaked(serviceId, msg.sender, sInfo.multisig, sInfo.nonce, sInfo.reward, sInfo.tsStart); + } + + /// @dev Calculates service staking reward at current timestamp. + /// @param serviceId Service Id. + /// @return reward Service reward. + function calculateServiceStakingReward(uint256 serviceId) external view returns (uint256 reward) { + // Get current service reward + ServiceInfo memory sInfo = mapServiceInfo[serviceId]; + reward = sInfo.reward; + + // Check if the service is staked + if (sInfo.tsStart == 0) { + revert ServiceNotStaked(serviceId); + } + + // Calculate overall staking rewards + (uint256 lastAvailableRewards, uint256 numServices, uint256 totalRewards, uint256[] memory eligibleServiceIds, + uint256[] memory eligibleServiceRewards, , ) = _calculateStakingRewards(); + + // If there are eligible services, proceed with staking calculation and update rewards for the service Id + if (numServices > 0) { + // Get the service index in the eligible service set and calculate its latest reward + for (uint256 i = 0; i < eligibleServiceIds.length; ++i) { + if (eligibleServiceIds[i] == serviceId) { + // If total allocated rewards are not enough, adjust the reward value + if (totalRewards > lastAvailableRewards) { + reward += (eligibleServiceRewards[i] * lastAvailableRewards) / totalRewards; + } else { + reward += eligibleServiceRewards[i]; + } + break; + } + } + } + } +} + + +// File contracts/staking/ServiceStakingNativeToken.sol +/// @title ServiceStakingNativeToken - Smart contract for staking a service with the service having a native network token as the deposit +/// @author Aleksandr Kuperman - +/// @author Andrey Lebedev - +/// @author Mariapia Moscatiello - +contract ServiceStakingNativeToken is ServiceStakingBase { + /// @dev ServiceStakingNativeToken constructor. + /// @param _stakingParams Service staking parameters. + /// @param _serviceRegistry ServiceRegistry contract address. + constructor(StakingParams memory _stakingParams, address _serviceRegistry) + ServiceStakingBase(_stakingParams, _serviceRegistry) + {} + + /// @dev Withdraws the reward amount to a service owner. + /// @param to Address to. + /// @param amount Amount to withdraw. + function _withdraw(address to, uint256 amount) internal override { + // Update the contract balance + // TODO: Fuzz this such that the amount is never bigger than the balance + balance -= amount; + + // Transfer the amount + (bool result, ) = to.call{value: amount}(""); + if (!result) { + revert TransferFailed(address(0), address(this), to, amount); + } + } + + receive() external payable { + // Add to the contract and available rewards balances + uint256 newBalance = balance + msg.value; + uint256 newAvailableRewards = availableRewards + msg.value; + + // Record the new actual balance and available rewards + balance = newBalance; + availableRewards = newAvailableRewards; + + emit Deposit(msg.sender, msg.value, newBalance, newAvailableRewards); + } +} diff --git a/audits/internal4/analysis/contracts/ServiceStakingToken-flatten.sol b/audits/internal4/analysis/contracts/ServiceStakingToken-flatten.sol new file mode 100644 index 00000000..ef74c5d6 --- /dev/null +++ b/audits/internal4/analysis/contracts/ServiceStakingToken-flatten.sol @@ -0,0 +1,1125 @@ +// Sources flattened with hardhat v2.17.1 https://hardhat.org + +// SPDX-License-Identifier: MIT + +// File contracts/interfaces/IErrorsRegistries.sol + +// Original license: SPDX_License_Identifier: MIT +pragma solidity ^0.8.21; + +/// @dev Errors. +interface IErrorsRegistries { + /// @dev Only `manager` has a privilege, but the `sender` was provided. + /// @param sender Sender address. + /// @param manager Required sender address as a manager. + error ManagerOnly(address sender, address manager); + + /// @dev Only `owner` has a privilege, but the `sender` was provided. + /// @param sender Sender address. + /// @param owner Required sender address as an owner. + error OwnerOnly(address sender, address owner); + + /// @dev Hash already exists in the records. + error HashExists(); + + /// @dev Provided zero address. + error ZeroAddress(); + + /// @dev Agent Id is not correctly provided for the current routine. + /// @param agentId Component Id. + error WrongAgentId(uint256 agentId); + + /// @dev Wrong length of two arrays. + /// @param numValues1 Number of values in a first array. + /// @param numValues2 Numberf of values in a second array. + error WrongArrayLength(uint256 numValues1, uint256 numValues2); + + /// @dev Canonical agent Id is not found. + /// @param agentId Canonical agent Id. + error AgentNotFound(uint256 agentId); + + /// @dev Component Id is not found. + /// @param componentId Component Id. + error ComponentNotFound(uint256 componentId); + + /// @dev Multisig threshold is out of bounds. + /// @param currentThreshold Current threshold value. + /// @param minThreshold Minimum possible threshold value. + /// @param maxThreshold Maximum possible threshold value. + error WrongThreshold(uint256 currentThreshold, uint256 minThreshold, uint256 maxThreshold); + + /// @dev Agent instance is already registered with a specified `operator`. + /// @param operator Operator that registered an instance. + error AgentInstanceRegistered(address operator); + + /// @dev Wrong operator is specified when interacting with a specified `serviceId`. + /// @param serviceId Service Id. + error WrongOperator(uint256 serviceId); + + /// @dev Operator has no registered instances in the service. + /// @param operator Operator address. + /// @param serviceId Service Id. + error OperatorHasNoInstances(address operator, uint256 serviceId); + + /// @dev Canonical `agentId` is not found as a part of `serviceId`. + /// @param agentId Canonical agent Id. + /// @param serviceId Service Id. + error AgentNotInService(uint256 agentId, uint256 serviceId); + + /// @dev The contract is paused. + error Paused(); + + /// @dev Zero value when it has to be different from zero. + error ZeroValue(); + + /// @dev Value overflow. + /// @param provided Overflow value. + /// @param max Maximum possible value. + error Overflow(uint256 provided, uint256 max); + + /// @dev Service must be inactive. + /// @param serviceId Service Id. + error ServiceMustBeInactive(uint256 serviceId); + + /// @dev All the agent instance slots for a specific `serviceId` are filled. + /// @param serviceId Service Id. + error AgentInstancesSlotsFilled(uint256 serviceId); + + /// @dev Wrong state of a service. + /// @param state Service state. + /// @param serviceId Service Id. + error WrongServiceState(uint256 state, uint256 serviceId); + + /// @dev Only own service multisig is allowed. + /// @param provided Provided address. + /// @param expected Expected multisig address. + /// @param serviceId Service Id. + error OnlyOwnServiceMultisig(address provided, address expected, uint256 serviceId); + + /// @dev Multisig is not whitelisted. + /// @param multisig Address of a multisig implementation. + error UnauthorizedMultisig(address multisig); + + /// @dev Incorrect deposit provided for the registration activation. + /// @param sent Sent amount. + /// @param expected Expected amount. + /// @param serviceId Service Id. + error IncorrectRegistrationDepositValue(uint256 sent, uint256 expected, uint256 serviceId); + + /// @dev Insufficient value provided for the agent instance bonding. + /// @param sent Sent amount. + /// @param expected Expected amount. + /// @param serviceId Service Id. + error IncorrectAgentBondingValue(uint256 sent, uint256 expected, uint256 serviceId); + + /// @dev Failure of a transfer. + /// @param token Address of a token. + /// @param from Address `from`. + /// @param to Address `to`. + /// @param value Value. + error TransferFailed(address token, address from, address to, uint256 value); + + /// @dev Caught reentrancy violation. + error ReentrancyGuard(); +} + + +// File lib/solmate/src/tokens/ERC721.sol +/// @notice Modern, minimalist, and gas efficient ERC-721 implementation. +/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC721.sol) +abstract contract ERC721 { + /*////////////////////////////////////////////////////////////// + EVENTS + //////////////////////////////////////////////////////////////*/ + + event Transfer(address indexed from, address indexed to, uint256 indexed id); + + event Approval(address indexed owner, address indexed spender, uint256 indexed id); + + event ApprovalForAll(address indexed owner, address indexed operator, bool approved); + + /*////////////////////////////////////////////////////////////// + METADATA STORAGE/LOGIC + //////////////////////////////////////////////////////////////*/ + + string public name; + + string public symbol; + + function tokenURI(uint256 id) public view virtual returns (string memory); + + /*////////////////////////////////////////////////////////////// + ERC721 BALANCE/OWNER STORAGE + //////////////////////////////////////////////////////////////*/ + + mapping(uint256 => address) internal _ownerOf; + + mapping(address => uint256) internal _balanceOf; + + function ownerOf(uint256 id) public view virtual returns (address owner) { + require((owner = _ownerOf[id]) != address(0), "NOT_MINTED"); + } + + function balanceOf(address owner) public view virtual returns (uint256) { + require(owner != address(0), "ZERO_ADDRESS"); + + return _balanceOf[owner]; + } + + /*////////////////////////////////////////////////////////////// + ERC721 APPROVAL STORAGE + //////////////////////////////////////////////////////////////*/ + + mapping(uint256 => address) public getApproved; + + mapping(address => mapping(address => bool)) public isApprovedForAll; + + /*////////////////////////////////////////////////////////////// + CONSTRUCTOR + //////////////////////////////////////////////////////////////*/ + + constructor(string memory _name, string memory _symbol) { + name = _name; + symbol = _symbol; + } + + /*////////////////////////////////////////////////////////////// + ERC721 LOGIC + //////////////////////////////////////////////////////////////*/ + + function approve(address spender, uint256 id) public virtual { + address owner = _ownerOf[id]; + + require(msg.sender == owner || isApprovedForAll[owner][msg.sender], "NOT_AUTHORIZED"); + + getApproved[id] = spender; + + emit Approval(owner, spender, id); + } + + function setApprovalForAll(address operator, bool approved) public virtual { + isApprovedForAll[msg.sender][operator] = approved; + + emit ApprovalForAll(msg.sender, operator, approved); + } + + function transferFrom( + address from, + address to, + uint256 id + ) public virtual { + require(from == _ownerOf[id], "WRONG_FROM"); + + require(to != address(0), "INVALID_RECIPIENT"); + + require( + msg.sender == from || isApprovedForAll[from][msg.sender] || msg.sender == getApproved[id], + "NOT_AUTHORIZED" + ); + + // Underflow of the sender's balance is impossible because we check for + // ownership above and the recipient's balance can't realistically overflow. + unchecked { + _balanceOf[from]--; + + _balanceOf[to]++; + } + + _ownerOf[id] = to; + + delete getApproved[id]; + + emit Transfer(from, to, id); + } + + function safeTransferFrom( + address from, + address to, + uint256 id + ) public virtual { + transferFrom(from, to, id); + + if (to.code.length != 0) + require( + ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, "") == + ERC721TokenReceiver.onERC721Received.selector, + "UNSAFE_RECIPIENT" + ); + } + + function safeTransferFrom( + address from, + address to, + uint256 id, + bytes calldata data + ) public virtual { + transferFrom(from, to, id); + + if (to.code.length != 0) + require( + ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, data) == + ERC721TokenReceiver.onERC721Received.selector, + "UNSAFE_RECIPIENT" + ); + } + + /*////////////////////////////////////////////////////////////// + ERC165 LOGIC + //////////////////////////////////////////////////////////////*/ + + function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) { + return + interfaceId == 0x01ffc9a7 || // ERC165 Interface ID for ERC165 + interfaceId == 0x80ac58cd || // ERC165 Interface ID for ERC721 + interfaceId == 0x5b5e139f; // ERC165 Interface ID for ERC721Metadata + } + + /*////////////////////////////////////////////////////////////// + INTERNAL MINT/BURN LOGIC + //////////////////////////////////////////////////////////////*/ + + function _mint(address to, uint256 id) internal virtual { + require(to != address(0), "INVALID_RECIPIENT"); + + require(_ownerOf[id] == address(0), "ALREADY_MINTED"); + + // Counter overflow is incredibly unrealistic. + unchecked { + _balanceOf[to]++; + } + + _ownerOf[id] = to; + + emit Transfer(address(0), to, id); + } + + function _burn(uint256 id) internal virtual { + address owner = _ownerOf[id]; + + require(owner != address(0), "NOT_MINTED"); + + // Ownership check above ensures no underflow. + unchecked { + _balanceOf[owner]--; + } + + delete _ownerOf[id]; + + delete getApproved[id]; + + emit Transfer(owner, address(0), id); + } + + /*////////////////////////////////////////////////////////////// + INTERNAL SAFE MINT LOGIC + //////////////////////////////////////////////////////////////*/ + + function _safeMint(address to, uint256 id) internal virtual { + _mint(to, id); + + if (to.code.length != 0) + require( + ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, "") == + ERC721TokenReceiver.onERC721Received.selector, + "UNSAFE_RECIPIENT" + ); + } + + function _safeMint( + address to, + uint256 id, + bytes memory data + ) internal virtual { + _mint(to, id); + + if (to.code.length != 0) + require( + ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, data) == + ERC721TokenReceiver.onERC721Received.selector, + "UNSAFE_RECIPIENT" + ); + } +} + +/// @notice A generic interface for a contract which properly accepts ERC721 tokens. +/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC721.sol) +abstract contract ERC721TokenReceiver { + function onERC721Received( + address, + address, + uint256, + bytes calldata + ) external virtual returns (bytes4) { + return ERC721TokenReceiver.onERC721Received.selector; + } +} + + +// File contracts/staking/ServiceStakingBase.sol +// Multisig interface +interface IMultisig { + /// @dev Gets the multisig nonce. + /// @return Multisig nonce. + function nonce() external view returns (uint256); +} + +// Service Registry interface +interface IService { + enum UnitType { + Component, + Agent + } + + /// @dev Transfers the service that was previously approved to this contract address. + /// @param from Account address to transfer from. + /// @param to Account address to transfer to. + /// @param id Service Id. + function safeTransferFrom(address from, address to, uint256 id) external; + + /// @dev Gets service parameters from the map of services. + /// @param serviceId Service Id. + /// @return securityDeposit Registration activation deposit. + /// @return multisig Service multisig address. + /// @return configHash IPFS hashes pointing to the config metadata. + /// @return threshold Agent instance signers threshold. + /// @return maxNumAgentInstances Total number of agent instances. + /// @return numAgentInstances Actual number of agent instances. + /// @return state Service state. + function mapServices(uint256 serviceId) external view returns ( + uint96 securityDeposit, + address multisig, + bytes32 configHash, + uint32 threshold, + uint32 maxNumAgentInstances, + uint32 numAgentInstances, + uint8 state + ); + + /// @dev Gets the full set of linearized components / canonical agent Ids for a specified service. + /// @notice The service must be / have been deployed in order to get the actual data. + /// @param serviceId Service Id. + /// @return numUnitIds Number of component / agent Ids. + /// @return unitIds Set of component / agent Ids. + function getUnitIdsOfService(UnitType unitType, uint256 serviceId) external view + returns (uint256 numUnitIds, uint32[] memory unitIds); +} + +/// @dev No rewards are available in the contract. +error NoRewardsAvailable(); + +/// @dev Maximum number of staking services is reached. +/// @param maxNumServices Maximum number of staking services. +error MaxNumServicesReached(uint256 maxNumServices); + +/// @dev Received lower value than the expected one. +/// @param provided Provided value is lower. +/// @param expected Expected value. +error LowerThan(uint256 provided, uint256 expected); + +/// @dev Required service configuration is wrong. +/// @param serviceId Service Id. +error WrongServiceConfiguration(uint256 serviceId); + +/// @dev Service is not staked. +/// @param serviceId Service Id. +error ServiceNotStaked(uint256 serviceId); + +// Service Info struct +struct ServiceInfo { + // Service multisig address + address multisig; + // Service owner + address owner; + // Service multisig nonce + uint256 nonce; + // Staking start time + uint256 tsStart; + // Accumulated service staking reward + uint256 reward; +} + +/// @title ServiceStakingBase - Base abstract smart contract for staking a service by its owner +/// @author Aleksandr Kuperman - +/// @author Andrey Lebedev - +/// @author Mariapia Moscatiello - +abstract contract ServiceStakingBase is ERC721TokenReceiver, IErrorsRegistries { + struct StakingParams { + // Maximum number of staking services + uint256 maxNumServices; + // Rewards per second + uint256 rewardsPerSecond; + // Minimum service staking deposit value required for staking + uint256 minStakingDeposit; + // Liveness period + uint256 livenessPeriod; + // Liveness ratio in the format of 1e18 + uint256 livenessRatio; + // Number of agent instances in the service + uint256 numAgentInstances; + // Optional agent Ids requirement + uint256[] agentIds; + // Optional service multisig threshold requirement + uint256 threshold; + // Optional service configuration hash requirement + bytes32 configHash; + } + + event ServiceStaked(uint256 indexed serviceId, address indexed owner, address indexed multisig, uint256 nonce); + event Checkpoint(uint256 availableRewards, uint256 numServices); + event ServiceUnstaked(uint256 indexed serviceId, address indexed owner, address indexed multisig, uint256 nonce, + uint256 reward, uint256 tsStart); + event Deposit(address indexed sender, uint256 amount, uint256 balance, uint256 availableRewards); + event Withdraw(address indexed to, uint256 amount); + + // Contract version + string public constant VERSION = "0.1.0"; + // Maximum number of staking services + uint256 public immutable maxNumServices; + // Rewards per second + uint256 public immutable rewardsPerSecond; + // Minimum service staking deposit value required for staking + uint256 public immutable minStakingDeposit; + // Liveness period + uint256 public immutable livenessPeriod; + // Liveness ratio in the format of 1e18 + uint256 public immutable livenessRatio; + // Number of agent instances in the service + uint256 public immutable numAgentInstances; + // Optional service multisig threshold requirement + uint256 public immutable threshold; + // Optional service configuration hash requirement + bytes32 public immutable configHash; + // ServiceRegistry contract address + address public immutable serviceRegistry; + + // Token / ETH balance + uint256 public balance; + // Token / ETH available rewards + uint256 public availableRewards; + // Timestamp of the last checkpoint + uint256 public tsCheckpoint; + // Optional agent Ids requirement + uint256[] public agentIds; + // Mapping of serviceId => staking service info + mapping (uint256 => ServiceInfo) public mapServiceInfo; + // Set of currently staking serviceIds + uint256[] public setServiceIds; + + /// @dev ServiceStakingBase constructor. + /// @param _stakingParams Service staking parameters. + /// @param _serviceRegistry ServiceRegistry contract address. + constructor(StakingParams memory _stakingParams, address _serviceRegistry) { + // Initial checks + if (_stakingParams.maxNumServices == 0 || _stakingParams.rewardsPerSecond == 0 || + _stakingParams.minStakingDeposit == 0 || _stakingParams.livenessPeriod == 0 || + _stakingParams.livenessRatio == 0 || _stakingParams.numAgentInstances == 0) { + revert ZeroValue(); + } + if (_serviceRegistry == address(0)) { + revert ZeroAddress(); + } + + // Assign all the required parameters + maxNumServices = _stakingParams.maxNumServices; + rewardsPerSecond = _stakingParams.rewardsPerSecond; + minStakingDeposit = _stakingParams.minStakingDeposit; + livenessPeriod = _stakingParams.livenessPeriod; + livenessRatio = _stakingParams.livenessRatio; + numAgentInstances = _stakingParams.numAgentInstances; + serviceRegistry = _serviceRegistry; + + // Assign optional parameters + threshold = _stakingParams.threshold; + configHash = _stakingParams.configHash; + + // Assign agent Ids, if applicable + uint256 size = _stakingParams.agentIds.length; + uint256 agentId; + if (size > 0) { + for (uint256 i = 0; i < size; ++i) { + // Agent Ids must be unique and in ascending order + if (_stakingParams.agentIds[i] <= agentId) { + revert WrongAgentId(_stakingParams.agentIds[i]); + } + agentId = _stakingParams.agentIds[i]; + agentIds.push(agentId); + } + } + + // Set the checkpoint timestamp to be the deployment one + tsCheckpoint = block.timestamp; + } + + /// @dev Checks token / ETH staking deposit. + /// @param stakingDeposit Staking deposit. + function _checkTokenStakingDeposit(uint256, uint256 stakingDeposit) internal view virtual { + // The staking deposit derived from a security deposit value must be greater or equal to the minimum defined one + if (stakingDeposit < minStakingDeposit) { + revert LowerThan(stakingDeposit, minStakingDeposit); + } + } + + /// @dev Withdraws the reward amount to a service owner. + /// @param to Address to. + /// @param amount Amount to withdraw. + function _withdraw(address to, uint256 amount) internal virtual; + + /// @dev Stakes the service. + /// @param serviceId Service Id. + function stake(uint256 serviceId) external { + // Check if there available rewards + if (availableRewards == 0) { + revert NoRewardsAvailable(); + } + + // Check for the maximum number of staking services + uint256 numStakingServices = setServiceIds.length; + if (numStakingServices == maxNumServices) { + revert MaxNumServicesReached(maxNumServices); + } + + // Check the service conditions for staking + (uint96 stakingDeposit, address multisig, bytes32 hash, uint256 agentThreshold, uint256 maxNumInstances, , uint8 state) = + IService(serviceRegistry).mapServices(serviceId); + + // Check the number of agent instances + if (numAgentInstances != maxNumInstances) { + revert WrongServiceConfiguration(serviceId); + } + + // Check the configuration hash, if applicable + if (configHash != bytes32(0) && configHash != hash) { + revert WrongServiceConfiguration(serviceId); + } + // Check the threshold, if applicable + if (threshold > 0 && threshold != agentThreshold) { + revert WrongServiceConfiguration(serviceId); + } + // The service must be deployed + if (state != 4) { + revert WrongServiceState(state, serviceId); + } + // Check the agent Ids requirement, if applicable + uint256 size = agentIds.length; + if (size > 0) { + (uint256 numAgents, uint32[] memory agents) = + IService(serviceRegistry).getUnitIdsOfService(IService.UnitType.Agent, serviceId); + + if (size != numAgents) { + revert WrongServiceConfiguration(serviceId); + } + for (uint256 i = 0; i < numAgents; ++i) { + if (agentIds[i] != agents[i]) { + revert WrongAgentId(agentIds[i]); + } + } + } + + // Check service staking deposit and token, if applicable + _checkTokenStakingDeposit(serviceId, stakingDeposit); + + // Transfer the service for staking + IService(serviceRegistry).safeTransferFrom(msg.sender, address(this), serviceId); + + // ServiceInfo struct will be an empty one since otherwise the safeTransferFrom above would fail + ServiceInfo storage sInfo = mapServiceInfo[serviceId]; + sInfo.multisig = multisig; + sInfo.owner = msg.sender; + uint256 nonce = IMultisig(multisig).nonce(); + sInfo.nonce = nonce; + sInfo.tsStart = block.timestamp; + + // Add the service Id to the set of staked services + setServiceIds.push(serviceId); + + emit ServiceStaked(serviceId, msg.sender, multisig, nonce); + } + + /// @dev Calculates staking rewards for all services at current timestamp. + /// @param lastAvailableRewards Available amount of rewards. + /// @param numServices Number of services eligible for the reward that passed the liveness check. + /// @param totalRewards Total calculated rewards. + /// @param eligibleServiceIds Service Ids eligible for rewards. + /// @param eligibleServiceRewards Corresponding rewards for eligible service Ids. + /// @param serviceIds All the staking service Ids. + /// @param serviceNonces Current service nonces. + function _calculateStakingRewards() internal view returns ( + uint256 lastAvailableRewards, + uint256 numServices, + uint256 totalRewards, + uint256[] memory eligibleServiceIds, + uint256[] memory eligibleServiceRewards, + uint256[] memory serviceIds, + uint256[] memory serviceNonces + ) + { + // Get the service Ids set length + uint256 size = setServiceIds.length; + serviceIds = new uint256[](size); + + // Record service Ids + for (uint256 i = 0; i < size; ++i) { + // Get current service Id + serviceIds[i] = setServiceIds[i]; + } + + // Check the last checkpoint timestamp and the liveness period + uint256 tsCheckpointLast = tsCheckpoint; + if (block.timestamp - tsCheckpointLast >= livenessPeriod) { + // Get available rewards and last checkpoint timestamp + lastAvailableRewards = availableRewards; + + // If available rewards are not zero, proceed with staking calculation + if (lastAvailableRewards > 0) { + // Get necessary arrays + eligibleServiceIds = new uint256[](size); + eligibleServiceRewards = new uint256[](size); + serviceNonces = new uint256[](size); + + // Calculate each staked service reward eligibility + for (uint256 i = 0; i < size; ++i) { + // Get the service info + ServiceInfo storage curInfo = mapServiceInfo[serviceIds[i]]; + + // Get current service multisig nonce + serviceNonces[i] = IMultisig(curInfo.multisig).nonce(); + + // Calculate the liveness nonce ratio + // Get the last service checkpoint: staking start time or the global checkpoint timestamp + uint256 serviceCheckpoint = tsCheckpointLast; + uint256 ts = curInfo.tsStart; + // Adjust the service checkpoint time if the service was staking less than the current staking period + if (ts > serviceCheckpoint) { + serviceCheckpoint = ts; + } + + // Calculate the liveness ratio in 1e18 value + // This subtraction is always positive or zero, as the last checkpoint can be at most block.timestamp + ts = block.timestamp - serviceCheckpoint; + uint256 ratio; + // If the checkpoint was called in the exact same block, the ratio is zero + if (ts > 0) { + ratio = ((serviceNonces[i] - curInfo.nonce) * 1e18) / ts; + } + + // Record the reward for the service if it has provided enough transactions + if (ratio >= livenessRatio) { + // Calculate the reward up until now and record its value for the corresponding service + uint256 reward = rewardsPerSecond * ts; + totalRewards += reward; + eligibleServiceRewards[numServices] = reward; + eligibleServiceIds[numServices] = serviceIds[i]; + ++numServices; + } + } + } + } + } + + /// @dev Checkpoint to allocate rewards up until a current time. + /// @return All staking service Ids. + /// @return All staking updated nonces. + /// @return Number of reward-eligible staking services during current checkpoint period. + /// @return Eligible service Ids. + /// @return Eligible service rewards. + /// @return success True, if the checkpoint was successful. + function checkpoint() public returns ( + uint256[] memory, + uint256[] memory, + uint256, + uint256[] memory, + uint256[] memory, + bool success + ) + { + // Calculate staking rewards + (uint256 lastAvailableRewards, uint256 numServices, uint256 totalRewards, + uint256[] memory eligibleServiceIds, uint256[] memory eligibleServiceRewards, + uint256[] memory serviceIds, uint256[] memory serviceNonces) = _calculateStakingRewards(); + + // If there are eligible services, proceed with staking calculation and update rewards + if (numServices > 0) { + // If total allocated rewards are not enough, adjust the reward value + if (totalRewards > lastAvailableRewards) { + // Traverse all the eligible services and adjust their rewards proportional to leftovers + uint256 updatedReward; + uint256 updatedTotalRewards; + uint256 curServiceId; + for (uint256 i = 1; i < numServices; ++i) { + // Calculate the updated reward + updatedReward = (eligibleServiceRewards[i] * lastAvailableRewards) / totalRewards; + // Add to the total updated reward + updatedTotalRewards += updatedReward; + // Add reward to the overall service reward + curServiceId = eligibleServiceIds[i]; + mapServiceInfo[curServiceId].reward += updatedReward; + } + + // Process the first service in the set + updatedReward = (eligibleServiceRewards[0] * lastAvailableRewards) / totalRewards; + updatedTotalRewards += updatedReward; + curServiceId = eligibleServiceIds[0]; + // If the reward adjustment happened to have small leftovers, add it to the first service + if (lastAvailableRewards > updatedTotalRewards) { + updatedReward += lastAvailableRewards - updatedTotalRewards; + } + // Add reward to the overall service reward + mapServiceInfo[curServiceId].reward += updatedReward; + // Set available rewards to zero + lastAvailableRewards = 0; + } else { + // Traverse all the eligible services and add to their rewards + for (uint256 i = 0; i < numServices; ++i) { + // Add reward to the service overall reward + uint256 curServiceId = eligibleServiceIds[i]; + mapServiceInfo[curServiceId].reward += eligibleServiceRewards[i]; + } + + // Adjust available rewards + // TODO: Fuzz this such that totalRewards is never bigger than lastAvailableRewards + lastAvailableRewards -= totalRewards; + } + + // Update the storage value of available rewards + availableRewards = lastAvailableRewards; + } + + // If service nonces were updated, then the checkpoint takes place, otherwise only service Ids are returned + if (serviceNonces.length > 0) { + // Updated current service nonces + for (uint256 i = 0; i < serviceIds.length; ++i) { + // Get the current service Id + uint256 curServiceId = serviceIds[i]; + mapServiceInfo[curServiceId].nonce = serviceNonces[i]; + } + + // Record the current timestamp such that next calculations start from this point of time + tsCheckpoint = block.timestamp; + + success = true; + + emit Checkpoint(lastAvailableRewards, numServices); + } + + return (serviceIds, serviceNonces, numServices, eligibleServiceIds, eligibleServiceRewards, success); + } + + /// @dev Unstakes the service. + /// @param serviceId Service Id. + function unstake(uint256 serviceId) external { + ServiceInfo memory sInfo = mapServiceInfo[serviceId]; + // Check for the service ownership + if (msg.sender != sInfo.owner) { + revert OwnerOnly(msg.sender, sInfo.owner); + } + + // Call the checkpoint + (uint256[] memory serviceIds, , , , , ) = checkpoint(); + + // Get the service index in the set of services + // The index must always exist as the service is currently staked, otherwise it has no record in the map + uint256 idx; + for (; idx < serviceIds.length; ++idx) { + if (serviceIds[idx] == serviceId) { + break; + } + } + + // Transfer the service back to the owner + IService(serviceRegistry).safeTransferFrom(address(this), msg.sender, serviceId); + + // Transfer accumulated rewards to the service multisig + if (sInfo.reward > 0) { + _withdraw(sInfo.multisig, sInfo.reward); + } + + // Clear all the data about the unstaked service + // Delete the service info struct + delete mapServiceInfo[serviceId]; + + // Update the set of staked service Ids + setServiceIds[idx] = setServiceIds[setServiceIds.length - 1]; + setServiceIds.pop(); + + emit ServiceUnstaked(serviceId, msg.sender, sInfo.multisig, sInfo.nonce, sInfo.reward, sInfo.tsStart); + } + + /// @dev Calculates service staking reward at current timestamp. + /// @param serviceId Service Id. + /// @return reward Service reward. + function calculateServiceStakingReward(uint256 serviceId) external view returns (uint256 reward) { + // Get current service reward + ServiceInfo memory sInfo = mapServiceInfo[serviceId]; + reward = sInfo.reward; + + // Check if the service is staked + if (sInfo.tsStart == 0) { + revert ServiceNotStaked(serviceId); + } + + // Calculate overall staking rewards + (uint256 lastAvailableRewards, uint256 numServices, uint256 totalRewards, uint256[] memory eligibleServiceIds, + uint256[] memory eligibleServiceRewards, , ) = _calculateStakingRewards(); + + // If there are eligible services, proceed with staking calculation and update rewards for the service Id + if (numServices > 0) { + // Get the service index in the eligible service set and calculate its latest reward + for (uint256 i = 0; i < eligibleServiceIds.length; ++i) { + if (eligibleServiceIds[i] == serviceId) { + // If total allocated rewards are not enough, adjust the reward value + if (totalRewards > lastAvailableRewards) { + reward += (eligibleServiceRewards[i] * lastAvailableRewards) / totalRewards; + } else { + reward += eligibleServiceRewards[i]; + } + break; + } + } + } + } +} + + +// File contracts/interfaces/IToken.sol +/// @dev Generic token interface for IERC20 and IERC721 tokens. +interface IToken { + /// @dev Gets the amount of tokens owned by a specified account. + /// @param account Account address. + /// @return Amount of tokens owned. + function balanceOf(address account) external view returns (uint256); + + /// @dev Gets the owner of the token Id. + /// @param tokenId Token Id. + /// @return Token Id owner address. + function ownerOf(uint256 tokenId) external view returns (address); + + /// @dev Gets the total amount of tokens stored by the contract. + /// @return Amount of tokens. + function totalSupply() external view returns (uint256); + + /// @dev Transfers the token amount. + /// @param to Address to transfer to. + /// @param amount The amount to transfer. + /// @return True if the function execution is successful. + function transfer(address to, uint256 amount) external returns (bool); + + /// @dev Gets remaining number of tokens that the `spender` can transfer on behalf of `owner`. + /// @param owner Token owner. + /// @param spender Account address that is able to transfer tokens on behalf of the owner. + /// @return Token amount allowed to be transferred. + function allowance(address owner, address spender) external view returns (uint256); + + /// @dev Sets `amount` as the allowance of `spender` over the caller's tokens. + /// @param spender Account address that will be able to transfer tokens on behalf of the caller. + /// @param amount Token amount. + /// @return True if the function execution is successful. + function approve(address spender, uint256 amount) external returns (bool); + + /// @dev Transfers the token amount that was previously approved up until the maximum allowance. + /// @param from Account address to transfer from. + /// @param to Account address to transfer to. + /// @param amount Amount to transfer to. + /// @return True if the function execution is successful. + function transferFrom(address from, address to, uint256 amount) external returns (bool); + + /// @dev Gets the number of token decimals. + /// @return Number of token decimals. + function decimals() external view returns (uint8); +} + + +// File contracts/utils/SafeTransferLib.sol +/// @dev Failure of a token transfer. +/// @param token Address of a token. +/// @param from Address `from`. +/// @param to Address `to`. +/// @param value Value. +error TokenTransferFailed(address token, address from, address to, uint256 value); + +/// @dev The implementation is fully copied from the audited MIT-licensed solmate code repository: +/// https://github.com/transmissions11/solmate/blob/v7/src/utils/SafeTransferLib.sol +/// The original library imports the `ERC20` abstract token contract, and thus embeds all that contract +/// related code that is not needed. In this version, `ERC20` is swapped with the `address` representation. +/// Also, the final `require` statement is modified with this contract own `revert` statement. +library SafeTransferLib { + /// @dev Safe token transferFrom implementation. + /// @param token Token address. + /// @param from Address to transfer tokens from. + /// @param to Address to transfer tokens to. + /// @param amount Token amount. + function safeTransferFrom(address token, address from, address to, uint256 amount) internal { + bool success; + + // solhint-disable-next-line no-inline-assembly + assembly { + // We'll write our calldata to this slot below, but restore it later. + let memPointer := mload(0x40) + + // Write the abi-encoded calldata into memory, beginning with the function selector. + mstore(0, 0x23b872dd00000000000000000000000000000000000000000000000000000000) + mstore(4, from) // Append the "from" argument. + mstore(36, to) // Append the "to" argument. + mstore(68, amount) // Append the "amount" argument. + + success := and( + // Set success to whether the call reverted, if not we check it either + // returned exactly 1 (can't just be non-zero data), or had no return data. + or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())), + // We use 100 because that's the total length of our calldata (4 + 32 * 3) + // Counterintuitively, this call() must be positioned after the or() in the + // surrounding and() because and() evaluates its arguments from right to left. + call(gas(), token, 0, 0, 100, 0, 32) + ) + + mstore(0x60, 0) // Restore the zero slot to zero. + mstore(0x40, memPointer) // Restore the memPointer. + } + + if (!success) { + revert TokenTransferFailed(token, from, to, amount); + } + } + + /// @dev Safe token transfer implementation. + /// @notice The implementation is fully copied from the audited MIT-licensed solmate code repository: + /// https://github.com/transmissions11/solmate/blob/v7/src/utils/SafeTransferLib.sol + /// The original library imports the `ERC20` abstract token contract, and thus embeds all that contract + /// related code that is not needed. In this version, `ERC20` is swapped with the `address` representation. + /// Also, the final `require` statement is modified with this contract own `revert` statement. + /// @param token Token address. + /// @param to Address to transfer tokens to. + /// @param amount Token amount. + function safeTransfer(address token, address to, uint256 amount) internal { + bool success; + + // solhint-disable-next-line no-inline-assembly + assembly { + // We'll write our calldata to this slot below, but restore it later. + let memPointer := mload(0x40) + + // Write the abi-encoded calldata into memory, beginning with the function selector. + mstore(0, 0xa9059cbb00000000000000000000000000000000000000000000000000000000) + mstore(4, to) // Append the "to" argument. + mstore(36, amount) // Append the "amount" argument. + + success := and( + // Set success to whether the call reverted, if not we check it either + // returned exactly 1 (can't just be non-zero data), or had no return data. + or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())), + // We use 68 because that's the total length of our calldata (4 + 32 * 2) + // Counterintuitively, this call() must be positioned after the or() in the + // surrounding and() because and() evaluates its arguments from right to left. + call(gas(), token, 0, 0, 68, 0, 32) + ) + + mstore(0x60, 0) // Restore the zero slot to zero. + mstore(0x40, memPointer) // Restore the memPointer. + } + + if (!success) { + revert TokenTransferFailed(token, address(this), to, amount); + } + } +} + + +// File contracts/staking/ServiceStakingToken.sol +// Service Registry Token Utility interface +interface IServiceTokenUtility { + /// @dev Gets the service security token info. + /// @param serviceId Service Id. + /// @return Token address. + /// @return Token security deposit. + function mapServiceIdTokenDeposit(uint256 serviceId) external view returns (address, uint96); +} + +/// @dev The token does not have enough decimals. +/// @param token Token address. +/// @param decimals Number of decimals. +error NotEnoughTokenDecimals(address token, uint8 decimals); + +/// @dev The staking token is wrong. +/// @param expected Expected staking token. +/// @param provided Provided staking token. +error WrongStakingToken(address expected, address provided); + + +/// @title ServiceStakingToken - Smart contract for staking a service by its owner when the service has an ERC20 token as the deposit +/// @author Aleksandr Kuperman - +/// @author Andrey Lebedev - +/// @author Mariapia Moscatiello - +contract ServiceStakingToken is ServiceStakingBase { + // ServiceRegistryTokenUtility address + address public immutable serviceRegistryTokenUtility; + // Security token address for staking corresponding to the service deposit token + address public immutable stakingToken; + + /// @dev ServiceStakingToken constructor. + /// @param _stakingParams Service staking parameters. + /// @param _serviceRegistry ServiceRegistry contract address. + /// @param _serviceRegistryTokenUtility ServiceRegistryTokenUtility contract address. + /// @param _stakingToken Address of a service staking token. + constructor( + StakingParams memory _stakingParams, + address _serviceRegistry, + address _serviceRegistryTokenUtility, + address _stakingToken + ) + ServiceStakingBase(_stakingParams, _serviceRegistry) + { + // Initial checks + if (_stakingToken == address(0) || _serviceRegistryTokenUtility == address(0)) { + revert ZeroAddress(); + } + + stakingToken = _stakingToken; + serviceRegistryTokenUtility = _serviceRegistryTokenUtility; + } + + /// @dev Checks token staking deposit. + /// @param serviceId Service Id. + function _checkTokenStakingDeposit(uint256 serviceId, uint256) internal view override { + // Get the service staking token and deposit + (address token, uint96 stakingDeposit) = + IServiceTokenUtility(serviceRegistryTokenUtility).mapServiceIdTokenDeposit(serviceId); + + // The staking token must match the contract token + if (stakingToken != token) { + revert WrongStakingToken(stakingToken, token); + } + + // The staking deposit must be greater or equal to the minimum defined one + if (stakingDeposit < minStakingDeposit) { + revert LowerThan(stakingDeposit, minStakingDeposit); + } + } + + /// @dev Withdraws the reward amount to a service owner. + /// @param to Address to. + /// @param amount Amount to withdraw. + function _withdraw(address to, uint256 amount) internal override { + // Update the contract balance + balance -= amount; + + SafeTransferLib.safeTransfer(stakingToken, to, amount); + + emit Withdraw(to, amount); + } + + /// @dev Deposits funds for staking. + /// @param amount Token amount to deposit. + function deposit(uint256 amount) external { + // Add to the overall balance + SafeTransferLib.safeTransferFrom(stakingToken, msg.sender, address(this), amount); + + // Add to the contract and available rewards balances + uint256 newBalance = balance + amount; + uint256 newAvailableRewards = availableRewards + amount; + + // Record the new actual balance and available rewards + balance = newBalance; + availableRewards = newAvailableRewards; + + emit Deposit(msg.sender, amount, newBalance, newAvailableRewards); + } +} diff --git a/audits/internal4/analysis/contracts/script.sh b/audits/internal4/analysis/contracts/script.sh new file mode 100755 index 00000000..286784b4 --- /dev/null +++ b/audits/internal4/analysis/contracts/script.sh @@ -0,0 +1,20 @@ +#!/bin/bash + + slither_options=("call-graph" "constructor-calls" "contract-summary" "data-dependency" "function-summary" + "human-summary" "inheritance" "inheritance-graph" "modifiers" "require" "variable-order" "vars-and-auth") + echo -e "\nRunning slither routines ..." + for so in "${slither_options[@]}"; do + echo -e "\t$so" + slither . --print ${so} &> "slither_$so.txt" + done + echo -e "\tfull report" + slither . &> "slither_full.txt" + + # moving generated .dot files to the audit folder + count=`ls -1 *.dot 2>/dev/null | wc -l` + echo -e "\tgenerated $count .dot files" + for _filename in *.dot; do + filename="${_filename%.*}" + cat $_filename | dot -Tpng > slither_$filename.png + done + rm *.dot diff --git a/audits/internal4/analysis/slither_ServiceStakingBase-flatten.sol.ERC721.call-graph.png b/audits/internal4/analysis/slither_ServiceStakingBase-flatten.sol.ERC721.call-graph.png new file mode 100644 index 00000000..c68b344e Binary files /dev/null and b/audits/internal4/analysis/slither_ServiceStakingBase-flatten.sol.ERC721.call-graph.png differ diff --git a/audits/internal4/analysis/slither_ServiceStakingBase-flatten.sol.IMultisig.call-graph.png b/audits/internal4/analysis/slither_ServiceStakingBase-flatten.sol.IMultisig.call-graph.png new file mode 100644 index 00000000..c08317ae Binary files /dev/null and b/audits/internal4/analysis/slither_ServiceStakingBase-flatten.sol.IMultisig.call-graph.png differ diff --git a/audits/internal4/analysis/slither_ServiceStakingBase-flatten.sol.IService.call-graph.png b/audits/internal4/analysis/slither_ServiceStakingBase-flatten.sol.IService.call-graph.png new file mode 100644 index 00000000..b2c101e7 Binary files /dev/null and b/audits/internal4/analysis/slither_ServiceStakingBase-flatten.sol.IService.call-graph.png differ diff --git a/audits/internal4/analysis/slither_ServiceStakingBase-flatten.sol.ServiceStakingBase.call-graph.png b/audits/internal4/analysis/slither_ServiceStakingBase-flatten.sol.ServiceStakingBase.call-graph.png new file mode 100644 index 00000000..3719416a Binary files /dev/null and b/audits/internal4/analysis/slither_ServiceStakingBase-flatten.sol.ServiceStakingBase.call-graph.png differ diff --git a/audits/internal4/analysis/slither_ServiceStakingBase-flatten.sol.all_contracts.call-graph.png b/audits/internal4/analysis/slither_ServiceStakingBase-flatten.sol.all_contracts.call-graph.png new file mode 100644 index 00000000..3ece430e Binary files /dev/null and b/audits/internal4/analysis/slither_ServiceStakingBase-flatten.sol.all_contracts.call-graph.png differ diff --git a/audits/internal4/analysis/slither_ServiceStakingBase-flatten.sol.inheritance-graph.png b/audits/internal4/analysis/slither_ServiceStakingBase-flatten.sol.inheritance-graph.png new file mode 100644 index 00000000..d877937e Binary files /dev/null and b/audits/internal4/analysis/slither_ServiceStakingBase-flatten.sol.inheritance-graph.png differ diff --git a/audits/internal4/analysis/slither_ServiceStakingNativeToken-flatten.sol.ERC721.call-graph.png b/audits/internal4/analysis/slither_ServiceStakingNativeToken-flatten.sol.ERC721.call-graph.png new file mode 100644 index 00000000..c68b344e Binary files /dev/null and b/audits/internal4/analysis/slither_ServiceStakingNativeToken-flatten.sol.ERC721.call-graph.png differ diff --git a/audits/internal4/analysis/slither_ServiceStakingNativeToken-flatten.sol.IMultisig.call-graph.png b/audits/internal4/analysis/slither_ServiceStakingNativeToken-flatten.sol.IMultisig.call-graph.png new file mode 100644 index 00000000..c08317ae Binary files /dev/null and b/audits/internal4/analysis/slither_ServiceStakingNativeToken-flatten.sol.IMultisig.call-graph.png differ diff --git a/audits/internal4/analysis/slither_ServiceStakingNativeToken-flatten.sol.IService.call-graph.png b/audits/internal4/analysis/slither_ServiceStakingNativeToken-flatten.sol.IService.call-graph.png new file mode 100644 index 00000000..b2c101e7 Binary files /dev/null and b/audits/internal4/analysis/slither_ServiceStakingNativeToken-flatten.sol.IService.call-graph.png differ diff --git a/audits/internal4/analysis/slither_ServiceStakingNativeToken-flatten.sol.ServiceStakingNativeToken.call-graph.png b/audits/internal4/analysis/slither_ServiceStakingNativeToken-flatten.sol.ServiceStakingNativeToken.call-graph.png new file mode 100644 index 00000000..6caa1646 Binary files /dev/null and b/audits/internal4/analysis/slither_ServiceStakingNativeToken-flatten.sol.ServiceStakingNativeToken.call-graph.png differ diff --git a/audits/internal4/analysis/slither_ServiceStakingNativeToken-flatten.sol.all_contracts.call-graph.png b/audits/internal4/analysis/slither_ServiceStakingNativeToken-flatten.sol.all_contracts.call-graph.png new file mode 100644 index 00000000..1fe9947c Binary files /dev/null and b/audits/internal4/analysis/slither_ServiceStakingNativeToken-flatten.sol.all_contracts.call-graph.png differ diff --git a/audits/internal4/analysis/slither_ServiceStakingNativeToken-flatten.sol.inheritance-graph.png b/audits/internal4/analysis/slither_ServiceStakingNativeToken-flatten.sol.inheritance-graph.png new file mode 100644 index 00000000..caaef80e Binary files /dev/null and b/audits/internal4/analysis/slither_ServiceStakingNativeToken-flatten.sol.inheritance-graph.png differ diff --git a/audits/internal4/analysis/slither_ServiceStakingToken-flatten.sol.ERC721.call-graph.png b/audits/internal4/analysis/slither_ServiceStakingToken-flatten.sol.ERC721.call-graph.png new file mode 100644 index 00000000..c68b344e Binary files /dev/null and b/audits/internal4/analysis/slither_ServiceStakingToken-flatten.sol.ERC721.call-graph.png differ diff --git a/audits/internal4/analysis/slither_ServiceStakingToken-flatten.sol.IMultisig.call-graph.png b/audits/internal4/analysis/slither_ServiceStakingToken-flatten.sol.IMultisig.call-graph.png new file mode 100644 index 00000000..c08317ae Binary files /dev/null and b/audits/internal4/analysis/slither_ServiceStakingToken-flatten.sol.IMultisig.call-graph.png differ diff --git a/audits/internal4/analysis/slither_ServiceStakingToken-flatten.sol.IService.call-graph.png b/audits/internal4/analysis/slither_ServiceStakingToken-flatten.sol.IService.call-graph.png new file mode 100644 index 00000000..b2c101e7 Binary files /dev/null and b/audits/internal4/analysis/slither_ServiceStakingToken-flatten.sol.IService.call-graph.png differ diff --git a/audits/internal4/analysis/slither_ServiceStakingToken-flatten.sol.IServiceTokenUtility.call-graph.png b/audits/internal4/analysis/slither_ServiceStakingToken-flatten.sol.IServiceTokenUtility.call-graph.png new file mode 100644 index 00000000..3d275398 Binary files /dev/null and b/audits/internal4/analysis/slither_ServiceStakingToken-flatten.sol.IServiceTokenUtility.call-graph.png differ diff --git a/audits/internal4/analysis/slither_ServiceStakingToken-flatten.sol.IToken.call-graph.png b/audits/internal4/analysis/slither_ServiceStakingToken-flatten.sol.IToken.call-graph.png new file mode 100644 index 00000000..76afcc69 Binary files /dev/null and b/audits/internal4/analysis/slither_ServiceStakingToken-flatten.sol.IToken.call-graph.png differ diff --git a/audits/internal4/analysis/slither_ServiceStakingToken-flatten.sol.SafeTransferLib.call-graph.png b/audits/internal4/analysis/slither_ServiceStakingToken-flatten.sol.SafeTransferLib.call-graph.png new file mode 100644 index 00000000..0684b77a Binary files /dev/null and b/audits/internal4/analysis/slither_ServiceStakingToken-flatten.sol.SafeTransferLib.call-graph.png differ diff --git a/audits/internal4/analysis/slither_ServiceStakingToken-flatten.sol.ServiceStakingToken.call-graph.png b/audits/internal4/analysis/slither_ServiceStakingToken-flatten.sol.ServiceStakingToken.call-graph.png new file mode 100644 index 00000000..0047e8bc Binary files /dev/null and b/audits/internal4/analysis/slither_ServiceStakingToken-flatten.sol.ServiceStakingToken.call-graph.png differ diff --git a/audits/internal4/analysis/slither_ServiceStakingToken-flatten.sol.all_contracts.call-graph.png b/audits/internal4/analysis/slither_ServiceStakingToken-flatten.sol.all_contracts.call-graph.png new file mode 100644 index 00000000..52c8cb5a Binary files /dev/null and b/audits/internal4/analysis/slither_ServiceStakingToken-flatten.sol.all_contracts.call-graph.png differ diff --git a/audits/internal4/analysis/slither_ServiceStakingToken-flatten.sol.inheritance-graph.png b/audits/internal4/analysis/slither_ServiceStakingToken-flatten.sol.inheritance-graph.png new file mode 100644 index 00000000..d14e42e2 Binary files /dev/null and b/audits/internal4/analysis/slither_ServiceStakingToken-flatten.sol.inheritance-graph.png differ diff --git a/audits/internal4/analysis/slither_call-graph.txt b/audits/internal4/analysis/slither_call-graph.txt new file mode 100644 index 00000000..f1113e59 --- /dev/null +++ b/audits/internal4/analysis/slither_call-graph.txt @@ -0,0 +1,28 @@ +'solc --version' running +'solc ./ServiceStakingNativeToken-flatten.sol --combined-json abi,ast,bin,bin-runtime,srcmap,srcmap-runtime,userdoc,devdoc,hashes --allow-paths .,/home/andrey/valory/autonolas-registries/audits/internal4/analysis/contracts' running +'solc --version' running +'solc ./ServiceStakingToken-flatten.sol --combined-json abi,ast,bin,bin-runtime,srcmap,srcmap-runtime,userdoc,devdoc,hashes --allow-paths .,/home/andrey/valory/autonolas-registries/audits/internal4/analysis/contracts' running +'solc --version' running +'solc ./ServiceStakingBase-flatten.sol --combined-json abi,ast,bin,bin-runtime,srcmap,srcmap-runtime,userdoc,devdoc,hashes --allow-paths .,/home/andrey/valory/autonolas-registries/audits/internal4/analysis/contracts' running +INFO:Printers:Call Graph: ./ServiceStakingNativeToken-flatten.sol.all_contracts.call-graph.dot +Call Graph: ./ServiceStakingNativeToken-flatten.sol.ERC721.call-graph.dot +Call Graph: ./ServiceStakingNativeToken-flatten.sol.IMultisig.call-graph.dot +Call Graph: ./ServiceStakingNativeToken-flatten.sol.IService.call-graph.dot +Call Graph: ./ServiceStakingNativeToken-flatten.sol.ServiceStakingNativeToken.call-graph.dot + +INFO:Printers:Call Graph: ./ServiceStakingToken-flatten.sol.all_contracts.call-graph.dot +Call Graph: ./ServiceStakingToken-flatten.sol.ERC721.call-graph.dot +Call Graph: ./ServiceStakingToken-flatten.sol.IMultisig.call-graph.dot +Call Graph: ./ServiceStakingToken-flatten.sol.IService.call-graph.dot +Call Graph: ./ServiceStakingToken-flatten.sol.IToken.call-graph.dot +Call Graph: ./ServiceStakingToken-flatten.sol.SafeTransferLib.call-graph.dot +Call Graph: ./ServiceStakingToken-flatten.sol.IServiceTokenUtility.call-graph.dot +Call Graph: ./ServiceStakingToken-flatten.sol.ServiceStakingToken.call-graph.dot + +INFO:Printers:Call Graph: ./ServiceStakingBase-flatten.sol.all_contracts.call-graph.dot +Call Graph: ./ServiceStakingBase-flatten.sol.ERC721.call-graph.dot +Call Graph: ./ServiceStakingBase-flatten.sol.IMultisig.call-graph.dot +Call Graph: ./ServiceStakingBase-flatten.sol.IService.call-graph.dot +Call Graph: ./ServiceStakingBase-flatten.sol.ServiceStakingBase.call-graph.dot + +INFO:Slither:. analyzed (23 contracts) diff --git a/audits/internal4/analysis/slither_constructor-calls.txt b/audits/internal4/analysis/slither_constructor-calls.txt new file mode 100644 index 00000000..47164f78 --- /dev/null +++ b/audits/internal4/analysis/slither_constructor-calls.txt @@ -0,0 +1,244 @@ +'solc --version' running +'solc ./ServiceStakingNativeToken-flatten.sol --combined-json abi,ast,bin,bin-runtime,srcmap,srcmap-runtime,userdoc,devdoc,hashes --allow-paths .,/home/andrey/valory/autonolas-registries/audits/internal4/analysis/contracts' running +'solc --version' running +'solc ./ServiceStakingToken-flatten.sol --combined-json abi,ast,bin,bin-runtime,srcmap,srcmap-runtime,userdoc,devdoc,hashes --allow-paths .,/home/andrey/valory/autonolas-registries/audits/internal4/analysis/contracts' running +'solc --version' running +'solc ./ServiceStakingBase-flatten.sol --combined-json abi,ast,bin,bin-runtime,srcmap,srcmap-runtime,userdoc,devdoc,hashes --allow-paths .,/home/andrey/valory/autonolas-registries/audits/internal4/analysis/contracts' running +INFO:Printers: +###################### +####### ERC721 ####### +###################### + +## Constructor Call Sequence + - ERC721 + +## Constructor Definitions + +### ERC721 + + constructor(string memory _name, string memory _symbol) { + name = _name; + symbol = _symbol; + } + +######################################### +####### ServiceStakingNativeToken ####### +######################################### + +## Constructor Call Sequence + - ServiceStakingBase + - ServiceStakingNativeToken + +## Constructor Definitions + +### ServiceStakingBase + + constructor(StakingParams memory _stakingParams, address _serviceRegistry) { + // Initial checks + if (_stakingParams.maxNumServices == 0 || _stakingParams.rewardsPerSecond == 0 || + _stakingParams.minStakingDeposit == 0 || _stakingParams.livenessPeriod == 0 || + _stakingParams.livenessRatio == 0 || _stakingParams.numAgentInstances == 0) { + revert ZeroValue(); + } + if (_serviceRegistry == address(0)) { + revert ZeroAddress(); + } + + // Assign all the required parameters + maxNumServices = _stakingParams.maxNumServices; + rewardsPerSecond = _stakingParams.rewardsPerSecond; + minStakingDeposit = _stakingParams.minStakingDeposit; + livenessPeriod = _stakingParams.livenessPeriod; + livenessRatio = _stakingParams.livenessRatio; + numAgentInstances = _stakingParams.numAgentInstances; + serviceRegistry = _serviceRegistry; + + // Assign optional parameters + threshold = _stakingParams.threshold; + configHash = _stakingParams.configHash; + + // Assign agent Ids, if applicable + uint256 size = _stakingParams.agentIds.length; + uint256 agentId; + if (size > 0) { + for (uint256 i = 0; i < size; ++i) { + // Agent Ids must be unique and in ascending order + if (_stakingParams.agentIds[i] <= agentId) { + revert WrongAgentId(_stakingParams.agentIds[i]); + } + agentId = _stakingParams.agentIds[i]; + agentIds.push(agentId); + } + } + + // Set the checkpoint timestamp to be the deployment one + tsCheckpoint = block.timestamp; + } + +### ServiceStakingNativeToken + + constructor(StakingParams memory _stakingParams, address _serviceRegistry) + ServiceStakingBase(_stakingParams, _serviceRegistry) + {} + +INFO:Printers: +###################### +####### ERC721 ####### +###################### + +## Constructor Call Sequence + - ERC721 + +## Constructor Definitions + +### ERC721 + + constructor(string memory _name, string memory _symbol) { + name = _name; + symbol = _symbol; + } + +################################### +####### ServiceStakingToken ####### +################################### + +## Constructor Call Sequence + - ServiceStakingBase + - ServiceStakingToken + +## Constructor Definitions + +### ServiceStakingBase + + constructor(StakingParams memory _stakingParams, address _serviceRegistry) { + // Initial checks + if (_stakingParams.maxNumServices == 0 || _stakingParams.rewardsPerSecond == 0 || + _stakingParams.minStakingDeposit == 0 || _stakingParams.livenessPeriod == 0 || + _stakingParams.livenessRatio == 0 || _stakingParams.numAgentInstances == 0) { + revert ZeroValue(); + } + if (_serviceRegistry == address(0)) { + revert ZeroAddress(); + } + + // Assign all the required parameters + maxNumServices = _stakingParams.maxNumServices; + rewardsPerSecond = _stakingParams.rewardsPerSecond; + minStakingDeposit = _stakingParams.minStakingDeposit; + livenessPeriod = _stakingParams.livenessPeriod; + livenessRatio = _stakingParams.livenessRatio; + numAgentInstances = _stakingParams.numAgentInstances; + serviceRegistry = _serviceRegistry; + + // Assign optional parameters + threshold = _stakingParams.threshold; + configHash = _stakingParams.configHash; + + // Assign agent Ids, if applicable + uint256 size = _stakingParams.agentIds.length; + uint256 agentId; + if (size > 0) { + for (uint256 i = 0; i < size; ++i) { + // Agent Ids must be unique and in ascending order + if (_stakingParams.agentIds[i] <= agentId) { + revert WrongAgentId(_stakingParams.agentIds[i]); + } + agentId = _stakingParams.agentIds[i]; + agentIds.push(agentId); + } + } + + // Set the checkpoint timestamp to be the deployment one + tsCheckpoint = block.timestamp; + } + +### ServiceStakingToken + + constructor( + StakingParams memory _stakingParams, + address _serviceRegistry, + address _serviceRegistryTokenUtility, + address _stakingToken + ) + ServiceStakingBase(_stakingParams, _serviceRegistry) + { + // Initial checks + if (_stakingToken == address(0) || _serviceRegistryTokenUtility == address(0)) { + revert ZeroAddress(); + } + + stakingToken = _stakingToken; + serviceRegistryTokenUtility = _serviceRegistryTokenUtility; + } + +INFO:Printers: +###################### +####### ERC721 ####### +###################### + +## Constructor Call Sequence + - ERC721 + +## Constructor Definitions + +### ERC721 + + constructor(string memory _name, string memory _symbol) { + name = _name; + symbol = _symbol; + } + +################################## +####### ServiceStakingBase ####### +################################## + +## Constructor Call Sequence + - ServiceStakingBase + +## Constructor Definitions + +### ServiceStakingBase + + constructor(StakingParams memory _stakingParams, address _serviceRegistry) { + // Initial checks + if (_stakingParams.maxNumServices == 0 || _stakingParams.rewardsPerSecond == 0 || + _stakingParams.minStakingDeposit == 0 || _stakingParams.livenessPeriod == 0 || + _stakingParams.livenessRatio == 0 || _stakingParams.numAgentInstances == 0) { + revert ZeroValue(); + } + if (_serviceRegistry == address(0)) { + revert ZeroAddress(); + } + + // Assign all the required parameters + maxNumServices = _stakingParams.maxNumServices; + rewardsPerSecond = _stakingParams.rewardsPerSecond; + minStakingDeposit = _stakingParams.minStakingDeposit; + livenessPeriod = _stakingParams.livenessPeriod; + livenessRatio = _stakingParams.livenessRatio; + numAgentInstances = _stakingParams.numAgentInstances; + serviceRegistry = _serviceRegistry; + + // Assign optional parameters + threshold = _stakingParams.threshold; + configHash = _stakingParams.configHash; + + // Assign agent Ids, if applicable + uint256 size = _stakingParams.agentIds.length; + uint256 agentId; + if (size > 0) { + for (uint256 i = 0; i < size; ++i) { + // Agent Ids must be unique and in ascending order + if (_stakingParams.agentIds[i] <= agentId) { + revert WrongAgentId(_stakingParams.agentIds[i]); + } + agentId = _stakingParams.agentIds[i]; + agentIds.push(agentId); + } + } + + // Set the checkpoint timestamp to be the deployment one + tsCheckpoint = block.timestamp; + } + +INFO:Slither:. analyzed (23 contracts) diff --git a/audits/internal4/analysis/slither_contract-summary.txt b/audits/internal4/analysis/slither_contract-summary.txt new file mode 100644 index 00000000..547374c1 --- /dev/null +++ b/audits/internal4/analysis/slither_contract-summary.txt @@ -0,0 +1,199 @@ +'solc --version' running +'solc ./ServiceStakingNativeToken-flatten.sol --combined-json abi,ast,bin,bin-runtime,srcmap,srcmap-runtime,userdoc,devdoc,hashes --allow-paths .,/home/andrey/valory/autonolas-registries/audits/internal4/analysis/contracts' running +'solc --version' running +'solc ./ServiceStakingToken-flatten.sol --combined-json abi,ast,bin,bin-runtime,srcmap,srcmap-runtime,userdoc,devdoc,hashes --allow-paths .,/home/andrey/valory/autonolas-registries/audits/internal4/analysis/contracts' running +'solc --version' running +'solc ./ServiceStakingBase-flatten.sol --combined-json abi,ast,bin,bin-runtime,srcmap,srcmap-runtime,userdoc,devdoc,hashes --allow-paths .,/home/andrey/valory/autonolas-registries/audits/internal4/analysis/contracts' running +INFO:Printers: ++ Contract IErrorsRegistries + ++ Contract ERC721 (Most derived contract) + - From ERC721 + - _burn(uint256) (internal) + - _mint(address,uint256) (internal) + - _safeMint(address,uint256) (internal) + - _safeMint(address,uint256,bytes) (internal) + - approve(address,uint256) (public) + - balanceOf(address) (public) + - constructor(string,string) (internal) + - ownerOf(uint256) (public) + - safeTransferFrom(address,address,uint256) (public) + - safeTransferFrom(address,address,uint256,bytes) (public) + - setApprovalForAll(address,bool) (public) + - supportsInterface(bytes4) (public) + - tokenURI(uint256) (public) + - transferFrom(address,address,uint256) (public) + ++ Contract ERC721TokenReceiver + - From ERC721TokenReceiver + - onERC721Received(address,address,uint256,bytes) (external) + ++ Contract IMultisig (Most derived contract) + - From IMultisig + - nonce() (external) + ++ Contract IService (Most derived contract) + - From IService + - getUnitIdsOfService(IService.UnitType,uint256) (external) + - mapServices(uint256) (external) + - safeTransferFrom(address,address,uint256) (external) + ++ Contract ServiceStakingBase + - From ERC721TokenReceiver + - onERC721Received(address,address,uint256,bytes) (external) + - From ServiceStakingBase + - _calculateStakingRewards() (internal) + - _checkTokenStakingDeposit(uint256,uint256) (internal) + - _withdraw(address,uint256) (internal) + - calculateServiceStakingReward(uint256) (external) + - checkpoint() (public) + - constructor(ServiceStakingBase.StakingParams,address) (internal) + - stake(uint256) (external) + - unstake(uint256) (external) + ++ Contract ServiceStakingNativeToken (Most derived contract) + - From ServiceStakingBase + - _calculateStakingRewards() (internal) + - _checkTokenStakingDeposit(uint256,uint256) (internal) + - calculateServiceStakingReward(uint256) (external) + - checkpoint() (public) + - stake(uint256) (external) + - unstake(uint256) (external) + - From ERC721TokenReceiver + - onERC721Received(address,address,uint256,bytes) (external) + - From ServiceStakingNativeToken + - _withdraw(address,uint256) (internal) + - constructor(ServiceStakingBase.StakingParams,address) (public) + - receive() (external) + +INFO:Printers: ++ Contract IErrorsRegistries + ++ Contract ERC721 (Most derived contract) + - From ERC721 + - _burn(uint256) (internal) + - _mint(address,uint256) (internal) + - _safeMint(address,uint256) (internal) + - _safeMint(address,uint256,bytes) (internal) + - approve(address,uint256) (public) + - balanceOf(address) (public) + - constructor(string,string) (internal) + - ownerOf(uint256) (public) + - safeTransferFrom(address,address,uint256) (public) + - safeTransferFrom(address,address,uint256,bytes) (public) + - setApprovalForAll(address,bool) (public) + - supportsInterface(bytes4) (public) + - tokenURI(uint256) (public) + - transferFrom(address,address,uint256) (public) + ++ Contract ERC721TokenReceiver + - From ERC721TokenReceiver + - onERC721Received(address,address,uint256,bytes) (external) + ++ Contract IMultisig (Most derived contract) + - From IMultisig + - nonce() (external) + ++ Contract IService (Most derived contract) + - From IService + - getUnitIdsOfService(IService.UnitType,uint256) (external) + - mapServices(uint256) (external) + - safeTransferFrom(address,address,uint256) (external) + ++ Contract ServiceStakingBase + - From ERC721TokenReceiver + - onERC721Received(address,address,uint256,bytes) (external) + - From ServiceStakingBase + - _calculateStakingRewards() (internal) + - _checkTokenStakingDeposit(uint256,uint256) (internal) + - _withdraw(address,uint256) (internal) + - calculateServiceStakingReward(uint256) (external) + - checkpoint() (public) + - constructor(ServiceStakingBase.StakingParams,address) (internal) + - stake(uint256) (external) + - unstake(uint256) (external) + ++ Contract IToken (Most derived contract) + - From IToken + - allowance(address,address) (external) + - approve(address,uint256) (external) + - balanceOf(address) (external) + - decimals() (external) + - ownerOf(uint256) (external) + - totalSupply() (external) + - transfer(address,uint256) (external) + - transferFrom(address,address,uint256) (external) + ++ Contract SafeTransferLib (Most derived contract) + - From SafeTransferLib + - safeTransfer(address,address,uint256) (internal) + - safeTransferFrom(address,address,address,uint256) (internal) + ++ Contract IServiceTokenUtility (Most derived contract) + - From IServiceTokenUtility + - mapServiceIdTokenDeposit(uint256) (external) + ++ Contract ServiceStakingToken (Most derived contract) + - From ServiceStakingBase + - _calculateStakingRewards() (internal) + - calculateServiceStakingReward(uint256) (external) + - checkpoint() (public) + - constructor(ServiceStakingBase.StakingParams,address) (internal) + - stake(uint256) (external) + - unstake(uint256) (external) + - From ERC721TokenReceiver + - onERC721Received(address,address,uint256,bytes) (external) + - From ServiceStakingToken + - _checkTokenStakingDeposit(uint256,uint256) (internal) + - _withdraw(address,uint256) (internal) + - constructor(ServiceStakingBase.StakingParams,address,address,address) (public) + - deposit(uint256) (external) + +INFO:Printers: ++ Contract IErrorsRegistries + ++ Contract ERC721 (Most derived contract) + - From ERC721 + - _burn(uint256) (internal) + - _mint(address,uint256) (internal) + - _safeMint(address,uint256) (internal) + - _safeMint(address,uint256,bytes) (internal) + - approve(address,uint256) (public) + - balanceOf(address) (public) + - constructor(string,string) (internal) + - ownerOf(uint256) (public) + - safeTransferFrom(address,address,uint256) (public) + - safeTransferFrom(address,address,uint256,bytes) (public) + - setApprovalForAll(address,bool) (public) + - supportsInterface(bytes4) (public) + - tokenURI(uint256) (public) + - transferFrom(address,address,uint256) (public) + ++ Contract ERC721TokenReceiver + - From ERC721TokenReceiver + - onERC721Received(address,address,uint256,bytes) (external) + ++ Contract IMultisig (Most derived contract) + - From IMultisig + - nonce() (external) + ++ Contract IService (Most derived contract) + - From IService + - getUnitIdsOfService(IService.UnitType,uint256) (external) + - mapServices(uint256) (external) + - safeTransferFrom(address,address,uint256) (external) + ++ Contract ServiceStakingBase (Most derived contract) + - From ERC721TokenReceiver + - onERC721Received(address,address,uint256,bytes) (external) + - From ServiceStakingBase + - _calculateStakingRewards() (internal) + - _checkTokenStakingDeposit(uint256,uint256) (internal) + - _withdraw(address,uint256) (internal) + - calculateServiceStakingReward(uint256) (external) + - checkpoint() (public) + - constructor(ServiceStakingBase.StakingParams,address) (internal) + - stake(uint256) (external) + - unstake(uint256) (external) + +INFO:Slither:. analyzed (23 contracts) diff --git a/audits/internal4/analysis/slither_data-dependency.txt b/audits/internal4/analysis/slither_data-dependency.txt new file mode 100644 index 00000000..4a889cf2 --- /dev/null +++ b/audits/internal4/analysis/slither_data-dependency.txt @@ -0,0 +1,7802 @@ +'solc --version' running +'solc ./ServiceStakingNativeToken-flatten.sol --combined-json abi,ast,bin,bin-runtime,srcmap,srcmap-runtime,userdoc,devdoc,hashes --allow-paths .,/home/andrey/valory/autonolas-registries/audits/internal4/analysis/contracts' running +'solc --version' running +'solc ./ServiceStakingToken-flatten.sol --combined-json abi,ast,bin,bin-runtime,srcmap,srcmap-runtime,userdoc,devdoc,hashes --allow-paths .,/home/andrey/valory/autonolas-registries/audits/internal4/analysis/contracts' running +'solc --version' running +'solc ./ServiceStakingBase-flatten.sol --combined-json abi,ast,bin,bin-runtime,srcmap,srcmap-runtime,userdoc,devdoc,hashes --allow-paths .,/home/andrey/valory/autonolas-registries/audits/internal4/analysis/contracts' running +INFO:Printers: +Contract IErrorsRegistries ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ ++----------+--------------+ + +INFO:Printers: +Contract IErrorsRegistries ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ ++----------+--------------+ + +Contract ERC721 ++------------------+----------------------------+ +| Variable | Dependencies | ++------------------+----------------------------+ +| name | ['_name'] | +| symbol | ['_symbol'] | +| _ownerOf | ['_ownerOf', 'to'] | +| _balanceOf | ['_balanceOf'] | +| getApproved | ['getApproved', 'spender'] | +| isApprovedForAll | ['isApprovedForAll'] | ++------------------+----------------------------+ + +Function tokenURI(uint256) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| id | [] | +| | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function ownerOf(uint256) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| id | [] | +| owner | ['_ownerOf'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf'] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function balanceOf(address) ++-------------------------+----------------+ +| Variable | Dependencies | ++-------------------------+----------------+ +| owner | [] | +| | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | ['_balanceOf'] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+----------------+ +Function constructor(string,string) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| _name | [] | +| _symbol | [] | +| ERC721.name | ['_name'] | +| ERC721.symbol | ['_symbol'] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function approve(address,uint256) ++-------------------------+----------------------------+ +| Variable | Dependencies | ++-------------------------+----------------------------+ +| spender | [] | +| id | [] | +| owner | ['_ownerOf'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf'] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | ['getApproved', 'spender'] | +| ERC721.isApprovedForAll | ['isApprovedForAll'] | ++-------------------------+----------------------------+ +Function setApprovalForAll(address,bool) ++-------------------------+----------------------+ +| Variable | Dependencies | ++-------------------------+----------------------+ +| operator | [] | +| approved | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | ['isApprovedForAll'] | ++-------------------------+----------------------+ +Function transferFrom(address,address,uint256) ++-------------------------+----------------------+ +| Variable | Dependencies | ++-------------------------+----------------------+ +| from | ['from'] | +| to | ['to'] | +| id | ['id'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf', 'to'] | +| ERC721._balanceOf | ['_balanceOf'] | +| ERC721.getApproved | ['getApproved'] | +| ERC721.isApprovedForAll | ['isApprovedForAll'] | ++-------------------------+----------------------+ +Function safeTransferFrom(address,address,uint256) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| from | [] | +| to | [] | +| id | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function safeTransferFrom(address,address,uint256,bytes) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| from | [] | +| to | [] | +| id | [] | +| data | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function supportsInterface(bytes4) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| interfaceId | [] | +| | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function _mint(address,uint256) ++-------------------------+--------------------+ +| Variable | Dependencies | ++-------------------------+--------------------+ +| to | ['to'] | +| id | ['id'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf', 'to'] | +| ERC721._balanceOf | ['_balanceOf'] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------------+ +Function _burn(uint256) ++-------------------------+-----------------+ +| Variable | Dependencies | ++-------------------------+-----------------+ +| id | [] | +| owner | ['_ownerOf'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf'] | +| ERC721._balanceOf | ['_balanceOf'] | +| ERC721.getApproved | ['getApproved'] | +| ERC721.isApprovedForAll | [] | ++-------------------------+-----------------+ +Function _safeMint(address,uint256) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| to | [] | +| id | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function _safeMint(address,uint256,bytes) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| to | [] | +| id | [] | +| data | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +INFO:Printers: +Contract IErrorsRegistries ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ ++----------+--------------+ + +Contract ERC721 ++------------------+----------------------------+ +| Variable | Dependencies | ++------------------+----------------------------+ +| name | ['_name'] | +| symbol | ['_symbol'] | +| _ownerOf | ['_ownerOf', 'to'] | +| _balanceOf | ['_balanceOf'] | +| getApproved | ['getApproved', 'spender'] | +| isApprovedForAll | ['isApprovedForAll'] | ++------------------+----------------------------+ + +Function tokenURI(uint256) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| id | [] | +| | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function ownerOf(uint256) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| id | [] | +| owner | ['_ownerOf'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf'] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function balanceOf(address) ++-------------------------+----------------+ +| Variable | Dependencies | ++-------------------------+----------------+ +| owner | [] | +| | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | ['_balanceOf'] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+----------------+ +Function constructor(string,string) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| _name | [] | +| _symbol | [] | +| ERC721.name | ['_name'] | +| ERC721.symbol | ['_symbol'] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function approve(address,uint256) ++-------------------------+----------------------------+ +| Variable | Dependencies | ++-------------------------+----------------------------+ +| spender | [] | +| id | [] | +| owner | ['_ownerOf'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf'] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | ['getApproved', 'spender'] | +| ERC721.isApprovedForAll | ['isApprovedForAll'] | ++-------------------------+----------------------------+ +Function setApprovalForAll(address,bool) ++-------------------------+----------------------+ +| Variable | Dependencies | ++-------------------------+----------------------+ +| operator | [] | +| approved | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | ['isApprovedForAll'] | ++-------------------------+----------------------+ +Function transferFrom(address,address,uint256) ++-------------------------+----------------------+ +| Variable | Dependencies | ++-------------------------+----------------------+ +| from | ['from'] | +| to | ['to'] | +| id | ['id'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf', 'to'] | +| ERC721._balanceOf | ['_balanceOf'] | +| ERC721.getApproved | ['getApproved'] | +| ERC721.isApprovedForAll | ['isApprovedForAll'] | ++-------------------------+----------------------+ +Function safeTransferFrom(address,address,uint256) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| from | [] | +| to | [] | +| id | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function safeTransferFrom(address,address,uint256,bytes) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| from | [] | +| to | [] | +| id | [] | +| data | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function supportsInterface(bytes4) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| interfaceId | [] | +| | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function _mint(address,uint256) ++-------------------------+--------------------+ +| Variable | Dependencies | ++-------------------------+--------------------+ +| to | ['to'] | +| id | ['id'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf', 'to'] | +| ERC721._balanceOf | ['_balanceOf'] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------------+ +Function _burn(uint256) ++-------------------------+-----------------+ +| Variable | Dependencies | ++-------------------------+-----------------+ +| id | [] | +| owner | ['_ownerOf'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf'] | +| ERC721._balanceOf | ['_balanceOf'] | +| ERC721.getApproved | ['getApproved'] | +| ERC721.isApprovedForAll | [] | ++-------------------------+-----------------+ +Function _safeMint(address,uint256) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| to | [] | +| id | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function _safeMint(address,uint256,bytes) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| to | [] | +| id | [] | +| data | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Contract ERC721TokenReceiver ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ ++----------+--------------+ + +Function onERC721Received(address,address,uint256,bytes) ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ +| | [] | ++----------+--------------+ +INFO:Printers: +Contract IErrorsRegistries ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ ++----------+--------------+ + +Contract ERC721 ++------------------+----------------------------+ +| Variable | Dependencies | ++------------------+----------------------------+ +| name | ['_name'] | +| symbol | ['_symbol'] | +| _ownerOf | ['_ownerOf', 'to'] | +| _balanceOf | ['_balanceOf'] | +| getApproved | ['getApproved', 'spender'] | +| isApprovedForAll | ['isApprovedForAll'] | ++------------------+----------------------------+ + +Function tokenURI(uint256) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| id | [] | +| | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function ownerOf(uint256) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| id | [] | +| owner | ['_ownerOf'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf'] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function balanceOf(address) ++-------------------------+----------------+ +| Variable | Dependencies | ++-------------------------+----------------+ +| owner | [] | +| | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | ['_balanceOf'] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+----------------+ +Function constructor(string,string) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| _name | [] | +| _symbol | [] | +| ERC721.name | ['_name'] | +| ERC721.symbol | ['_symbol'] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function approve(address,uint256) ++-------------------------+----------------------------+ +| Variable | Dependencies | ++-------------------------+----------------------------+ +| spender | [] | +| id | [] | +| owner | ['_ownerOf'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf'] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | ['getApproved', 'spender'] | +| ERC721.isApprovedForAll | ['isApprovedForAll'] | ++-------------------------+----------------------------+ +Function setApprovalForAll(address,bool) ++-------------------------+----------------------+ +| Variable | Dependencies | ++-------------------------+----------------------+ +| operator | [] | +| approved | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | ['isApprovedForAll'] | ++-------------------------+----------------------+ +Function transferFrom(address,address,uint256) ++-------------------------+----------------------+ +| Variable | Dependencies | ++-------------------------+----------------------+ +| from | ['from'] | +| to | ['to'] | +| id | ['id'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf', 'to'] | +| ERC721._balanceOf | ['_balanceOf'] | +| ERC721.getApproved | ['getApproved'] | +| ERC721.isApprovedForAll | ['isApprovedForAll'] | ++-------------------------+----------------------+ +Function safeTransferFrom(address,address,uint256) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| from | [] | +| to | [] | +| id | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function safeTransferFrom(address,address,uint256,bytes) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| from | [] | +| to | [] | +| id | [] | +| data | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function supportsInterface(bytes4) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| interfaceId | [] | +| | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function _mint(address,uint256) ++-------------------------+--------------------+ +| Variable | Dependencies | ++-------------------------+--------------------+ +| to | ['to'] | +| id | ['id'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf', 'to'] | +| ERC721._balanceOf | ['_balanceOf'] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------------+ +Function _burn(uint256) ++-------------------------+-----------------+ +| Variable | Dependencies | ++-------------------------+-----------------+ +| id | [] | +| owner | ['_ownerOf'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf'] | +| ERC721._balanceOf | ['_balanceOf'] | +| ERC721.getApproved | ['getApproved'] | +| ERC721.isApprovedForAll | [] | ++-------------------------+-----------------+ +Function _safeMint(address,uint256) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| to | [] | +| id | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function _safeMint(address,uint256,bytes) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| to | [] | +| id | [] | +| data | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Contract ERC721TokenReceiver ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ ++----------+--------------+ + +Function onERC721Received(address,address,uint256,bytes) ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ +| | [] | ++----------+--------------+ +Contract IMultisig ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ ++----------+--------------+ + +Function nonce() ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ +| | [] | ++----------+--------------+ +INFO:Printers: +Contract IErrorsRegistries ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ ++----------+--------------+ + +Contract ERC721 ++------------------+----------------------------+ +| Variable | Dependencies | ++------------------+----------------------------+ +| name | ['_name'] | +| symbol | ['_symbol'] | +| _ownerOf | ['_ownerOf', 'to'] | +| _balanceOf | ['_balanceOf'] | +| getApproved | ['getApproved', 'spender'] | +| isApprovedForAll | ['isApprovedForAll'] | ++------------------+----------------------------+ + +Function tokenURI(uint256) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| id | [] | +| | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function ownerOf(uint256) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| id | [] | +| owner | ['_ownerOf'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf'] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function balanceOf(address) ++-------------------------+----------------+ +| Variable | Dependencies | ++-------------------------+----------------+ +| owner | [] | +| | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | ['_balanceOf'] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+----------------+ +Function constructor(string,string) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| _name | [] | +| _symbol | [] | +| ERC721.name | ['_name'] | +| ERC721.symbol | ['_symbol'] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function approve(address,uint256) ++-------------------------+----------------------------+ +| Variable | Dependencies | ++-------------------------+----------------------------+ +| spender | [] | +| id | [] | +| owner | ['_ownerOf'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf'] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | ['getApproved', 'spender'] | +| ERC721.isApprovedForAll | ['isApprovedForAll'] | ++-------------------------+----------------------------+ +Function setApprovalForAll(address,bool) ++-------------------------+----------------------+ +| Variable | Dependencies | ++-------------------------+----------------------+ +| operator | [] | +| approved | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | ['isApprovedForAll'] | ++-------------------------+----------------------+ +Function transferFrom(address,address,uint256) ++-------------------------+----------------------+ +| Variable | Dependencies | ++-------------------------+----------------------+ +| from | ['from'] | +| to | ['to'] | +| id | ['id'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf', 'to'] | +| ERC721._balanceOf | ['_balanceOf'] | +| ERC721.getApproved | ['getApproved'] | +| ERC721.isApprovedForAll | ['isApprovedForAll'] | ++-------------------------+----------------------+ +Function safeTransferFrom(address,address,uint256) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| from | [] | +| to | [] | +| id | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function safeTransferFrom(address,address,uint256,bytes) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| from | [] | +| to | [] | +| id | [] | +| data | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function supportsInterface(bytes4) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| interfaceId | [] | +| | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function _mint(address,uint256) ++-------------------------+--------------------+ +| Variable | Dependencies | ++-------------------------+--------------------+ +| to | ['to'] | +| id | ['id'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf', 'to'] | +| ERC721._balanceOf | ['_balanceOf'] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------------+ +Function _burn(uint256) ++-------------------------+-----------------+ +| Variable | Dependencies | ++-------------------------+-----------------+ +| id | [] | +| owner | ['_ownerOf'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf'] | +| ERC721._balanceOf | ['_balanceOf'] | +| ERC721.getApproved | ['getApproved'] | +| ERC721.isApprovedForAll | [] | ++-------------------------+-----------------+ +Function _safeMint(address,uint256) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| to | [] | +| id | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function _safeMint(address,uint256,bytes) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| to | [] | +| id | [] | +| data | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Contract ERC721TokenReceiver ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ ++----------+--------------+ + +Function onERC721Received(address,address,uint256,bytes) ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ +| | [] | ++----------+--------------+ +Contract IMultisig ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ ++----------+--------------+ + +Function nonce() ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ +| | [] | ++----------+--------------+ +Contract IService ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ ++----------+--------------+ + +Function safeTransferFrom(address,address,uint256) ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ +| from | [] | +| to | [] | +| id | [] | ++----------+--------------+ +Function mapServices(uint256) ++----------------------+--------------+ +| Variable | Dependencies | ++----------------------+--------------+ +| serviceId | [] | +| securityDeposit | [] | +| multisig | [] | +| configHash | [] | +| threshold | [] | +| maxNumAgentInstances | [] | +| numAgentInstances | [] | +| state | [] | ++----------------------+--------------+ +Function getUnitIdsOfService(IService.UnitType,uint256) ++------------+--------------+ +| Variable | Dependencies | ++------------+--------------+ +| unitType | [] | +| serviceId | [] | +| numUnitIds | [] | +| unitIds | [] | ++------------+--------------+ +INFO:Printers: +Contract IErrorsRegistries ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ ++----------+--------------+ + +Contract ERC721 ++------------------+----------------------------+ +| Variable | Dependencies | ++------------------+----------------------------+ +| name | ['_name'] | +| symbol | ['_symbol'] | +| _ownerOf | ['_ownerOf', 'to'] | +| _balanceOf | ['_balanceOf'] | +| getApproved | ['getApproved', 'spender'] | +| isApprovedForAll | ['isApprovedForAll'] | ++------------------+----------------------------+ + +Function tokenURI(uint256) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| id | [] | +| | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function ownerOf(uint256) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| id | [] | +| owner | ['_ownerOf'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf'] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function balanceOf(address) ++-------------------------+----------------+ +| Variable | Dependencies | ++-------------------------+----------------+ +| owner | [] | +| | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | ['_balanceOf'] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+----------------+ +Function constructor(string,string) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| _name | [] | +| _symbol | [] | +| ERC721.name | ['_name'] | +| ERC721.symbol | ['_symbol'] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function approve(address,uint256) ++-------------------------+----------------------------+ +| Variable | Dependencies | ++-------------------------+----------------------------+ +| spender | [] | +| id | [] | +| owner | ['_ownerOf'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf'] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | ['getApproved', 'spender'] | +| ERC721.isApprovedForAll | ['isApprovedForAll'] | ++-------------------------+----------------------------+ +Function setApprovalForAll(address,bool) ++-------------------------+----------------------+ +| Variable | Dependencies | ++-------------------------+----------------------+ +| operator | [] | +| approved | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | ['isApprovedForAll'] | ++-------------------------+----------------------+ +Function transferFrom(address,address,uint256) ++-------------------------+----------------------+ +| Variable | Dependencies | ++-------------------------+----------------------+ +| from | ['from'] | +| to | ['to'] | +| id | ['id'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf', 'to'] | +| ERC721._balanceOf | ['_balanceOf'] | +| ERC721.getApproved | ['getApproved'] | +| ERC721.isApprovedForAll | ['isApprovedForAll'] | ++-------------------------+----------------------+ +Function safeTransferFrom(address,address,uint256) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| from | [] | +| to | [] | +| id | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function safeTransferFrom(address,address,uint256,bytes) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| from | [] | +| to | [] | +| id | [] | +| data | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function supportsInterface(bytes4) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| interfaceId | [] | +| | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function _mint(address,uint256) ++-------------------------+--------------------+ +| Variable | Dependencies | ++-------------------------+--------------------+ +| to | ['to'] | +| id | ['id'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf', 'to'] | +| ERC721._balanceOf | ['_balanceOf'] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------------+ +Function _burn(uint256) ++-------------------------+-----------------+ +| Variable | Dependencies | ++-------------------------+-----------------+ +| id | [] | +| owner | ['_ownerOf'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf'] | +| ERC721._balanceOf | ['_balanceOf'] | +| ERC721.getApproved | ['getApproved'] | +| ERC721.isApprovedForAll | [] | ++-------------------------+-----------------+ +Function _safeMint(address,uint256) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| to | [] | +| id | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function _safeMint(address,uint256,bytes) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| to | [] | +| id | [] | +| data | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Contract ERC721TokenReceiver ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ ++----------+--------------+ + +Function onERC721Received(address,address,uint256,bytes) ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ +| | [] | ++----------+--------------+ +Contract IMultisig ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ ++----------+--------------+ + +Function nonce() ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ +| | [] | ++----------+--------------+ +Contract IService ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ ++----------+--------------+ + +Function safeTransferFrom(address,address,uint256) ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ +| from | [] | +| to | [] | +| id | [] | ++----------+--------------+ +Function mapServices(uint256) ++----------------------+--------------+ +| Variable | Dependencies | ++----------------------+--------------+ +| serviceId | [] | +| securityDeposit | [] | +| multisig | [] | +| configHash | [] | +| threshold | [] | +| maxNumAgentInstances | [] | +| numAgentInstances | [] | +| state | [] | ++----------------------+--------------+ +Function getUnitIdsOfService(IService.UnitType,uint256) ++------------+--------------+ +| Variable | Dependencies | ++------------+--------------+ +| unitType | [] | +| serviceId | [] | +| numUnitIds | [] | +| unitIds | [] | ++------------+--------------+ +Contract ServiceStakingBase ++-------------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ +| Variable | Dependencies | ++-------------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ +| VERSION | [] | +| maxNumServices | ['_stakingParams', 'maxNumServices'] | +| rewardsPerSecond | ['_stakingParams', 'rewardsPerSecond'] | +| minStakingDeposit | ['_stakingParams', 'minStakingDeposit'] | +| livenessPeriod | ['_stakingParams', 'livenessPeriod'] | +| livenessRatio | ['_stakingParams', 'livenessRatio'] | +| numAgentInstances | ['_stakingParams', 'numAgentInstances'] | +| threshold | ['_stakingParams', 'threshold'] | +| configHash | ['_stakingParams', 'configHash'] | +| serviceRegistry | ['_serviceRegistry', 'serviceRegistry'] | +| balance | [] | +| availableRewards | ['TUPLE_2', 'availableRewards', 'lastAvailableRewards', 'totalRewards'] | +| tsCheckpoint | ['block.timestamp', 'tsCheckpoint'] | +| agentIds | ['_stakingParams', 'agentId', 'agentIds'] | +| mapServiceInfo | ['TUPLE_0', '_serviceRegistry', 'block.timestamp', 'mapServiceInfo', 'msg.sender', 'multisig', 'nonce', 'sInfo', 'serviceId', 'serviceRegistry'] | +| setServiceIds | ['serviceId', 'setServiceIds'] | ++-------------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ + +Function constructor(ServiceStakingBase.StakingParams,address) ++--------------------------------------+-------------------------------------------+ +| Variable | Dependencies | ++--------------------------------------+-------------------------------------------+ +| _stakingParams | ['_stakingParams'] | +| _serviceRegistry | ['_serviceRegistry'] | +| size | ['_stakingParams'] | +| agentId | ['_stakingParams', 'agentId'] | +| i | ['i'] | +| ServiceStakingBase.VERSION | [] | +| ServiceStakingBase.maxNumServices | ['_stakingParams'] | +| ServiceStakingBase.rewardsPerSecond | ['_stakingParams'] | +| ServiceStakingBase.minStakingDeposit | ['_stakingParams'] | +| ServiceStakingBase.livenessPeriod | ['_stakingParams'] | +| ServiceStakingBase.livenessRatio | ['_stakingParams'] | +| ServiceStakingBase.numAgentInstances | ['_stakingParams'] | +| ServiceStakingBase.threshold | ['_stakingParams'] | +| ServiceStakingBase.configHash | ['_stakingParams'] | +| ServiceStakingBase.serviceRegistry | ['_serviceRegistry'] | +| ServiceStakingBase.balance | [] | +| ServiceStakingBase.availableRewards | [] | +| ServiceStakingBase.tsCheckpoint | ['block.timestamp'] | +| ServiceStakingBase.agentIds | ['_stakingParams', 'agentId', 'agentIds'] | +| ServiceStakingBase.mapServiceInfo | [] | +| ServiceStakingBase.setServiceIds | [] | ++--------------------------------------+-------------------------------------------+ +Function _checkTokenStakingDeposit(uint256,uint256) ++--------------------------------------+-----------------------+ +| Variable | Dependencies | ++--------------------------------------+-----------------------+ +| | [] | +| stakingDeposit | ['stakingDeposit'] | +| ServiceStakingBase.VERSION | [] | +| ServiceStakingBase.maxNumServices | [] | +| ServiceStakingBase.rewardsPerSecond | [] | +| ServiceStakingBase.minStakingDeposit | ['minStakingDeposit'] | +| ServiceStakingBase.livenessPeriod | [] | +| ServiceStakingBase.livenessRatio | [] | +| ServiceStakingBase.numAgentInstances | [] | +| ServiceStakingBase.threshold | [] | +| ServiceStakingBase.configHash | [] | +| ServiceStakingBase.serviceRegistry | [] | +| ServiceStakingBase.balance | [] | +| ServiceStakingBase.availableRewards | [] | +| ServiceStakingBase.tsCheckpoint | [] | +| ServiceStakingBase.agentIds | [] | +| ServiceStakingBase.mapServiceInfo | [] | +| ServiceStakingBase.setServiceIds | [] | ++--------------------------------------+-----------------------+ +Function _withdraw(address,uint256) ++--------------------------------------+--------------+ +| Variable | Dependencies | ++--------------------------------------+--------------+ +| to | [] | +| amount | [] | +| ServiceStakingBase.VERSION | [] | +| ServiceStakingBase.maxNumServices | [] | +| ServiceStakingBase.rewardsPerSecond | [] | +| ServiceStakingBase.minStakingDeposit | [] | +| ServiceStakingBase.livenessPeriod | [] | +| ServiceStakingBase.livenessRatio | [] | +| ServiceStakingBase.numAgentInstances | [] | +| ServiceStakingBase.threshold | [] | +| ServiceStakingBase.configHash | [] | +| ServiceStakingBase.serviceRegistry | [] | +| ServiceStakingBase.balance | [] | +| ServiceStakingBase.availableRewards | [] | +| ServiceStakingBase.tsCheckpoint | [] | +| ServiceStakingBase.agentIds | [] | +| ServiceStakingBase.mapServiceInfo | [] | +| ServiceStakingBase.setServiceIds | [] | ++--------------------------------------+--------------+ +Function stake(uint256) ++--------------------------------------+------------------------------------------------------------------------------------------------------------------------------+ +| Variable | Dependencies | ++--------------------------------------+------------------------------------------------------------------------------------------------------------------------------+ +| serviceId | [] | +| numStakingServices | ['serviceId', 'setServiceIds'] | +| stakingDeposit | ['TUPLE_0', 'serviceId', 'serviceRegistry'] | +| multisig | ['TUPLE_0', 'serviceId', 'serviceRegistry'] | +| hash | ['TUPLE_0', 'serviceId', 'serviceRegistry'] | +| agentThreshold | ['TUPLE_0', 'serviceId', 'serviceRegistry'] | +| maxNumInstances | ['TUPLE_0', 'serviceId', 'serviceRegistry'] | +| state | ['TUPLE_0', 'serviceId', 'serviceRegistry'] | +| size | ['agentIds'] | +| numAgents | ['IService', 'TUPLE_1', 'serviceId', 'serviceRegistry'] | +| agents | ['IService', 'TUPLE_1', 'agents', 'serviceId', 'serviceRegistry'] | +| i | ['i'] | +| sInfo | ['TUPLE_0', 'block.timestamp', 'msg.sender', 'multisig', 'nonce', 'sInfo', 'serviceId', 'serviceRegistry'] | +| nonce | ['TUPLE_0', 'multisig', 'serviceId', 'serviceRegistry'] | +| ServiceStakingBase.VERSION | [] | +| ServiceStakingBase.maxNumServices | ['maxNumServices'] | +| ServiceStakingBase.rewardsPerSecond | [] | +| ServiceStakingBase.minStakingDeposit | [] | +| ServiceStakingBase.livenessPeriod | [] | +| ServiceStakingBase.livenessRatio | [] | +| ServiceStakingBase.numAgentInstances | ['numAgentInstances'] | +| ServiceStakingBase.threshold | ['threshold'] | +| ServiceStakingBase.configHash | ['configHash'] | +| ServiceStakingBase.serviceRegistry | ['serviceRegistry'] | +| ServiceStakingBase.balance | [] | +| ServiceStakingBase.availableRewards | ['availableRewards'] | +| ServiceStakingBase.tsCheckpoint | [] | +| ServiceStakingBase.agentIds | ['agentIds'] | +| ServiceStakingBase.mapServiceInfo | ['TUPLE_0', 'block.timestamp', 'mapServiceInfo', 'msg.sender', 'multisig', 'nonce', 'sInfo', 'serviceId', 'serviceRegistry'] | +| ServiceStakingBase.setServiceIds | ['serviceId', 'setServiceIds'] | ++--------------------------------------+------------------------------------------------------------------------------------------------------------------------------+ +Function _calculateStakingRewards() ++--------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| Variable | Dependencies | ++--------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| lastAvailableRewards | ['availableRewards'] | +| numServices | ['numServices'] | +| totalRewards | ['block.timestamp', 'curInfo', 'reward', 'rewardsPerSecond', 'serviceCheckpoint', 'totalRewards', 'ts', 'tsCheckpoint', 'tsCheckpointLast'] | +| eligibleServiceIds | ['eligibleServiceIds', 'serviceIds', 'setServiceIds', 'size'] | +| eligibleServiceRewards | ['block.timestamp', 'curInfo', 'eligibleServiceRewards', 'reward', 'rewardsPerSecond', 'serviceCheckpoint', 'setServiceIds', 'size', 'ts', 'tsCheckpoint', 'tsCheckpointLast'] | +| serviceIds | ['serviceIds', 'setServiceIds', 'size'] | +| serviceNonces | ['curInfo', 'serviceNonces', 'setServiceIds', 'size'] | +| size | ['setServiceIds'] | +| i | ['i'] | +| tsCheckpointLast | ['tsCheckpoint'] | +| i_scope_0 | ['i_scope_0'] | +| curInfo | ['curInfo'] | +| serviceCheckpoint | ['curInfo', 'serviceCheckpoint', 'ts', 'tsCheckpoint', 'tsCheckpointLast'] | +| ts | ['block.timestamp', 'curInfo', 'serviceCheckpoint', 'ts', 'tsCheckpoint', 'tsCheckpointLast'] | +| ratio | ['block.timestamp', 'curInfo', 'ratio', 'serviceCheckpoint', 'serviceNonces', 'setServiceIds', 'size', 'ts', 'tsCheckpoint', 'tsCheckpointLast'] | +| reward | ['block.timestamp', 'curInfo', 'rewardsPerSecond', 'serviceCheckpoint', 'ts', 'tsCheckpoint', 'tsCheckpointLast'] | +| ServiceStakingBase.VERSION | [] | +| ServiceStakingBase.maxNumServices | [] | +| ServiceStakingBase.rewardsPerSecond | ['rewardsPerSecond'] | +| ServiceStakingBase.minStakingDeposit | [] | +| ServiceStakingBase.livenessPeriod | ['livenessPeriod'] | +| ServiceStakingBase.livenessRatio | ['livenessRatio'] | +| ServiceStakingBase.numAgentInstances | [] | +| ServiceStakingBase.threshold | [] | +| ServiceStakingBase.configHash | [] | +| ServiceStakingBase.serviceRegistry | [] | +| ServiceStakingBase.balance | [] | +| ServiceStakingBase.availableRewards | ['availableRewards'] | +| ServiceStakingBase.tsCheckpoint | ['tsCheckpoint'] | +| ServiceStakingBase.agentIds | [] | +| ServiceStakingBase.mapServiceInfo | ['mapServiceInfo'] | +| ServiceStakingBase.setServiceIds | ['setServiceIds'] | ++--------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +Function checkpoint() ++--------------------------------------+-----------------------------------------------------------------------------------------------------------------------+ +| Variable | Dependencies | ++--------------------------------------+-----------------------------------------------------------------------------------------------------------------------+ +| | [] | +| success | ['success'] | +| lastAvailableRewards | ['TUPLE_2', 'lastAvailableRewards', 'totalRewards'] | +| numServices | ['TUPLE_2'] | +| totalRewards | ['TUPLE_2'] | +| eligibleServiceIds | ['TUPLE_2', 'eligibleServiceIds'] | +| eligibleServiceRewards | ['TUPLE_2', 'eligibleServiceRewards'] | +| serviceIds | ['TUPLE_2', 'serviceIds'] | +| serviceNonces | ['TUPLE_2', 'serviceNonces'] | +| updatedReward | ['TUPLE_2', 'eligibleServiceRewards', 'lastAvailableRewards', 'totalRewards', 'updatedReward', 'updatedTotalRewards'] | +| updatedTotalRewards | ['TUPLE_2', 'eligibleServiceRewards', 'lastAvailableRewards', 'totalRewards', 'updatedReward', 'updatedTotalRewards'] | +| curServiceId | ['TUPLE_2', 'eligibleServiceIds'] | +| i | ['i'] | +| i_scope_0 | ['i_scope_0'] | +| curServiceId_scope_1 | ['TUPLE_2', 'eligibleServiceIds'] | +| i_scope_2 | ['i_scope_2'] | +| curServiceId_scope_3 | ['TUPLE_2', 'serviceIds'] | +| ServiceStakingBase.VERSION | [] | +| ServiceStakingBase.maxNumServices | [] | +| ServiceStakingBase.rewardsPerSecond | [] | +| ServiceStakingBase.minStakingDeposit | [] | +| ServiceStakingBase.livenessPeriod | [] | +| ServiceStakingBase.livenessRatio | [] | +| ServiceStakingBase.numAgentInstances | [] | +| ServiceStakingBase.threshold | [] | +| ServiceStakingBase.configHash | [] | +| ServiceStakingBase.serviceRegistry | [] | +| ServiceStakingBase.balance | [] | +| ServiceStakingBase.availableRewards | ['TUPLE_2', 'lastAvailableRewards', 'totalRewards'] | +| ServiceStakingBase.tsCheckpoint | ['block.timestamp'] | +| ServiceStakingBase.agentIds | [] | +| ServiceStakingBase.mapServiceInfo | ['mapServiceInfo'] | +| ServiceStakingBase.setServiceIds | [] | ++--------------------------------------+-----------------------------------------------------------------------------------------------------------------------+ +Function unstake(uint256) ++--------------------------------------+----------------------------------------------------------------------------------------------------------------------+ +| Variable | Dependencies | ++--------------------------------------+----------------------------------------------------------------------------------------------------------------------+ +| serviceId | [] | +| sInfo | ['mapServiceInfo', 'sInfo'] | +| serviceIds | ['TUPLE_3', 'eligibleServiceIds', 'eligibleServiceRewards', 'numServices', 'serviceIds', 'serviceNonces', 'success'] | +| idx | ['idx'] | +| ServiceStakingBase.VERSION | [] | +| ServiceStakingBase.maxNumServices | [] | +| ServiceStakingBase.rewardsPerSecond | [] | +| ServiceStakingBase.minStakingDeposit | [] | +| ServiceStakingBase.livenessPeriod | [] | +| ServiceStakingBase.livenessRatio | [] | +| ServiceStakingBase.numAgentInstances | [] | +| ServiceStakingBase.threshold | [] | +| ServiceStakingBase.configHash | [] | +| ServiceStakingBase.serviceRegistry | ['serviceRegistry'] | +| ServiceStakingBase.balance | [] | +| ServiceStakingBase.availableRewards | [] | +| ServiceStakingBase.tsCheckpoint | [] | +| ServiceStakingBase.agentIds | [] | +| ServiceStakingBase.mapServiceInfo | ['mapServiceInfo'] | +| ServiceStakingBase.setServiceIds | ['setServiceIds'] | ++--------------------------------------+----------------------------------------------------------------------------------------------------------------------+ +Function calculateServiceStakingReward(uint256) ++--------------------------------------+--------------------------------------------------------------------------------------------------------------------+ +| Variable | Dependencies | ++--------------------------------------+--------------------------------------------------------------------------------------------------------------------+ +| serviceId | [] | +| reward | ['TUPLE_4', 'eligibleServiceRewards', 'lastAvailableRewards', 'mapServiceInfo', 'reward', 'sInfo', 'totalRewards'] | +| sInfo | ['mapServiceInfo', 'sInfo'] | +| lastAvailableRewards | ['TUPLE_4'] | +| numServices | ['TUPLE_4'] | +| totalRewards | ['TUPLE_4'] | +| eligibleServiceIds | ['TUPLE_4', 'eligibleServiceIds'] | +| eligibleServiceRewards | ['TUPLE_4', 'eligibleServiceRewards'] | +| i | ['i'] | +| ServiceStakingBase.VERSION | [] | +| ServiceStakingBase.maxNumServices | [] | +| ServiceStakingBase.rewardsPerSecond | [] | +| ServiceStakingBase.minStakingDeposit | [] | +| ServiceStakingBase.livenessPeriod | [] | +| ServiceStakingBase.livenessRatio | [] | +| ServiceStakingBase.numAgentInstances | [] | +| ServiceStakingBase.threshold | [] | +| ServiceStakingBase.configHash | [] | +| ServiceStakingBase.serviceRegistry | [] | +| ServiceStakingBase.balance | [] | +| ServiceStakingBase.availableRewards | [] | +| ServiceStakingBase.tsCheckpoint | [] | +| ServiceStakingBase.agentIds | [] | +| ServiceStakingBase.mapServiceInfo | ['mapServiceInfo'] | +| ServiceStakingBase.setServiceIds | [] | ++--------------------------------------+--------------------------------------------------------------------------------------------------------------------+ +Function slitherConstructorConstantVariables() ++--------------------------------------+--------------+ +| Variable | Dependencies | ++--------------------------------------+--------------+ +| ServiceStakingBase.VERSION | [] | +| ServiceStakingBase.maxNumServices | [] | +| ServiceStakingBase.rewardsPerSecond | [] | +| ServiceStakingBase.minStakingDeposit | [] | +| ServiceStakingBase.livenessPeriod | [] | +| ServiceStakingBase.livenessRatio | [] | +| ServiceStakingBase.numAgentInstances | [] | +| ServiceStakingBase.threshold | [] | +| ServiceStakingBase.configHash | [] | +| ServiceStakingBase.serviceRegistry | [] | +| ServiceStakingBase.balance | [] | +| ServiceStakingBase.availableRewards | [] | +| ServiceStakingBase.tsCheckpoint | [] | +| ServiceStakingBase.agentIds | [] | +| ServiceStakingBase.mapServiceInfo | [] | +| ServiceStakingBase.setServiceIds | [] | ++--------------------------------------+--------------+ +INFO:Printers: +Contract IErrorsRegistries ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ ++----------+--------------+ + +Contract ERC721 ++------------------+----------------------------+ +| Variable | Dependencies | ++------------------+----------------------------+ +| name | ['_name'] | +| symbol | ['_symbol'] | +| _ownerOf | ['_ownerOf', 'to'] | +| _balanceOf | ['_balanceOf'] | +| getApproved | ['getApproved', 'spender'] | +| isApprovedForAll | ['isApprovedForAll'] | ++------------------+----------------------------+ + +Function tokenURI(uint256) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| id | [] | +| | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function ownerOf(uint256) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| id | [] | +| owner | ['_ownerOf'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf'] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function balanceOf(address) ++-------------------------+----------------+ +| Variable | Dependencies | ++-------------------------+----------------+ +| owner | [] | +| | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | ['_balanceOf'] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+----------------+ +Function constructor(string,string) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| _name | [] | +| _symbol | [] | +| ERC721.name | ['_name'] | +| ERC721.symbol | ['_symbol'] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function approve(address,uint256) ++-------------------------+----------------------------+ +| Variable | Dependencies | ++-------------------------+----------------------------+ +| spender | [] | +| id | [] | +| owner | ['_ownerOf'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf'] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | ['getApproved', 'spender'] | +| ERC721.isApprovedForAll | ['isApprovedForAll'] | ++-------------------------+----------------------------+ +Function setApprovalForAll(address,bool) ++-------------------------+----------------------+ +| Variable | Dependencies | ++-------------------------+----------------------+ +| operator | [] | +| approved | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | ['isApprovedForAll'] | ++-------------------------+----------------------+ +Function transferFrom(address,address,uint256) ++-------------------------+----------------------+ +| Variable | Dependencies | ++-------------------------+----------------------+ +| from | ['from'] | +| to | ['to'] | +| id | ['id'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf', 'to'] | +| ERC721._balanceOf | ['_balanceOf'] | +| ERC721.getApproved | ['getApproved'] | +| ERC721.isApprovedForAll | ['isApprovedForAll'] | ++-------------------------+----------------------+ +Function safeTransferFrom(address,address,uint256) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| from | [] | +| to | [] | +| id | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function safeTransferFrom(address,address,uint256,bytes) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| from | [] | +| to | [] | +| id | [] | +| data | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function supportsInterface(bytes4) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| interfaceId | [] | +| | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function _mint(address,uint256) ++-------------------------+--------------------+ +| Variable | Dependencies | ++-------------------------+--------------------+ +| to | ['to'] | +| id | ['id'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf', 'to'] | +| ERC721._balanceOf | ['_balanceOf'] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------------+ +Function _burn(uint256) ++-------------------------+-----------------+ +| Variable | Dependencies | ++-------------------------+-----------------+ +| id | [] | +| owner | ['_ownerOf'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf'] | +| ERC721._balanceOf | ['_balanceOf'] | +| ERC721.getApproved | ['getApproved'] | +| ERC721.isApprovedForAll | [] | ++-------------------------+-----------------+ +Function _safeMint(address,uint256) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| to | [] | +| id | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function _safeMint(address,uint256,bytes) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| to | [] | +| id | [] | +| data | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Contract ERC721TokenReceiver ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ ++----------+--------------+ + +Function onERC721Received(address,address,uint256,bytes) ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ +| | [] | ++----------+--------------+ +Contract IMultisig ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ ++----------+--------------+ + +Function nonce() ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ +| | [] | ++----------+--------------+ +Contract IService ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ ++----------+--------------+ + +Function safeTransferFrom(address,address,uint256) ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ +| from | [] | +| to | [] | +| id | [] | ++----------+--------------+ +Function mapServices(uint256) ++----------------------+--------------+ +| Variable | Dependencies | ++----------------------+--------------+ +| serviceId | [] | +| securityDeposit | [] | +| multisig | [] | +| configHash | [] | +| threshold | [] | +| maxNumAgentInstances | [] | +| numAgentInstances | [] | +| state | [] | ++----------------------+--------------+ +Function getUnitIdsOfService(IService.UnitType,uint256) ++------------+--------------+ +| Variable | Dependencies | ++------------+--------------+ +| unitType | [] | +| serviceId | [] | +| numUnitIds | [] | +| unitIds | [] | ++------------+--------------+ +Contract ServiceStakingBase ++-------------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ +| Variable | Dependencies | ++-------------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ +| VERSION | [] | +| maxNumServices | ['_stakingParams', 'maxNumServices'] | +| rewardsPerSecond | ['_stakingParams', 'rewardsPerSecond'] | +| minStakingDeposit | ['_stakingParams', 'minStakingDeposit'] | +| livenessPeriod | ['_stakingParams', 'livenessPeriod'] | +| livenessRatio | ['_stakingParams', 'livenessRatio'] | +| numAgentInstances | ['_stakingParams', 'numAgentInstances'] | +| threshold | ['_stakingParams', 'threshold'] | +| configHash | ['_stakingParams', 'configHash'] | +| serviceRegistry | ['_serviceRegistry', 'serviceRegistry'] | +| balance | [] | +| availableRewards | ['TUPLE_2', 'availableRewards', 'lastAvailableRewards', 'totalRewards'] | +| tsCheckpoint | ['block.timestamp', 'tsCheckpoint'] | +| agentIds | ['_stakingParams', 'agentId', 'agentIds'] | +| mapServiceInfo | ['TUPLE_0', '_serviceRegistry', 'block.timestamp', 'mapServiceInfo', 'msg.sender', 'multisig', 'nonce', 'sInfo', 'serviceId', 'serviceRegistry'] | +| setServiceIds | ['serviceId', 'setServiceIds'] | ++-------------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ + +Function constructor(ServiceStakingBase.StakingParams,address) ++--------------------------------------+-------------------------------------------+ +| Variable | Dependencies | ++--------------------------------------+-------------------------------------------+ +| _stakingParams | ['_stakingParams'] | +| _serviceRegistry | ['_serviceRegistry'] | +| size | ['_stakingParams'] | +| agentId | ['_stakingParams', 'agentId'] | +| i | ['i'] | +| ServiceStakingBase.VERSION | [] | +| ServiceStakingBase.maxNumServices | ['_stakingParams'] | +| ServiceStakingBase.rewardsPerSecond | ['_stakingParams'] | +| ServiceStakingBase.minStakingDeposit | ['_stakingParams'] | +| ServiceStakingBase.livenessPeriod | ['_stakingParams'] | +| ServiceStakingBase.livenessRatio | ['_stakingParams'] | +| ServiceStakingBase.numAgentInstances | ['_stakingParams'] | +| ServiceStakingBase.threshold | ['_stakingParams'] | +| ServiceStakingBase.configHash | ['_stakingParams'] | +| ServiceStakingBase.serviceRegistry | ['_serviceRegistry'] | +| ServiceStakingBase.balance | [] | +| ServiceStakingBase.availableRewards | [] | +| ServiceStakingBase.tsCheckpoint | ['block.timestamp'] | +| ServiceStakingBase.agentIds | ['_stakingParams', 'agentId', 'agentIds'] | +| ServiceStakingBase.mapServiceInfo | [] | +| ServiceStakingBase.setServiceIds | [] | ++--------------------------------------+-------------------------------------------+ +Function _checkTokenStakingDeposit(uint256,uint256) ++--------------------------------------+-----------------------+ +| Variable | Dependencies | ++--------------------------------------+-----------------------+ +| | [] | +| stakingDeposit | ['stakingDeposit'] | +| ServiceStakingBase.VERSION | [] | +| ServiceStakingBase.maxNumServices | [] | +| ServiceStakingBase.rewardsPerSecond | [] | +| ServiceStakingBase.minStakingDeposit | ['minStakingDeposit'] | +| ServiceStakingBase.livenessPeriod | [] | +| ServiceStakingBase.livenessRatio | [] | +| ServiceStakingBase.numAgentInstances | [] | +| ServiceStakingBase.threshold | [] | +| ServiceStakingBase.configHash | [] | +| ServiceStakingBase.serviceRegistry | [] | +| ServiceStakingBase.balance | [] | +| ServiceStakingBase.availableRewards | [] | +| ServiceStakingBase.tsCheckpoint | [] | +| ServiceStakingBase.agentIds | [] | +| ServiceStakingBase.mapServiceInfo | [] | +| ServiceStakingBase.setServiceIds | [] | ++--------------------------------------+-----------------------+ +Function _withdraw(address,uint256) ++--------------------------------------+--------------+ +| Variable | Dependencies | ++--------------------------------------+--------------+ +| to | [] | +| amount | [] | +| ServiceStakingBase.VERSION | [] | +| ServiceStakingBase.maxNumServices | [] | +| ServiceStakingBase.rewardsPerSecond | [] | +| ServiceStakingBase.minStakingDeposit | [] | +| ServiceStakingBase.livenessPeriod | [] | +| ServiceStakingBase.livenessRatio | [] | +| ServiceStakingBase.numAgentInstances | [] | +| ServiceStakingBase.threshold | [] | +| ServiceStakingBase.configHash | [] | +| ServiceStakingBase.serviceRegistry | [] | +| ServiceStakingBase.balance | [] | +| ServiceStakingBase.availableRewards | [] | +| ServiceStakingBase.tsCheckpoint | [] | +| ServiceStakingBase.agentIds | [] | +| ServiceStakingBase.mapServiceInfo | [] | +| ServiceStakingBase.setServiceIds | [] | ++--------------------------------------+--------------+ +Function stake(uint256) ++--------------------------------------+------------------------------------------------------------------------------------------------------------------------------+ +| Variable | Dependencies | ++--------------------------------------+------------------------------------------------------------------------------------------------------------------------------+ +| serviceId | [] | +| numStakingServices | ['serviceId', 'setServiceIds'] | +| stakingDeposit | ['TUPLE_0', 'serviceId', 'serviceRegistry'] | +| multisig | ['TUPLE_0', 'serviceId', 'serviceRegistry'] | +| hash | ['TUPLE_0', 'serviceId', 'serviceRegistry'] | +| agentThreshold | ['TUPLE_0', 'serviceId', 'serviceRegistry'] | +| maxNumInstances | ['TUPLE_0', 'serviceId', 'serviceRegistry'] | +| state | ['TUPLE_0', 'serviceId', 'serviceRegistry'] | +| size | ['agentIds'] | +| numAgents | ['IService', 'TUPLE_1', 'serviceId', 'serviceRegistry'] | +| agents | ['IService', 'TUPLE_1', 'agents', 'serviceId', 'serviceRegistry'] | +| i | ['i'] | +| sInfo | ['TUPLE_0', 'block.timestamp', 'msg.sender', 'multisig', 'nonce', 'sInfo', 'serviceId', 'serviceRegistry'] | +| nonce | ['TUPLE_0', 'multisig', 'serviceId', 'serviceRegistry'] | +| ServiceStakingBase.VERSION | [] | +| ServiceStakingBase.maxNumServices | ['maxNumServices'] | +| ServiceStakingBase.rewardsPerSecond | [] | +| ServiceStakingBase.minStakingDeposit | [] | +| ServiceStakingBase.livenessPeriod | [] | +| ServiceStakingBase.livenessRatio | [] | +| ServiceStakingBase.numAgentInstances | ['numAgentInstances'] | +| ServiceStakingBase.threshold | ['threshold'] | +| ServiceStakingBase.configHash | ['configHash'] | +| ServiceStakingBase.serviceRegistry | ['serviceRegistry'] | +| ServiceStakingBase.balance | [] | +| ServiceStakingBase.availableRewards | ['availableRewards'] | +| ServiceStakingBase.tsCheckpoint | [] | +| ServiceStakingBase.agentIds | ['agentIds'] | +| ServiceStakingBase.mapServiceInfo | ['TUPLE_0', 'block.timestamp', 'mapServiceInfo', 'msg.sender', 'multisig', 'nonce', 'sInfo', 'serviceId', 'serviceRegistry'] | +| ServiceStakingBase.setServiceIds | ['serviceId', 'setServiceIds'] | ++--------------------------------------+------------------------------------------------------------------------------------------------------------------------------+ +Function _calculateStakingRewards() ++--------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| Variable | Dependencies | ++--------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| lastAvailableRewards | ['availableRewards'] | +| numServices | ['numServices'] | +| totalRewards | ['block.timestamp', 'curInfo', 'reward', 'rewardsPerSecond', 'serviceCheckpoint', 'totalRewards', 'ts', 'tsCheckpoint', 'tsCheckpointLast'] | +| eligibleServiceIds | ['eligibleServiceIds', 'serviceIds', 'setServiceIds', 'size'] | +| eligibleServiceRewards | ['block.timestamp', 'curInfo', 'eligibleServiceRewards', 'reward', 'rewardsPerSecond', 'serviceCheckpoint', 'setServiceIds', 'size', 'ts', 'tsCheckpoint', 'tsCheckpointLast'] | +| serviceIds | ['serviceIds', 'setServiceIds', 'size'] | +| serviceNonces | ['curInfo', 'serviceNonces', 'setServiceIds', 'size'] | +| size | ['setServiceIds'] | +| i | ['i'] | +| tsCheckpointLast | ['tsCheckpoint'] | +| i_scope_0 | ['i_scope_0'] | +| curInfo | ['curInfo'] | +| serviceCheckpoint | ['curInfo', 'serviceCheckpoint', 'ts', 'tsCheckpoint', 'tsCheckpointLast'] | +| ts | ['block.timestamp', 'curInfo', 'serviceCheckpoint', 'ts', 'tsCheckpoint', 'tsCheckpointLast'] | +| ratio | ['block.timestamp', 'curInfo', 'ratio', 'serviceCheckpoint', 'serviceNonces', 'setServiceIds', 'size', 'ts', 'tsCheckpoint', 'tsCheckpointLast'] | +| reward | ['block.timestamp', 'curInfo', 'rewardsPerSecond', 'serviceCheckpoint', 'ts', 'tsCheckpoint', 'tsCheckpointLast'] | +| ServiceStakingBase.VERSION | [] | +| ServiceStakingBase.maxNumServices | [] | +| ServiceStakingBase.rewardsPerSecond | ['rewardsPerSecond'] | +| ServiceStakingBase.minStakingDeposit | [] | +| ServiceStakingBase.livenessPeriod | ['livenessPeriod'] | +| ServiceStakingBase.livenessRatio | ['livenessRatio'] | +| ServiceStakingBase.numAgentInstances | [] | +| ServiceStakingBase.threshold | [] | +| ServiceStakingBase.configHash | [] | +| ServiceStakingBase.serviceRegistry | [] | +| ServiceStakingBase.balance | [] | +| ServiceStakingBase.availableRewards | ['availableRewards'] | +| ServiceStakingBase.tsCheckpoint | ['tsCheckpoint'] | +| ServiceStakingBase.agentIds | [] | +| ServiceStakingBase.mapServiceInfo | ['mapServiceInfo'] | +| ServiceStakingBase.setServiceIds | ['setServiceIds'] | ++--------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +Function checkpoint() ++--------------------------------------+-----------------------------------------------------------------------------------------------------------------------+ +| Variable | Dependencies | ++--------------------------------------+-----------------------------------------------------------------------------------------------------------------------+ +| | [] | +| success | ['success'] | +| lastAvailableRewards | ['TUPLE_2', 'lastAvailableRewards', 'totalRewards'] | +| numServices | ['TUPLE_2'] | +| totalRewards | ['TUPLE_2'] | +| eligibleServiceIds | ['TUPLE_2', 'eligibleServiceIds'] | +| eligibleServiceRewards | ['TUPLE_2', 'eligibleServiceRewards'] | +| serviceIds | ['TUPLE_2', 'serviceIds'] | +| serviceNonces | ['TUPLE_2', 'serviceNonces'] | +| updatedReward | ['TUPLE_2', 'eligibleServiceRewards', 'lastAvailableRewards', 'totalRewards', 'updatedReward', 'updatedTotalRewards'] | +| updatedTotalRewards | ['TUPLE_2', 'eligibleServiceRewards', 'lastAvailableRewards', 'totalRewards', 'updatedReward', 'updatedTotalRewards'] | +| curServiceId | ['TUPLE_2', 'eligibleServiceIds'] | +| i | ['i'] | +| i_scope_0 | ['i_scope_0'] | +| curServiceId_scope_1 | ['TUPLE_2', 'eligibleServiceIds'] | +| i_scope_2 | ['i_scope_2'] | +| curServiceId_scope_3 | ['TUPLE_2', 'serviceIds'] | +| ServiceStakingBase.VERSION | [] | +| ServiceStakingBase.maxNumServices | [] | +| ServiceStakingBase.rewardsPerSecond | [] | +| ServiceStakingBase.minStakingDeposit | [] | +| ServiceStakingBase.livenessPeriod | [] | +| ServiceStakingBase.livenessRatio | [] | +| ServiceStakingBase.numAgentInstances | [] | +| ServiceStakingBase.threshold | [] | +| ServiceStakingBase.configHash | [] | +| ServiceStakingBase.serviceRegistry | [] | +| ServiceStakingBase.balance | [] | +| ServiceStakingBase.availableRewards | ['TUPLE_2', 'lastAvailableRewards', 'totalRewards'] | +| ServiceStakingBase.tsCheckpoint | ['block.timestamp'] | +| ServiceStakingBase.agentIds | [] | +| ServiceStakingBase.mapServiceInfo | ['mapServiceInfo'] | +| ServiceStakingBase.setServiceIds | [] | ++--------------------------------------+-----------------------------------------------------------------------------------------------------------------------+ +Function unstake(uint256) ++--------------------------------------+----------------------------------------------------------------------------------------------------------------------+ +| Variable | Dependencies | ++--------------------------------------+----------------------------------------------------------------------------------------------------------------------+ +| serviceId | [] | +| sInfo | ['mapServiceInfo', 'sInfo'] | +| serviceIds | ['TUPLE_3', 'eligibleServiceIds', 'eligibleServiceRewards', 'numServices', 'serviceIds', 'serviceNonces', 'success'] | +| idx | ['idx'] | +| ServiceStakingBase.VERSION | [] | +| ServiceStakingBase.maxNumServices | [] | +| ServiceStakingBase.rewardsPerSecond | [] | +| ServiceStakingBase.minStakingDeposit | [] | +| ServiceStakingBase.livenessPeriod | [] | +| ServiceStakingBase.livenessRatio | [] | +| ServiceStakingBase.numAgentInstances | [] | +| ServiceStakingBase.threshold | [] | +| ServiceStakingBase.configHash | [] | +| ServiceStakingBase.serviceRegistry | ['serviceRegistry'] | +| ServiceStakingBase.balance | [] | +| ServiceStakingBase.availableRewards | [] | +| ServiceStakingBase.tsCheckpoint | [] | +| ServiceStakingBase.agentIds | [] | +| ServiceStakingBase.mapServiceInfo | ['mapServiceInfo'] | +| ServiceStakingBase.setServiceIds | ['setServiceIds'] | ++--------------------------------------+----------------------------------------------------------------------------------------------------------------------+ +Function calculateServiceStakingReward(uint256) ++--------------------------------------+--------------------------------------------------------------------------------------------------------------------+ +| Variable | Dependencies | ++--------------------------------------+--------------------------------------------------------------------------------------------------------------------+ +| serviceId | [] | +| reward | ['TUPLE_4', 'eligibleServiceRewards', 'lastAvailableRewards', 'mapServiceInfo', 'reward', 'sInfo', 'totalRewards'] | +| sInfo | ['mapServiceInfo', 'sInfo'] | +| lastAvailableRewards | ['TUPLE_4'] | +| numServices | ['TUPLE_4'] | +| totalRewards | ['TUPLE_4'] | +| eligibleServiceIds | ['TUPLE_4', 'eligibleServiceIds'] | +| eligibleServiceRewards | ['TUPLE_4', 'eligibleServiceRewards'] | +| i | ['i'] | +| ServiceStakingBase.VERSION | [] | +| ServiceStakingBase.maxNumServices | [] | +| ServiceStakingBase.rewardsPerSecond | [] | +| ServiceStakingBase.minStakingDeposit | [] | +| ServiceStakingBase.livenessPeriod | [] | +| ServiceStakingBase.livenessRatio | [] | +| ServiceStakingBase.numAgentInstances | [] | +| ServiceStakingBase.threshold | [] | +| ServiceStakingBase.configHash | [] | +| ServiceStakingBase.serviceRegistry | [] | +| ServiceStakingBase.balance | [] | +| ServiceStakingBase.availableRewards | [] | +| ServiceStakingBase.tsCheckpoint | [] | +| ServiceStakingBase.agentIds | [] | +| ServiceStakingBase.mapServiceInfo | ['mapServiceInfo'] | +| ServiceStakingBase.setServiceIds | [] | ++--------------------------------------+--------------------------------------------------------------------------------------------------------------------+ +Function slitherConstructorConstantVariables() ++--------------------------------------+--------------+ +| Variable | Dependencies | ++--------------------------------------+--------------+ +| ServiceStakingBase.VERSION | [] | +| ServiceStakingBase.maxNumServices | [] | +| ServiceStakingBase.rewardsPerSecond | [] | +| ServiceStakingBase.minStakingDeposit | [] | +| ServiceStakingBase.livenessPeriod | [] | +| ServiceStakingBase.livenessRatio | [] | +| ServiceStakingBase.numAgentInstances | [] | +| ServiceStakingBase.threshold | [] | +| ServiceStakingBase.configHash | [] | +| ServiceStakingBase.serviceRegistry | [] | +| ServiceStakingBase.balance | [] | +| ServiceStakingBase.availableRewards | [] | +| ServiceStakingBase.tsCheckpoint | [] | +| ServiceStakingBase.agentIds | [] | +| ServiceStakingBase.mapServiceInfo | [] | +| ServiceStakingBase.setServiceIds | [] | ++--------------------------------------+--------------+ +Contract ServiceStakingNativeToken ++-------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| Variable | Dependencies | ++-------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| VERSION | [] | +| maxNumServices | ['_stakingParams', 'maxNumServices'] | +| rewardsPerSecond | ['_stakingParams', 'rewardsPerSecond'] | +| minStakingDeposit | ['_stakingParams', 'minStakingDeposit'] | +| livenessPeriod | ['_stakingParams', 'livenessPeriod'] | +| livenessRatio | ['_stakingParams', 'livenessRatio'] | +| numAgentInstances | ['_stakingParams', 'numAgentInstances'] | +| threshold | ['_stakingParams', 'threshold'] | +| configHash | ['_stakingParams', 'configHash'] | +| serviceRegistry | ['_serviceRegistry', 'serviceRegistry'] | +| balance | ['TUPLE_5', '_serviceRegistry', 'amount', 'balance', 'block.timestamp', 'mapServiceInfo', 'msg.sender', 'msg.value', 'multisig', 'newBalance', 'nonce', 'sInfo', 'serviceId', 'serviceRegistry'] | +| availableRewards | ['TUPLE_7', 'availableRewards', 'lastAvailableRewards', 'msg.value', 'newAvailableRewards', 'totalRewards'] | +| tsCheckpoint | ['block.timestamp', 'tsCheckpoint'] | +| agentIds | ['_stakingParams', 'agentId', 'agentIds'] | +| mapServiceInfo | ['TUPLE_5', '_serviceRegistry', 'block.timestamp', 'mapServiceInfo', 'msg.sender', 'multisig', 'nonce', 'sInfo', 'serviceId', 'serviceRegistry'] | +| setServiceIds | ['serviceId', 'setServiceIds'] | ++-------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ + +Function constructor(ServiceStakingBase.StakingParams,address) ++--------------------------------------+--------------+ +| Variable | Dependencies | ++--------------------------------------+--------------+ +| _stakingParams | [] | +| _serviceRegistry | [] | +| ServiceStakingBase.VERSION | [] | +| ServiceStakingBase.maxNumServices | [] | +| ServiceStakingBase.rewardsPerSecond | [] | +| ServiceStakingBase.minStakingDeposit | [] | +| ServiceStakingBase.livenessPeriod | [] | +| ServiceStakingBase.livenessRatio | [] | +| ServiceStakingBase.numAgentInstances | [] | +| ServiceStakingBase.threshold | [] | +| ServiceStakingBase.configHash | [] | +| ServiceStakingBase.serviceRegistry | [] | +| ServiceStakingBase.balance | [] | +| ServiceStakingBase.availableRewards | [] | +| ServiceStakingBase.tsCheckpoint | [] | +| ServiceStakingBase.agentIds | [] | +| ServiceStakingBase.mapServiceInfo | [] | +| ServiceStakingBase.setServiceIds | [] | ++--------------------------------------+--------------+ +Function _withdraw(address,uint256) ++--------------------------------------+------------------------------+ +| Variable | Dependencies | ++--------------------------------------+------------------------------+ +| to | [] | +| amount | [] | +| result | ['TUPLE_10', 'amount', 'to'] | +| ServiceStakingBase.VERSION | [] | +| ServiceStakingBase.maxNumServices | [] | +| ServiceStakingBase.rewardsPerSecond | [] | +| ServiceStakingBase.minStakingDeposit | [] | +| ServiceStakingBase.livenessPeriod | [] | +| ServiceStakingBase.livenessRatio | [] | +| ServiceStakingBase.numAgentInstances | [] | +| ServiceStakingBase.threshold | [] | +| ServiceStakingBase.configHash | [] | +| ServiceStakingBase.serviceRegistry | [] | +| ServiceStakingBase.balance | ['amount', 'balance'] | +| ServiceStakingBase.availableRewards | [] | +| ServiceStakingBase.tsCheckpoint | [] | +| ServiceStakingBase.agentIds | [] | +| ServiceStakingBase.mapServiceInfo | [] | +| ServiceStakingBase.setServiceIds | [] | ++--------------------------------------+------------------------------+ +Function receive() ++--------------------------------------+----------------------------------------------------------+ +| Variable | Dependencies | ++--------------------------------------+----------------------------------------------------------+ +| newBalance | ['balance', 'msg.value'] | +| newAvailableRewards | ['availableRewards', 'msg.value'] | +| ServiceStakingBase.VERSION | [] | +| ServiceStakingBase.maxNumServices | [] | +| ServiceStakingBase.rewardsPerSecond | [] | +| ServiceStakingBase.minStakingDeposit | [] | +| ServiceStakingBase.livenessPeriod | [] | +| ServiceStakingBase.livenessRatio | [] | +| ServiceStakingBase.numAgentInstances | [] | +| ServiceStakingBase.threshold | [] | +| ServiceStakingBase.configHash | [] | +| ServiceStakingBase.serviceRegistry | [] | +| ServiceStakingBase.balance | ['balance', 'msg.value', 'newBalance'] | +| ServiceStakingBase.availableRewards | ['availableRewards', 'msg.value', 'newAvailableRewards'] | +| ServiceStakingBase.tsCheckpoint | [] | +| ServiceStakingBase.agentIds | [] | +| ServiceStakingBase.mapServiceInfo | [] | +| ServiceStakingBase.setServiceIds | [] | ++--------------------------------------+----------------------------------------------------------+ +Function slitherConstructorConstantVariables() ++--------------------------------------+--------------+ +| Variable | Dependencies | ++--------------------------------------+--------------+ +| ServiceStakingBase.VERSION | [] | +| ServiceStakingBase.maxNumServices | [] | +| ServiceStakingBase.rewardsPerSecond | [] | +| ServiceStakingBase.minStakingDeposit | [] | +| ServiceStakingBase.livenessPeriod | [] | +| ServiceStakingBase.livenessRatio | [] | +| ServiceStakingBase.numAgentInstances | [] | +| ServiceStakingBase.threshold | [] | +| ServiceStakingBase.configHash | [] | +| ServiceStakingBase.serviceRegistry | [] | +| ServiceStakingBase.balance | [] | +| ServiceStakingBase.availableRewards | [] | +| ServiceStakingBase.tsCheckpoint | [] | +| ServiceStakingBase.agentIds | [] | +| ServiceStakingBase.mapServiceInfo | [] | +| ServiceStakingBase.setServiceIds | [] | ++--------------------------------------+--------------+ +INFO:Printers: +Contract IErrorsRegistries ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ ++----------+--------------+ + +INFO:Printers: +Contract IErrorsRegistries ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ ++----------+--------------+ + +Contract ERC721 ++------------------+----------------------------+ +| Variable | Dependencies | ++------------------+----------------------------+ +| name | ['_name'] | +| symbol | ['_symbol'] | +| _ownerOf | ['_ownerOf', 'to'] | +| _balanceOf | ['_balanceOf'] | +| getApproved | ['getApproved', 'spender'] | +| isApprovedForAll | ['isApprovedForAll'] | ++------------------+----------------------------+ + +Function tokenURI(uint256) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| id | [] | +| | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function ownerOf(uint256) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| id | [] | +| owner | ['_ownerOf'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf'] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function balanceOf(address) ++-------------------------+----------------+ +| Variable | Dependencies | ++-------------------------+----------------+ +| owner | [] | +| | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | ['_balanceOf'] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+----------------+ +Function constructor(string,string) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| _name | [] | +| _symbol | [] | +| ERC721.name | ['_name'] | +| ERC721.symbol | ['_symbol'] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function approve(address,uint256) ++-------------------------+----------------------------+ +| Variable | Dependencies | ++-------------------------+----------------------------+ +| spender | [] | +| id | [] | +| owner | ['_ownerOf'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf'] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | ['getApproved', 'spender'] | +| ERC721.isApprovedForAll | ['isApprovedForAll'] | ++-------------------------+----------------------------+ +Function setApprovalForAll(address,bool) ++-------------------------+----------------------+ +| Variable | Dependencies | ++-------------------------+----------------------+ +| operator | [] | +| approved | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | ['isApprovedForAll'] | ++-------------------------+----------------------+ +Function transferFrom(address,address,uint256) ++-------------------------+----------------------+ +| Variable | Dependencies | ++-------------------------+----------------------+ +| from | ['from'] | +| to | ['to'] | +| id | ['id'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf', 'to'] | +| ERC721._balanceOf | ['_balanceOf'] | +| ERC721.getApproved | ['getApproved'] | +| ERC721.isApprovedForAll | ['isApprovedForAll'] | ++-------------------------+----------------------+ +Function safeTransferFrom(address,address,uint256) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| from | [] | +| to | [] | +| id | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function safeTransferFrom(address,address,uint256,bytes) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| from | [] | +| to | [] | +| id | [] | +| data | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function supportsInterface(bytes4) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| interfaceId | [] | +| | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function _mint(address,uint256) ++-------------------------+--------------------+ +| Variable | Dependencies | ++-------------------------+--------------------+ +| to | ['to'] | +| id | ['id'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf', 'to'] | +| ERC721._balanceOf | ['_balanceOf'] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------------+ +Function _burn(uint256) ++-------------------------+-----------------+ +| Variable | Dependencies | ++-------------------------+-----------------+ +| id | [] | +| owner | ['_ownerOf'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf'] | +| ERC721._balanceOf | ['_balanceOf'] | +| ERC721.getApproved | ['getApproved'] | +| ERC721.isApprovedForAll | [] | ++-------------------------+-----------------+ +Function _safeMint(address,uint256) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| to | [] | +| id | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function _safeMint(address,uint256,bytes) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| to | [] | +| id | [] | +| data | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +INFO:Printers: +Contract IErrorsRegistries ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ ++----------+--------------+ + +Contract ERC721 ++------------------+----------------------------+ +| Variable | Dependencies | ++------------------+----------------------------+ +| name | ['_name'] | +| symbol | ['_symbol'] | +| _ownerOf | ['_ownerOf', 'to'] | +| _balanceOf | ['_balanceOf'] | +| getApproved | ['getApproved', 'spender'] | +| isApprovedForAll | ['isApprovedForAll'] | ++------------------+----------------------------+ + +Function tokenURI(uint256) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| id | [] | +| | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function ownerOf(uint256) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| id | [] | +| owner | ['_ownerOf'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf'] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function balanceOf(address) ++-------------------------+----------------+ +| Variable | Dependencies | ++-------------------------+----------------+ +| owner | [] | +| | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | ['_balanceOf'] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+----------------+ +Function constructor(string,string) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| _name | [] | +| _symbol | [] | +| ERC721.name | ['_name'] | +| ERC721.symbol | ['_symbol'] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function approve(address,uint256) ++-------------------------+----------------------------+ +| Variable | Dependencies | ++-------------------------+----------------------------+ +| spender | [] | +| id | [] | +| owner | ['_ownerOf'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf'] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | ['getApproved', 'spender'] | +| ERC721.isApprovedForAll | ['isApprovedForAll'] | ++-------------------------+----------------------------+ +Function setApprovalForAll(address,bool) ++-------------------------+----------------------+ +| Variable | Dependencies | ++-------------------------+----------------------+ +| operator | [] | +| approved | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | ['isApprovedForAll'] | ++-------------------------+----------------------+ +Function transferFrom(address,address,uint256) ++-------------------------+----------------------+ +| Variable | Dependencies | ++-------------------------+----------------------+ +| from | ['from'] | +| to | ['to'] | +| id | ['id'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf', 'to'] | +| ERC721._balanceOf | ['_balanceOf'] | +| ERC721.getApproved | ['getApproved'] | +| ERC721.isApprovedForAll | ['isApprovedForAll'] | ++-------------------------+----------------------+ +Function safeTransferFrom(address,address,uint256) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| from | [] | +| to | [] | +| id | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function safeTransferFrom(address,address,uint256,bytes) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| from | [] | +| to | [] | +| id | [] | +| data | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function supportsInterface(bytes4) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| interfaceId | [] | +| | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function _mint(address,uint256) ++-------------------------+--------------------+ +| Variable | Dependencies | ++-------------------------+--------------------+ +| to | ['to'] | +| id | ['id'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf', 'to'] | +| ERC721._balanceOf | ['_balanceOf'] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------------+ +Function _burn(uint256) ++-------------------------+-----------------+ +| Variable | Dependencies | ++-------------------------+-----------------+ +| id | [] | +| owner | ['_ownerOf'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf'] | +| ERC721._balanceOf | ['_balanceOf'] | +| ERC721.getApproved | ['getApproved'] | +| ERC721.isApprovedForAll | [] | ++-------------------------+-----------------+ +Function _safeMint(address,uint256) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| to | [] | +| id | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function _safeMint(address,uint256,bytes) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| to | [] | +| id | [] | +| data | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Contract ERC721TokenReceiver ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ ++----------+--------------+ + +Function onERC721Received(address,address,uint256,bytes) ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ +| | [] | ++----------+--------------+ +INFO:Printers: +Contract IErrorsRegistries ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ ++----------+--------------+ + +Contract ERC721 ++------------------+----------------------------+ +| Variable | Dependencies | ++------------------+----------------------------+ +| name | ['_name'] | +| symbol | ['_symbol'] | +| _ownerOf | ['_ownerOf', 'to'] | +| _balanceOf | ['_balanceOf'] | +| getApproved | ['getApproved', 'spender'] | +| isApprovedForAll | ['isApprovedForAll'] | ++------------------+----------------------------+ + +Function tokenURI(uint256) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| id | [] | +| | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function ownerOf(uint256) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| id | [] | +| owner | ['_ownerOf'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf'] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function balanceOf(address) ++-------------------------+----------------+ +| Variable | Dependencies | ++-------------------------+----------------+ +| owner | [] | +| | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | ['_balanceOf'] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+----------------+ +Function constructor(string,string) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| _name | [] | +| _symbol | [] | +| ERC721.name | ['_name'] | +| ERC721.symbol | ['_symbol'] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function approve(address,uint256) ++-------------------------+----------------------------+ +| Variable | Dependencies | ++-------------------------+----------------------------+ +| spender | [] | +| id | [] | +| owner | ['_ownerOf'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf'] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | ['getApproved', 'spender'] | +| ERC721.isApprovedForAll | ['isApprovedForAll'] | ++-------------------------+----------------------------+ +Function setApprovalForAll(address,bool) ++-------------------------+----------------------+ +| Variable | Dependencies | ++-------------------------+----------------------+ +| operator | [] | +| approved | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | ['isApprovedForAll'] | ++-------------------------+----------------------+ +Function transferFrom(address,address,uint256) ++-------------------------+----------------------+ +| Variable | Dependencies | ++-------------------------+----------------------+ +| from | ['from'] | +| to | ['to'] | +| id | ['id'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf', 'to'] | +| ERC721._balanceOf | ['_balanceOf'] | +| ERC721.getApproved | ['getApproved'] | +| ERC721.isApprovedForAll | ['isApprovedForAll'] | ++-------------------------+----------------------+ +Function safeTransferFrom(address,address,uint256) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| from | [] | +| to | [] | +| id | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function safeTransferFrom(address,address,uint256,bytes) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| from | [] | +| to | [] | +| id | [] | +| data | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function supportsInterface(bytes4) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| interfaceId | [] | +| | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function _mint(address,uint256) ++-------------------------+--------------------+ +| Variable | Dependencies | ++-------------------------+--------------------+ +| to | ['to'] | +| id | ['id'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf', 'to'] | +| ERC721._balanceOf | ['_balanceOf'] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------------+ +Function _burn(uint256) ++-------------------------+-----------------+ +| Variable | Dependencies | ++-------------------------+-----------------+ +| id | [] | +| owner | ['_ownerOf'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf'] | +| ERC721._balanceOf | ['_balanceOf'] | +| ERC721.getApproved | ['getApproved'] | +| ERC721.isApprovedForAll | [] | ++-------------------------+-----------------+ +Function _safeMint(address,uint256) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| to | [] | +| id | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function _safeMint(address,uint256,bytes) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| to | [] | +| id | [] | +| data | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Contract ERC721TokenReceiver ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ ++----------+--------------+ + +Function onERC721Received(address,address,uint256,bytes) ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ +| | [] | ++----------+--------------+ +Contract IMultisig ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ ++----------+--------------+ + +Function nonce() ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ +| | [] | ++----------+--------------+ +INFO:Printers: +Contract IErrorsRegistries ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ ++----------+--------------+ + +Contract ERC721 ++------------------+----------------------------+ +| Variable | Dependencies | ++------------------+----------------------------+ +| name | ['_name'] | +| symbol | ['_symbol'] | +| _ownerOf | ['_ownerOf', 'to'] | +| _balanceOf | ['_balanceOf'] | +| getApproved | ['getApproved', 'spender'] | +| isApprovedForAll | ['isApprovedForAll'] | ++------------------+----------------------------+ + +Function tokenURI(uint256) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| id | [] | +| | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function ownerOf(uint256) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| id | [] | +| owner | ['_ownerOf'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf'] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function balanceOf(address) ++-------------------------+----------------+ +| Variable | Dependencies | ++-------------------------+----------------+ +| owner | [] | +| | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | ['_balanceOf'] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+----------------+ +Function constructor(string,string) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| _name | [] | +| _symbol | [] | +| ERC721.name | ['_name'] | +| ERC721.symbol | ['_symbol'] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function approve(address,uint256) ++-------------------------+----------------------------+ +| Variable | Dependencies | ++-------------------------+----------------------------+ +| spender | [] | +| id | [] | +| owner | ['_ownerOf'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf'] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | ['getApproved', 'spender'] | +| ERC721.isApprovedForAll | ['isApprovedForAll'] | ++-------------------------+----------------------------+ +Function setApprovalForAll(address,bool) ++-------------------------+----------------------+ +| Variable | Dependencies | ++-------------------------+----------------------+ +| operator | [] | +| approved | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | ['isApprovedForAll'] | ++-------------------------+----------------------+ +Function transferFrom(address,address,uint256) ++-------------------------+----------------------+ +| Variable | Dependencies | ++-------------------------+----------------------+ +| from | ['from'] | +| to | ['to'] | +| id | ['id'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf', 'to'] | +| ERC721._balanceOf | ['_balanceOf'] | +| ERC721.getApproved | ['getApproved'] | +| ERC721.isApprovedForAll | ['isApprovedForAll'] | ++-------------------------+----------------------+ +Function safeTransferFrom(address,address,uint256) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| from | [] | +| to | [] | +| id | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function safeTransferFrom(address,address,uint256,bytes) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| from | [] | +| to | [] | +| id | [] | +| data | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function supportsInterface(bytes4) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| interfaceId | [] | +| | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function _mint(address,uint256) ++-------------------------+--------------------+ +| Variable | Dependencies | ++-------------------------+--------------------+ +| to | ['to'] | +| id | ['id'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf', 'to'] | +| ERC721._balanceOf | ['_balanceOf'] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------------+ +Function _burn(uint256) ++-------------------------+-----------------+ +| Variable | Dependencies | ++-------------------------+-----------------+ +| id | [] | +| owner | ['_ownerOf'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf'] | +| ERC721._balanceOf | ['_balanceOf'] | +| ERC721.getApproved | ['getApproved'] | +| ERC721.isApprovedForAll | [] | ++-------------------------+-----------------+ +Function _safeMint(address,uint256) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| to | [] | +| id | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function _safeMint(address,uint256,bytes) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| to | [] | +| id | [] | +| data | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Contract ERC721TokenReceiver ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ ++----------+--------------+ + +Function onERC721Received(address,address,uint256,bytes) ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ +| | [] | ++----------+--------------+ +Contract IMultisig ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ ++----------+--------------+ + +Function nonce() ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ +| | [] | ++----------+--------------+ +Contract IService ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ ++----------+--------------+ + +Function safeTransferFrom(address,address,uint256) ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ +| from | [] | +| to | [] | +| id | [] | ++----------+--------------+ +Function mapServices(uint256) ++----------------------+--------------+ +| Variable | Dependencies | ++----------------------+--------------+ +| serviceId | [] | +| securityDeposit | [] | +| multisig | [] | +| configHash | [] | +| threshold | [] | +| maxNumAgentInstances | [] | +| numAgentInstances | [] | +| state | [] | ++----------------------+--------------+ +Function getUnitIdsOfService(IService.UnitType,uint256) ++------------+--------------+ +| Variable | Dependencies | ++------------+--------------+ +| unitType | [] | +| serviceId | [] | +| numUnitIds | [] | +| unitIds | [] | ++------------+--------------+ +INFO:Printers: +Contract IErrorsRegistries ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ ++----------+--------------+ + +Contract ERC721 ++------------------+----------------------------+ +| Variable | Dependencies | ++------------------+----------------------------+ +| name | ['_name'] | +| symbol | ['_symbol'] | +| _ownerOf | ['_ownerOf', 'to'] | +| _balanceOf | ['_balanceOf'] | +| getApproved | ['getApproved', 'spender'] | +| isApprovedForAll | ['isApprovedForAll'] | ++------------------+----------------------------+ + +Function tokenURI(uint256) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| id | [] | +| | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function ownerOf(uint256) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| id | [] | +| owner | ['_ownerOf'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf'] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function balanceOf(address) ++-------------------------+----------------+ +| Variable | Dependencies | ++-------------------------+----------------+ +| owner | [] | +| | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | ['_balanceOf'] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+----------------+ +Function constructor(string,string) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| _name | [] | +| _symbol | [] | +| ERC721.name | ['_name'] | +| ERC721.symbol | ['_symbol'] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function approve(address,uint256) ++-------------------------+----------------------------+ +| Variable | Dependencies | ++-------------------------+----------------------------+ +| spender | [] | +| id | [] | +| owner | ['_ownerOf'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf'] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | ['getApproved', 'spender'] | +| ERC721.isApprovedForAll | ['isApprovedForAll'] | ++-------------------------+----------------------------+ +Function setApprovalForAll(address,bool) ++-------------------------+----------------------+ +| Variable | Dependencies | ++-------------------------+----------------------+ +| operator | [] | +| approved | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | ['isApprovedForAll'] | ++-------------------------+----------------------+ +Function transferFrom(address,address,uint256) ++-------------------------+----------------------+ +| Variable | Dependencies | ++-------------------------+----------------------+ +| from | ['from'] | +| to | ['to'] | +| id | ['id'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf', 'to'] | +| ERC721._balanceOf | ['_balanceOf'] | +| ERC721.getApproved | ['getApproved'] | +| ERC721.isApprovedForAll | ['isApprovedForAll'] | ++-------------------------+----------------------+ +Function safeTransferFrom(address,address,uint256) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| from | [] | +| to | [] | +| id | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function safeTransferFrom(address,address,uint256,bytes) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| from | [] | +| to | [] | +| id | [] | +| data | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function supportsInterface(bytes4) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| interfaceId | [] | +| | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function _mint(address,uint256) ++-------------------------+--------------------+ +| Variable | Dependencies | ++-------------------------+--------------------+ +| to | ['to'] | +| id | ['id'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf', 'to'] | +| ERC721._balanceOf | ['_balanceOf'] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------------+ +Function _burn(uint256) ++-------------------------+-----------------+ +| Variable | Dependencies | ++-------------------------+-----------------+ +| id | [] | +| owner | ['_ownerOf'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf'] | +| ERC721._balanceOf | ['_balanceOf'] | +| ERC721.getApproved | ['getApproved'] | +| ERC721.isApprovedForAll | [] | ++-------------------------+-----------------+ +Function _safeMint(address,uint256) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| to | [] | +| id | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function _safeMint(address,uint256,bytes) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| to | [] | +| id | [] | +| data | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Contract ERC721TokenReceiver ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ ++----------+--------------+ + +Function onERC721Received(address,address,uint256,bytes) ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ +| | [] | ++----------+--------------+ +Contract IMultisig ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ ++----------+--------------+ + +Function nonce() ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ +| | [] | ++----------+--------------+ +Contract IService ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ ++----------+--------------+ + +Function safeTransferFrom(address,address,uint256) ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ +| from | [] | +| to | [] | +| id | [] | ++----------+--------------+ +Function mapServices(uint256) ++----------------------+--------------+ +| Variable | Dependencies | ++----------------------+--------------+ +| serviceId | [] | +| securityDeposit | [] | +| multisig | [] | +| configHash | [] | +| threshold | [] | +| maxNumAgentInstances | [] | +| numAgentInstances | [] | +| state | [] | ++----------------------+--------------+ +Function getUnitIdsOfService(IService.UnitType,uint256) ++------------+--------------+ +| Variable | Dependencies | ++------------+--------------+ +| unitType | [] | +| serviceId | [] | +| numUnitIds | [] | +| unitIds | [] | ++------------+--------------+ +Contract ServiceStakingBase ++-------------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ +| Variable | Dependencies | ++-------------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ +| VERSION | [] | +| maxNumServices | ['_stakingParams', 'maxNumServices'] | +| rewardsPerSecond | ['_stakingParams', 'rewardsPerSecond'] | +| minStakingDeposit | ['_stakingParams', 'minStakingDeposit'] | +| livenessPeriod | ['_stakingParams', 'livenessPeriod'] | +| livenessRatio | ['_stakingParams', 'livenessRatio'] | +| numAgentInstances | ['_stakingParams', 'numAgentInstances'] | +| threshold | ['_stakingParams', 'threshold'] | +| configHash | ['_stakingParams', 'configHash'] | +| serviceRegistry | ['_serviceRegistry', 'serviceRegistry'] | +| balance | [] | +| availableRewards | ['TUPLE_2', 'availableRewards', 'lastAvailableRewards', 'totalRewards'] | +| tsCheckpoint | ['block.timestamp', 'tsCheckpoint'] | +| agentIds | ['_stakingParams', 'agentId', 'agentIds'] | +| mapServiceInfo | ['TUPLE_0', '_serviceRegistry', 'block.timestamp', 'mapServiceInfo', 'msg.sender', 'multisig', 'nonce', 'sInfo', 'serviceId', 'serviceRegistry'] | +| setServiceIds | ['serviceId', 'setServiceIds'] | ++-------------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ + +Function constructor(ServiceStakingBase.StakingParams,address) ++--------------------------------------+-------------------------------------------+ +| Variable | Dependencies | ++--------------------------------------+-------------------------------------------+ +| _stakingParams | ['_stakingParams'] | +| _serviceRegistry | ['_serviceRegistry'] | +| size | ['_stakingParams'] | +| agentId | ['_stakingParams', 'agentId'] | +| i | ['i'] | +| ServiceStakingBase.VERSION | [] | +| ServiceStakingBase.maxNumServices | ['_stakingParams'] | +| ServiceStakingBase.rewardsPerSecond | ['_stakingParams'] | +| ServiceStakingBase.minStakingDeposit | ['_stakingParams'] | +| ServiceStakingBase.livenessPeriod | ['_stakingParams'] | +| ServiceStakingBase.livenessRatio | ['_stakingParams'] | +| ServiceStakingBase.numAgentInstances | ['_stakingParams'] | +| ServiceStakingBase.threshold | ['_stakingParams'] | +| ServiceStakingBase.configHash | ['_stakingParams'] | +| ServiceStakingBase.serviceRegistry | ['_serviceRegistry'] | +| ServiceStakingBase.balance | [] | +| ServiceStakingBase.availableRewards | [] | +| ServiceStakingBase.tsCheckpoint | ['block.timestamp'] | +| ServiceStakingBase.agentIds | ['_stakingParams', 'agentId', 'agentIds'] | +| ServiceStakingBase.mapServiceInfo | [] | +| ServiceStakingBase.setServiceIds | [] | ++--------------------------------------+-------------------------------------------+ +Function _checkTokenStakingDeposit(uint256,uint256) ++--------------------------------------+-----------------------+ +| Variable | Dependencies | ++--------------------------------------+-----------------------+ +| | [] | +| stakingDeposit | ['stakingDeposit'] | +| ServiceStakingBase.VERSION | [] | +| ServiceStakingBase.maxNumServices | [] | +| ServiceStakingBase.rewardsPerSecond | [] | +| ServiceStakingBase.minStakingDeposit | ['minStakingDeposit'] | +| ServiceStakingBase.livenessPeriod | [] | +| ServiceStakingBase.livenessRatio | [] | +| ServiceStakingBase.numAgentInstances | [] | +| ServiceStakingBase.threshold | [] | +| ServiceStakingBase.configHash | [] | +| ServiceStakingBase.serviceRegistry | [] | +| ServiceStakingBase.balance | [] | +| ServiceStakingBase.availableRewards | [] | +| ServiceStakingBase.tsCheckpoint | [] | +| ServiceStakingBase.agentIds | [] | +| ServiceStakingBase.mapServiceInfo | [] | +| ServiceStakingBase.setServiceIds | [] | ++--------------------------------------+-----------------------+ +Function _withdraw(address,uint256) ++--------------------------------------+--------------+ +| Variable | Dependencies | ++--------------------------------------+--------------+ +| to | [] | +| amount | [] | +| ServiceStakingBase.VERSION | [] | +| ServiceStakingBase.maxNumServices | [] | +| ServiceStakingBase.rewardsPerSecond | [] | +| ServiceStakingBase.minStakingDeposit | [] | +| ServiceStakingBase.livenessPeriod | [] | +| ServiceStakingBase.livenessRatio | [] | +| ServiceStakingBase.numAgentInstances | [] | +| ServiceStakingBase.threshold | [] | +| ServiceStakingBase.configHash | [] | +| ServiceStakingBase.serviceRegistry | [] | +| ServiceStakingBase.balance | [] | +| ServiceStakingBase.availableRewards | [] | +| ServiceStakingBase.tsCheckpoint | [] | +| ServiceStakingBase.agentIds | [] | +| ServiceStakingBase.mapServiceInfo | [] | +| ServiceStakingBase.setServiceIds | [] | ++--------------------------------------+--------------+ +Function stake(uint256) ++--------------------------------------+------------------------------------------------------------------------------------------------------------------------------+ +| Variable | Dependencies | ++--------------------------------------+------------------------------------------------------------------------------------------------------------------------------+ +| serviceId | [] | +| numStakingServices | ['serviceId', 'setServiceIds'] | +| stakingDeposit | ['TUPLE_0', 'serviceId', 'serviceRegistry'] | +| multisig | ['TUPLE_0', 'serviceId', 'serviceRegistry'] | +| hash | ['TUPLE_0', 'serviceId', 'serviceRegistry'] | +| agentThreshold | ['TUPLE_0', 'serviceId', 'serviceRegistry'] | +| maxNumInstances | ['TUPLE_0', 'serviceId', 'serviceRegistry'] | +| state | ['TUPLE_0', 'serviceId', 'serviceRegistry'] | +| size | ['agentIds'] | +| numAgents | ['IService', 'TUPLE_1', 'serviceId', 'serviceRegistry'] | +| agents | ['IService', 'TUPLE_1', 'agents', 'serviceId', 'serviceRegistry'] | +| i | ['i'] | +| sInfo | ['TUPLE_0', 'block.timestamp', 'msg.sender', 'multisig', 'nonce', 'sInfo', 'serviceId', 'serviceRegistry'] | +| nonce | ['TUPLE_0', 'multisig', 'serviceId', 'serviceRegistry'] | +| ServiceStakingBase.VERSION | [] | +| ServiceStakingBase.maxNumServices | ['maxNumServices'] | +| ServiceStakingBase.rewardsPerSecond | [] | +| ServiceStakingBase.minStakingDeposit | [] | +| ServiceStakingBase.livenessPeriod | [] | +| ServiceStakingBase.livenessRatio | [] | +| ServiceStakingBase.numAgentInstances | ['numAgentInstances'] | +| ServiceStakingBase.threshold | ['threshold'] | +| ServiceStakingBase.configHash | ['configHash'] | +| ServiceStakingBase.serviceRegistry | ['serviceRegistry'] | +| ServiceStakingBase.balance | [] | +| ServiceStakingBase.availableRewards | ['availableRewards'] | +| ServiceStakingBase.tsCheckpoint | [] | +| ServiceStakingBase.agentIds | ['agentIds'] | +| ServiceStakingBase.mapServiceInfo | ['TUPLE_0', 'block.timestamp', 'mapServiceInfo', 'msg.sender', 'multisig', 'nonce', 'sInfo', 'serviceId', 'serviceRegistry'] | +| ServiceStakingBase.setServiceIds | ['serviceId', 'setServiceIds'] | ++--------------------------------------+------------------------------------------------------------------------------------------------------------------------------+ +Function _calculateStakingRewards() ++--------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| Variable | Dependencies | ++--------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| lastAvailableRewards | ['availableRewards'] | +| numServices | ['numServices'] | +| totalRewards | ['block.timestamp', 'curInfo', 'reward', 'rewardsPerSecond', 'serviceCheckpoint', 'totalRewards', 'ts', 'tsCheckpoint', 'tsCheckpointLast'] | +| eligibleServiceIds | ['eligibleServiceIds', 'serviceIds', 'setServiceIds', 'size'] | +| eligibleServiceRewards | ['block.timestamp', 'curInfo', 'eligibleServiceRewards', 'reward', 'rewardsPerSecond', 'serviceCheckpoint', 'setServiceIds', 'size', 'ts', 'tsCheckpoint', 'tsCheckpointLast'] | +| serviceIds | ['serviceIds', 'setServiceIds', 'size'] | +| serviceNonces | ['curInfo', 'serviceNonces', 'setServiceIds', 'size'] | +| size | ['setServiceIds'] | +| i | ['i'] | +| tsCheckpointLast | ['tsCheckpoint'] | +| i_scope_0 | ['i_scope_0'] | +| curInfo | ['curInfo'] | +| serviceCheckpoint | ['curInfo', 'serviceCheckpoint', 'ts', 'tsCheckpoint', 'tsCheckpointLast'] | +| ts | ['block.timestamp', 'curInfo', 'serviceCheckpoint', 'ts', 'tsCheckpoint', 'tsCheckpointLast'] | +| ratio | ['block.timestamp', 'curInfo', 'ratio', 'serviceCheckpoint', 'serviceNonces', 'setServiceIds', 'size', 'ts', 'tsCheckpoint', 'tsCheckpointLast'] | +| reward | ['block.timestamp', 'curInfo', 'rewardsPerSecond', 'serviceCheckpoint', 'ts', 'tsCheckpoint', 'tsCheckpointLast'] | +| ServiceStakingBase.VERSION | [] | +| ServiceStakingBase.maxNumServices | [] | +| ServiceStakingBase.rewardsPerSecond | ['rewardsPerSecond'] | +| ServiceStakingBase.minStakingDeposit | [] | +| ServiceStakingBase.livenessPeriod | ['livenessPeriod'] | +| ServiceStakingBase.livenessRatio | ['livenessRatio'] | +| ServiceStakingBase.numAgentInstances | [] | +| ServiceStakingBase.threshold | [] | +| ServiceStakingBase.configHash | [] | +| ServiceStakingBase.serviceRegistry | [] | +| ServiceStakingBase.balance | [] | +| ServiceStakingBase.availableRewards | ['availableRewards'] | +| ServiceStakingBase.tsCheckpoint | ['tsCheckpoint'] | +| ServiceStakingBase.agentIds | [] | +| ServiceStakingBase.mapServiceInfo | ['mapServiceInfo'] | +| ServiceStakingBase.setServiceIds | ['setServiceIds'] | ++--------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +Function checkpoint() ++--------------------------------------+-----------------------------------------------------------------------------------------------------------------------+ +| Variable | Dependencies | ++--------------------------------------+-----------------------------------------------------------------------------------------------------------------------+ +| | [] | +| success | ['success'] | +| lastAvailableRewards | ['TUPLE_2', 'lastAvailableRewards', 'totalRewards'] | +| numServices | ['TUPLE_2'] | +| totalRewards | ['TUPLE_2'] | +| eligibleServiceIds | ['TUPLE_2', 'eligibleServiceIds'] | +| eligibleServiceRewards | ['TUPLE_2', 'eligibleServiceRewards'] | +| serviceIds | ['TUPLE_2', 'serviceIds'] | +| serviceNonces | ['TUPLE_2', 'serviceNonces'] | +| updatedReward | ['TUPLE_2', 'eligibleServiceRewards', 'lastAvailableRewards', 'totalRewards', 'updatedReward', 'updatedTotalRewards'] | +| updatedTotalRewards | ['TUPLE_2', 'eligibleServiceRewards', 'lastAvailableRewards', 'totalRewards', 'updatedReward', 'updatedTotalRewards'] | +| curServiceId | ['TUPLE_2', 'eligibleServiceIds'] | +| i | ['i'] | +| i_scope_0 | ['i_scope_0'] | +| curServiceId_scope_1 | ['TUPLE_2', 'eligibleServiceIds'] | +| i_scope_2 | ['i_scope_2'] | +| curServiceId_scope_3 | ['TUPLE_2', 'serviceIds'] | +| ServiceStakingBase.VERSION | [] | +| ServiceStakingBase.maxNumServices | [] | +| ServiceStakingBase.rewardsPerSecond | [] | +| ServiceStakingBase.minStakingDeposit | [] | +| ServiceStakingBase.livenessPeriod | [] | +| ServiceStakingBase.livenessRatio | [] | +| ServiceStakingBase.numAgentInstances | [] | +| ServiceStakingBase.threshold | [] | +| ServiceStakingBase.configHash | [] | +| ServiceStakingBase.serviceRegistry | [] | +| ServiceStakingBase.balance | [] | +| ServiceStakingBase.availableRewards | ['TUPLE_2', 'lastAvailableRewards', 'totalRewards'] | +| ServiceStakingBase.tsCheckpoint | ['block.timestamp'] | +| ServiceStakingBase.agentIds | [] | +| ServiceStakingBase.mapServiceInfo | ['mapServiceInfo'] | +| ServiceStakingBase.setServiceIds | [] | ++--------------------------------------+-----------------------------------------------------------------------------------------------------------------------+ +Function unstake(uint256) ++--------------------------------------+----------------------------------------------------------------------------------------------------------------------+ +| Variable | Dependencies | ++--------------------------------------+----------------------------------------------------------------------------------------------------------------------+ +| serviceId | [] | +| sInfo | ['mapServiceInfo', 'sInfo'] | +| serviceIds | ['TUPLE_3', 'eligibleServiceIds', 'eligibleServiceRewards', 'numServices', 'serviceIds', 'serviceNonces', 'success'] | +| idx | ['idx'] | +| ServiceStakingBase.VERSION | [] | +| ServiceStakingBase.maxNumServices | [] | +| ServiceStakingBase.rewardsPerSecond | [] | +| ServiceStakingBase.minStakingDeposit | [] | +| ServiceStakingBase.livenessPeriod | [] | +| ServiceStakingBase.livenessRatio | [] | +| ServiceStakingBase.numAgentInstances | [] | +| ServiceStakingBase.threshold | [] | +| ServiceStakingBase.configHash | [] | +| ServiceStakingBase.serviceRegistry | ['serviceRegistry'] | +| ServiceStakingBase.balance | [] | +| ServiceStakingBase.availableRewards | [] | +| ServiceStakingBase.tsCheckpoint | [] | +| ServiceStakingBase.agentIds | [] | +| ServiceStakingBase.mapServiceInfo | ['mapServiceInfo'] | +| ServiceStakingBase.setServiceIds | ['setServiceIds'] | ++--------------------------------------+----------------------------------------------------------------------------------------------------------------------+ +Function calculateServiceStakingReward(uint256) ++--------------------------------------+--------------------------------------------------------------------------------------------------------------------+ +| Variable | Dependencies | ++--------------------------------------+--------------------------------------------------------------------------------------------------------------------+ +| serviceId | [] | +| reward | ['TUPLE_4', 'eligibleServiceRewards', 'lastAvailableRewards', 'mapServiceInfo', 'reward', 'sInfo', 'totalRewards'] | +| sInfo | ['mapServiceInfo', 'sInfo'] | +| lastAvailableRewards | ['TUPLE_4'] | +| numServices | ['TUPLE_4'] | +| totalRewards | ['TUPLE_4'] | +| eligibleServiceIds | ['TUPLE_4', 'eligibleServiceIds'] | +| eligibleServiceRewards | ['TUPLE_4', 'eligibleServiceRewards'] | +| i | ['i'] | +| ServiceStakingBase.VERSION | [] | +| ServiceStakingBase.maxNumServices | [] | +| ServiceStakingBase.rewardsPerSecond | [] | +| ServiceStakingBase.minStakingDeposit | [] | +| ServiceStakingBase.livenessPeriod | [] | +| ServiceStakingBase.livenessRatio | [] | +| ServiceStakingBase.numAgentInstances | [] | +| ServiceStakingBase.threshold | [] | +| ServiceStakingBase.configHash | [] | +| ServiceStakingBase.serviceRegistry | [] | +| ServiceStakingBase.balance | [] | +| ServiceStakingBase.availableRewards | [] | +| ServiceStakingBase.tsCheckpoint | [] | +| ServiceStakingBase.agentIds | [] | +| ServiceStakingBase.mapServiceInfo | ['mapServiceInfo'] | +| ServiceStakingBase.setServiceIds | [] | ++--------------------------------------+--------------------------------------------------------------------------------------------------------------------+ +Function slitherConstructorConstantVariables() ++--------------------------------------+--------------+ +| Variable | Dependencies | ++--------------------------------------+--------------+ +| ServiceStakingBase.VERSION | [] | +| ServiceStakingBase.maxNumServices | [] | +| ServiceStakingBase.rewardsPerSecond | [] | +| ServiceStakingBase.minStakingDeposit | [] | +| ServiceStakingBase.livenessPeriod | [] | +| ServiceStakingBase.livenessRatio | [] | +| ServiceStakingBase.numAgentInstances | [] | +| ServiceStakingBase.threshold | [] | +| ServiceStakingBase.configHash | [] | +| ServiceStakingBase.serviceRegistry | [] | +| ServiceStakingBase.balance | [] | +| ServiceStakingBase.availableRewards | [] | +| ServiceStakingBase.tsCheckpoint | [] | +| ServiceStakingBase.agentIds | [] | +| ServiceStakingBase.mapServiceInfo | [] | +| ServiceStakingBase.setServiceIds | [] | ++--------------------------------------+--------------+ +INFO:Printers: +Contract IErrorsRegistries ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ ++----------+--------------+ + +Contract ERC721 ++------------------+----------------------------+ +| Variable | Dependencies | ++------------------+----------------------------+ +| name | ['_name'] | +| symbol | ['_symbol'] | +| _ownerOf | ['_ownerOf', 'to'] | +| _balanceOf | ['_balanceOf'] | +| getApproved | ['getApproved', 'spender'] | +| isApprovedForAll | ['isApprovedForAll'] | ++------------------+----------------------------+ + +Function tokenURI(uint256) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| id | [] | +| | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function ownerOf(uint256) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| id | [] | +| owner | ['_ownerOf'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf'] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function balanceOf(address) ++-------------------------+----------------+ +| Variable | Dependencies | ++-------------------------+----------------+ +| owner | [] | +| | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | ['_balanceOf'] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+----------------+ +Function constructor(string,string) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| _name | [] | +| _symbol | [] | +| ERC721.name | ['_name'] | +| ERC721.symbol | ['_symbol'] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function approve(address,uint256) ++-------------------------+----------------------------+ +| Variable | Dependencies | ++-------------------------+----------------------------+ +| spender | [] | +| id | [] | +| owner | ['_ownerOf'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf'] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | ['getApproved', 'spender'] | +| ERC721.isApprovedForAll | ['isApprovedForAll'] | ++-------------------------+----------------------------+ +Function setApprovalForAll(address,bool) ++-------------------------+----------------------+ +| Variable | Dependencies | ++-------------------------+----------------------+ +| operator | [] | +| approved | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | ['isApprovedForAll'] | ++-------------------------+----------------------+ +Function transferFrom(address,address,uint256) ++-------------------------+----------------------+ +| Variable | Dependencies | ++-------------------------+----------------------+ +| from | ['from'] | +| to | ['to'] | +| id | ['id'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf', 'to'] | +| ERC721._balanceOf | ['_balanceOf'] | +| ERC721.getApproved | ['getApproved'] | +| ERC721.isApprovedForAll | ['isApprovedForAll'] | ++-------------------------+----------------------+ +Function safeTransferFrom(address,address,uint256) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| from | [] | +| to | [] | +| id | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function safeTransferFrom(address,address,uint256,bytes) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| from | [] | +| to | [] | +| id | [] | +| data | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function supportsInterface(bytes4) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| interfaceId | [] | +| | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function _mint(address,uint256) ++-------------------------+--------------------+ +| Variable | Dependencies | ++-------------------------+--------------------+ +| to | ['to'] | +| id | ['id'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf', 'to'] | +| ERC721._balanceOf | ['_balanceOf'] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------------+ +Function _burn(uint256) ++-------------------------+-----------------+ +| Variable | Dependencies | ++-------------------------+-----------------+ +| id | [] | +| owner | ['_ownerOf'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf'] | +| ERC721._balanceOf | ['_balanceOf'] | +| ERC721.getApproved | ['getApproved'] | +| ERC721.isApprovedForAll | [] | ++-------------------------+-----------------+ +Function _safeMint(address,uint256) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| to | [] | +| id | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function _safeMint(address,uint256,bytes) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| to | [] | +| id | [] | +| data | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Contract ERC721TokenReceiver ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ ++----------+--------------+ + +Function onERC721Received(address,address,uint256,bytes) ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ +| | [] | ++----------+--------------+ +Contract IMultisig ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ ++----------+--------------+ + +Function nonce() ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ +| | [] | ++----------+--------------+ +Contract IService ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ ++----------+--------------+ + +Function safeTransferFrom(address,address,uint256) ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ +| from | [] | +| to | [] | +| id | [] | ++----------+--------------+ +Function mapServices(uint256) ++----------------------+--------------+ +| Variable | Dependencies | ++----------------------+--------------+ +| serviceId | [] | +| securityDeposit | [] | +| multisig | [] | +| configHash | [] | +| threshold | [] | +| maxNumAgentInstances | [] | +| numAgentInstances | [] | +| state | [] | ++----------------------+--------------+ +Function getUnitIdsOfService(IService.UnitType,uint256) ++------------+--------------+ +| Variable | Dependencies | ++------------+--------------+ +| unitType | [] | +| serviceId | [] | +| numUnitIds | [] | +| unitIds | [] | ++------------+--------------+ +Contract ServiceStakingBase ++-------------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ +| Variable | Dependencies | ++-------------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ +| VERSION | [] | +| maxNumServices | ['_stakingParams', 'maxNumServices'] | +| rewardsPerSecond | ['_stakingParams', 'rewardsPerSecond'] | +| minStakingDeposit | ['_stakingParams', 'minStakingDeposit'] | +| livenessPeriod | ['_stakingParams', 'livenessPeriod'] | +| livenessRatio | ['_stakingParams', 'livenessRatio'] | +| numAgentInstances | ['_stakingParams', 'numAgentInstances'] | +| threshold | ['_stakingParams', 'threshold'] | +| configHash | ['_stakingParams', 'configHash'] | +| serviceRegistry | ['_serviceRegistry', 'serviceRegistry'] | +| balance | [] | +| availableRewards | ['TUPLE_2', 'availableRewards', 'lastAvailableRewards', 'totalRewards'] | +| tsCheckpoint | ['block.timestamp', 'tsCheckpoint'] | +| agentIds | ['_stakingParams', 'agentId', 'agentIds'] | +| mapServiceInfo | ['TUPLE_0', '_serviceRegistry', 'block.timestamp', 'mapServiceInfo', 'msg.sender', 'multisig', 'nonce', 'sInfo', 'serviceId', 'serviceRegistry'] | +| setServiceIds | ['serviceId', 'setServiceIds'] | ++-------------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ + +Function constructor(ServiceStakingBase.StakingParams,address) ++--------------------------------------+-------------------------------------------+ +| Variable | Dependencies | ++--------------------------------------+-------------------------------------------+ +| _stakingParams | ['_stakingParams'] | +| _serviceRegistry | ['_serviceRegistry'] | +| size | ['_stakingParams'] | +| agentId | ['_stakingParams', 'agentId'] | +| i | ['i'] | +| ServiceStakingBase.VERSION | [] | +| ServiceStakingBase.maxNumServices | ['_stakingParams'] | +| ServiceStakingBase.rewardsPerSecond | ['_stakingParams'] | +| ServiceStakingBase.minStakingDeposit | ['_stakingParams'] | +| ServiceStakingBase.livenessPeriod | ['_stakingParams'] | +| ServiceStakingBase.livenessRatio | ['_stakingParams'] | +| ServiceStakingBase.numAgentInstances | ['_stakingParams'] | +| ServiceStakingBase.threshold | ['_stakingParams'] | +| ServiceStakingBase.configHash | ['_stakingParams'] | +| ServiceStakingBase.serviceRegistry | ['_serviceRegistry'] | +| ServiceStakingBase.balance | [] | +| ServiceStakingBase.availableRewards | [] | +| ServiceStakingBase.tsCheckpoint | ['block.timestamp'] | +| ServiceStakingBase.agentIds | ['_stakingParams', 'agentId', 'agentIds'] | +| ServiceStakingBase.mapServiceInfo | [] | +| ServiceStakingBase.setServiceIds | [] | ++--------------------------------------+-------------------------------------------+ +Function _checkTokenStakingDeposit(uint256,uint256) ++--------------------------------------+-----------------------+ +| Variable | Dependencies | ++--------------------------------------+-----------------------+ +| | [] | +| stakingDeposit | ['stakingDeposit'] | +| ServiceStakingBase.VERSION | [] | +| ServiceStakingBase.maxNumServices | [] | +| ServiceStakingBase.rewardsPerSecond | [] | +| ServiceStakingBase.minStakingDeposit | ['minStakingDeposit'] | +| ServiceStakingBase.livenessPeriod | [] | +| ServiceStakingBase.livenessRatio | [] | +| ServiceStakingBase.numAgentInstances | [] | +| ServiceStakingBase.threshold | [] | +| ServiceStakingBase.configHash | [] | +| ServiceStakingBase.serviceRegistry | [] | +| ServiceStakingBase.balance | [] | +| ServiceStakingBase.availableRewards | [] | +| ServiceStakingBase.tsCheckpoint | [] | +| ServiceStakingBase.agentIds | [] | +| ServiceStakingBase.mapServiceInfo | [] | +| ServiceStakingBase.setServiceIds | [] | ++--------------------------------------+-----------------------+ +Function _withdraw(address,uint256) ++--------------------------------------+--------------+ +| Variable | Dependencies | ++--------------------------------------+--------------+ +| to | [] | +| amount | [] | +| ServiceStakingBase.VERSION | [] | +| ServiceStakingBase.maxNumServices | [] | +| ServiceStakingBase.rewardsPerSecond | [] | +| ServiceStakingBase.minStakingDeposit | [] | +| ServiceStakingBase.livenessPeriod | [] | +| ServiceStakingBase.livenessRatio | [] | +| ServiceStakingBase.numAgentInstances | [] | +| ServiceStakingBase.threshold | [] | +| ServiceStakingBase.configHash | [] | +| ServiceStakingBase.serviceRegistry | [] | +| ServiceStakingBase.balance | [] | +| ServiceStakingBase.availableRewards | [] | +| ServiceStakingBase.tsCheckpoint | [] | +| ServiceStakingBase.agentIds | [] | +| ServiceStakingBase.mapServiceInfo | [] | +| ServiceStakingBase.setServiceIds | [] | ++--------------------------------------+--------------+ +Function stake(uint256) ++--------------------------------------+------------------------------------------------------------------------------------------------------------------------------+ +| Variable | Dependencies | ++--------------------------------------+------------------------------------------------------------------------------------------------------------------------------+ +| serviceId | [] | +| numStakingServices | ['serviceId', 'setServiceIds'] | +| stakingDeposit | ['TUPLE_0', 'serviceId', 'serviceRegistry'] | +| multisig | ['TUPLE_0', 'serviceId', 'serviceRegistry'] | +| hash | ['TUPLE_0', 'serviceId', 'serviceRegistry'] | +| agentThreshold | ['TUPLE_0', 'serviceId', 'serviceRegistry'] | +| maxNumInstances | ['TUPLE_0', 'serviceId', 'serviceRegistry'] | +| state | ['TUPLE_0', 'serviceId', 'serviceRegistry'] | +| size | ['agentIds'] | +| numAgents | ['IService', 'TUPLE_1', 'serviceId', 'serviceRegistry'] | +| agents | ['IService', 'TUPLE_1', 'agents', 'serviceId', 'serviceRegistry'] | +| i | ['i'] | +| sInfo | ['TUPLE_0', 'block.timestamp', 'msg.sender', 'multisig', 'nonce', 'sInfo', 'serviceId', 'serviceRegistry'] | +| nonce | ['TUPLE_0', 'multisig', 'serviceId', 'serviceRegistry'] | +| ServiceStakingBase.VERSION | [] | +| ServiceStakingBase.maxNumServices | ['maxNumServices'] | +| ServiceStakingBase.rewardsPerSecond | [] | +| ServiceStakingBase.minStakingDeposit | [] | +| ServiceStakingBase.livenessPeriod | [] | +| ServiceStakingBase.livenessRatio | [] | +| ServiceStakingBase.numAgentInstances | ['numAgentInstances'] | +| ServiceStakingBase.threshold | ['threshold'] | +| ServiceStakingBase.configHash | ['configHash'] | +| ServiceStakingBase.serviceRegistry | ['serviceRegistry'] | +| ServiceStakingBase.balance | [] | +| ServiceStakingBase.availableRewards | ['availableRewards'] | +| ServiceStakingBase.tsCheckpoint | [] | +| ServiceStakingBase.agentIds | ['agentIds'] | +| ServiceStakingBase.mapServiceInfo | ['TUPLE_0', 'block.timestamp', 'mapServiceInfo', 'msg.sender', 'multisig', 'nonce', 'sInfo', 'serviceId', 'serviceRegistry'] | +| ServiceStakingBase.setServiceIds | ['serviceId', 'setServiceIds'] | ++--------------------------------------+------------------------------------------------------------------------------------------------------------------------------+ +Function _calculateStakingRewards() ++--------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| Variable | Dependencies | ++--------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| lastAvailableRewards | ['availableRewards'] | +| numServices | ['numServices'] | +| totalRewards | ['block.timestamp', 'curInfo', 'reward', 'rewardsPerSecond', 'serviceCheckpoint', 'totalRewards', 'ts', 'tsCheckpoint', 'tsCheckpointLast'] | +| eligibleServiceIds | ['eligibleServiceIds', 'serviceIds', 'setServiceIds', 'size'] | +| eligibleServiceRewards | ['block.timestamp', 'curInfo', 'eligibleServiceRewards', 'reward', 'rewardsPerSecond', 'serviceCheckpoint', 'setServiceIds', 'size', 'ts', 'tsCheckpoint', 'tsCheckpointLast'] | +| serviceIds | ['serviceIds', 'setServiceIds', 'size'] | +| serviceNonces | ['curInfo', 'serviceNonces', 'setServiceIds', 'size'] | +| size | ['setServiceIds'] | +| i | ['i'] | +| tsCheckpointLast | ['tsCheckpoint'] | +| i_scope_0 | ['i_scope_0'] | +| curInfo | ['curInfo'] | +| serviceCheckpoint | ['curInfo', 'serviceCheckpoint', 'ts', 'tsCheckpoint', 'tsCheckpointLast'] | +| ts | ['block.timestamp', 'curInfo', 'serviceCheckpoint', 'ts', 'tsCheckpoint', 'tsCheckpointLast'] | +| ratio | ['block.timestamp', 'curInfo', 'ratio', 'serviceCheckpoint', 'serviceNonces', 'setServiceIds', 'size', 'ts', 'tsCheckpoint', 'tsCheckpointLast'] | +| reward | ['block.timestamp', 'curInfo', 'rewardsPerSecond', 'serviceCheckpoint', 'ts', 'tsCheckpoint', 'tsCheckpointLast'] | +| ServiceStakingBase.VERSION | [] | +| ServiceStakingBase.maxNumServices | [] | +| ServiceStakingBase.rewardsPerSecond | ['rewardsPerSecond'] | +| ServiceStakingBase.minStakingDeposit | [] | +| ServiceStakingBase.livenessPeriod | ['livenessPeriod'] | +| ServiceStakingBase.livenessRatio | ['livenessRatio'] | +| ServiceStakingBase.numAgentInstances | [] | +| ServiceStakingBase.threshold | [] | +| ServiceStakingBase.configHash | [] | +| ServiceStakingBase.serviceRegistry | [] | +| ServiceStakingBase.balance | [] | +| ServiceStakingBase.availableRewards | ['availableRewards'] | +| ServiceStakingBase.tsCheckpoint | ['tsCheckpoint'] | +| ServiceStakingBase.agentIds | [] | +| ServiceStakingBase.mapServiceInfo | ['mapServiceInfo'] | +| ServiceStakingBase.setServiceIds | ['setServiceIds'] | ++--------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +Function checkpoint() ++--------------------------------------+-----------------------------------------------------------------------------------------------------------------------+ +| Variable | Dependencies | ++--------------------------------------+-----------------------------------------------------------------------------------------------------------------------+ +| | [] | +| success | ['success'] | +| lastAvailableRewards | ['TUPLE_2', 'lastAvailableRewards', 'totalRewards'] | +| numServices | ['TUPLE_2'] | +| totalRewards | ['TUPLE_2'] | +| eligibleServiceIds | ['TUPLE_2', 'eligibleServiceIds'] | +| eligibleServiceRewards | ['TUPLE_2', 'eligibleServiceRewards'] | +| serviceIds | ['TUPLE_2', 'serviceIds'] | +| serviceNonces | ['TUPLE_2', 'serviceNonces'] | +| updatedReward | ['TUPLE_2', 'eligibleServiceRewards', 'lastAvailableRewards', 'totalRewards', 'updatedReward', 'updatedTotalRewards'] | +| updatedTotalRewards | ['TUPLE_2', 'eligibleServiceRewards', 'lastAvailableRewards', 'totalRewards', 'updatedReward', 'updatedTotalRewards'] | +| curServiceId | ['TUPLE_2', 'eligibleServiceIds'] | +| i | ['i'] | +| i_scope_0 | ['i_scope_0'] | +| curServiceId_scope_1 | ['TUPLE_2', 'eligibleServiceIds'] | +| i_scope_2 | ['i_scope_2'] | +| curServiceId_scope_3 | ['TUPLE_2', 'serviceIds'] | +| ServiceStakingBase.VERSION | [] | +| ServiceStakingBase.maxNumServices | [] | +| ServiceStakingBase.rewardsPerSecond | [] | +| ServiceStakingBase.minStakingDeposit | [] | +| ServiceStakingBase.livenessPeriod | [] | +| ServiceStakingBase.livenessRatio | [] | +| ServiceStakingBase.numAgentInstances | [] | +| ServiceStakingBase.threshold | [] | +| ServiceStakingBase.configHash | [] | +| ServiceStakingBase.serviceRegistry | [] | +| ServiceStakingBase.balance | [] | +| ServiceStakingBase.availableRewards | ['TUPLE_2', 'lastAvailableRewards', 'totalRewards'] | +| ServiceStakingBase.tsCheckpoint | ['block.timestamp'] | +| ServiceStakingBase.agentIds | [] | +| ServiceStakingBase.mapServiceInfo | ['mapServiceInfo'] | +| ServiceStakingBase.setServiceIds | [] | ++--------------------------------------+-----------------------------------------------------------------------------------------------------------------------+ +Function unstake(uint256) ++--------------------------------------+----------------------------------------------------------------------------------------------------------------------+ +| Variable | Dependencies | ++--------------------------------------+----------------------------------------------------------------------------------------------------------------------+ +| serviceId | [] | +| sInfo | ['mapServiceInfo', 'sInfo'] | +| serviceIds | ['TUPLE_3', 'eligibleServiceIds', 'eligibleServiceRewards', 'numServices', 'serviceIds', 'serviceNonces', 'success'] | +| idx | ['idx'] | +| ServiceStakingBase.VERSION | [] | +| ServiceStakingBase.maxNumServices | [] | +| ServiceStakingBase.rewardsPerSecond | [] | +| ServiceStakingBase.minStakingDeposit | [] | +| ServiceStakingBase.livenessPeriod | [] | +| ServiceStakingBase.livenessRatio | [] | +| ServiceStakingBase.numAgentInstances | [] | +| ServiceStakingBase.threshold | [] | +| ServiceStakingBase.configHash | [] | +| ServiceStakingBase.serviceRegistry | ['serviceRegistry'] | +| ServiceStakingBase.balance | [] | +| ServiceStakingBase.availableRewards | [] | +| ServiceStakingBase.tsCheckpoint | [] | +| ServiceStakingBase.agentIds | [] | +| ServiceStakingBase.mapServiceInfo | ['mapServiceInfo'] | +| ServiceStakingBase.setServiceIds | ['setServiceIds'] | ++--------------------------------------+----------------------------------------------------------------------------------------------------------------------+ +Function calculateServiceStakingReward(uint256) ++--------------------------------------+--------------------------------------------------------------------------------------------------------------------+ +| Variable | Dependencies | ++--------------------------------------+--------------------------------------------------------------------------------------------------------------------+ +| serviceId | [] | +| reward | ['TUPLE_4', 'eligibleServiceRewards', 'lastAvailableRewards', 'mapServiceInfo', 'reward', 'sInfo', 'totalRewards'] | +| sInfo | ['mapServiceInfo', 'sInfo'] | +| lastAvailableRewards | ['TUPLE_4'] | +| numServices | ['TUPLE_4'] | +| totalRewards | ['TUPLE_4'] | +| eligibleServiceIds | ['TUPLE_4', 'eligibleServiceIds'] | +| eligibleServiceRewards | ['TUPLE_4', 'eligibleServiceRewards'] | +| i | ['i'] | +| ServiceStakingBase.VERSION | [] | +| ServiceStakingBase.maxNumServices | [] | +| ServiceStakingBase.rewardsPerSecond | [] | +| ServiceStakingBase.minStakingDeposit | [] | +| ServiceStakingBase.livenessPeriod | [] | +| ServiceStakingBase.livenessRatio | [] | +| ServiceStakingBase.numAgentInstances | [] | +| ServiceStakingBase.threshold | [] | +| ServiceStakingBase.configHash | [] | +| ServiceStakingBase.serviceRegistry | [] | +| ServiceStakingBase.balance | [] | +| ServiceStakingBase.availableRewards | [] | +| ServiceStakingBase.tsCheckpoint | [] | +| ServiceStakingBase.agentIds | [] | +| ServiceStakingBase.mapServiceInfo | ['mapServiceInfo'] | +| ServiceStakingBase.setServiceIds | [] | ++--------------------------------------+--------------------------------------------------------------------------------------------------------------------+ +Function slitherConstructorConstantVariables() ++--------------------------------------+--------------+ +| Variable | Dependencies | ++--------------------------------------+--------------+ +| ServiceStakingBase.VERSION | [] | +| ServiceStakingBase.maxNumServices | [] | +| ServiceStakingBase.rewardsPerSecond | [] | +| ServiceStakingBase.minStakingDeposit | [] | +| ServiceStakingBase.livenessPeriod | [] | +| ServiceStakingBase.livenessRatio | [] | +| ServiceStakingBase.numAgentInstances | [] | +| ServiceStakingBase.threshold | [] | +| ServiceStakingBase.configHash | [] | +| ServiceStakingBase.serviceRegistry | [] | +| ServiceStakingBase.balance | [] | +| ServiceStakingBase.availableRewards | [] | +| ServiceStakingBase.tsCheckpoint | [] | +| ServiceStakingBase.agentIds | [] | +| ServiceStakingBase.mapServiceInfo | [] | +| ServiceStakingBase.setServiceIds | [] | ++--------------------------------------+--------------+ +Contract IToken ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ ++----------+--------------+ + +Function balanceOf(address) ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ +| account | [] | +| | [] | ++----------+--------------+ +Function ownerOf(uint256) ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ +| tokenId | [] | +| | [] | ++----------+--------------+ +Function totalSupply() ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ +| | [] | ++----------+--------------+ +Function transfer(address,uint256) ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ +| to | [] | +| amount | [] | +| | [] | ++----------+--------------+ +Function allowance(address,address) ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ +| owner | [] | +| spender | [] | +| | [] | ++----------+--------------+ +Function approve(address,uint256) ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ +| spender | [] | +| amount | [] | +| | [] | ++----------+--------------+ +Function transferFrom(address,address,uint256) ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ +| from | [] | +| to | [] | +| amount | [] | +| | [] | ++----------+--------------+ +Function decimals() ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ +| | [] | ++----------+--------------+ +INFO:Printers: +Contract IErrorsRegistries ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ ++----------+--------------+ + +Contract ERC721 ++------------------+----------------------------+ +| Variable | Dependencies | ++------------------+----------------------------+ +| name | ['_name'] | +| symbol | ['_symbol'] | +| _ownerOf | ['_ownerOf', 'to'] | +| _balanceOf | ['_balanceOf'] | +| getApproved | ['getApproved', 'spender'] | +| isApprovedForAll | ['isApprovedForAll'] | ++------------------+----------------------------+ + +Function tokenURI(uint256) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| id | [] | +| | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function ownerOf(uint256) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| id | [] | +| owner | ['_ownerOf'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf'] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function balanceOf(address) ++-------------------------+----------------+ +| Variable | Dependencies | ++-------------------------+----------------+ +| owner | [] | +| | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | ['_balanceOf'] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+----------------+ +Function constructor(string,string) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| _name | [] | +| _symbol | [] | +| ERC721.name | ['_name'] | +| ERC721.symbol | ['_symbol'] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function approve(address,uint256) ++-------------------------+----------------------------+ +| Variable | Dependencies | ++-------------------------+----------------------------+ +| spender | [] | +| id | [] | +| owner | ['_ownerOf'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf'] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | ['getApproved', 'spender'] | +| ERC721.isApprovedForAll | ['isApprovedForAll'] | ++-------------------------+----------------------------+ +Function setApprovalForAll(address,bool) ++-------------------------+----------------------+ +| Variable | Dependencies | ++-------------------------+----------------------+ +| operator | [] | +| approved | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | ['isApprovedForAll'] | ++-------------------------+----------------------+ +Function transferFrom(address,address,uint256) ++-------------------------+----------------------+ +| Variable | Dependencies | ++-------------------------+----------------------+ +| from | ['from'] | +| to | ['to'] | +| id | ['id'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf', 'to'] | +| ERC721._balanceOf | ['_balanceOf'] | +| ERC721.getApproved | ['getApproved'] | +| ERC721.isApprovedForAll | ['isApprovedForAll'] | ++-------------------------+----------------------+ +Function safeTransferFrom(address,address,uint256) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| from | [] | +| to | [] | +| id | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function safeTransferFrom(address,address,uint256,bytes) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| from | [] | +| to | [] | +| id | [] | +| data | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function supportsInterface(bytes4) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| interfaceId | [] | +| | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function _mint(address,uint256) ++-------------------------+--------------------+ +| Variable | Dependencies | ++-------------------------+--------------------+ +| to | ['to'] | +| id | ['id'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf', 'to'] | +| ERC721._balanceOf | ['_balanceOf'] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------------+ +Function _burn(uint256) ++-------------------------+-----------------+ +| Variable | Dependencies | ++-------------------------+-----------------+ +| id | [] | +| owner | ['_ownerOf'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf'] | +| ERC721._balanceOf | ['_balanceOf'] | +| ERC721.getApproved | ['getApproved'] | +| ERC721.isApprovedForAll | [] | ++-------------------------+-----------------+ +Function _safeMint(address,uint256) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| to | [] | +| id | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function _safeMint(address,uint256,bytes) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| to | [] | +| id | [] | +| data | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Contract ERC721TokenReceiver ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ ++----------+--------------+ + +Function onERC721Received(address,address,uint256,bytes) ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ +| | [] | ++----------+--------------+ +Contract IMultisig ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ ++----------+--------------+ + +Function nonce() ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ +| | [] | ++----------+--------------+ +Contract IService ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ ++----------+--------------+ + +Function safeTransferFrom(address,address,uint256) ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ +| from | [] | +| to | [] | +| id | [] | ++----------+--------------+ +Function mapServices(uint256) ++----------------------+--------------+ +| Variable | Dependencies | ++----------------------+--------------+ +| serviceId | [] | +| securityDeposit | [] | +| multisig | [] | +| configHash | [] | +| threshold | [] | +| maxNumAgentInstances | [] | +| numAgentInstances | [] | +| state | [] | ++----------------------+--------------+ +Function getUnitIdsOfService(IService.UnitType,uint256) ++------------+--------------+ +| Variable | Dependencies | ++------------+--------------+ +| unitType | [] | +| serviceId | [] | +| numUnitIds | [] | +| unitIds | [] | ++------------+--------------+ +Contract ServiceStakingBase ++-------------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ +| Variable | Dependencies | ++-------------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ +| VERSION | [] | +| maxNumServices | ['_stakingParams', 'maxNumServices'] | +| rewardsPerSecond | ['_stakingParams', 'rewardsPerSecond'] | +| minStakingDeposit | ['_stakingParams', 'minStakingDeposit'] | +| livenessPeriod | ['_stakingParams', 'livenessPeriod'] | +| livenessRatio | ['_stakingParams', 'livenessRatio'] | +| numAgentInstances | ['_stakingParams', 'numAgentInstances'] | +| threshold | ['_stakingParams', 'threshold'] | +| configHash | ['_stakingParams', 'configHash'] | +| serviceRegistry | ['_serviceRegistry', 'serviceRegistry'] | +| balance | [] | +| availableRewards | ['TUPLE_2', 'availableRewards', 'lastAvailableRewards', 'totalRewards'] | +| tsCheckpoint | ['block.timestamp', 'tsCheckpoint'] | +| agentIds | ['_stakingParams', 'agentId', 'agentIds'] | +| mapServiceInfo | ['TUPLE_0', '_serviceRegistry', 'block.timestamp', 'mapServiceInfo', 'msg.sender', 'multisig', 'nonce', 'sInfo', 'serviceId', 'serviceRegistry'] | +| setServiceIds | ['serviceId', 'setServiceIds'] | ++-------------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ + +Function constructor(ServiceStakingBase.StakingParams,address) ++--------------------------------------+-------------------------------------------+ +| Variable | Dependencies | ++--------------------------------------+-------------------------------------------+ +| _stakingParams | ['_stakingParams'] | +| _serviceRegistry | ['_serviceRegistry'] | +| size | ['_stakingParams'] | +| agentId | ['_stakingParams', 'agentId'] | +| i | ['i'] | +| ServiceStakingBase.VERSION | [] | +| ServiceStakingBase.maxNumServices | ['_stakingParams'] | +| ServiceStakingBase.rewardsPerSecond | ['_stakingParams'] | +| ServiceStakingBase.minStakingDeposit | ['_stakingParams'] | +| ServiceStakingBase.livenessPeriod | ['_stakingParams'] | +| ServiceStakingBase.livenessRatio | ['_stakingParams'] | +| ServiceStakingBase.numAgentInstances | ['_stakingParams'] | +| ServiceStakingBase.threshold | ['_stakingParams'] | +| ServiceStakingBase.configHash | ['_stakingParams'] | +| ServiceStakingBase.serviceRegistry | ['_serviceRegistry'] | +| ServiceStakingBase.balance | [] | +| ServiceStakingBase.availableRewards | [] | +| ServiceStakingBase.tsCheckpoint | ['block.timestamp'] | +| ServiceStakingBase.agentIds | ['_stakingParams', 'agentId', 'agentIds'] | +| ServiceStakingBase.mapServiceInfo | [] | +| ServiceStakingBase.setServiceIds | [] | ++--------------------------------------+-------------------------------------------+ +Function _checkTokenStakingDeposit(uint256,uint256) ++--------------------------------------+-----------------------+ +| Variable | Dependencies | ++--------------------------------------+-----------------------+ +| | [] | +| stakingDeposit | ['stakingDeposit'] | +| ServiceStakingBase.VERSION | [] | +| ServiceStakingBase.maxNumServices | [] | +| ServiceStakingBase.rewardsPerSecond | [] | +| ServiceStakingBase.minStakingDeposit | ['minStakingDeposit'] | +| ServiceStakingBase.livenessPeriod | [] | +| ServiceStakingBase.livenessRatio | [] | +| ServiceStakingBase.numAgentInstances | [] | +| ServiceStakingBase.threshold | [] | +| ServiceStakingBase.configHash | [] | +| ServiceStakingBase.serviceRegistry | [] | +| ServiceStakingBase.balance | [] | +| ServiceStakingBase.availableRewards | [] | +| ServiceStakingBase.tsCheckpoint | [] | +| ServiceStakingBase.agentIds | [] | +| ServiceStakingBase.mapServiceInfo | [] | +| ServiceStakingBase.setServiceIds | [] | ++--------------------------------------+-----------------------+ +Function _withdraw(address,uint256) ++--------------------------------------+--------------+ +| Variable | Dependencies | ++--------------------------------------+--------------+ +| to | [] | +| amount | [] | +| ServiceStakingBase.VERSION | [] | +| ServiceStakingBase.maxNumServices | [] | +| ServiceStakingBase.rewardsPerSecond | [] | +| ServiceStakingBase.minStakingDeposit | [] | +| ServiceStakingBase.livenessPeriod | [] | +| ServiceStakingBase.livenessRatio | [] | +| ServiceStakingBase.numAgentInstances | [] | +| ServiceStakingBase.threshold | [] | +| ServiceStakingBase.configHash | [] | +| ServiceStakingBase.serviceRegistry | [] | +| ServiceStakingBase.balance | [] | +| ServiceStakingBase.availableRewards | [] | +| ServiceStakingBase.tsCheckpoint | [] | +| ServiceStakingBase.agentIds | [] | +| ServiceStakingBase.mapServiceInfo | [] | +| ServiceStakingBase.setServiceIds | [] | ++--------------------------------------+--------------+ +Function stake(uint256) ++--------------------------------------+------------------------------------------------------------------------------------------------------------------------------+ +| Variable | Dependencies | ++--------------------------------------+------------------------------------------------------------------------------------------------------------------------------+ +| serviceId | [] | +| numStakingServices | ['serviceId', 'setServiceIds'] | +| stakingDeposit | ['TUPLE_0', 'serviceId', 'serviceRegistry'] | +| multisig | ['TUPLE_0', 'serviceId', 'serviceRegistry'] | +| hash | ['TUPLE_0', 'serviceId', 'serviceRegistry'] | +| agentThreshold | ['TUPLE_0', 'serviceId', 'serviceRegistry'] | +| maxNumInstances | ['TUPLE_0', 'serviceId', 'serviceRegistry'] | +| state | ['TUPLE_0', 'serviceId', 'serviceRegistry'] | +| size | ['agentIds'] | +| numAgents | ['IService', 'TUPLE_1', 'serviceId', 'serviceRegistry'] | +| agents | ['IService', 'TUPLE_1', 'agents', 'serviceId', 'serviceRegistry'] | +| i | ['i'] | +| sInfo | ['TUPLE_0', 'block.timestamp', 'msg.sender', 'multisig', 'nonce', 'sInfo', 'serviceId', 'serviceRegistry'] | +| nonce | ['TUPLE_0', 'multisig', 'serviceId', 'serviceRegistry'] | +| ServiceStakingBase.VERSION | [] | +| ServiceStakingBase.maxNumServices | ['maxNumServices'] | +| ServiceStakingBase.rewardsPerSecond | [] | +| ServiceStakingBase.minStakingDeposit | [] | +| ServiceStakingBase.livenessPeriod | [] | +| ServiceStakingBase.livenessRatio | [] | +| ServiceStakingBase.numAgentInstances | ['numAgentInstances'] | +| ServiceStakingBase.threshold | ['threshold'] | +| ServiceStakingBase.configHash | ['configHash'] | +| ServiceStakingBase.serviceRegistry | ['serviceRegistry'] | +| ServiceStakingBase.balance | [] | +| ServiceStakingBase.availableRewards | ['availableRewards'] | +| ServiceStakingBase.tsCheckpoint | [] | +| ServiceStakingBase.agentIds | ['agentIds'] | +| ServiceStakingBase.mapServiceInfo | ['TUPLE_0', 'block.timestamp', 'mapServiceInfo', 'msg.sender', 'multisig', 'nonce', 'sInfo', 'serviceId', 'serviceRegistry'] | +| ServiceStakingBase.setServiceIds | ['serviceId', 'setServiceIds'] | ++--------------------------------------+------------------------------------------------------------------------------------------------------------------------------+ +Function _calculateStakingRewards() ++--------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| Variable | Dependencies | ++--------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| lastAvailableRewards | ['availableRewards'] | +| numServices | ['numServices'] | +| totalRewards | ['block.timestamp', 'curInfo', 'reward', 'rewardsPerSecond', 'serviceCheckpoint', 'totalRewards', 'ts', 'tsCheckpoint', 'tsCheckpointLast'] | +| eligibleServiceIds | ['eligibleServiceIds', 'serviceIds', 'setServiceIds', 'size'] | +| eligibleServiceRewards | ['block.timestamp', 'curInfo', 'eligibleServiceRewards', 'reward', 'rewardsPerSecond', 'serviceCheckpoint', 'setServiceIds', 'size', 'ts', 'tsCheckpoint', 'tsCheckpointLast'] | +| serviceIds | ['serviceIds', 'setServiceIds', 'size'] | +| serviceNonces | ['curInfo', 'serviceNonces', 'setServiceIds', 'size'] | +| size | ['setServiceIds'] | +| i | ['i'] | +| tsCheckpointLast | ['tsCheckpoint'] | +| i_scope_0 | ['i_scope_0'] | +| curInfo | ['curInfo'] | +| serviceCheckpoint | ['curInfo', 'serviceCheckpoint', 'ts', 'tsCheckpoint', 'tsCheckpointLast'] | +| ts | ['block.timestamp', 'curInfo', 'serviceCheckpoint', 'ts', 'tsCheckpoint', 'tsCheckpointLast'] | +| ratio | ['block.timestamp', 'curInfo', 'ratio', 'serviceCheckpoint', 'serviceNonces', 'setServiceIds', 'size', 'ts', 'tsCheckpoint', 'tsCheckpointLast'] | +| reward | ['block.timestamp', 'curInfo', 'rewardsPerSecond', 'serviceCheckpoint', 'ts', 'tsCheckpoint', 'tsCheckpointLast'] | +| ServiceStakingBase.VERSION | [] | +| ServiceStakingBase.maxNumServices | [] | +| ServiceStakingBase.rewardsPerSecond | ['rewardsPerSecond'] | +| ServiceStakingBase.minStakingDeposit | [] | +| ServiceStakingBase.livenessPeriod | ['livenessPeriod'] | +| ServiceStakingBase.livenessRatio | ['livenessRatio'] | +| ServiceStakingBase.numAgentInstances | [] | +| ServiceStakingBase.threshold | [] | +| ServiceStakingBase.configHash | [] | +| ServiceStakingBase.serviceRegistry | [] | +| ServiceStakingBase.balance | [] | +| ServiceStakingBase.availableRewards | ['availableRewards'] | +| ServiceStakingBase.tsCheckpoint | ['tsCheckpoint'] | +| ServiceStakingBase.agentIds | [] | +| ServiceStakingBase.mapServiceInfo | ['mapServiceInfo'] | +| ServiceStakingBase.setServiceIds | ['setServiceIds'] | ++--------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +Function checkpoint() ++--------------------------------------+-----------------------------------------------------------------------------------------------------------------------+ +| Variable | Dependencies | ++--------------------------------------+-----------------------------------------------------------------------------------------------------------------------+ +| | [] | +| success | ['success'] | +| lastAvailableRewards | ['TUPLE_2', 'lastAvailableRewards', 'totalRewards'] | +| numServices | ['TUPLE_2'] | +| totalRewards | ['TUPLE_2'] | +| eligibleServiceIds | ['TUPLE_2', 'eligibleServiceIds'] | +| eligibleServiceRewards | ['TUPLE_2', 'eligibleServiceRewards'] | +| serviceIds | ['TUPLE_2', 'serviceIds'] | +| serviceNonces | ['TUPLE_2', 'serviceNonces'] | +| updatedReward | ['TUPLE_2', 'eligibleServiceRewards', 'lastAvailableRewards', 'totalRewards', 'updatedReward', 'updatedTotalRewards'] | +| updatedTotalRewards | ['TUPLE_2', 'eligibleServiceRewards', 'lastAvailableRewards', 'totalRewards', 'updatedReward', 'updatedTotalRewards'] | +| curServiceId | ['TUPLE_2', 'eligibleServiceIds'] | +| i | ['i'] | +| i_scope_0 | ['i_scope_0'] | +| curServiceId_scope_1 | ['TUPLE_2', 'eligibleServiceIds'] | +| i_scope_2 | ['i_scope_2'] | +| curServiceId_scope_3 | ['TUPLE_2', 'serviceIds'] | +| ServiceStakingBase.VERSION | [] | +| ServiceStakingBase.maxNumServices | [] | +| ServiceStakingBase.rewardsPerSecond | [] | +| ServiceStakingBase.minStakingDeposit | [] | +| ServiceStakingBase.livenessPeriod | [] | +| ServiceStakingBase.livenessRatio | [] | +| ServiceStakingBase.numAgentInstances | [] | +| ServiceStakingBase.threshold | [] | +| ServiceStakingBase.configHash | [] | +| ServiceStakingBase.serviceRegistry | [] | +| ServiceStakingBase.balance | [] | +| ServiceStakingBase.availableRewards | ['TUPLE_2', 'lastAvailableRewards', 'totalRewards'] | +| ServiceStakingBase.tsCheckpoint | ['block.timestamp'] | +| ServiceStakingBase.agentIds | [] | +| ServiceStakingBase.mapServiceInfo | ['mapServiceInfo'] | +| ServiceStakingBase.setServiceIds | [] | ++--------------------------------------+-----------------------------------------------------------------------------------------------------------------------+ +Function unstake(uint256) ++--------------------------------------+----------------------------------------------------------------------------------------------------------------------+ +| Variable | Dependencies | ++--------------------------------------+----------------------------------------------------------------------------------------------------------------------+ +| serviceId | [] | +| sInfo | ['mapServiceInfo', 'sInfo'] | +| serviceIds | ['TUPLE_3', 'eligibleServiceIds', 'eligibleServiceRewards', 'numServices', 'serviceIds', 'serviceNonces', 'success'] | +| idx | ['idx'] | +| ServiceStakingBase.VERSION | [] | +| ServiceStakingBase.maxNumServices | [] | +| ServiceStakingBase.rewardsPerSecond | [] | +| ServiceStakingBase.minStakingDeposit | [] | +| ServiceStakingBase.livenessPeriod | [] | +| ServiceStakingBase.livenessRatio | [] | +| ServiceStakingBase.numAgentInstances | [] | +| ServiceStakingBase.threshold | [] | +| ServiceStakingBase.configHash | [] | +| ServiceStakingBase.serviceRegistry | ['serviceRegistry'] | +| ServiceStakingBase.balance | [] | +| ServiceStakingBase.availableRewards | [] | +| ServiceStakingBase.tsCheckpoint | [] | +| ServiceStakingBase.agentIds | [] | +| ServiceStakingBase.mapServiceInfo | ['mapServiceInfo'] | +| ServiceStakingBase.setServiceIds | ['setServiceIds'] | ++--------------------------------------+----------------------------------------------------------------------------------------------------------------------+ +Function calculateServiceStakingReward(uint256) ++--------------------------------------+--------------------------------------------------------------------------------------------------------------------+ +| Variable | Dependencies | ++--------------------------------------+--------------------------------------------------------------------------------------------------------------------+ +| serviceId | [] | +| reward | ['TUPLE_4', 'eligibleServiceRewards', 'lastAvailableRewards', 'mapServiceInfo', 'reward', 'sInfo', 'totalRewards'] | +| sInfo | ['mapServiceInfo', 'sInfo'] | +| lastAvailableRewards | ['TUPLE_4'] | +| numServices | ['TUPLE_4'] | +| totalRewards | ['TUPLE_4'] | +| eligibleServiceIds | ['TUPLE_4', 'eligibleServiceIds'] | +| eligibleServiceRewards | ['TUPLE_4', 'eligibleServiceRewards'] | +| i | ['i'] | +| ServiceStakingBase.VERSION | [] | +| ServiceStakingBase.maxNumServices | [] | +| ServiceStakingBase.rewardsPerSecond | [] | +| ServiceStakingBase.minStakingDeposit | [] | +| ServiceStakingBase.livenessPeriod | [] | +| ServiceStakingBase.livenessRatio | [] | +| ServiceStakingBase.numAgentInstances | [] | +| ServiceStakingBase.threshold | [] | +| ServiceStakingBase.configHash | [] | +| ServiceStakingBase.serviceRegistry | [] | +| ServiceStakingBase.balance | [] | +| ServiceStakingBase.availableRewards | [] | +| ServiceStakingBase.tsCheckpoint | [] | +| ServiceStakingBase.agentIds | [] | +| ServiceStakingBase.mapServiceInfo | ['mapServiceInfo'] | +| ServiceStakingBase.setServiceIds | [] | ++--------------------------------------+--------------------------------------------------------------------------------------------------------------------+ +Function slitherConstructorConstantVariables() ++--------------------------------------+--------------+ +| Variable | Dependencies | ++--------------------------------------+--------------+ +| ServiceStakingBase.VERSION | [] | +| ServiceStakingBase.maxNumServices | [] | +| ServiceStakingBase.rewardsPerSecond | [] | +| ServiceStakingBase.minStakingDeposit | [] | +| ServiceStakingBase.livenessPeriod | [] | +| ServiceStakingBase.livenessRatio | [] | +| ServiceStakingBase.numAgentInstances | [] | +| ServiceStakingBase.threshold | [] | +| ServiceStakingBase.configHash | [] | +| ServiceStakingBase.serviceRegistry | [] | +| ServiceStakingBase.balance | [] | +| ServiceStakingBase.availableRewards | [] | +| ServiceStakingBase.tsCheckpoint | [] | +| ServiceStakingBase.agentIds | [] | +| ServiceStakingBase.mapServiceInfo | [] | +| ServiceStakingBase.setServiceIds | [] | ++--------------------------------------+--------------+ +Contract IToken ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ ++----------+--------------+ + +Function balanceOf(address) ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ +| account | [] | +| | [] | ++----------+--------------+ +Function ownerOf(uint256) ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ +| tokenId | [] | +| | [] | ++----------+--------------+ +Function totalSupply() ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ +| | [] | ++----------+--------------+ +Function transfer(address,uint256) ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ +| to | [] | +| amount | [] | +| | [] | ++----------+--------------+ +Function allowance(address,address) ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ +| owner | [] | +| spender | [] | +| | [] | ++----------+--------------+ +Function approve(address,uint256) ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ +| spender | [] | +| amount | [] | +| | [] | ++----------+--------------+ +Function transferFrom(address,address,uint256) ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ +| from | [] | +| to | [] | +| amount | [] | +| | [] | ++----------+--------------+ +Function decimals() ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ +| | [] | ++----------+--------------+ +Contract SafeTransferLib ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ ++----------+--------------+ + +Function safeTransferFrom(address,address,address,uint256) ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ +| token | [] | +| from | [] | +| to | [] | +| amount | [] | +| success | ['token'] | ++----------+--------------+ +Function safeTransfer(address,address,uint256) ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ +| token | [] | +| to | [] | +| amount | [] | +| success | ['token'] | ++----------+--------------+ +INFO:Printers: +Contract IErrorsRegistries ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ ++----------+--------------+ + +Contract ERC721 ++------------------+----------------------------+ +| Variable | Dependencies | ++------------------+----------------------------+ +| name | ['_name'] | +| symbol | ['_symbol'] | +| _ownerOf | ['_ownerOf', 'to'] | +| _balanceOf | ['_balanceOf'] | +| getApproved | ['getApproved', 'spender'] | +| isApprovedForAll | ['isApprovedForAll'] | ++------------------+----------------------------+ + +Function tokenURI(uint256) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| id | [] | +| | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function ownerOf(uint256) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| id | [] | +| owner | ['_ownerOf'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf'] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function balanceOf(address) ++-------------------------+----------------+ +| Variable | Dependencies | ++-------------------------+----------------+ +| owner | [] | +| | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | ['_balanceOf'] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+----------------+ +Function constructor(string,string) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| _name | [] | +| _symbol | [] | +| ERC721.name | ['_name'] | +| ERC721.symbol | ['_symbol'] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function approve(address,uint256) ++-------------------------+----------------------------+ +| Variable | Dependencies | ++-------------------------+----------------------------+ +| spender | [] | +| id | [] | +| owner | ['_ownerOf'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf'] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | ['getApproved', 'spender'] | +| ERC721.isApprovedForAll | ['isApprovedForAll'] | ++-------------------------+----------------------------+ +Function setApprovalForAll(address,bool) ++-------------------------+----------------------+ +| Variable | Dependencies | ++-------------------------+----------------------+ +| operator | [] | +| approved | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | ['isApprovedForAll'] | ++-------------------------+----------------------+ +Function transferFrom(address,address,uint256) ++-------------------------+----------------------+ +| Variable | Dependencies | ++-------------------------+----------------------+ +| from | ['from'] | +| to | ['to'] | +| id | ['id'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf', 'to'] | +| ERC721._balanceOf | ['_balanceOf'] | +| ERC721.getApproved | ['getApproved'] | +| ERC721.isApprovedForAll | ['isApprovedForAll'] | ++-------------------------+----------------------+ +Function safeTransferFrom(address,address,uint256) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| from | [] | +| to | [] | +| id | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function safeTransferFrom(address,address,uint256,bytes) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| from | [] | +| to | [] | +| id | [] | +| data | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function supportsInterface(bytes4) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| interfaceId | [] | +| | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function _mint(address,uint256) ++-------------------------+--------------------+ +| Variable | Dependencies | ++-------------------------+--------------------+ +| to | ['to'] | +| id | ['id'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf', 'to'] | +| ERC721._balanceOf | ['_balanceOf'] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------------+ +Function _burn(uint256) ++-------------------------+-----------------+ +| Variable | Dependencies | ++-------------------------+-----------------+ +| id | [] | +| owner | ['_ownerOf'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf'] | +| ERC721._balanceOf | ['_balanceOf'] | +| ERC721.getApproved | ['getApproved'] | +| ERC721.isApprovedForAll | [] | ++-------------------------+-----------------+ +Function _safeMint(address,uint256) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| to | [] | +| id | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function _safeMint(address,uint256,bytes) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| to | [] | +| id | [] | +| data | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Contract ERC721TokenReceiver ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ ++----------+--------------+ + +Function onERC721Received(address,address,uint256,bytes) ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ +| | [] | ++----------+--------------+ +Contract IMultisig ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ ++----------+--------------+ + +Function nonce() ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ +| | [] | ++----------+--------------+ +Contract IService ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ ++----------+--------------+ + +Function safeTransferFrom(address,address,uint256) ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ +| from | [] | +| to | [] | +| id | [] | ++----------+--------------+ +Function mapServices(uint256) ++----------------------+--------------+ +| Variable | Dependencies | ++----------------------+--------------+ +| serviceId | [] | +| securityDeposit | [] | +| multisig | [] | +| configHash | [] | +| threshold | [] | +| maxNumAgentInstances | [] | +| numAgentInstances | [] | +| state | [] | ++----------------------+--------------+ +Function getUnitIdsOfService(IService.UnitType,uint256) ++------------+--------------+ +| Variable | Dependencies | ++------------+--------------+ +| unitType | [] | +| serviceId | [] | +| numUnitIds | [] | +| unitIds | [] | ++------------+--------------+ +Contract ServiceStakingBase ++-------------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ +| Variable | Dependencies | ++-------------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ +| VERSION | [] | +| maxNumServices | ['_stakingParams', 'maxNumServices'] | +| rewardsPerSecond | ['_stakingParams', 'rewardsPerSecond'] | +| minStakingDeposit | ['_stakingParams', 'minStakingDeposit'] | +| livenessPeriod | ['_stakingParams', 'livenessPeriod'] | +| livenessRatio | ['_stakingParams', 'livenessRatio'] | +| numAgentInstances | ['_stakingParams', 'numAgentInstances'] | +| threshold | ['_stakingParams', 'threshold'] | +| configHash | ['_stakingParams', 'configHash'] | +| serviceRegistry | ['_serviceRegistry', 'serviceRegistry'] | +| balance | [] | +| availableRewards | ['TUPLE_2', 'availableRewards', 'lastAvailableRewards', 'totalRewards'] | +| tsCheckpoint | ['block.timestamp', 'tsCheckpoint'] | +| agentIds | ['_stakingParams', 'agentId', 'agentIds'] | +| mapServiceInfo | ['TUPLE_0', '_serviceRegistry', 'block.timestamp', 'mapServiceInfo', 'msg.sender', 'multisig', 'nonce', 'sInfo', 'serviceId', 'serviceRegistry'] | +| setServiceIds | ['serviceId', 'setServiceIds'] | ++-------------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ + +Function constructor(ServiceStakingBase.StakingParams,address) ++--------------------------------------+-------------------------------------------+ +| Variable | Dependencies | ++--------------------------------------+-------------------------------------------+ +| _stakingParams | ['_stakingParams'] | +| _serviceRegistry | ['_serviceRegistry'] | +| size | ['_stakingParams'] | +| agentId | ['_stakingParams', 'agentId'] | +| i | ['i'] | +| ServiceStakingBase.VERSION | [] | +| ServiceStakingBase.maxNumServices | ['_stakingParams'] | +| ServiceStakingBase.rewardsPerSecond | ['_stakingParams'] | +| ServiceStakingBase.minStakingDeposit | ['_stakingParams'] | +| ServiceStakingBase.livenessPeriod | ['_stakingParams'] | +| ServiceStakingBase.livenessRatio | ['_stakingParams'] | +| ServiceStakingBase.numAgentInstances | ['_stakingParams'] | +| ServiceStakingBase.threshold | ['_stakingParams'] | +| ServiceStakingBase.configHash | ['_stakingParams'] | +| ServiceStakingBase.serviceRegistry | ['_serviceRegistry'] | +| ServiceStakingBase.balance | [] | +| ServiceStakingBase.availableRewards | [] | +| ServiceStakingBase.tsCheckpoint | ['block.timestamp'] | +| ServiceStakingBase.agentIds | ['_stakingParams', 'agentId', 'agentIds'] | +| ServiceStakingBase.mapServiceInfo | [] | +| ServiceStakingBase.setServiceIds | [] | ++--------------------------------------+-------------------------------------------+ +Function _checkTokenStakingDeposit(uint256,uint256) ++--------------------------------------+-----------------------+ +| Variable | Dependencies | ++--------------------------------------+-----------------------+ +| | [] | +| stakingDeposit | ['stakingDeposit'] | +| ServiceStakingBase.VERSION | [] | +| ServiceStakingBase.maxNumServices | [] | +| ServiceStakingBase.rewardsPerSecond | [] | +| ServiceStakingBase.minStakingDeposit | ['minStakingDeposit'] | +| ServiceStakingBase.livenessPeriod | [] | +| ServiceStakingBase.livenessRatio | [] | +| ServiceStakingBase.numAgentInstances | [] | +| ServiceStakingBase.threshold | [] | +| ServiceStakingBase.configHash | [] | +| ServiceStakingBase.serviceRegistry | [] | +| ServiceStakingBase.balance | [] | +| ServiceStakingBase.availableRewards | [] | +| ServiceStakingBase.tsCheckpoint | [] | +| ServiceStakingBase.agentIds | [] | +| ServiceStakingBase.mapServiceInfo | [] | +| ServiceStakingBase.setServiceIds | [] | ++--------------------------------------+-----------------------+ +Function _withdraw(address,uint256) ++--------------------------------------+--------------+ +| Variable | Dependencies | ++--------------------------------------+--------------+ +| to | [] | +| amount | [] | +| ServiceStakingBase.VERSION | [] | +| ServiceStakingBase.maxNumServices | [] | +| ServiceStakingBase.rewardsPerSecond | [] | +| ServiceStakingBase.minStakingDeposit | [] | +| ServiceStakingBase.livenessPeriod | [] | +| ServiceStakingBase.livenessRatio | [] | +| ServiceStakingBase.numAgentInstances | [] | +| ServiceStakingBase.threshold | [] | +| ServiceStakingBase.configHash | [] | +| ServiceStakingBase.serviceRegistry | [] | +| ServiceStakingBase.balance | [] | +| ServiceStakingBase.availableRewards | [] | +| ServiceStakingBase.tsCheckpoint | [] | +| ServiceStakingBase.agentIds | [] | +| ServiceStakingBase.mapServiceInfo | [] | +| ServiceStakingBase.setServiceIds | [] | ++--------------------------------------+--------------+ +Function stake(uint256) ++--------------------------------------+------------------------------------------------------------------------------------------------------------------------------+ +| Variable | Dependencies | ++--------------------------------------+------------------------------------------------------------------------------------------------------------------------------+ +| serviceId | [] | +| numStakingServices | ['serviceId', 'setServiceIds'] | +| stakingDeposit | ['TUPLE_0', 'serviceId', 'serviceRegistry'] | +| multisig | ['TUPLE_0', 'serviceId', 'serviceRegistry'] | +| hash | ['TUPLE_0', 'serviceId', 'serviceRegistry'] | +| agentThreshold | ['TUPLE_0', 'serviceId', 'serviceRegistry'] | +| maxNumInstances | ['TUPLE_0', 'serviceId', 'serviceRegistry'] | +| state | ['TUPLE_0', 'serviceId', 'serviceRegistry'] | +| size | ['agentIds'] | +| numAgents | ['IService', 'TUPLE_1', 'serviceId', 'serviceRegistry'] | +| agents | ['IService', 'TUPLE_1', 'agents', 'serviceId', 'serviceRegistry'] | +| i | ['i'] | +| sInfo | ['TUPLE_0', 'block.timestamp', 'msg.sender', 'multisig', 'nonce', 'sInfo', 'serviceId', 'serviceRegistry'] | +| nonce | ['TUPLE_0', 'multisig', 'serviceId', 'serviceRegistry'] | +| ServiceStakingBase.VERSION | [] | +| ServiceStakingBase.maxNumServices | ['maxNumServices'] | +| ServiceStakingBase.rewardsPerSecond | [] | +| ServiceStakingBase.minStakingDeposit | [] | +| ServiceStakingBase.livenessPeriod | [] | +| ServiceStakingBase.livenessRatio | [] | +| ServiceStakingBase.numAgentInstances | ['numAgentInstances'] | +| ServiceStakingBase.threshold | ['threshold'] | +| ServiceStakingBase.configHash | ['configHash'] | +| ServiceStakingBase.serviceRegistry | ['serviceRegistry'] | +| ServiceStakingBase.balance | [] | +| ServiceStakingBase.availableRewards | ['availableRewards'] | +| ServiceStakingBase.tsCheckpoint | [] | +| ServiceStakingBase.agentIds | ['agentIds'] | +| ServiceStakingBase.mapServiceInfo | ['TUPLE_0', 'block.timestamp', 'mapServiceInfo', 'msg.sender', 'multisig', 'nonce', 'sInfo', 'serviceId', 'serviceRegistry'] | +| ServiceStakingBase.setServiceIds | ['serviceId', 'setServiceIds'] | ++--------------------------------------+------------------------------------------------------------------------------------------------------------------------------+ +Function _calculateStakingRewards() ++--------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| Variable | Dependencies | ++--------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| lastAvailableRewards | ['availableRewards'] | +| numServices | ['numServices'] | +| totalRewards | ['block.timestamp', 'curInfo', 'reward', 'rewardsPerSecond', 'serviceCheckpoint', 'totalRewards', 'ts', 'tsCheckpoint', 'tsCheckpointLast'] | +| eligibleServiceIds | ['eligibleServiceIds', 'serviceIds', 'setServiceIds', 'size'] | +| eligibleServiceRewards | ['block.timestamp', 'curInfo', 'eligibleServiceRewards', 'reward', 'rewardsPerSecond', 'serviceCheckpoint', 'setServiceIds', 'size', 'ts', 'tsCheckpoint', 'tsCheckpointLast'] | +| serviceIds | ['serviceIds', 'setServiceIds', 'size'] | +| serviceNonces | ['curInfo', 'serviceNonces', 'setServiceIds', 'size'] | +| size | ['setServiceIds'] | +| i | ['i'] | +| tsCheckpointLast | ['tsCheckpoint'] | +| i_scope_0 | ['i_scope_0'] | +| curInfo | ['curInfo'] | +| serviceCheckpoint | ['curInfo', 'serviceCheckpoint', 'ts', 'tsCheckpoint', 'tsCheckpointLast'] | +| ts | ['block.timestamp', 'curInfo', 'serviceCheckpoint', 'ts', 'tsCheckpoint', 'tsCheckpointLast'] | +| ratio | ['block.timestamp', 'curInfo', 'ratio', 'serviceCheckpoint', 'serviceNonces', 'setServiceIds', 'size', 'ts', 'tsCheckpoint', 'tsCheckpointLast'] | +| reward | ['block.timestamp', 'curInfo', 'rewardsPerSecond', 'serviceCheckpoint', 'ts', 'tsCheckpoint', 'tsCheckpointLast'] | +| ServiceStakingBase.VERSION | [] | +| ServiceStakingBase.maxNumServices | [] | +| ServiceStakingBase.rewardsPerSecond | ['rewardsPerSecond'] | +| ServiceStakingBase.minStakingDeposit | [] | +| ServiceStakingBase.livenessPeriod | ['livenessPeriod'] | +| ServiceStakingBase.livenessRatio | ['livenessRatio'] | +| ServiceStakingBase.numAgentInstances | [] | +| ServiceStakingBase.threshold | [] | +| ServiceStakingBase.configHash | [] | +| ServiceStakingBase.serviceRegistry | [] | +| ServiceStakingBase.balance | [] | +| ServiceStakingBase.availableRewards | ['availableRewards'] | +| ServiceStakingBase.tsCheckpoint | ['tsCheckpoint'] | +| ServiceStakingBase.agentIds | [] | +| ServiceStakingBase.mapServiceInfo | ['mapServiceInfo'] | +| ServiceStakingBase.setServiceIds | ['setServiceIds'] | ++--------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +Function checkpoint() ++--------------------------------------+-----------------------------------------------------------------------------------------------------------------------+ +| Variable | Dependencies | ++--------------------------------------+-----------------------------------------------------------------------------------------------------------------------+ +| | [] | +| success | ['success'] | +| lastAvailableRewards | ['TUPLE_2', 'lastAvailableRewards', 'totalRewards'] | +| numServices | ['TUPLE_2'] | +| totalRewards | ['TUPLE_2'] | +| eligibleServiceIds | ['TUPLE_2', 'eligibleServiceIds'] | +| eligibleServiceRewards | ['TUPLE_2', 'eligibleServiceRewards'] | +| serviceIds | ['TUPLE_2', 'serviceIds'] | +| serviceNonces | ['TUPLE_2', 'serviceNonces'] | +| updatedReward | ['TUPLE_2', 'eligibleServiceRewards', 'lastAvailableRewards', 'totalRewards', 'updatedReward', 'updatedTotalRewards'] | +| updatedTotalRewards | ['TUPLE_2', 'eligibleServiceRewards', 'lastAvailableRewards', 'totalRewards', 'updatedReward', 'updatedTotalRewards'] | +| curServiceId | ['TUPLE_2', 'eligibleServiceIds'] | +| i | ['i'] | +| i_scope_0 | ['i_scope_0'] | +| curServiceId_scope_1 | ['TUPLE_2', 'eligibleServiceIds'] | +| i_scope_2 | ['i_scope_2'] | +| curServiceId_scope_3 | ['TUPLE_2', 'serviceIds'] | +| ServiceStakingBase.VERSION | [] | +| ServiceStakingBase.maxNumServices | [] | +| ServiceStakingBase.rewardsPerSecond | [] | +| ServiceStakingBase.minStakingDeposit | [] | +| ServiceStakingBase.livenessPeriod | [] | +| ServiceStakingBase.livenessRatio | [] | +| ServiceStakingBase.numAgentInstances | [] | +| ServiceStakingBase.threshold | [] | +| ServiceStakingBase.configHash | [] | +| ServiceStakingBase.serviceRegistry | [] | +| ServiceStakingBase.balance | [] | +| ServiceStakingBase.availableRewards | ['TUPLE_2', 'lastAvailableRewards', 'totalRewards'] | +| ServiceStakingBase.tsCheckpoint | ['block.timestamp'] | +| ServiceStakingBase.agentIds | [] | +| ServiceStakingBase.mapServiceInfo | ['mapServiceInfo'] | +| ServiceStakingBase.setServiceIds | [] | ++--------------------------------------+-----------------------------------------------------------------------------------------------------------------------+ +Function unstake(uint256) ++--------------------------------------+----------------------------------------------------------------------------------------------------------------------+ +| Variable | Dependencies | ++--------------------------------------+----------------------------------------------------------------------------------------------------------------------+ +| serviceId | [] | +| sInfo | ['mapServiceInfo', 'sInfo'] | +| serviceIds | ['TUPLE_3', 'eligibleServiceIds', 'eligibleServiceRewards', 'numServices', 'serviceIds', 'serviceNonces', 'success'] | +| idx | ['idx'] | +| ServiceStakingBase.VERSION | [] | +| ServiceStakingBase.maxNumServices | [] | +| ServiceStakingBase.rewardsPerSecond | [] | +| ServiceStakingBase.minStakingDeposit | [] | +| ServiceStakingBase.livenessPeriod | [] | +| ServiceStakingBase.livenessRatio | [] | +| ServiceStakingBase.numAgentInstances | [] | +| ServiceStakingBase.threshold | [] | +| ServiceStakingBase.configHash | [] | +| ServiceStakingBase.serviceRegistry | ['serviceRegistry'] | +| ServiceStakingBase.balance | [] | +| ServiceStakingBase.availableRewards | [] | +| ServiceStakingBase.tsCheckpoint | [] | +| ServiceStakingBase.agentIds | [] | +| ServiceStakingBase.mapServiceInfo | ['mapServiceInfo'] | +| ServiceStakingBase.setServiceIds | ['setServiceIds'] | ++--------------------------------------+----------------------------------------------------------------------------------------------------------------------+ +Function calculateServiceStakingReward(uint256) ++--------------------------------------+--------------------------------------------------------------------------------------------------------------------+ +| Variable | Dependencies | ++--------------------------------------+--------------------------------------------------------------------------------------------------------------------+ +| serviceId | [] | +| reward | ['TUPLE_4', 'eligibleServiceRewards', 'lastAvailableRewards', 'mapServiceInfo', 'reward', 'sInfo', 'totalRewards'] | +| sInfo | ['mapServiceInfo', 'sInfo'] | +| lastAvailableRewards | ['TUPLE_4'] | +| numServices | ['TUPLE_4'] | +| totalRewards | ['TUPLE_4'] | +| eligibleServiceIds | ['TUPLE_4', 'eligibleServiceIds'] | +| eligibleServiceRewards | ['TUPLE_4', 'eligibleServiceRewards'] | +| i | ['i'] | +| ServiceStakingBase.VERSION | [] | +| ServiceStakingBase.maxNumServices | [] | +| ServiceStakingBase.rewardsPerSecond | [] | +| ServiceStakingBase.minStakingDeposit | [] | +| ServiceStakingBase.livenessPeriod | [] | +| ServiceStakingBase.livenessRatio | [] | +| ServiceStakingBase.numAgentInstances | [] | +| ServiceStakingBase.threshold | [] | +| ServiceStakingBase.configHash | [] | +| ServiceStakingBase.serviceRegistry | [] | +| ServiceStakingBase.balance | [] | +| ServiceStakingBase.availableRewards | [] | +| ServiceStakingBase.tsCheckpoint | [] | +| ServiceStakingBase.agentIds | [] | +| ServiceStakingBase.mapServiceInfo | ['mapServiceInfo'] | +| ServiceStakingBase.setServiceIds | [] | ++--------------------------------------+--------------------------------------------------------------------------------------------------------------------+ +Function slitherConstructorConstantVariables() ++--------------------------------------+--------------+ +| Variable | Dependencies | ++--------------------------------------+--------------+ +| ServiceStakingBase.VERSION | [] | +| ServiceStakingBase.maxNumServices | [] | +| ServiceStakingBase.rewardsPerSecond | [] | +| ServiceStakingBase.minStakingDeposit | [] | +| ServiceStakingBase.livenessPeriod | [] | +| ServiceStakingBase.livenessRatio | [] | +| ServiceStakingBase.numAgentInstances | [] | +| ServiceStakingBase.threshold | [] | +| ServiceStakingBase.configHash | [] | +| ServiceStakingBase.serviceRegistry | [] | +| ServiceStakingBase.balance | [] | +| ServiceStakingBase.availableRewards | [] | +| ServiceStakingBase.tsCheckpoint | [] | +| ServiceStakingBase.agentIds | [] | +| ServiceStakingBase.mapServiceInfo | [] | +| ServiceStakingBase.setServiceIds | [] | ++--------------------------------------+--------------+ +Contract IToken ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ ++----------+--------------+ + +Function balanceOf(address) ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ +| account | [] | +| | [] | ++----------+--------------+ +Function ownerOf(uint256) ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ +| tokenId | [] | +| | [] | ++----------+--------------+ +Function totalSupply() ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ +| | [] | ++----------+--------------+ +Function transfer(address,uint256) ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ +| to | [] | +| amount | [] | +| | [] | ++----------+--------------+ +Function allowance(address,address) ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ +| owner | [] | +| spender | [] | +| | [] | ++----------+--------------+ +Function approve(address,uint256) ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ +| spender | [] | +| amount | [] | +| | [] | ++----------+--------------+ +Function transferFrom(address,address,uint256) ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ +| from | [] | +| to | [] | +| amount | [] | +| | [] | ++----------+--------------+ +Function decimals() ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ +| | [] | ++----------+--------------+ +Contract SafeTransferLib ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ ++----------+--------------+ + +Function safeTransferFrom(address,address,address,uint256) ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ +| token | [] | +| from | [] | +| to | [] | +| amount | [] | +| success | ['token'] | ++----------+--------------+ +Function safeTransfer(address,address,uint256) ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ +| token | [] | +| to | [] | +| amount | [] | +| success | ['token'] | ++----------+--------------+ +Contract IServiceTokenUtility ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ ++----------+--------------+ + +Function mapServiceIdTokenDeposit(uint256) ++-----------+--------------+ +| Variable | Dependencies | ++-----------+--------------+ +| serviceId | [] | +| | [] | ++-----------+--------------+ +INFO:Printers: +Contract IErrorsRegistries ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ ++----------+--------------+ + +Contract ERC721 ++------------------+----------------------------+ +| Variable | Dependencies | ++------------------+----------------------------+ +| name | ['_name'] | +| symbol | ['_symbol'] | +| _ownerOf | ['_ownerOf', 'to'] | +| _balanceOf | ['_balanceOf'] | +| getApproved | ['getApproved', 'spender'] | +| isApprovedForAll | ['isApprovedForAll'] | ++------------------+----------------------------+ + +Function tokenURI(uint256) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| id | [] | +| | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function ownerOf(uint256) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| id | [] | +| owner | ['_ownerOf'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf'] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function balanceOf(address) ++-------------------------+----------------+ +| Variable | Dependencies | ++-------------------------+----------------+ +| owner | [] | +| | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | ['_balanceOf'] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+----------------+ +Function constructor(string,string) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| _name | [] | +| _symbol | [] | +| ERC721.name | ['_name'] | +| ERC721.symbol | ['_symbol'] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function approve(address,uint256) ++-------------------------+----------------------------+ +| Variable | Dependencies | ++-------------------------+----------------------------+ +| spender | [] | +| id | [] | +| owner | ['_ownerOf'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf'] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | ['getApproved', 'spender'] | +| ERC721.isApprovedForAll | ['isApprovedForAll'] | ++-------------------------+----------------------------+ +Function setApprovalForAll(address,bool) ++-------------------------+----------------------+ +| Variable | Dependencies | ++-------------------------+----------------------+ +| operator | [] | +| approved | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | ['isApprovedForAll'] | ++-------------------------+----------------------+ +Function transferFrom(address,address,uint256) ++-------------------------+----------------------+ +| Variable | Dependencies | ++-------------------------+----------------------+ +| from | ['from'] | +| to | ['to'] | +| id | ['id'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf', 'to'] | +| ERC721._balanceOf | ['_balanceOf'] | +| ERC721.getApproved | ['getApproved'] | +| ERC721.isApprovedForAll | ['isApprovedForAll'] | ++-------------------------+----------------------+ +Function safeTransferFrom(address,address,uint256) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| from | [] | +| to | [] | +| id | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function safeTransferFrom(address,address,uint256,bytes) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| from | [] | +| to | [] | +| id | [] | +| data | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function supportsInterface(bytes4) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| interfaceId | [] | +| | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function _mint(address,uint256) ++-------------------------+--------------------+ +| Variable | Dependencies | ++-------------------------+--------------------+ +| to | ['to'] | +| id | ['id'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf', 'to'] | +| ERC721._balanceOf | ['_balanceOf'] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------------+ +Function _burn(uint256) ++-------------------------+-----------------+ +| Variable | Dependencies | ++-------------------------+-----------------+ +| id | [] | +| owner | ['_ownerOf'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf'] | +| ERC721._balanceOf | ['_balanceOf'] | +| ERC721.getApproved | ['getApproved'] | +| ERC721.isApprovedForAll | [] | ++-------------------------+-----------------+ +Function _safeMint(address,uint256) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| to | [] | +| id | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function _safeMint(address,uint256,bytes) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| to | [] | +| id | [] | +| data | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Contract ERC721TokenReceiver ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ ++----------+--------------+ + +Function onERC721Received(address,address,uint256,bytes) ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ +| | [] | ++----------+--------------+ +Contract IMultisig ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ ++----------+--------------+ + +Function nonce() ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ +| | [] | ++----------+--------------+ +Contract IService ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ ++----------+--------------+ + +Function safeTransferFrom(address,address,uint256) ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ +| from | [] | +| to | [] | +| id | [] | ++----------+--------------+ +Function mapServices(uint256) ++----------------------+--------------+ +| Variable | Dependencies | ++----------------------+--------------+ +| serviceId | [] | +| securityDeposit | [] | +| multisig | [] | +| configHash | [] | +| threshold | [] | +| maxNumAgentInstances | [] | +| numAgentInstances | [] | +| state | [] | ++----------------------+--------------+ +Function getUnitIdsOfService(IService.UnitType,uint256) ++------------+--------------+ +| Variable | Dependencies | ++------------+--------------+ +| unitType | [] | +| serviceId | [] | +| numUnitIds | [] | +| unitIds | [] | ++------------+--------------+ +Contract ServiceStakingBase ++-------------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ +| Variable | Dependencies | ++-------------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ +| VERSION | [] | +| maxNumServices | ['_stakingParams', 'maxNumServices'] | +| rewardsPerSecond | ['_stakingParams', 'rewardsPerSecond'] | +| minStakingDeposit | ['_stakingParams', 'minStakingDeposit'] | +| livenessPeriod | ['_stakingParams', 'livenessPeriod'] | +| livenessRatio | ['_stakingParams', 'livenessRatio'] | +| numAgentInstances | ['_stakingParams', 'numAgentInstances'] | +| threshold | ['_stakingParams', 'threshold'] | +| configHash | ['_stakingParams', 'configHash'] | +| serviceRegistry | ['_serviceRegistry', 'serviceRegistry'] | +| balance | [] | +| availableRewards | ['TUPLE_2', 'availableRewards', 'lastAvailableRewards', 'totalRewards'] | +| tsCheckpoint | ['block.timestamp', 'tsCheckpoint'] | +| agentIds | ['_stakingParams', 'agentId', 'agentIds'] | +| mapServiceInfo | ['TUPLE_0', '_serviceRegistry', 'block.timestamp', 'mapServiceInfo', 'msg.sender', 'multisig', 'nonce', 'sInfo', 'serviceId', 'serviceRegistry'] | +| setServiceIds | ['serviceId', 'setServiceIds'] | ++-------------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ + +Function constructor(ServiceStakingBase.StakingParams,address) ++--------------------------------------+-------------------------------------------+ +| Variable | Dependencies | ++--------------------------------------+-------------------------------------------+ +| _stakingParams | ['_stakingParams'] | +| _serviceRegistry | ['_serviceRegistry'] | +| size | ['_stakingParams'] | +| agentId | ['_stakingParams', 'agentId'] | +| i | ['i'] | +| ServiceStakingBase.VERSION | [] | +| ServiceStakingBase.maxNumServices | ['_stakingParams'] | +| ServiceStakingBase.rewardsPerSecond | ['_stakingParams'] | +| ServiceStakingBase.minStakingDeposit | ['_stakingParams'] | +| ServiceStakingBase.livenessPeriod | ['_stakingParams'] | +| ServiceStakingBase.livenessRatio | ['_stakingParams'] | +| ServiceStakingBase.numAgentInstances | ['_stakingParams'] | +| ServiceStakingBase.threshold | ['_stakingParams'] | +| ServiceStakingBase.configHash | ['_stakingParams'] | +| ServiceStakingBase.serviceRegistry | ['_serviceRegistry'] | +| ServiceStakingBase.balance | [] | +| ServiceStakingBase.availableRewards | [] | +| ServiceStakingBase.tsCheckpoint | ['block.timestamp'] | +| ServiceStakingBase.agentIds | ['_stakingParams', 'agentId', 'agentIds'] | +| ServiceStakingBase.mapServiceInfo | [] | +| ServiceStakingBase.setServiceIds | [] | ++--------------------------------------+-------------------------------------------+ +Function _checkTokenStakingDeposit(uint256,uint256) ++--------------------------------------+-----------------------+ +| Variable | Dependencies | ++--------------------------------------+-----------------------+ +| | [] | +| stakingDeposit | ['stakingDeposit'] | +| ServiceStakingBase.VERSION | [] | +| ServiceStakingBase.maxNumServices | [] | +| ServiceStakingBase.rewardsPerSecond | [] | +| ServiceStakingBase.minStakingDeposit | ['minStakingDeposit'] | +| ServiceStakingBase.livenessPeriod | [] | +| ServiceStakingBase.livenessRatio | [] | +| ServiceStakingBase.numAgentInstances | [] | +| ServiceStakingBase.threshold | [] | +| ServiceStakingBase.configHash | [] | +| ServiceStakingBase.serviceRegistry | [] | +| ServiceStakingBase.balance | [] | +| ServiceStakingBase.availableRewards | [] | +| ServiceStakingBase.tsCheckpoint | [] | +| ServiceStakingBase.agentIds | [] | +| ServiceStakingBase.mapServiceInfo | [] | +| ServiceStakingBase.setServiceIds | [] | ++--------------------------------------+-----------------------+ +Function _withdraw(address,uint256) ++--------------------------------------+--------------+ +| Variable | Dependencies | ++--------------------------------------+--------------+ +| to | [] | +| amount | [] | +| ServiceStakingBase.VERSION | [] | +| ServiceStakingBase.maxNumServices | [] | +| ServiceStakingBase.rewardsPerSecond | [] | +| ServiceStakingBase.minStakingDeposit | [] | +| ServiceStakingBase.livenessPeriod | [] | +| ServiceStakingBase.livenessRatio | [] | +| ServiceStakingBase.numAgentInstances | [] | +| ServiceStakingBase.threshold | [] | +| ServiceStakingBase.configHash | [] | +| ServiceStakingBase.serviceRegistry | [] | +| ServiceStakingBase.balance | [] | +| ServiceStakingBase.availableRewards | [] | +| ServiceStakingBase.tsCheckpoint | [] | +| ServiceStakingBase.agentIds | [] | +| ServiceStakingBase.mapServiceInfo | [] | +| ServiceStakingBase.setServiceIds | [] | ++--------------------------------------+--------------+ +Function stake(uint256) ++--------------------------------------+------------------------------------------------------------------------------------------------------------------------------+ +| Variable | Dependencies | ++--------------------------------------+------------------------------------------------------------------------------------------------------------------------------+ +| serviceId | [] | +| numStakingServices | ['serviceId', 'setServiceIds'] | +| stakingDeposit | ['TUPLE_0', 'serviceId', 'serviceRegistry'] | +| multisig | ['TUPLE_0', 'serviceId', 'serviceRegistry'] | +| hash | ['TUPLE_0', 'serviceId', 'serviceRegistry'] | +| agentThreshold | ['TUPLE_0', 'serviceId', 'serviceRegistry'] | +| maxNumInstances | ['TUPLE_0', 'serviceId', 'serviceRegistry'] | +| state | ['TUPLE_0', 'serviceId', 'serviceRegistry'] | +| size | ['agentIds'] | +| numAgents | ['IService', 'TUPLE_1', 'serviceId', 'serviceRegistry'] | +| agents | ['IService', 'TUPLE_1', 'agents', 'serviceId', 'serviceRegistry'] | +| i | ['i'] | +| sInfo | ['TUPLE_0', 'block.timestamp', 'msg.sender', 'multisig', 'nonce', 'sInfo', 'serviceId', 'serviceRegistry'] | +| nonce | ['TUPLE_0', 'multisig', 'serviceId', 'serviceRegistry'] | +| ServiceStakingBase.VERSION | [] | +| ServiceStakingBase.maxNumServices | ['maxNumServices'] | +| ServiceStakingBase.rewardsPerSecond | [] | +| ServiceStakingBase.minStakingDeposit | [] | +| ServiceStakingBase.livenessPeriod | [] | +| ServiceStakingBase.livenessRatio | [] | +| ServiceStakingBase.numAgentInstances | ['numAgentInstances'] | +| ServiceStakingBase.threshold | ['threshold'] | +| ServiceStakingBase.configHash | ['configHash'] | +| ServiceStakingBase.serviceRegistry | ['serviceRegistry'] | +| ServiceStakingBase.balance | [] | +| ServiceStakingBase.availableRewards | ['availableRewards'] | +| ServiceStakingBase.tsCheckpoint | [] | +| ServiceStakingBase.agentIds | ['agentIds'] | +| ServiceStakingBase.mapServiceInfo | ['TUPLE_0', 'block.timestamp', 'mapServiceInfo', 'msg.sender', 'multisig', 'nonce', 'sInfo', 'serviceId', 'serviceRegistry'] | +| ServiceStakingBase.setServiceIds | ['serviceId', 'setServiceIds'] | ++--------------------------------------+------------------------------------------------------------------------------------------------------------------------------+ +Function _calculateStakingRewards() ++--------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| Variable | Dependencies | ++--------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| lastAvailableRewards | ['availableRewards'] | +| numServices | ['numServices'] | +| totalRewards | ['block.timestamp', 'curInfo', 'reward', 'rewardsPerSecond', 'serviceCheckpoint', 'totalRewards', 'ts', 'tsCheckpoint', 'tsCheckpointLast'] | +| eligibleServiceIds | ['eligibleServiceIds', 'serviceIds', 'setServiceIds', 'size'] | +| eligibleServiceRewards | ['block.timestamp', 'curInfo', 'eligibleServiceRewards', 'reward', 'rewardsPerSecond', 'serviceCheckpoint', 'setServiceIds', 'size', 'ts', 'tsCheckpoint', 'tsCheckpointLast'] | +| serviceIds | ['serviceIds', 'setServiceIds', 'size'] | +| serviceNonces | ['curInfo', 'serviceNonces', 'setServiceIds', 'size'] | +| size | ['setServiceIds'] | +| i | ['i'] | +| tsCheckpointLast | ['tsCheckpoint'] | +| i_scope_0 | ['i_scope_0'] | +| curInfo | ['curInfo'] | +| serviceCheckpoint | ['curInfo', 'serviceCheckpoint', 'ts', 'tsCheckpoint', 'tsCheckpointLast'] | +| ts | ['block.timestamp', 'curInfo', 'serviceCheckpoint', 'ts', 'tsCheckpoint', 'tsCheckpointLast'] | +| ratio | ['block.timestamp', 'curInfo', 'ratio', 'serviceCheckpoint', 'serviceNonces', 'setServiceIds', 'size', 'ts', 'tsCheckpoint', 'tsCheckpointLast'] | +| reward | ['block.timestamp', 'curInfo', 'rewardsPerSecond', 'serviceCheckpoint', 'ts', 'tsCheckpoint', 'tsCheckpointLast'] | +| ServiceStakingBase.VERSION | [] | +| ServiceStakingBase.maxNumServices | [] | +| ServiceStakingBase.rewardsPerSecond | ['rewardsPerSecond'] | +| ServiceStakingBase.minStakingDeposit | [] | +| ServiceStakingBase.livenessPeriod | ['livenessPeriod'] | +| ServiceStakingBase.livenessRatio | ['livenessRatio'] | +| ServiceStakingBase.numAgentInstances | [] | +| ServiceStakingBase.threshold | [] | +| ServiceStakingBase.configHash | [] | +| ServiceStakingBase.serviceRegistry | [] | +| ServiceStakingBase.balance | [] | +| ServiceStakingBase.availableRewards | ['availableRewards'] | +| ServiceStakingBase.tsCheckpoint | ['tsCheckpoint'] | +| ServiceStakingBase.agentIds | [] | +| ServiceStakingBase.mapServiceInfo | ['mapServiceInfo'] | +| ServiceStakingBase.setServiceIds | ['setServiceIds'] | ++--------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +Function checkpoint() ++--------------------------------------+-----------------------------------------------------------------------------------------------------------------------+ +| Variable | Dependencies | ++--------------------------------------+-----------------------------------------------------------------------------------------------------------------------+ +| | [] | +| success | ['success'] | +| lastAvailableRewards | ['TUPLE_2', 'lastAvailableRewards', 'totalRewards'] | +| numServices | ['TUPLE_2'] | +| totalRewards | ['TUPLE_2'] | +| eligibleServiceIds | ['TUPLE_2', 'eligibleServiceIds'] | +| eligibleServiceRewards | ['TUPLE_2', 'eligibleServiceRewards'] | +| serviceIds | ['TUPLE_2', 'serviceIds'] | +| serviceNonces | ['TUPLE_2', 'serviceNonces'] | +| updatedReward | ['TUPLE_2', 'eligibleServiceRewards', 'lastAvailableRewards', 'totalRewards', 'updatedReward', 'updatedTotalRewards'] | +| updatedTotalRewards | ['TUPLE_2', 'eligibleServiceRewards', 'lastAvailableRewards', 'totalRewards', 'updatedReward', 'updatedTotalRewards'] | +| curServiceId | ['TUPLE_2', 'eligibleServiceIds'] | +| i | ['i'] | +| i_scope_0 | ['i_scope_0'] | +| curServiceId_scope_1 | ['TUPLE_2', 'eligibleServiceIds'] | +| i_scope_2 | ['i_scope_2'] | +| curServiceId_scope_3 | ['TUPLE_2', 'serviceIds'] | +| ServiceStakingBase.VERSION | [] | +| ServiceStakingBase.maxNumServices | [] | +| ServiceStakingBase.rewardsPerSecond | [] | +| ServiceStakingBase.minStakingDeposit | [] | +| ServiceStakingBase.livenessPeriod | [] | +| ServiceStakingBase.livenessRatio | [] | +| ServiceStakingBase.numAgentInstances | [] | +| ServiceStakingBase.threshold | [] | +| ServiceStakingBase.configHash | [] | +| ServiceStakingBase.serviceRegistry | [] | +| ServiceStakingBase.balance | [] | +| ServiceStakingBase.availableRewards | ['TUPLE_2', 'lastAvailableRewards', 'totalRewards'] | +| ServiceStakingBase.tsCheckpoint | ['block.timestamp'] | +| ServiceStakingBase.agentIds | [] | +| ServiceStakingBase.mapServiceInfo | ['mapServiceInfo'] | +| ServiceStakingBase.setServiceIds | [] | ++--------------------------------------+-----------------------------------------------------------------------------------------------------------------------+ +Function unstake(uint256) ++--------------------------------------+----------------------------------------------------------------------------------------------------------------------+ +| Variable | Dependencies | ++--------------------------------------+----------------------------------------------------------------------------------------------------------------------+ +| serviceId | [] | +| sInfo | ['mapServiceInfo', 'sInfo'] | +| serviceIds | ['TUPLE_3', 'eligibleServiceIds', 'eligibleServiceRewards', 'numServices', 'serviceIds', 'serviceNonces', 'success'] | +| idx | ['idx'] | +| ServiceStakingBase.VERSION | [] | +| ServiceStakingBase.maxNumServices | [] | +| ServiceStakingBase.rewardsPerSecond | [] | +| ServiceStakingBase.minStakingDeposit | [] | +| ServiceStakingBase.livenessPeriod | [] | +| ServiceStakingBase.livenessRatio | [] | +| ServiceStakingBase.numAgentInstances | [] | +| ServiceStakingBase.threshold | [] | +| ServiceStakingBase.configHash | [] | +| ServiceStakingBase.serviceRegistry | ['serviceRegistry'] | +| ServiceStakingBase.balance | [] | +| ServiceStakingBase.availableRewards | [] | +| ServiceStakingBase.tsCheckpoint | [] | +| ServiceStakingBase.agentIds | [] | +| ServiceStakingBase.mapServiceInfo | ['mapServiceInfo'] | +| ServiceStakingBase.setServiceIds | ['setServiceIds'] | ++--------------------------------------+----------------------------------------------------------------------------------------------------------------------+ +Function calculateServiceStakingReward(uint256) ++--------------------------------------+--------------------------------------------------------------------------------------------------------------------+ +| Variable | Dependencies | ++--------------------------------------+--------------------------------------------------------------------------------------------------------------------+ +| serviceId | [] | +| reward | ['TUPLE_4', 'eligibleServiceRewards', 'lastAvailableRewards', 'mapServiceInfo', 'reward', 'sInfo', 'totalRewards'] | +| sInfo | ['mapServiceInfo', 'sInfo'] | +| lastAvailableRewards | ['TUPLE_4'] | +| numServices | ['TUPLE_4'] | +| totalRewards | ['TUPLE_4'] | +| eligibleServiceIds | ['TUPLE_4', 'eligibleServiceIds'] | +| eligibleServiceRewards | ['TUPLE_4', 'eligibleServiceRewards'] | +| i | ['i'] | +| ServiceStakingBase.VERSION | [] | +| ServiceStakingBase.maxNumServices | [] | +| ServiceStakingBase.rewardsPerSecond | [] | +| ServiceStakingBase.minStakingDeposit | [] | +| ServiceStakingBase.livenessPeriod | [] | +| ServiceStakingBase.livenessRatio | [] | +| ServiceStakingBase.numAgentInstances | [] | +| ServiceStakingBase.threshold | [] | +| ServiceStakingBase.configHash | [] | +| ServiceStakingBase.serviceRegistry | [] | +| ServiceStakingBase.balance | [] | +| ServiceStakingBase.availableRewards | [] | +| ServiceStakingBase.tsCheckpoint | [] | +| ServiceStakingBase.agentIds | [] | +| ServiceStakingBase.mapServiceInfo | ['mapServiceInfo'] | +| ServiceStakingBase.setServiceIds | [] | ++--------------------------------------+--------------------------------------------------------------------------------------------------------------------+ +Function slitherConstructorConstantVariables() ++--------------------------------------+--------------+ +| Variable | Dependencies | ++--------------------------------------+--------------+ +| ServiceStakingBase.VERSION | [] | +| ServiceStakingBase.maxNumServices | [] | +| ServiceStakingBase.rewardsPerSecond | [] | +| ServiceStakingBase.minStakingDeposit | [] | +| ServiceStakingBase.livenessPeriod | [] | +| ServiceStakingBase.livenessRatio | [] | +| ServiceStakingBase.numAgentInstances | [] | +| ServiceStakingBase.threshold | [] | +| ServiceStakingBase.configHash | [] | +| ServiceStakingBase.serviceRegistry | [] | +| ServiceStakingBase.balance | [] | +| ServiceStakingBase.availableRewards | [] | +| ServiceStakingBase.tsCheckpoint | [] | +| ServiceStakingBase.agentIds | [] | +| ServiceStakingBase.mapServiceInfo | [] | +| ServiceStakingBase.setServiceIds | [] | ++--------------------------------------+--------------+ +Contract IToken ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ ++----------+--------------+ + +Function balanceOf(address) ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ +| account | [] | +| | [] | ++----------+--------------+ +Function ownerOf(uint256) ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ +| tokenId | [] | +| | [] | ++----------+--------------+ +Function totalSupply() ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ +| | [] | ++----------+--------------+ +Function transfer(address,uint256) ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ +| to | [] | +| amount | [] | +| | [] | ++----------+--------------+ +Function allowance(address,address) ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ +| owner | [] | +| spender | [] | +| | [] | ++----------+--------------+ +Function approve(address,uint256) ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ +| spender | [] | +| amount | [] | +| | [] | ++----------+--------------+ +Function transferFrom(address,address,uint256) ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ +| from | [] | +| to | [] | +| amount | [] | +| | [] | ++----------+--------------+ +Function decimals() ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ +| | [] | ++----------+--------------+ +Contract SafeTransferLib ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ ++----------+--------------+ + +Function safeTransferFrom(address,address,address,uint256) ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ +| token | [] | +| from | [] | +| to | [] | +| amount | [] | +| success | ['token'] | ++----------+--------------+ +Function safeTransfer(address,address,uint256) ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ +| token | [] | +| to | [] | +| amount | [] | +| success | ['token'] | ++----------+--------------+ +Contract IServiceTokenUtility ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ ++----------+--------------+ + +Function mapServiceIdTokenDeposit(uint256) ++-----------+--------------+ +| Variable | Dependencies | ++-----------+--------------+ +| serviceId | [] | +| | [] | ++-----------+--------------+ +Contract ServiceStakingToken ++-----------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| Variable | Dependencies | ++-----------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| VERSION | [] | +| maxNumServices | ['_stakingParams', 'maxNumServices'] | +| rewardsPerSecond | ['_stakingParams', 'rewardsPerSecond'] | +| minStakingDeposit | ['_stakingParams', 'minStakingDeposit'] | +| livenessPeriod | ['_stakingParams', 'livenessPeriod'] | +| livenessRatio | ['_stakingParams', 'livenessRatio'] | +| numAgentInstances | ['_stakingParams', 'numAgentInstances'] | +| threshold | ['_stakingParams', 'threshold'] | +| configHash | ['_stakingParams', 'configHash'] | +| serviceRegistry | ['_serviceRegistry', 'serviceRegistry'] | +| balance | ['TUPLE_5', '_serviceRegistry', 'amount', 'balance', 'block.timestamp', 'mapServiceInfo', 'msg.sender', 'multisig', 'newBalance', 'nonce', 'sInfo', 'serviceId', 'serviceRegistry'] | +| availableRewards | ['TUPLE_7', 'amount', 'availableRewards', 'lastAvailableRewards', 'newAvailableRewards', 'totalRewards'] | +| tsCheckpoint | ['block.timestamp', 'tsCheckpoint'] | +| agentIds | ['_stakingParams', 'agentId', 'agentIds'] | +| mapServiceInfo | ['TUPLE_5', '_serviceRegistry', 'block.timestamp', 'mapServiceInfo', 'msg.sender', 'multisig', 'nonce', 'sInfo', 'serviceId', 'serviceRegistry'] | +| setServiceIds | ['serviceId', 'setServiceIds'] | +| serviceRegistryTokenUtility | ['_serviceRegistryTokenUtility', 'serviceRegistryTokenUtility'] | +| stakingToken | ['_stakingToken', 'stakingToken'] | ++-----------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ + +Function constructor(ServiceStakingBase.StakingParams,address,address,address) ++-------------------------------------------------+----------------------------------+ +| Variable | Dependencies | ++-------------------------------------------------+----------------------------------+ +| _stakingParams | [] | +| _serviceRegistry | [] | +| _serviceRegistryTokenUtility | [] | +| _stakingToken | [] | +| ServiceStakingBase.VERSION | [] | +| ServiceStakingBase.maxNumServices | [] | +| ServiceStakingBase.rewardsPerSecond | [] | +| ServiceStakingBase.minStakingDeposit | [] | +| ServiceStakingBase.livenessPeriod | [] | +| ServiceStakingBase.livenessRatio | [] | +| ServiceStakingBase.numAgentInstances | [] | +| ServiceStakingBase.threshold | [] | +| ServiceStakingBase.configHash | [] | +| ServiceStakingBase.serviceRegistry | [] | +| ServiceStakingBase.balance | [] | +| ServiceStakingBase.availableRewards | [] | +| ServiceStakingBase.tsCheckpoint | [] | +| ServiceStakingBase.agentIds | [] | +| ServiceStakingBase.mapServiceInfo | [] | +| ServiceStakingBase.setServiceIds | [] | +| ServiceStakingToken.serviceRegistryTokenUtility | ['_serviceRegistryTokenUtility'] | +| ServiceStakingToken.stakingToken | ['_stakingToken'] | ++-------------------------------------------------+----------------------------------+ +Function _checkTokenStakingDeposit(uint256,uint256) ++-------------------------------------------------+----------------------------------------------------------+ +| Variable | Dependencies | ++-------------------------------------------------+----------------------------------------------------------+ +| serviceId | ['serviceId'] | +| | [] | +| token | ['TUPLE_10', 'serviceId', 'serviceRegistryTokenUtility'] | +| stakingDeposit | ['TUPLE_10', 'serviceId', 'serviceRegistryTokenUtility'] | +| ServiceStakingBase.VERSION | [] | +| ServiceStakingBase.maxNumServices | [] | +| ServiceStakingBase.rewardsPerSecond | [] | +| ServiceStakingBase.minStakingDeposit | ['minStakingDeposit'] | +| ServiceStakingBase.livenessPeriod | [] | +| ServiceStakingBase.livenessRatio | [] | +| ServiceStakingBase.numAgentInstances | [] | +| ServiceStakingBase.threshold | [] | +| ServiceStakingBase.configHash | [] | +| ServiceStakingBase.serviceRegistry | [] | +| ServiceStakingBase.balance | [] | +| ServiceStakingBase.availableRewards | [] | +| ServiceStakingBase.tsCheckpoint | [] | +| ServiceStakingBase.agentIds | [] | +| ServiceStakingBase.mapServiceInfo | [] | +| ServiceStakingBase.setServiceIds | [] | +| ServiceStakingToken.serviceRegistryTokenUtility | ['serviceRegistryTokenUtility'] | +| ServiceStakingToken.stakingToken | ['stakingToken'] | ++-------------------------------------------------+----------------------------------------------------------+ +Function _withdraw(address,uint256) ++-------------------------------------------------+-----------------------+ +| Variable | Dependencies | ++-------------------------------------------------+-----------------------+ +| to | [] | +| amount | [] | +| ServiceStakingBase.VERSION | [] | +| ServiceStakingBase.maxNumServices | [] | +| ServiceStakingBase.rewardsPerSecond | [] | +| ServiceStakingBase.minStakingDeposit | [] | +| ServiceStakingBase.livenessPeriod | [] | +| ServiceStakingBase.livenessRatio | [] | +| ServiceStakingBase.numAgentInstances | [] | +| ServiceStakingBase.threshold | [] | +| ServiceStakingBase.configHash | [] | +| ServiceStakingBase.serviceRegistry | [] | +| ServiceStakingBase.balance | ['amount', 'balance'] | +| ServiceStakingBase.availableRewards | [] | +| ServiceStakingBase.tsCheckpoint | [] | +| ServiceStakingBase.agentIds | [] | +| ServiceStakingBase.mapServiceInfo | [] | +| ServiceStakingBase.setServiceIds | [] | +| ServiceStakingToken.serviceRegistryTokenUtility | [] | +| ServiceStakingToken.stakingToken | ['stakingToken'] | ++-------------------------------------------------+-----------------------+ +Function deposit(uint256) ++-------------------------------------------------+-------------------------------------------------------+ +| Variable | Dependencies | ++-------------------------------------------------+-------------------------------------------------------+ +| amount | [] | +| newBalance | ['amount', 'balance'] | +| newAvailableRewards | ['amount', 'availableRewards'] | +| ServiceStakingBase.VERSION | [] | +| ServiceStakingBase.maxNumServices | [] | +| ServiceStakingBase.rewardsPerSecond | [] | +| ServiceStakingBase.minStakingDeposit | [] | +| ServiceStakingBase.livenessPeriod | [] | +| ServiceStakingBase.livenessRatio | [] | +| ServiceStakingBase.numAgentInstances | [] | +| ServiceStakingBase.threshold | [] | +| ServiceStakingBase.configHash | [] | +| ServiceStakingBase.serviceRegistry | [] | +| ServiceStakingBase.balance | ['amount', 'balance', 'newBalance'] | +| ServiceStakingBase.availableRewards | ['amount', 'availableRewards', 'newAvailableRewards'] | +| ServiceStakingBase.tsCheckpoint | [] | +| ServiceStakingBase.agentIds | [] | +| ServiceStakingBase.mapServiceInfo | [] | +| ServiceStakingBase.setServiceIds | [] | +| ServiceStakingToken.serviceRegistryTokenUtility | [] | +| ServiceStakingToken.stakingToken | ['stakingToken'] | ++-------------------------------------------------+-------------------------------------------------------+ +Function slitherConstructorConstantVariables() ++-------------------------------------------------+--------------+ +| Variable | Dependencies | ++-------------------------------------------------+--------------+ +| ServiceStakingBase.VERSION | [] | +| ServiceStakingBase.maxNumServices | [] | +| ServiceStakingBase.rewardsPerSecond | [] | +| ServiceStakingBase.minStakingDeposit | [] | +| ServiceStakingBase.livenessPeriod | [] | +| ServiceStakingBase.livenessRatio | [] | +| ServiceStakingBase.numAgentInstances | [] | +| ServiceStakingBase.threshold | [] | +| ServiceStakingBase.configHash | [] | +| ServiceStakingBase.serviceRegistry | [] | +| ServiceStakingBase.balance | [] | +| ServiceStakingBase.availableRewards | [] | +| ServiceStakingBase.tsCheckpoint | [] | +| ServiceStakingBase.agentIds | [] | +| ServiceStakingBase.mapServiceInfo | [] | +| ServiceStakingBase.setServiceIds | [] | +| ServiceStakingToken.serviceRegistryTokenUtility | [] | +| ServiceStakingToken.stakingToken | [] | ++-------------------------------------------------+--------------+ +INFO:Printers: +Contract IErrorsRegistries ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ ++----------+--------------+ + +INFO:Printers: +Contract IErrorsRegistries ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ ++----------+--------------+ + +Contract ERC721 ++------------------+----------------------------+ +| Variable | Dependencies | ++------------------+----------------------------+ +| name | ['_name'] | +| symbol | ['_symbol'] | +| _ownerOf | ['_ownerOf', 'to'] | +| _balanceOf | ['_balanceOf'] | +| getApproved | ['getApproved', 'spender'] | +| isApprovedForAll | ['isApprovedForAll'] | ++------------------+----------------------------+ + +Function tokenURI(uint256) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| id | [] | +| | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function ownerOf(uint256) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| id | [] | +| owner | ['_ownerOf'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf'] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function balanceOf(address) ++-------------------------+----------------+ +| Variable | Dependencies | ++-------------------------+----------------+ +| owner | [] | +| | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | ['_balanceOf'] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+----------------+ +Function constructor(string,string) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| _name | [] | +| _symbol | [] | +| ERC721.name | ['_name'] | +| ERC721.symbol | ['_symbol'] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function approve(address,uint256) ++-------------------------+----------------------------+ +| Variable | Dependencies | ++-------------------------+----------------------------+ +| spender | [] | +| id | [] | +| owner | ['_ownerOf'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf'] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | ['getApproved', 'spender'] | +| ERC721.isApprovedForAll | ['isApprovedForAll'] | ++-------------------------+----------------------------+ +Function setApprovalForAll(address,bool) ++-------------------------+----------------------+ +| Variable | Dependencies | ++-------------------------+----------------------+ +| operator | [] | +| approved | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | ['isApprovedForAll'] | ++-------------------------+----------------------+ +Function transferFrom(address,address,uint256) ++-------------------------+----------------------+ +| Variable | Dependencies | ++-------------------------+----------------------+ +| from | ['from'] | +| to | ['to'] | +| id | ['id'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf', 'to'] | +| ERC721._balanceOf | ['_balanceOf'] | +| ERC721.getApproved | ['getApproved'] | +| ERC721.isApprovedForAll | ['isApprovedForAll'] | ++-------------------------+----------------------+ +Function safeTransferFrom(address,address,uint256) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| from | [] | +| to | [] | +| id | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function safeTransferFrom(address,address,uint256,bytes) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| from | [] | +| to | [] | +| id | [] | +| data | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function supportsInterface(bytes4) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| interfaceId | [] | +| | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function _mint(address,uint256) ++-------------------------+--------------------+ +| Variable | Dependencies | ++-------------------------+--------------------+ +| to | ['to'] | +| id | ['id'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf', 'to'] | +| ERC721._balanceOf | ['_balanceOf'] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------------+ +Function _burn(uint256) ++-------------------------+-----------------+ +| Variable | Dependencies | ++-------------------------+-----------------+ +| id | [] | +| owner | ['_ownerOf'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf'] | +| ERC721._balanceOf | ['_balanceOf'] | +| ERC721.getApproved | ['getApproved'] | +| ERC721.isApprovedForAll | [] | ++-------------------------+-----------------+ +Function _safeMint(address,uint256) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| to | [] | +| id | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function _safeMint(address,uint256,bytes) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| to | [] | +| id | [] | +| data | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +INFO:Printers: +Contract IErrorsRegistries ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ ++----------+--------------+ + +Contract ERC721 ++------------------+----------------------------+ +| Variable | Dependencies | ++------------------+----------------------------+ +| name | ['_name'] | +| symbol | ['_symbol'] | +| _ownerOf | ['_ownerOf', 'to'] | +| _balanceOf | ['_balanceOf'] | +| getApproved | ['getApproved', 'spender'] | +| isApprovedForAll | ['isApprovedForAll'] | ++------------------+----------------------------+ + +Function tokenURI(uint256) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| id | [] | +| | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function ownerOf(uint256) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| id | [] | +| owner | ['_ownerOf'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf'] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function balanceOf(address) ++-------------------------+----------------+ +| Variable | Dependencies | ++-------------------------+----------------+ +| owner | [] | +| | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | ['_balanceOf'] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+----------------+ +Function constructor(string,string) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| _name | [] | +| _symbol | [] | +| ERC721.name | ['_name'] | +| ERC721.symbol | ['_symbol'] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function approve(address,uint256) ++-------------------------+----------------------------+ +| Variable | Dependencies | ++-------------------------+----------------------------+ +| spender | [] | +| id | [] | +| owner | ['_ownerOf'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf'] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | ['getApproved', 'spender'] | +| ERC721.isApprovedForAll | ['isApprovedForAll'] | ++-------------------------+----------------------------+ +Function setApprovalForAll(address,bool) ++-------------------------+----------------------+ +| Variable | Dependencies | ++-------------------------+----------------------+ +| operator | [] | +| approved | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | ['isApprovedForAll'] | ++-------------------------+----------------------+ +Function transferFrom(address,address,uint256) ++-------------------------+----------------------+ +| Variable | Dependencies | ++-------------------------+----------------------+ +| from | ['from'] | +| to | ['to'] | +| id | ['id'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf', 'to'] | +| ERC721._balanceOf | ['_balanceOf'] | +| ERC721.getApproved | ['getApproved'] | +| ERC721.isApprovedForAll | ['isApprovedForAll'] | ++-------------------------+----------------------+ +Function safeTransferFrom(address,address,uint256) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| from | [] | +| to | [] | +| id | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function safeTransferFrom(address,address,uint256,bytes) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| from | [] | +| to | [] | +| id | [] | +| data | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function supportsInterface(bytes4) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| interfaceId | [] | +| | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function _mint(address,uint256) ++-------------------------+--------------------+ +| Variable | Dependencies | ++-------------------------+--------------------+ +| to | ['to'] | +| id | ['id'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf', 'to'] | +| ERC721._balanceOf | ['_balanceOf'] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------------+ +Function _burn(uint256) ++-------------------------+-----------------+ +| Variable | Dependencies | ++-------------------------+-----------------+ +| id | [] | +| owner | ['_ownerOf'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf'] | +| ERC721._balanceOf | ['_balanceOf'] | +| ERC721.getApproved | ['getApproved'] | +| ERC721.isApprovedForAll | [] | ++-------------------------+-----------------+ +Function _safeMint(address,uint256) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| to | [] | +| id | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function _safeMint(address,uint256,bytes) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| to | [] | +| id | [] | +| data | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Contract ERC721TokenReceiver ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ ++----------+--------------+ + +Function onERC721Received(address,address,uint256,bytes) ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ +| | [] | ++----------+--------------+ +INFO:Printers: +Contract IErrorsRegistries ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ ++----------+--------------+ + +Contract ERC721 ++------------------+----------------------------+ +| Variable | Dependencies | ++------------------+----------------------------+ +| name | ['_name'] | +| symbol | ['_symbol'] | +| _ownerOf | ['_ownerOf', 'to'] | +| _balanceOf | ['_balanceOf'] | +| getApproved | ['getApproved', 'spender'] | +| isApprovedForAll | ['isApprovedForAll'] | ++------------------+----------------------------+ + +Function tokenURI(uint256) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| id | [] | +| | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function ownerOf(uint256) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| id | [] | +| owner | ['_ownerOf'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf'] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function balanceOf(address) ++-------------------------+----------------+ +| Variable | Dependencies | ++-------------------------+----------------+ +| owner | [] | +| | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | ['_balanceOf'] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+----------------+ +Function constructor(string,string) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| _name | [] | +| _symbol | [] | +| ERC721.name | ['_name'] | +| ERC721.symbol | ['_symbol'] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function approve(address,uint256) ++-------------------------+----------------------------+ +| Variable | Dependencies | ++-------------------------+----------------------------+ +| spender | [] | +| id | [] | +| owner | ['_ownerOf'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf'] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | ['getApproved', 'spender'] | +| ERC721.isApprovedForAll | ['isApprovedForAll'] | ++-------------------------+----------------------------+ +Function setApprovalForAll(address,bool) ++-------------------------+----------------------+ +| Variable | Dependencies | ++-------------------------+----------------------+ +| operator | [] | +| approved | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | ['isApprovedForAll'] | ++-------------------------+----------------------+ +Function transferFrom(address,address,uint256) ++-------------------------+----------------------+ +| Variable | Dependencies | ++-------------------------+----------------------+ +| from | ['from'] | +| to | ['to'] | +| id | ['id'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf', 'to'] | +| ERC721._balanceOf | ['_balanceOf'] | +| ERC721.getApproved | ['getApproved'] | +| ERC721.isApprovedForAll | ['isApprovedForAll'] | ++-------------------------+----------------------+ +Function safeTransferFrom(address,address,uint256) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| from | [] | +| to | [] | +| id | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function safeTransferFrom(address,address,uint256,bytes) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| from | [] | +| to | [] | +| id | [] | +| data | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function supportsInterface(bytes4) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| interfaceId | [] | +| | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function _mint(address,uint256) ++-------------------------+--------------------+ +| Variable | Dependencies | ++-------------------------+--------------------+ +| to | ['to'] | +| id | ['id'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf', 'to'] | +| ERC721._balanceOf | ['_balanceOf'] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------------+ +Function _burn(uint256) ++-------------------------+-----------------+ +| Variable | Dependencies | ++-------------------------+-----------------+ +| id | [] | +| owner | ['_ownerOf'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf'] | +| ERC721._balanceOf | ['_balanceOf'] | +| ERC721.getApproved | ['getApproved'] | +| ERC721.isApprovedForAll | [] | ++-------------------------+-----------------+ +Function _safeMint(address,uint256) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| to | [] | +| id | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function _safeMint(address,uint256,bytes) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| to | [] | +| id | [] | +| data | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Contract ERC721TokenReceiver ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ ++----------+--------------+ + +Function onERC721Received(address,address,uint256,bytes) ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ +| | [] | ++----------+--------------+ +Contract IMultisig ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ ++----------+--------------+ + +Function nonce() ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ +| | [] | ++----------+--------------+ +INFO:Printers: +Contract IErrorsRegistries ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ ++----------+--------------+ + +Contract ERC721 ++------------------+----------------------------+ +| Variable | Dependencies | ++------------------+----------------------------+ +| name | ['_name'] | +| symbol | ['_symbol'] | +| _ownerOf | ['_ownerOf', 'to'] | +| _balanceOf | ['_balanceOf'] | +| getApproved | ['getApproved', 'spender'] | +| isApprovedForAll | ['isApprovedForAll'] | ++------------------+----------------------------+ + +Function tokenURI(uint256) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| id | [] | +| | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function ownerOf(uint256) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| id | [] | +| owner | ['_ownerOf'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf'] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function balanceOf(address) ++-------------------------+----------------+ +| Variable | Dependencies | ++-------------------------+----------------+ +| owner | [] | +| | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | ['_balanceOf'] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+----------------+ +Function constructor(string,string) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| _name | [] | +| _symbol | [] | +| ERC721.name | ['_name'] | +| ERC721.symbol | ['_symbol'] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function approve(address,uint256) ++-------------------------+----------------------------+ +| Variable | Dependencies | ++-------------------------+----------------------------+ +| spender | [] | +| id | [] | +| owner | ['_ownerOf'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf'] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | ['getApproved', 'spender'] | +| ERC721.isApprovedForAll | ['isApprovedForAll'] | ++-------------------------+----------------------------+ +Function setApprovalForAll(address,bool) ++-------------------------+----------------------+ +| Variable | Dependencies | ++-------------------------+----------------------+ +| operator | [] | +| approved | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | ['isApprovedForAll'] | ++-------------------------+----------------------+ +Function transferFrom(address,address,uint256) ++-------------------------+----------------------+ +| Variable | Dependencies | ++-------------------------+----------------------+ +| from | ['from'] | +| to | ['to'] | +| id | ['id'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf', 'to'] | +| ERC721._balanceOf | ['_balanceOf'] | +| ERC721.getApproved | ['getApproved'] | +| ERC721.isApprovedForAll | ['isApprovedForAll'] | ++-------------------------+----------------------+ +Function safeTransferFrom(address,address,uint256) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| from | [] | +| to | [] | +| id | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function safeTransferFrom(address,address,uint256,bytes) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| from | [] | +| to | [] | +| id | [] | +| data | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function supportsInterface(bytes4) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| interfaceId | [] | +| | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function _mint(address,uint256) ++-------------------------+--------------------+ +| Variable | Dependencies | ++-------------------------+--------------------+ +| to | ['to'] | +| id | ['id'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf', 'to'] | +| ERC721._balanceOf | ['_balanceOf'] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------------+ +Function _burn(uint256) ++-------------------------+-----------------+ +| Variable | Dependencies | ++-------------------------+-----------------+ +| id | [] | +| owner | ['_ownerOf'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf'] | +| ERC721._balanceOf | ['_balanceOf'] | +| ERC721.getApproved | ['getApproved'] | +| ERC721.isApprovedForAll | [] | ++-------------------------+-----------------+ +Function _safeMint(address,uint256) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| to | [] | +| id | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function _safeMint(address,uint256,bytes) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| to | [] | +| id | [] | +| data | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Contract ERC721TokenReceiver ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ ++----------+--------------+ + +Function onERC721Received(address,address,uint256,bytes) ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ +| | [] | ++----------+--------------+ +Contract IMultisig ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ ++----------+--------------+ + +Function nonce() ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ +| | [] | ++----------+--------------+ +Contract IService ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ ++----------+--------------+ + +Function safeTransferFrom(address,address,uint256) ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ +| from | [] | +| to | [] | +| id | [] | ++----------+--------------+ +Function mapServices(uint256) ++----------------------+--------------+ +| Variable | Dependencies | ++----------------------+--------------+ +| serviceId | [] | +| securityDeposit | [] | +| multisig | [] | +| configHash | [] | +| threshold | [] | +| maxNumAgentInstances | [] | +| numAgentInstances | [] | +| state | [] | ++----------------------+--------------+ +Function getUnitIdsOfService(IService.UnitType,uint256) ++------------+--------------+ +| Variable | Dependencies | ++------------+--------------+ +| unitType | [] | +| serviceId | [] | +| numUnitIds | [] | +| unitIds | [] | ++------------+--------------+ +INFO:Printers: +Contract IErrorsRegistries ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ ++----------+--------------+ + +Contract ERC721 ++------------------+----------------------------+ +| Variable | Dependencies | ++------------------+----------------------------+ +| name | ['_name'] | +| symbol | ['_symbol'] | +| _ownerOf | ['_ownerOf', 'to'] | +| _balanceOf | ['_balanceOf'] | +| getApproved | ['getApproved', 'spender'] | +| isApprovedForAll | ['isApprovedForAll'] | ++------------------+----------------------------+ + +Function tokenURI(uint256) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| id | [] | +| | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function ownerOf(uint256) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| id | [] | +| owner | ['_ownerOf'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf'] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function balanceOf(address) ++-------------------------+----------------+ +| Variable | Dependencies | ++-------------------------+----------------+ +| owner | [] | +| | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | ['_balanceOf'] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+----------------+ +Function constructor(string,string) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| _name | [] | +| _symbol | [] | +| ERC721.name | ['_name'] | +| ERC721.symbol | ['_symbol'] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function approve(address,uint256) ++-------------------------+----------------------------+ +| Variable | Dependencies | ++-------------------------+----------------------------+ +| spender | [] | +| id | [] | +| owner | ['_ownerOf'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf'] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | ['getApproved', 'spender'] | +| ERC721.isApprovedForAll | ['isApprovedForAll'] | ++-------------------------+----------------------------+ +Function setApprovalForAll(address,bool) ++-------------------------+----------------------+ +| Variable | Dependencies | ++-------------------------+----------------------+ +| operator | [] | +| approved | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | ['isApprovedForAll'] | ++-------------------------+----------------------+ +Function transferFrom(address,address,uint256) ++-------------------------+----------------------+ +| Variable | Dependencies | ++-------------------------+----------------------+ +| from | ['from'] | +| to | ['to'] | +| id | ['id'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf', 'to'] | +| ERC721._balanceOf | ['_balanceOf'] | +| ERC721.getApproved | ['getApproved'] | +| ERC721.isApprovedForAll | ['isApprovedForAll'] | ++-------------------------+----------------------+ +Function safeTransferFrom(address,address,uint256) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| from | [] | +| to | [] | +| id | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function safeTransferFrom(address,address,uint256,bytes) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| from | [] | +| to | [] | +| id | [] | +| data | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function supportsInterface(bytes4) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| interfaceId | [] | +| | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function _mint(address,uint256) ++-------------------------+--------------------+ +| Variable | Dependencies | ++-------------------------+--------------------+ +| to | ['to'] | +| id | ['id'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf', 'to'] | +| ERC721._balanceOf | ['_balanceOf'] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------------+ +Function _burn(uint256) ++-------------------------+-----------------+ +| Variable | Dependencies | ++-------------------------+-----------------+ +| id | [] | +| owner | ['_ownerOf'] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | ['_ownerOf'] | +| ERC721._balanceOf | ['_balanceOf'] | +| ERC721.getApproved | ['getApproved'] | +| ERC721.isApprovedForAll | [] | ++-------------------------+-----------------+ +Function _safeMint(address,uint256) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| to | [] | +| id | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Function _safeMint(address,uint256,bytes) ++-------------------------+--------------+ +| Variable | Dependencies | ++-------------------------+--------------+ +| to | [] | +| id | [] | +| data | [] | +| ERC721.name | [] | +| ERC721.symbol | [] | +| ERC721._ownerOf | [] | +| ERC721._balanceOf | [] | +| ERC721.getApproved | [] | +| ERC721.isApprovedForAll | [] | ++-------------------------+--------------+ +Contract ERC721TokenReceiver ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ ++----------+--------------+ + +Function onERC721Received(address,address,uint256,bytes) ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ +| | [] | ++----------+--------------+ +Contract IMultisig ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ ++----------+--------------+ + +Function nonce() ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ +| | [] | ++----------+--------------+ +Contract IService ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ ++----------+--------------+ + +Function safeTransferFrom(address,address,uint256) ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ +| from | [] | +| to | [] | +| id | [] | ++----------+--------------+ +Function mapServices(uint256) ++----------------------+--------------+ +| Variable | Dependencies | ++----------------------+--------------+ +| serviceId | [] | +| securityDeposit | [] | +| multisig | [] | +| configHash | [] | +| threshold | [] | +| maxNumAgentInstances | [] | +| numAgentInstances | [] | +| state | [] | ++----------------------+--------------+ +Function getUnitIdsOfService(IService.UnitType,uint256) ++------------+--------------+ +| Variable | Dependencies | ++------------+--------------+ +| unitType | [] | +| serviceId | [] | +| numUnitIds | [] | +| unitIds | [] | ++------------+--------------+ +Contract ServiceStakingBase ++-------------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ +| Variable | Dependencies | ++-------------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ +| VERSION | [] | +| maxNumServices | ['_stakingParams', 'maxNumServices'] | +| rewardsPerSecond | ['_stakingParams', 'rewardsPerSecond'] | +| minStakingDeposit | ['_stakingParams', 'minStakingDeposit'] | +| livenessPeriod | ['_stakingParams', 'livenessPeriod'] | +| livenessRatio | ['_stakingParams', 'livenessRatio'] | +| numAgentInstances | ['_stakingParams', 'numAgentInstances'] | +| threshold | ['_stakingParams', 'threshold'] | +| configHash | ['_stakingParams', 'configHash'] | +| serviceRegistry | ['_serviceRegistry', 'serviceRegistry'] | +| balance | [] | +| availableRewards | ['TUPLE_2', 'availableRewards', 'lastAvailableRewards', 'totalRewards'] | +| tsCheckpoint | ['block.timestamp', 'tsCheckpoint'] | +| agentIds | ['_stakingParams', 'agentId', 'agentIds'] | +| mapServiceInfo | ['TUPLE_0', '_serviceRegistry', 'block.timestamp', 'mapServiceInfo', 'msg.sender', 'multisig', 'nonce', 'sInfo', 'serviceId', 'serviceRegistry'] | +| setServiceIds | ['serviceId', 'setServiceIds'] | ++-------------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ + +Function constructor(ServiceStakingBase.StakingParams,address) ++--------------------------------------+-------------------------------------------+ +| Variable | Dependencies | ++--------------------------------------+-------------------------------------------+ +| _stakingParams | ['_stakingParams'] | +| _serviceRegistry | [] | +| size | ['_stakingParams'] | +| agentId | ['_stakingParams', 'agentId'] | +| i | ['i'] | +| ServiceStakingBase.VERSION | [] | +| ServiceStakingBase.maxNumServices | ['_stakingParams'] | +| ServiceStakingBase.rewardsPerSecond | ['_stakingParams'] | +| ServiceStakingBase.minStakingDeposit | ['_stakingParams'] | +| ServiceStakingBase.livenessPeriod | ['_stakingParams'] | +| ServiceStakingBase.livenessRatio | ['_stakingParams'] | +| ServiceStakingBase.numAgentInstances | ['_stakingParams'] | +| ServiceStakingBase.threshold | ['_stakingParams'] | +| ServiceStakingBase.configHash | ['_stakingParams'] | +| ServiceStakingBase.serviceRegistry | ['_serviceRegistry'] | +| ServiceStakingBase.balance | [] | +| ServiceStakingBase.availableRewards | [] | +| ServiceStakingBase.tsCheckpoint | ['block.timestamp'] | +| ServiceStakingBase.agentIds | ['_stakingParams', 'agentId', 'agentIds'] | +| ServiceStakingBase.mapServiceInfo | [] | +| ServiceStakingBase.setServiceIds | [] | ++--------------------------------------+-------------------------------------------+ +Function _checkTokenStakingDeposit(uint256,uint256) ++--------------------------------------+-----------------------+ +| Variable | Dependencies | ++--------------------------------------+-----------------------+ +| | [] | +| stakingDeposit | ['stakingDeposit'] | +| ServiceStakingBase.VERSION | [] | +| ServiceStakingBase.maxNumServices | [] | +| ServiceStakingBase.rewardsPerSecond | [] | +| ServiceStakingBase.minStakingDeposit | ['minStakingDeposit'] | +| ServiceStakingBase.livenessPeriod | [] | +| ServiceStakingBase.livenessRatio | [] | +| ServiceStakingBase.numAgentInstances | [] | +| ServiceStakingBase.threshold | [] | +| ServiceStakingBase.configHash | [] | +| ServiceStakingBase.serviceRegistry | [] | +| ServiceStakingBase.balance | [] | +| ServiceStakingBase.availableRewards | [] | +| ServiceStakingBase.tsCheckpoint | [] | +| ServiceStakingBase.agentIds | [] | +| ServiceStakingBase.mapServiceInfo | [] | +| ServiceStakingBase.setServiceIds | [] | ++--------------------------------------+-----------------------+ +Function _withdraw(address,uint256) ++--------------------------------------+--------------+ +| Variable | Dependencies | ++--------------------------------------+--------------+ +| to | [] | +| amount | [] | +| ServiceStakingBase.VERSION | [] | +| ServiceStakingBase.maxNumServices | [] | +| ServiceStakingBase.rewardsPerSecond | [] | +| ServiceStakingBase.minStakingDeposit | [] | +| ServiceStakingBase.livenessPeriod | [] | +| ServiceStakingBase.livenessRatio | [] | +| ServiceStakingBase.numAgentInstances | [] | +| ServiceStakingBase.threshold | [] | +| ServiceStakingBase.configHash | [] | +| ServiceStakingBase.serviceRegistry | [] | +| ServiceStakingBase.balance | [] | +| ServiceStakingBase.availableRewards | [] | +| ServiceStakingBase.tsCheckpoint | [] | +| ServiceStakingBase.agentIds | [] | +| ServiceStakingBase.mapServiceInfo | [] | +| ServiceStakingBase.setServiceIds | [] | ++--------------------------------------+--------------+ +Function stake(uint256) ++--------------------------------------+------------------------------------------------------------------------------------------------------------------------------+ +| Variable | Dependencies | ++--------------------------------------+------------------------------------------------------------------------------------------------------------------------------+ +| serviceId | [] | +| numStakingServices | ['serviceId', 'setServiceIds'] | +| stakingDeposit | ['TUPLE_0', 'serviceId', 'serviceRegistry'] | +| multisig | ['TUPLE_0', 'serviceId', 'serviceRegistry'] | +| hash | ['TUPLE_0', 'serviceId', 'serviceRegistry'] | +| agentThreshold | ['TUPLE_0', 'serviceId', 'serviceRegistry'] | +| maxNumInstances | ['TUPLE_0', 'serviceId', 'serviceRegistry'] | +| state | ['TUPLE_0', 'serviceId', 'serviceRegistry'] | +| size | ['agentIds'] | +| numAgents | ['IService', 'TUPLE_1', 'serviceId', 'serviceRegistry'] | +| agents | ['IService', 'TUPLE_1', 'agents', 'serviceId', 'serviceRegistry'] | +| i | ['i'] | +| sInfo | ['TUPLE_0', 'block.timestamp', 'msg.sender', 'multisig', 'nonce', 'sInfo', 'serviceId', 'serviceRegistry'] | +| nonce | ['TUPLE_0', 'multisig', 'serviceId', 'serviceRegistry'] | +| ServiceStakingBase.VERSION | [] | +| ServiceStakingBase.maxNumServices | ['maxNumServices'] | +| ServiceStakingBase.rewardsPerSecond | [] | +| ServiceStakingBase.minStakingDeposit | [] | +| ServiceStakingBase.livenessPeriod | [] | +| ServiceStakingBase.livenessRatio | [] | +| ServiceStakingBase.numAgentInstances | ['numAgentInstances'] | +| ServiceStakingBase.threshold | ['threshold'] | +| ServiceStakingBase.configHash | ['configHash'] | +| ServiceStakingBase.serviceRegistry | ['serviceRegistry'] | +| ServiceStakingBase.balance | [] | +| ServiceStakingBase.availableRewards | ['availableRewards'] | +| ServiceStakingBase.tsCheckpoint | [] | +| ServiceStakingBase.agentIds | ['agentIds'] | +| ServiceStakingBase.mapServiceInfo | ['TUPLE_0', 'block.timestamp', 'mapServiceInfo', 'msg.sender', 'multisig', 'nonce', 'sInfo', 'serviceId', 'serviceRegistry'] | +| ServiceStakingBase.setServiceIds | ['serviceId', 'setServiceIds'] | ++--------------------------------------+------------------------------------------------------------------------------------------------------------------------------+ +Function _calculateStakingRewards() ++--------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| Variable | Dependencies | ++--------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| lastAvailableRewards | ['availableRewards'] | +| numServices | ['numServices'] | +| totalRewards | ['block.timestamp', 'curInfo', 'reward', 'rewardsPerSecond', 'serviceCheckpoint', 'totalRewards', 'ts', 'tsCheckpoint', 'tsCheckpointLast'] | +| eligibleServiceIds | ['eligibleServiceIds', 'serviceIds', 'setServiceIds', 'size'] | +| eligibleServiceRewards | ['block.timestamp', 'curInfo', 'eligibleServiceRewards', 'reward', 'rewardsPerSecond', 'serviceCheckpoint', 'setServiceIds', 'size', 'ts', 'tsCheckpoint', 'tsCheckpointLast'] | +| serviceIds | ['serviceIds', 'setServiceIds', 'size'] | +| serviceNonces | ['curInfo', 'serviceNonces', 'setServiceIds', 'size'] | +| size | ['setServiceIds'] | +| i | ['i'] | +| tsCheckpointLast | ['tsCheckpoint'] | +| i_scope_0 | ['i_scope_0'] | +| curInfo | ['curInfo'] | +| serviceCheckpoint | ['curInfo', 'serviceCheckpoint', 'ts', 'tsCheckpoint', 'tsCheckpointLast'] | +| ts | ['block.timestamp', 'curInfo', 'serviceCheckpoint', 'ts', 'tsCheckpoint', 'tsCheckpointLast'] | +| ratio | ['block.timestamp', 'curInfo', 'ratio', 'serviceCheckpoint', 'serviceNonces', 'setServiceIds', 'size', 'ts', 'tsCheckpoint', 'tsCheckpointLast'] | +| reward | ['block.timestamp', 'curInfo', 'rewardsPerSecond', 'serviceCheckpoint', 'ts', 'tsCheckpoint', 'tsCheckpointLast'] | +| ServiceStakingBase.VERSION | [] | +| ServiceStakingBase.maxNumServices | [] | +| ServiceStakingBase.rewardsPerSecond | ['rewardsPerSecond'] | +| ServiceStakingBase.minStakingDeposit | [] | +| ServiceStakingBase.livenessPeriod | ['livenessPeriod'] | +| ServiceStakingBase.livenessRatio | ['livenessRatio'] | +| ServiceStakingBase.numAgentInstances | [] | +| ServiceStakingBase.threshold | [] | +| ServiceStakingBase.configHash | [] | +| ServiceStakingBase.serviceRegistry | [] | +| ServiceStakingBase.balance | [] | +| ServiceStakingBase.availableRewards | ['availableRewards'] | +| ServiceStakingBase.tsCheckpoint | ['tsCheckpoint'] | +| ServiceStakingBase.agentIds | [] | +| ServiceStakingBase.mapServiceInfo | ['mapServiceInfo'] | +| ServiceStakingBase.setServiceIds | ['setServiceIds'] | ++--------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +Function checkpoint() ++--------------------------------------+-----------------------------------------------------------------------------------------------------------------------+ +| Variable | Dependencies | ++--------------------------------------+-----------------------------------------------------------------------------------------------------------------------+ +| | [] | +| success | ['success'] | +| lastAvailableRewards | ['TUPLE_2', 'lastAvailableRewards', 'totalRewards'] | +| numServices | ['TUPLE_2'] | +| totalRewards | ['TUPLE_2'] | +| eligibleServiceIds | ['TUPLE_2', 'eligibleServiceIds'] | +| eligibleServiceRewards | ['TUPLE_2', 'eligibleServiceRewards'] | +| serviceIds | ['TUPLE_2', 'serviceIds'] | +| serviceNonces | ['TUPLE_2', 'serviceNonces'] | +| updatedReward | ['TUPLE_2', 'eligibleServiceRewards', 'lastAvailableRewards', 'totalRewards', 'updatedReward', 'updatedTotalRewards'] | +| updatedTotalRewards | ['TUPLE_2', 'eligibleServiceRewards', 'lastAvailableRewards', 'totalRewards', 'updatedReward', 'updatedTotalRewards'] | +| curServiceId | ['TUPLE_2', 'eligibleServiceIds'] | +| i | ['i'] | +| i_scope_0 | ['i_scope_0'] | +| curServiceId_scope_1 | ['TUPLE_2', 'eligibleServiceIds'] | +| i_scope_2 | ['i_scope_2'] | +| curServiceId_scope_3 | ['TUPLE_2', 'serviceIds'] | +| ServiceStakingBase.VERSION | [] | +| ServiceStakingBase.maxNumServices | [] | +| ServiceStakingBase.rewardsPerSecond | [] | +| ServiceStakingBase.minStakingDeposit | [] | +| ServiceStakingBase.livenessPeriod | [] | +| ServiceStakingBase.livenessRatio | [] | +| ServiceStakingBase.numAgentInstances | [] | +| ServiceStakingBase.threshold | [] | +| ServiceStakingBase.configHash | [] | +| ServiceStakingBase.serviceRegistry | [] | +| ServiceStakingBase.balance | [] | +| ServiceStakingBase.availableRewards | ['TUPLE_2', 'lastAvailableRewards', 'totalRewards'] | +| ServiceStakingBase.tsCheckpoint | ['block.timestamp'] | +| ServiceStakingBase.agentIds | [] | +| ServiceStakingBase.mapServiceInfo | ['mapServiceInfo'] | +| ServiceStakingBase.setServiceIds | [] | ++--------------------------------------+-----------------------------------------------------------------------------------------------------------------------+ +Function unstake(uint256) ++--------------------------------------+----------------------------------------------------------------------------------------------------------------------+ +| Variable | Dependencies | ++--------------------------------------+----------------------------------------------------------------------------------------------------------------------+ +| serviceId | [] | +| sInfo | ['mapServiceInfo', 'sInfo'] | +| serviceIds | ['TUPLE_3', 'eligibleServiceIds', 'eligibleServiceRewards', 'numServices', 'serviceIds', 'serviceNonces', 'success'] | +| idx | ['idx'] | +| ServiceStakingBase.VERSION | [] | +| ServiceStakingBase.maxNumServices | [] | +| ServiceStakingBase.rewardsPerSecond | [] | +| ServiceStakingBase.minStakingDeposit | [] | +| ServiceStakingBase.livenessPeriod | [] | +| ServiceStakingBase.livenessRatio | [] | +| ServiceStakingBase.numAgentInstances | [] | +| ServiceStakingBase.threshold | [] | +| ServiceStakingBase.configHash | [] | +| ServiceStakingBase.serviceRegistry | ['serviceRegistry'] | +| ServiceStakingBase.balance | [] | +| ServiceStakingBase.availableRewards | [] | +| ServiceStakingBase.tsCheckpoint | [] | +| ServiceStakingBase.agentIds | [] | +| ServiceStakingBase.mapServiceInfo | ['mapServiceInfo'] | +| ServiceStakingBase.setServiceIds | ['setServiceIds'] | ++--------------------------------------+----------------------------------------------------------------------------------------------------------------------+ +Function calculateServiceStakingReward(uint256) ++--------------------------------------+--------------------------------------------------------------------------------------------------------------------+ +| Variable | Dependencies | ++--------------------------------------+--------------------------------------------------------------------------------------------------------------------+ +| serviceId | [] | +| reward | ['TUPLE_4', 'eligibleServiceRewards', 'lastAvailableRewards', 'mapServiceInfo', 'reward', 'sInfo', 'totalRewards'] | +| sInfo | ['mapServiceInfo', 'sInfo'] | +| lastAvailableRewards | ['TUPLE_4'] | +| numServices | ['TUPLE_4'] | +| totalRewards | ['TUPLE_4'] | +| eligibleServiceIds | ['TUPLE_4', 'eligibleServiceIds'] | +| eligibleServiceRewards | ['TUPLE_4', 'eligibleServiceRewards'] | +| i | ['i'] | +| ServiceStakingBase.VERSION | [] | +| ServiceStakingBase.maxNumServices | [] | +| ServiceStakingBase.rewardsPerSecond | [] | +| ServiceStakingBase.minStakingDeposit | [] | +| ServiceStakingBase.livenessPeriod | [] | +| ServiceStakingBase.livenessRatio | [] | +| ServiceStakingBase.numAgentInstances | [] | +| ServiceStakingBase.threshold | [] | +| ServiceStakingBase.configHash | [] | +| ServiceStakingBase.serviceRegistry | [] | +| ServiceStakingBase.balance | [] | +| ServiceStakingBase.availableRewards | [] | +| ServiceStakingBase.tsCheckpoint | [] | +| ServiceStakingBase.agentIds | [] | +| ServiceStakingBase.mapServiceInfo | ['mapServiceInfo'] | +| ServiceStakingBase.setServiceIds | [] | ++--------------------------------------+--------------------------------------------------------------------------------------------------------------------+ +Function slitherConstructorConstantVariables() ++--------------------------------------+--------------+ +| Variable | Dependencies | ++--------------------------------------+--------------+ +| ServiceStakingBase.VERSION | [] | +| ServiceStakingBase.maxNumServices | [] | +| ServiceStakingBase.rewardsPerSecond | [] | +| ServiceStakingBase.minStakingDeposit | [] | +| ServiceStakingBase.livenessPeriod | [] | +| ServiceStakingBase.livenessRatio | [] | +| ServiceStakingBase.numAgentInstances | [] | +| ServiceStakingBase.threshold | [] | +| ServiceStakingBase.configHash | [] | +| ServiceStakingBase.serviceRegistry | [] | +| ServiceStakingBase.balance | [] | +| ServiceStakingBase.availableRewards | [] | +| ServiceStakingBase.tsCheckpoint | [] | +| ServiceStakingBase.agentIds | [] | +| ServiceStakingBase.mapServiceInfo | [] | +| ServiceStakingBase.setServiceIds | [] | ++--------------------------------------+--------------+ +INFO:Slither:. analyzed (23 contracts) diff --git a/audits/internal4/analysis/slither_full.txt b/audits/internal4/analysis/slither_full.txt new file mode 100644 index 00000000..8394f7ab --- /dev/null +++ b/audits/internal4/analysis/slither_full.txt @@ -0,0 +1,1226 @@ +Notes: False positive. _withdraw is internal function under control above logic +INFO:Detectors: +ServiceStakingNativeToken._withdraw(address,uint256) (ServiceStakingNativeToken-flatten.sol#899-909) sends eth to arbitrary user + Dangerous calls: + - (result) = to.call{value: amount}() (ServiceStakingNativeToken-flatten.sol#905) +Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#functions-that-send-ether-to-arbitrary-destinations + +Notes: False positive. Non-readonly-reentrancy +INFO:Detectors: +Potential vulnerable to readonly-reentrancy function (if read in other function) ServiceStakingBase.calculateServiceStakingReward(uint256) (ServiceStakingNativeToken-flatten.sol#850-879): + State variables read that were written after the external call(s): + - ServiceStakingBase.mapServiceInfo (ServiceStakingNativeToken-flatten.sol#504) was read at sInfo = mapServiceInfo[serviceId] (ServiceStakingNativeToken-flatten.sol#852) + This variable was written at (after external call): + - delete mapServiceInfo[serviceId] (ServiceStakingNativeToken-flatten.sol#838) + - sInfo.multisig = multisig (ServiceStakingNativeToken-flatten.sol#626) + - sInfo.owner = msg.sender (ServiceStakingNativeToken-flatten.sol#627) + - sInfo.nonce = nonce (ServiceStakingNativeToken-flatten.sol#629) + - sInfo.tsStart = block.timestamp (ServiceStakingNativeToken-flatten.sol#630) + - ServiceStakingBase.mapServiceInfo (ServiceStakingNativeToken-flatten.sol#504) was read at reward = sInfo.reward (ServiceStakingNativeToken-flatten.sol#853) + This variable was written at (after external call): + - delete mapServiceInfo[serviceId] (ServiceStakingNativeToken-flatten.sol#838) + - sInfo.multisig = multisig (ServiceStakingNativeToken-flatten.sol#626) + - sInfo.owner = msg.sender (ServiceStakingNativeToken-flatten.sol#627) + - sInfo.nonce = nonce (ServiceStakingNativeToken-flatten.sol#629) + - sInfo.tsStart = block.timestamp (ServiceStakingNativeToken-flatten.sol#630) + - ServiceStakingBase.mapServiceInfo (ServiceStakingNativeToken-flatten.sol#504) was read at sInfo.tsStart == 0 (ServiceStakingNativeToken-flatten.sol#856) + This variable was written at (after external call): + - delete mapServiceInfo[serviceId] (ServiceStakingNativeToken-flatten.sol#838) + - sInfo.multisig = multisig (ServiceStakingNativeToken-flatten.sol#626) + - sInfo.owner = msg.sender (ServiceStakingNativeToken-flatten.sol#627) + - sInfo.nonce = nonce (ServiceStakingNativeToken-flatten.sol#629) + - sInfo.tsStart = block.timestamp (ServiceStakingNativeToken-flatten.sol#630) + - ServiceStakingBase.mapServiceInfo (ServiceStakingNativeToken-flatten.sol#504) was read at revert ServiceNotStaked(uint256)(serviceId) (ServiceStakingNativeToken-flatten.sol#857) + This variable was written at (after external call): + - delete mapServiceInfo[serviceId] (ServiceStakingNativeToken-flatten.sol#838) + - sInfo.multisig = multisig (ServiceStakingNativeToken-flatten.sol#626) + - sInfo.owner = msg.sender (ServiceStakingNativeToken-flatten.sol#627) + - sInfo.nonce = nonce (ServiceStakingNativeToken-flatten.sol#629) + - sInfo.tsStart = block.timestamp (ServiceStakingNativeToken-flatten.sol#630) + - ServiceStakingBase.mapServiceInfo (ServiceStakingNativeToken-flatten.sol#504) was read at END_IF (ServiceStakingNativeToken-flatten.sol#856-858) + This variable was written at (after external call): + - delete mapServiceInfo[serviceId] (ServiceStakingNativeToken-flatten.sol#838) + - sInfo.multisig = multisig (ServiceStakingNativeToken-flatten.sol#626) + - sInfo.owner = msg.sender (ServiceStakingNativeToken-flatten.sol#627) + - sInfo.nonce = nonce (ServiceStakingNativeToken-flatten.sol#629) + - sInfo.tsStart = block.timestamp (ServiceStakingNativeToken-flatten.sol#630) + - ServiceStakingBase.mapServiceInfo (ServiceStakingNativeToken-flatten.sol#504) was read at NEW VARIABLE lastAvailableRewards (ServiceStakingNativeToken-flatten.sol#861) + This variable was written at (after external call): + - delete mapServiceInfo[serviceId] (ServiceStakingNativeToken-flatten.sol#838) + - sInfo.multisig = multisig (ServiceStakingNativeToken-flatten.sol#626) + - sInfo.owner = msg.sender (ServiceStakingNativeToken-flatten.sol#627) + - sInfo.nonce = nonce (ServiceStakingNativeToken-flatten.sol#629) + - sInfo.tsStart = block.timestamp (ServiceStakingNativeToken-flatten.sol#630) + - ServiceStakingBase.mapServiceInfo (ServiceStakingNativeToken-flatten.sol#504) was read at NEW VARIABLE numServices (ServiceStakingNativeToken-flatten.sol#861) + This variable was written at (after external call): + - delete mapServiceInfo[serviceId] (ServiceStakingNativeToken-flatten.sol#838) + - sInfo.multisig = multisig (ServiceStakingNativeToken-flatten.sol#626) + - sInfo.owner = msg.sender (ServiceStakingNativeToken-flatten.sol#627) + - sInfo.nonce = nonce (ServiceStakingNativeToken-flatten.sol#629) + - sInfo.tsStart = block.timestamp (ServiceStakingNativeToken-flatten.sol#630) + - ServiceStakingBase.mapServiceInfo (ServiceStakingNativeToken-flatten.sol#504) was read at NEW VARIABLE totalRewards (ServiceStakingNativeToken-flatten.sol#861) + This variable was written at (after external call): + - delete mapServiceInfo[serviceId] (ServiceStakingNativeToken-flatten.sol#838) + - sInfo.multisig = multisig (ServiceStakingNativeToken-flatten.sol#626) + - sInfo.owner = msg.sender (ServiceStakingNativeToken-flatten.sol#627) + - sInfo.nonce = nonce (ServiceStakingNativeToken-flatten.sol#629) + - sInfo.tsStart = block.timestamp (ServiceStakingNativeToken-flatten.sol#630) + - ServiceStakingBase.mapServiceInfo (ServiceStakingNativeToken-flatten.sol#504) was read at NEW VARIABLE eligibleServiceIds (ServiceStakingNativeToken-flatten.sol#861) + This variable was written at (after external call): + - delete mapServiceInfo[serviceId] (ServiceStakingNativeToken-flatten.sol#838) + - sInfo.multisig = multisig (ServiceStakingNativeToken-flatten.sol#626) + - sInfo.owner = msg.sender (ServiceStakingNativeToken-flatten.sol#627) + - sInfo.nonce = nonce (ServiceStakingNativeToken-flatten.sol#629) + - sInfo.tsStart = block.timestamp (ServiceStakingNativeToken-flatten.sol#630) + - ServiceStakingBase.mapServiceInfo (ServiceStakingNativeToken-flatten.sol#504) was read at NEW VARIABLE eligibleServiceRewards (ServiceStakingNativeToken-flatten.sol#862) + This variable was written at (after external call): + - delete mapServiceInfo[serviceId] (ServiceStakingNativeToken-flatten.sol#838) + - sInfo.multisig = multisig (ServiceStakingNativeToken-flatten.sol#626) + - sInfo.owner = msg.sender (ServiceStakingNativeToken-flatten.sol#627) + - sInfo.nonce = nonce (ServiceStakingNativeToken-flatten.sol#629) + - sInfo.tsStart = block.timestamp (ServiceStakingNativeToken-flatten.sol#630) + - ServiceStakingBase.mapServiceInfo (ServiceStakingNativeToken-flatten.sol#504) was read at (lastAvailableRewards,numServices,totalRewards,eligibleServiceIds,eligibleServiceRewards) = _calculateStakingRewards() (ServiceStakingNativeToken-flatten.sol#861-862) + This variable was written at (after external call): + - delete mapServiceInfo[serviceId] (ServiceStakingNativeToken-flatten.sol#838) + - sInfo.multisig = multisig (ServiceStakingNativeToken-flatten.sol#626) + - sInfo.owner = msg.sender (ServiceStakingNativeToken-flatten.sol#627) + - sInfo.nonce = nonce (ServiceStakingNativeToken-flatten.sol#629) + - sInfo.tsStart = block.timestamp (ServiceStakingNativeToken-flatten.sol#630) + - ServiceStakingBase.mapServiceInfo (ServiceStakingNativeToken-flatten.sol#504) was read at numServices > 0 (ServiceStakingNativeToken-flatten.sol#865) + This variable was written at (after external call): + - delete mapServiceInfo[serviceId] (ServiceStakingNativeToken-flatten.sol#838) + - sInfo.multisig = multisig (ServiceStakingNativeToken-flatten.sol#626) + - sInfo.owner = msg.sender (ServiceStakingNativeToken-flatten.sol#627) + - sInfo.nonce = nonce (ServiceStakingNativeToken-flatten.sol#629) + - sInfo.tsStart = block.timestamp (ServiceStakingNativeToken-flatten.sol#630) + - ServiceStakingBase.mapServiceInfo (ServiceStakingNativeToken-flatten.sol#504) was read at BEGIN_LOOP (ServiceStakingNativeToken-flatten.sol#867-877) + This variable was written at (after external call): + - delete mapServiceInfo[serviceId] (ServiceStakingNativeToken-flatten.sol#838) + - sInfo.multisig = multisig (ServiceStakingNativeToken-flatten.sol#626) + - sInfo.owner = msg.sender (ServiceStakingNativeToken-flatten.sol#627) + - sInfo.nonce = nonce (ServiceStakingNativeToken-flatten.sol#629) + - sInfo.tsStart = block.timestamp (ServiceStakingNativeToken-flatten.sol#630) + - ServiceStakingBase.mapServiceInfo (ServiceStakingNativeToken-flatten.sol#504) was read at END_LOOP (ServiceStakingNativeToken-flatten.sol#867-877) + This variable was written at (after external call): + - delete mapServiceInfo[serviceId] (ServiceStakingNativeToken-flatten.sol#838) + - sInfo.multisig = multisig (ServiceStakingNativeToken-flatten.sol#626) + - sInfo.owner = msg.sender (ServiceStakingNativeToken-flatten.sol#627) + - sInfo.nonce = nonce (ServiceStakingNativeToken-flatten.sol#629) + - sInfo.tsStart = block.timestamp (ServiceStakingNativeToken-flatten.sol#630) + - ServiceStakingBase.mapServiceInfo (ServiceStakingNativeToken-flatten.sol#504) was read at i = 0 (ServiceStakingNativeToken-flatten.sol#867) + This variable was written at (after external call): + - delete mapServiceInfo[serviceId] (ServiceStakingNativeToken-flatten.sol#838) + - sInfo.multisig = multisig (ServiceStakingNativeToken-flatten.sol#626) + - sInfo.owner = msg.sender (ServiceStakingNativeToken-flatten.sol#627) + - sInfo.nonce = nonce (ServiceStakingNativeToken-flatten.sol#629) + - sInfo.tsStart = block.timestamp (ServiceStakingNativeToken-flatten.sol#630) + - ServiceStakingBase.mapServiceInfo (ServiceStakingNativeToken-flatten.sol#504) was read at i < eligibleServiceIds.length (ServiceStakingNativeToken-flatten.sol#867) + This variable was written at (after external call): + - delete mapServiceInfo[serviceId] (ServiceStakingNativeToken-flatten.sol#838) + - sInfo.multisig = multisig (ServiceStakingNativeToken-flatten.sol#626) + - sInfo.owner = msg.sender (ServiceStakingNativeToken-flatten.sol#627) + - sInfo.nonce = nonce (ServiceStakingNativeToken-flatten.sol#629) + - sInfo.tsStart = block.timestamp (ServiceStakingNativeToken-flatten.sol#630) + - ServiceStakingBase.mapServiceInfo (ServiceStakingNativeToken-flatten.sol#504) was read at eligibleServiceIds[i] == serviceId (ServiceStakingNativeToken-flatten.sol#868) + This variable was written at (after external call): + - delete mapServiceInfo[serviceId] (ServiceStakingNativeToken-flatten.sol#838) + - sInfo.multisig = multisig (ServiceStakingNativeToken-flatten.sol#626) + - sInfo.owner = msg.sender (ServiceStakingNativeToken-flatten.sol#627) + - sInfo.nonce = nonce (ServiceStakingNativeToken-flatten.sol#629) + - sInfo.tsStart = block.timestamp (ServiceStakingNativeToken-flatten.sol#630) + - ServiceStakingBase.mapServiceInfo (ServiceStakingNativeToken-flatten.sol#504) was read at totalRewards > lastAvailableRewards (ServiceStakingNativeToken-flatten.sol#870) + This variable was written at (after external call): + - delete mapServiceInfo[serviceId] (ServiceStakingNativeToken-flatten.sol#838) + - sInfo.multisig = multisig (ServiceStakingNativeToken-flatten.sol#626) + - sInfo.owner = msg.sender (ServiceStakingNativeToken-flatten.sol#627) + - sInfo.nonce = nonce (ServiceStakingNativeToken-flatten.sol#629) + - sInfo.tsStart = block.timestamp (ServiceStakingNativeToken-flatten.sol#630) + - ServiceStakingBase.mapServiceInfo (ServiceStakingNativeToken-flatten.sol#504) was read at reward += (eligibleServiceRewards[i] * lastAvailableRewards) / totalRewards (ServiceStakingNativeToken-flatten.sol#871) + This variable was written at (after external call): + - delete mapServiceInfo[serviceId] (ServiceStakingNativeToken-flatten.sol#838) + - sInfo.multisig = multisig (ServiceStakingNativeToken-flatten.sol#626) + - sInfo.owner = msg.sender (ServiceStakingNativeToken-flatten.sol#627) + - sInfo.nonce = nonce (ServiceStakingNativeToken-flatten.sol#629) + - sInfo.tsStart = block.timestamp (ServiceStakingNativeToken-flatten.sol#630) + - ServiceStakingBase.mapServiceInfo (ServiceStakingNativeToken-flatten.sol#504) was read at reward += eligibleServiceRewards[i] (ServiceStakingNativeToken-flatten.sol#873) + This variable was written at (after external call): + - delete mapServiceInfo[serviceId] (ServiceStakingNativeToken-flatten.sol#838) + - sInfo.multisig = multisig (ServiceStakingNativeToken-flatten.sol#626) + - sInfo.owner = msg.sender (ServiceStakingNativeToken-flatten.sol#627) + - sInfo.nonce = nonce (ServiceStakingNativeToken-flatten.sol#629) + - sInfo.tsStart = block.timestamp (ServiceStakingNativeToken-flatten.sol#630) + - ServiceStakingBase.mapServiceInfo (ServiceStakingNativeToken-flatten.sol#504) was read at END_IF (ServiceStakingNativeToken-flatten.sol#870-874) + This variable was written at (after external call): + - delete mapServiceInfo[serviceId] (ServiceStakingNativeToken-flatten.sol#838) + - sInfo.multisig = multisig (ServiceStakingNativeToken-flatten.sol#626) + - sInfo.owner = msg.sender (ServiceStakingNativeToken-flatten.sol#627) + - sInfo.nonce = nonce (ServiceStakingNativeToken-flatten.sol#629) + - sInfo.tsStart = block.timestamp (ServiceStakingNativeToken-flatten.sol#630) + - ServiceStakingBase.mapServiceInfo (ServiceStakingNativeToken-flatten.sol#504) was read at BREAK (ServiceStakingNativeToken-flatten.sol#875) + This variable was written at (after external call): + - delete mapServiceInfo[serviceId] (ServiceStakingNativeToken-flatten.sol#838) + - sInfo.multisig = multisig (ServiceStakingNativeToken-flatten.sol#626) + - sInfo.owner = msg.sender (ServiceStakingNativeToken-flatten.sol#627) + - sInfo.nonce = nonce (ServiceStakingNativeToken-flatten.sol#629) + - sInfo.tsStart = block.timestamp (ServiceStakingNativeToken-flatten.sol#630) + - ServiceStakingBase.mapServiceInfo (ServiceStakingNativeToken-flatten.sol#504) was read at END_IF (ServiceStakingNativeToken-flatten.sol#868-876) + This variable was written at (after external call): + - delete mapServiceInfo[serviceId] (ServiceStakingNativeToken-flatten.sol#838) + - sInfo.multisig = multisig (ServiceStakingNativeToken-flatten.sol#626) + - sInfo.owner = msg.sender (ServiceStakingNativeToken-flatten.sol#627) + - sInfo.nonce = nonce (ServiceStakingNativeToken-flatten.sol#629) + - sInfo.tsStart = block.timestamp (ServiceStakingNativeToken-flatten.sol#630) + - ServiceStakingBase.mapServiceInfo (ServiceStakingNativeToken-flatten.sol#504) was read at ++ i (ServiceStakingNativeToken-flatten.sol#867) + This variable was written at (after external call): + - delete mapServiceInfo[serviceId] (ServiceStakingNativeToken-flatten.sol#838) + - sInfo.multisig = multisig (ServiceStakingNativeToken-flatten.sol#626) + - sInfo.owner = msg.sender (ServiceStakingNativeToken-flatten.sol#627) + - sInfo.nonce = nonce (ServiceStakingNativeToken-flatten.sol#629) + - sInfo.tsStart = block.timestamp (ServiceStakingNativeToken-flatten.sol#630) + - ServiceStakingBase.mapServiceInfo (ServiceStakingNativeToken-flatten.sol#504) was read at END_IF (ServiceStakingNativeToken-flatten.sol#865-878) + This variable was written at (after external call): + - delete mapServiceInfo[serviceId] (ServiceStakingNativeToken-flatten.sol#838) + - sInfo.multisig = multisig (ServiceStakingNativeToken-flatten.sol#626) + - sInfo.owner = msg.sender (ServiceStakingNativeToken-flatten.sol#627) + - sInfo.nonce = nonce (ServiceStakingNativeToken-flatten.sol#629) + - sInfo.tsStart = block.timestamp (ServiceStakingNativeToken-flatten.sol#630) + - ServiceStakingBase.setServiceIds (ServiceStakingNativeToken-flatten.sol#506) was read at (lastAvailableRewards,numServices,totalRewards,eligibleServiceIds,eligibleServiceRewards) = _calculateStakingRewards() (ServiceStakingNativeToken-flatten.sol#861-862) + This variable was written at (after external call): + - setServiceIds[idx] = setServiceIds[setServiceIds.length - 1] (ServiceStakingNativeToken-flatten.sol#841) + - setServiceIds.pop() (ServiceStakingNativeToken-flatten.sol#842) + - setServiceIds.push(serviceId) (ServiceStakingNativeToken-flatten.sol#633) + - ServiceStakingBase.setServiceIds (ServiceStakingNativeToken-flatten.sol#506) was read at numServices > 0 (ServiceStakingNativeToken-flatten.sol#865) + This variable was written at (after external call): + - setServiceIds[idx] = setServiceIds[setServiceIds.length - 1] (ServiceStakingNativeToken-flatten.sol#841) + - setServiceIds.pop() (ServiceStakingNativeToken-flatten.sol#842) + - setServiceIds.push(serviceId) (ServiceStakingNativeToken-flatten.sol#633) + - ServiceStakingBase.setServiceIds (ServiceStakingNativeToken-flatten.sol#506) was read at BEGIN_LOOP (ServiceStakingNativeToken-flatten.sol#867-877) + This variable was written at (after external call): + - setServiceIds[idx] = setServiceIds[setServiceIds.length - 1] (ServiceStakingNativeToken-flatten.sol#841) + - setServiceIds.pop() (ServiceStakingNativeToken-flatten.sol#842) + - setServiceIds.push(serviceId) (ServiceStakingNativeToken-flatten.sol#633) + - ServiceStakingBase.setServiceIds (ServiceStakingNativeToken-flatten.sol#506) was read at END_LOOP (ServiceStakingNativeToken-flatten.sol#867-877) + This variable was written at (after external call): + - setServiceIds[idx] = setServiceIds[setServiceIds.length - 1] (ServiceStakingNativeToken-flatten.sol#841) + - setServiceIds.pop() (ServiceStakingNativeToken-flatten.sol#842) + - setServiceIds.push(serviceId) (ServiceStakingNativeToken-flatten.sol#633) + - ServiceStakingBase.setServiceIds (ServiceStakingNativeToken-flatten.sol#506) was read at i = 0 (ServiceStakingNativeToken-flatten.sol#867) + This variable was written at (after external call): + - setServiceIds[idx] = setServiceIds[setServiceIds.length - 1] (ServiceStakingNativeToken-flatten.sol#841) + - setServiceIds.pop() (ServiceStakingNativeToken-flatten.sol#842) + - setServiceIds.push(serviceId) (ServiceStakingNativeToken-flatten.sol#633) + - ServiceStakingBase.setServiceIds (ServiceStakingNativeToken-flatten.sol#506) was read at i < eligibleServiceIds.length (ServiceStakingNativeToken-flatten.sol#867) + This variable was written at (after external call): + - setServiceIds[idx] = setServiceIds[setServiceIds.length - 1] (ServiceStakingNativeToken-flatten.sol#841) + - setServiceIds.pop() (ServiceStakingNativeToken-flatten.sol#842) + - setServiceIds.push(serviceId) (ServiceStakingNativeToken-flatten.sol#633) + - ServiceStakingBase.setServiceIds (ServiceStakingNativeToken-flatten.sol#506) was read at eligibleServiceIds[i] == serviceId (ServiceStakingNativeToken-flatten.sol#868) + This variable was written at (after external call): + - setServiceIds[idx] = setServiceIds[setServiceIds.length - 1] (ServiceStakingNativeToken-flatten.sol#841) + - setServiceIds.pop() (ServiceStakingNativeToken-flatten.sol#842) + - setServiceIds.push(serviceId) (ServiceStakingNativeToken-flatten.sol#633) + - ServiceStakingBase.setServiceIds (ServiceStakingNativeToken-flatten.sol#506) was read at totalRewards > lastAvailableRewards (ServiceStakingNativeToken-flatten.sol#870) + This variable was written at (after external call): + - setServiceIds[idx] = setServiceIds[setServiceIds.length - 1] (ServiceStakingNativeToken-flatten.sol#841) + - setServiceIds.pop() (ServiceStakingNativeToken-flatten.sol#842) + - setServiceIds.push(serviceId) (ServiceStakingNativeToken-flatten.sol#633) + - ServiceStakingBase.setServiceIds (ServiceStakingNativeToken-flatten.sol#506) was read at reward += (eligibleServiceRewards[i] * lastAvailableRewards) / totalRewards (ServiceStakingNativeToken-flatten.sol#871) + This variable was written at (after external call): + - setServiceIds[idx] = setServiceIds[setServiceIds.length - 1] (ServiceStakingNativeToken-flatten.sol#841) + - setServiceIds.pop() (ServiceStakingNativeToken-flatten.sol#842) + - setServiceIds.push(serviceId) (ServiceStakingNativeToken-flatten.sol#633) + - ServiceStakingBase.setServiceIds (ServiceStakingNativeToken-flatten.sol#506) was read at reward += eligibleServiceRewards[i] (ServiceStakingNativeToken-flatten.sol#873) + This variable was written at (after external call): + - setServiceIds[idx] = setServiceIds[setServiceIds.length - 1] (ServiceStakingNativeToken-flatten.sol#841) + - setServiceIds.pop() (ServiceStakingNativeToken-flatten.sol#842) + - setServiceIds.push(serviceId) (ServiceStakingNativeToken-flatten.sol#633) + - ServiceStakingBase.setServiceIds (ServiceStakingNativeToken-flatten.sol#506) was read at END_IF (ServiceStakingNativeToken-flatten.sol#870-874) + This variable was written at (after external call): + - setServiceIds[idx] = setServiceIds[setServiceIds.length - 1] (ServiceStakingNativeToken-flatten.sol#841) + - setServiceIds.pop() (ServiceStakingNativeToken-flatten.sol#842) + - setServiceIds.push(serviceId) (ServiceStakingNativeToken-flatten.sol#633) + - ServiceStakingBase.setServiceIds (ServiceStakingNativeToken-flatten.sol#506) was read at BREAK (ServiceStakingNativeToken-flatten.sol#875) + This variable was written at (after external call): + - setServiceIds[idx] = setServiceIds[setServiceIds.length - 1] (ServiceStakingNativeToken-flatten.sol#841) + - setServiceIds.pop() (ServiceStakingNativeToken-flatten.sol#842) + - setServiceIds.push(serviceId) (ServiceStakingNativeToken-flatten.sol#633) + - ServiceStakingBase.setServiceIds (ServiceStakingNativeToken-flatten.sol#506) was read at END_IF (ServiceStakingNativeToken-flatten.sol#868-876) + This variable was written at (after external call): + - setServiceIds[idx] = setServiceIds[setServiceIds.length - 1] (ServiceStakingNativeToken-flatten.sol#841) + - setServiceIds.pop() (ServiceStakingNativeToken-flatten.sol#842) + - setServiceIds.push(serviceId) (ServiceStakingNativeToken-flatten.sol#633) + - ServiceStakingBase.setServiceIds (ServiceStakingNativeToken-flatten.sol#506) was read at ++ i (ServiceStakingNativeToken-flatten.sol#867) + This variable was written at (after external call): + - setServiceIds[idx] = setServiceIds[setServiceIds.length - 1] (ServiceStakingNativeToken-flatten.sol#841) + - setServiceIds.pop() (ServiceStakingNativeToken-flatten.sol#842) + - setServiceIds.push(serviceId) (ServiceStakingNativeToken-flatten.sol#633) + - ServiceStakingBase.setServiceIds (ServiceStakingNativeToken-flatten.sol#506) was read at END_IF (ServiceStakingNativeToken-flatten.sol#865-878) + This variable was written at (after external call): + - setServiceIds[idx] = setServiceIds[setServiceIds.length - 1] (ServiceStakingNativeToken-flatten.sol#841) + - setServiceIds.pop() (ServiceStakingNativeToken-flatten.sol#842) + - setServiceIds.push(serviceId) (ServiceStakingNativeToken-flatten.sol#633) +Reference: https://github.com/pessimistic-io/slitherin/blob/master/docs/readonly_reentrancy.md + +Notes: False positive. Code by design. +INFO:Detectors: +ServiceStakingBase.calculateServiceStakingReward(uint256) (ServiceStakingNativeToken-flatten.sol#850-879) uses a dangerous strict equality: + - sInfo.tsStart == 0 (ServiceStakingNativeToken-flatten.sol#856) +Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#dangerous-strict-equalities + +Notes: False positive. IService(serviceRegistry).safeTransferFrom non-reentrancy if erviceRegistry is trusted contract. +INFO:Detectors: +Reentrancy in ServiceStakingBase.stake(uint256) (ServiceStakingNativeToken-flatten.sol#569-636): + External calls: + - IService(serviceRegistry).safeTransferFrom(msg.sender,address(this),serviceId) (ServiceStakingNativeToken-flatten.sol#622) + State variables written after the call(s): + - setServiceIds.push(serviceId) (ServiceStakingNativeToken-flatten.sol#633) + ServiceStakingBase.setServiceIds (ServiceStakingNativeToken-flatten.sol#506) can be used in cross function reentrancies: + - ServiceStakingBase._calculateStakingRewards() (ServiceStakingNativeToken-flatten.sol#646-717) + - ServiceStakingBase.setServiceIds (ServiceStakingNativeToken-flatten.sol#506) + - ServiceStakingBase.stake(uint256) (ServiceStakingNativeToken-flatten.sol#569-636) + - ServiceStakingBase.unstake(uint256) (ServiceStakingNativeToken-flatten.sol#809-845) +Reentrancy in ServiceStakingBase.unstake(uint256) (ServiceStakingNativeToken-flatten.sol#809-845): + External calls: + - IService(serviceRegistry).safeTransferFrom(address(this),msg.sender,serviceId) (ServiceStakingNativeToken-flatten.sol#829) + State variables written after the call(s): + - delete mapServiceInfo[serviceId] (ServiceStakingNativeToken-flatten.sol#838) + ServiceStakingBase.mapServiceInfo (ServiceStakingNativeToken-flatten.sol#504) can be used in cross function reentrancies: + - ServiceStakingBase._calculateStakingRewards() (ServiceStakingNativeToken-flatten.sol#646-717) + - ServiceStakingBase.calculateServiceStakingReward(uint256) (ServiceStakingNativeToken-flatten.sol#850-879) + - ServiceStakingBase.checkpoint() (ServiceStakingNativeToken-flatten.sol#726-805) + - ServiceStakingBase.mapServiceInfo (ServiceStakingNativeToken-flatten.sol#504) + - ServiceStakingBase.stake(uint256) (ServiceStakingNativeToken-flatten.sol#569-636) + - ServiceStakingBase.unstake(uint256) (ServiceStakingNativeToken-flatten.sol#809-845) + - setServiceIds[idx] = setServiceIds[setServiceIds.length - 1] (ServiceStakingNativeToken-flatten.sol#841) + ServiceStakingBase.setServiceIds (ServiceStakingNativeToken-flatten.sol#506) can be used in cross function reentrancies: + - ServiceStakingBase._calculateStakingRewards() (ServiceStakingNativeToken-flatten.sol#646-717) + - ServiceStakingBase.setServiceIds (ServiceStakingNativeToken-flatten.sol#506) + - ServiceStakingBase.stake(uint256) (ServiceStakingNativeToken-flatten.sol#569-636) + - ServiceStakingBase.unstake(uint256) (ServiceStakingNativeToken-flatten.sol#809-845) + - setServiceIds.pop() (ServiceStakingNativeToken-flatten.sol#842) + ServiceStakingBase.setServiceIds (ServiceStakingNativeToken-flatten.sol#506) can be used in cross function reentrancies: + - ServiceStakingBase._calculateStakingRewards() (ServiceStakingNativeToken-flatten.sol#646-717) + - ServiceStakingBase.setServiceIds (ServiceStakingNativeToken-flatten.sol#506) + - ServiceStakingBase.stake(uint256) (ServiceStakingNativeToken-flatten.sol#569-636) + - ServiceStakingBase.unstake(uint256) (ServiceStakingNativeToken-flatten.sol#809-845) +Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#reentrancy-vulnerabilities-1 + +Notes: False positive. Zero by design. +INFO:Detectors: +ServiceStakingBase._calculateStakingRewards().ratio (ServiceStakingNativeToken-flatten.sol#699) is a local variable never initialized +Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#uninitialized-local-variables + +Notes: False positive. +INFO:Detectors: +ServiceStakingBase.stake(uint256) (ServiceStakingNativeToken-flatten.sol#569-636) ignores return value by (stakingDeposit,multisig,hash,agentThreshold,maxNumInstances,state) = IService(serviceRegistry).mapServices(serviceId) (ServiceStakingNativeToken-flatten.sol#582-583) +Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#unused-return + +Notes: False positive. By code: +``` + if (msg.sender != sInfo.owner) { + revert OwnerOnly(msg.sender, sInfo.owner); + } +``` +INFO:Detectors: +ServiceStakingBase unstake parameter from is not related to msg.sender IService(serviceRegistry).safeTransferFrom(address(this),msg.sender,serviceId) (ServiceStakingNativeToken-flatten.sol#829) +Reference: https://ventral.digital/posts/2022/8/18/sznsdaos-bountyboard-unauthorized-transferfrom-vulnerability + +Notes: False positive. OK by design. +INFO:Detectors: +Function ServiceStakingNativeToken._withdraw(address,uint256) (ServiceStakingNativeToken-flatten.sol#899-909) contains a low level call to a custom address +Reference: https://github.com/pessimistic-io/slitherin/blob/master/docs/call_forward_to_protected.md + +Notes: False positive. IService(serviceRegistry).safeTransferFrom this call is safe. +INFO:Detectors: +Reentrancy in ServiceStakingBase.stake(uint256) (ServiceStakingNativeToken-flatten.sol#569-636): + External calls: + - IService(serviceRegistry).safeTransferFrom(msg.sender,address(this),serviceId) (ServiceStakingNativeToken-flatten.sol#622) + State variables written after the call(s): + - sInfo.multisig = multisig (ServiceStakingNativeToken-flatten.sol#626) + - sInfo.owner = msg.sender (ServiceStakingNativeToken-flatten.sol#627) + - sInfo.nonce = nonce (ServiceStakingNativeToken-flatten.sol#629) + - sInfo.tsStart = block.timestamp (ServiceStakingNativeToken-flatten.sol#630) +Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#reentrancy-vulnerabilities-2 + +Notes: False positive. See above. +INFO:Detectors: +Reentrancy in ServiceStakingBase.stake(uint256) (ServiceStakingNativeToken-flatten.sol#569-636): + External calls: + - IService(serviceRegistry).safeTransferFrom(msg.sender,address(this),serviceId) (ServiceStakingNativeToken-flatten.sol#622) + Event emitted after the call(s): + - ServiceStaked(serviceId,msg.sender,multisig,nonce) (ServiceStakingNativeToken-flatten.sol#635) +Reentrancy in ServiceStakingBase.unstake(uint256) (ServiceStakingNativeToken-flatten.sol#809-845): + External calls: + - IService(serviceRegistry).safeTransferFrom(address(this),msg.sender,serviceId) (ServiceStakingNativeToken-flatten.sol#829) + Event emitted after the call(s): + - ServiceUnstaked(serviceId,msg.sender,sInfo.multisig,sInfo.nonce,sInfo.reward,sInfo.tsStart) (ServiceStakingNativeToken-flatten.sol#844) +Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#reentrancy-vulnerabilities-3 + +Notes: False positive. OK by design. +INFO:Detectors: +ServiceStakingBase._calculateStakingRewards() (ServiceStakingNativeToken-flatten.sol#646-717) uses timestamp for comparisons + Dangerous comparisons: + - block.timestamp - tsCheckpointLast >= livenessPeriod (ServiceStakingNativeToken-flatten.sol#668) + - ts > serviceCheckpoint (ServiceStakingNativeToken-flatten.sol#692) + - ts > 0 (ServiceStakingNativeToken-flatten.sol#701) + - ratio >= livenessRatio (ServiceStakingNativeToken-flatten.sol#706) +ServiceStakingBase.unstake(uint256) (ServiceStakingNativeToken-flatten.sol#809-845) uses timestamp for comparisons + Dangerous comparisons: + - msg.sender != sInfo.owner (ServiceStakingNativeToken-flatten.sol#812) + - sInfo.reward > 0 (ServiceStakingNativeToken-flatten.sol#832) +ServiceStakingBase.calculateServiceStakingReward(uint256) (ServiceStakingNativeToken-flatten.sol#850-879) uses timestamp for comparisons + Dangerous comparisons: + - sInfo.tsStart == 0 (ServiceStakingNativeToken-flatten.sol#856) +Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#block-timestamp + +Notes: False positive. OK by design. +INFO:Detectors: +ERC721._burn(uint256) (ServiceStakingNativeToken-flatten.sol#296-311) is never used and should be removed +ERC721._mint(address,uint256) (ServiceStakingNativeToken-flatten.sol#281-294) is never used and should be removed +ERC721._safeMint(address,uint256) (ServiceStakingNativeToken-flatten.sol#317-326) is never used and should be removed +ERC721._safeMint(address,uint256,bytes) (ServiceStakingNativeToken-flatten.sol#328-341) is never used and should be removed +Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#dead-code + +Notes: False positive. OK by design. +INFO:Detectors: +Low level call in ServiceStakingNativeToken._withdraw(address,uint256) (ServiceStakingNativeToken-flatten.sol#899-909): + - (result) = to.call{value: amount}() (ServiceStakingNativeToken-flatten.sol#905) +Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#low-level-calls + +Notes: False positive. Ignore it. +INFO:Detectors: +Variable ERC721._ownerOf (ServiceStakingNativeToken-flatten.sol#155) is not in mixedCase +Variable ERC721._balanceOf (ServiceStakingNativeToken-flatten.sol#157) is not in mixedCase +Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#conformance-to-solidity-naming-conventions + +Notes: Low priority. +INFO:Detectors: +Variable ServiceStakingBase.checkpoint().curServiceId_scope_1 (ServiceStakingNativeToken-flatten.sol#774) is too similar to ServiceStakingBase.checkpoint().curServiceId_scope_3 (ServiceStakingNativeToken-flatten.sol#792) +Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#variable-names-too-similar + +Notes: False positive. Ignore it. +INFO:Detectors: +ERC721 (ServiceStakingNativeToken-flatten.sol#130-342) does not implement functions: + - ERC721.tokenURI(uint256) (ServiceStakingNativeToken-flatten.sol#149) +Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#unimplemented-functions + +Notes: Low priority. +INFO:Detectors: +Function ServiceStakingBase.stake(uint256) (ServiceStakingNativeToken-flatten.sol#569-636) contains magic number: 4 +Reference: https://github.com/pessimistic-io/slitherin/blob/master/docs/magic_number.md + +Notes: False positive. Non-readonly-reentrancy +INFO:Detectors: +Potential vulnerable to readonly-reentrancy function (if read in other function) ServiceStakingBase.calculateServiceStakingReward(uint256) (ServiceStakingToken-flatten.sol#850-879): + State variables read that were written after the external call(s): + - ServiceStakingBase.mapServiceInfo (ServiceStakingToken-flatten.sol#504) was read at sInfo = mapServiceInfo[serviceId] (ServiceStakingToken-flatten.sol#852) + This variable was written at (after external call): + - delete mapServiceInfo[serviceId] (ServiceStakingToken-flatten.sol#838) + - sInfo.multisig = multisig (ServiceStakingToken-flatten.sol#626) + - sInfo.owner = msg.sender (ServiceStakingToken-flatten.sol#627) + - sInfo.nonce = nonce (ServiceStakingToken-flatten.sol#629) + - sInfo.tsStart = block.timestamp (ServiceStakingToken-flatten.sol#630) + - ServiceStakingBase.mapServiceInfo (ServiceStakingToken-flatten.sol#504) was read at reward = sInfo.reward (ServiceStakingToken-flatten.sol#853) + This variable was written at (after external call): + - delete mapServiceInfo[serviceId] (ServiceStakingToken-flatten.sol#838) + - sInfo.multisig = multisig (ServiceStakingToken-flatten.sol#626) + - sInfo.owner = msg.sender (ServiceStakingToken-flatten.sol#627) + - sInfo.nonce = nonce (ServiceStakingToken-flatten.sol#629) + - sInfo.tsStart = block.timestamp (ServiceStakingToken-flatten.sol#630) + - ServiceStakingBase.mapServiceInfo (ServiceStakingToken-flatten.sol#504) was read at sInfo.tsStart == 0 (ServiceStakingToken-flatten.sol#856) + This variable was written at (after external call): + - delete mapServiceInfo[serviceId] (ServiceStakingToken-flatten.sol#838) + - sInfo.multisig = multisig (ServiceStakingToken-flatten.sol#626) + - sInfo.owner = msg.sender (ServiceStakingToken-flatten.sol#627) + - sInfo.nonce = nonce (ServiceStakingToken-flatten.sol#629) + - sInfo.tsStart = block.timestamp (ServiceStakingToken-flatten.sol#630) + - ServiceStakingBase.mapServiceInfo (ServiceStakingToken-flatten.sol#504) was read at revert ServiceNotStaked(uint256)(serviceId) (ServiceStakingToken-flatten.sol#857) + This variable was written at (after external call): + - delete mapServiceInfo[serviceId] (ServiceStakingToken-flatten.sol#838) + - sInfo.multisig = multisig (ServiceStakingToken-flatten.sol#626) + - sInfo.owner = msg.sender (ServiceStakingToken-flatten.sol#627) + - sInfo.nonce = nonce (ServiceStakingToken-flatten.sol#629) + - sInfo.tsStart = block.timestamp (ServiceStakingToken-flatten.sol#630) + - ServiceStakingBase.mapServiceInfo (ServiceStakingToken-flatten.sol#504) was read at END_IF (ServiceStakingToken-flatten.sol#856-858) + This variable was written at (after external call): + - delete mapServiceInfo[serviceId] (ServiceStakingToken-flatten.sol#838) + - sInfo.multisig = multisig (ServiceStakingToken-flatten.sol#626) + - sInfo.owner = msg.sender (ServiceStakingToken-flatten.sol#627) + - sInfo.nonce = nonce (ServiceStakingToken-flatten.sol#629) + - sInfo.tsStart = block.timestamp (ServiceStakingToken-flatten.sol#630) + - ServiceStakingBase.mapServiceInfo (ServiceStakingToken-flatten.sol#504) was read at NEW VARIABLE lastAvailableRewards (ServiceStakingToken-flatten.sol#861) + This variable was written at (after external call): + - delete mapServiceInfo[serviceId] (ServiceStakingToken-flatten.sol#838) + - sInfo.multisig = multisig (ServiceStakingToken-flatten.sol#626) + - sInfo.owner = msg.sender (ServiceStakingToken-flatten.sol#627) + - sInfo.nonce = nonce (ServiceStakingToken-flatten.sol#629) + - sInfo.tsStart = block.timestamp (ServiceStakingToken-flatten.sol#630) + - ServiceStakingBase.mapServiceInfo (ServiceStakingToken-flatten.sol#504) was read at NEW VARIABLE numServices (ServiceStakingToken-flatten.sol#861) + This variable was written at (after external call): + - delete mapServiceInfo[serviceId] (ServiceStakingToken-flatten.sol#838) + - sInfo.multisig = multisig (ServiceStakingToken-flatten.sol#626) + - sInfo.owner = msg.sender (ServiceStakingToken-flatten.sol#627) + - sInfo.nonce = nonce (ServiceStakingToken-flatten.sol#629) + - sInfo.tsStart = block.timestamp (ServiceStakingToken-flatten.sol#630) + - ServiceStakingBase.mapServiceInfo (ServiceStakingToken-flatten.sol#504) was read at NEW VARIABLE totalRewards (ServiceStakingToken-flatten.sol#861) + This variable was written at (after external call): + - delete mapServiceInfo[serviceId] (ServiceStakingToken-flatten.sol#838) + - sInfo.multisig = multisig (ServiceStakingToken-flatten.sol#626) + - sInfo.owner = msg.sender (ServiceStakingToken-flatten.sol#627) + - sInfo.nonce = nonce (ServiceStakingToken-flatten.sol#629) + - sInfo.tsStart = block.timestamp (ServiceStakingToken-flatten.sol#630) + - ServiceStakingBase.mapServiceInfo (ServiceStakingToken-flatten.sol#504) was read at NEW VARIABLE eligibleServiceIds (ServiceStakingToken-flatten.sol#861) + This variable was written at (after external call): + - delete mapServiceInfo[serviceId] (ServiceStakingToken-flatten.sol#838) + - sInfo.multisig = multisig (ServiceStakingToken-flatten.sol#626) + - sInfo.owner = msg.sender (ServiceStakingToken-flatten.sol#627) + - sInfo.nonce = nonce (ServiceStakingToken-flatten.sol#629) + - sInfo.tsStart = block.timestamp (ServiceStakingToken-flatten.sol#630) + - ServiceStakingBase.mapServiceInfo (ServiceStakingToken-flatten.sol#504) was read at NEW VARIABLE eligibleServiceRewards (ServiceStakingToken-flatten.sol#862) + This variable was written at (after external call): + - delete mapServiceInfo[serviceId] (ServiceStakingToken-flatten.sol#838) + - sInfo.multisig = multisig (ServiceStakingToken-flatten.sol#626) + - sInfo.owner = msg.sender (ServiceStakingToken-flatten.sol#627) + - sInfo.nonce = nonce (ServiceStakingToken-flatten.sol#629) + - sInfo.tsStart = block.timestamp (ServiceStakingToken-flatten.sol#630) + - ServiceStakingBase.mapServiceInfo (ServiceStakingToken-flatten.sol#504) was read at (lastAvailableRewards,numServices,totalRewards,eligibleServiceIds,eligibleServiceRewards) = _calculateStakingRewards() (ServiceStakingToken-flatten.sol#861-862) + This variable was written at (after external call): + - delete mapServiceInfo[serviceId] (ServiceStakingToken-flatten.sol#838) + - sInfo.multisig = multisig (ServiceStakingToken-flatten.sol#626) + - sInfo.owner = msg.sender (ServiceStakingToken-flatten.sol#627) + - sInfo.nonce = nonce (ServiceStakingToken-flatten.sol#629) + - sInfo.tsStart = block.timestamp (ServiceStakingToken-flatten.sol#630) + - ServiceStakingBase.mapServiceInfo (ServiceStakingToken-flatten.sol#504) was read at numServices > 0 (ServiceStakingToken-flatten.sol#865) + This variable was written at (after external call): + - delete mapServiceInfo[serviceId] (ServiceStakingToken-flatten.sol#838) + - sInfo.multisig = multisig (ServiceStakingToken-flatten.sol#626) + - sInfo.owner = msg.sender (ServiceStakingToken-flatten.sol#627) + - sInfo.nonce = nonce (ServiceStakingToken-flatten.sol#629) + - sInfo.tsStart = block.timestamp (ServiceStakingToken-flatten.sol#630) + - ServiceStakingBase.mapServiceInfo (ServiceStakingToken-flatten.sol#504) was read at BEGIN_LOOP (ServiceStakingToken-flatten.sol#867-877) + This variable was written at (after external call): + - delete mapServiceInfo[serviceId] (ServiceStakingToken-flatten.sol#838) + - sInfo.multisig = multisig (ServiceStakingToken-flatten.sol#626) + - sInfo.owner = msg.sender (ServiceStakingToken-flatten.sol#627) + - sInfo.nonce = nonce (ServiceStakingToken-flatten.sol#629) + - sInfo.tsStart = block.timestamp (ServiceStakingToken-flatten.sol#630) + - ServiceStakingBase.mapServiceInfo (ServiceStakingToken-flatten.sol#504) was read at END_LOOP (ServiceStakingToken-flatten.sol#867-877) + This variable was written at (after external call): + - delete mapServiceInfo[serviceId] (ServiceStakingToken-flatten.sol#838) + - sInfo.multisig = multisig (ServiceStakingToken-flatten.sol#626) + - sInfo.owner = msg.sender (ServiceStakingToken-flatten.sol#627) + - sInfo.nonce = nonce (ServiceStakingToken-flatten.sol#629) + - sInfo.tsStart = block.timestamp (ServiceStakingToken-flatten.sol#630) + - ServiceStakingBase.mapServiceInfo (ServiceStakingToken-flatten.sol#504) was read at i = 0 (ServiceStakingToken-flatten.sol#867) + This variable was written at (after external call): + - delete mapServiceInfo[serviceId] (ServiceStakingToken-flatten.sol#838) + - sInfo.multisig = multisig (ServiceStakingToken-flatten.sol#626) + - sInfo.owner = msg.sender (ServiceStakingToken-flatten.sol#627) + - sInfo.nonce = nonce (ServiceStakingToken-flatten.sol#629) + - sInfo.tsStart = block.timestamp (ServiceStakingToken-flatten.sol#630) + - ServiceStakingBase.mapServiceInfo (ServiceStakingToken-flatten.sol#504) was read at i < eligibleServiceIds.length (ServiceStakingToken-flatten.sol#867) + This variable was written at (after external call): + - delete mapServiceInfo[serviceId] (ServiceStakingToken-flatten.sol#838) + - sInfo.multisig = multisig (ServiceStakingToken-flatten.sol#626) + - sInfo.owner = msg.sender (ServiceStakingToken-flatten.sol#627) + - sInfo.nonce = nonce (ServiceStakingToken-flatten.sol#629) + - sInfo.tsStart = block.timestamp (ServiceStakingToken-flatten.sol#630) + - ServiceStakingBase.mapServiceInfo (ServiceStakingToken-flatten.sol#504) was read at eligibleServiceIds[i] == serviceId (ServiceStakingToken-flatten.sol#868) + This variable was written at (after external call): + - delete mapServiceInfo[serviceId] (ServiceStakingToken-flatten.sol#838) + - sInfo.multisig = multisig (ServiceStakingToken-flatten.sol#626) + - sInfo.owner = msg.sender (ServiceStakingToken-flatten.sol#627) + - sInfo.nonce = nonce (ServiceStakingToken-flatten.sol#629) + - sInfo.tsStart = block.timestamp (ServiceStakingToken-flatten.sol#630) + - ServiceStakingBase.mapServiceInfo (ServiceStakingToken-flatten.sol#504) was read at totalRewards > lastAvailableRewards (ServiceStakingToken-flatten.sol#870) + This variable was written at (after external call): + - delete mapServiceInfo[serviceId] (ServiceStakingToken-flatten.sol#838) + - sInfo.multisig = multisig (ServiceStakingToken-flatten.sol#626) + - sInfo.owner = msg.sender (ServiceStakingToken-flatten.sol#627) + - sInfo.nonce = nonce (ServiceStakingToken-flatten.sol#629) + - sInfo.tsStart = block.timestamp (ServiceStakingToken-flatten.sol#630) + - ServiceStakingBase.mapServiceInfo (ServiceStakingToken-flatten.sol#504) was read at reward += (eligibleServiceRewards[i] * lastAvailableRewards) / totalRewards (ServiceStakingToken-flatten.sol#871) + This variable was written at (after external call): + - delete mapServiceInfo[serviceId] (ServiceStakingToken-flatten.sol#838) + - sInfo.multisig = multisig (ServiceStakingToken-flatten.sol#626) + - sInfo.owner = msg.sender (ServiceStakingToken-flatten.sol#627) + - sInfo.nonce = nonce (ServiceStakingToken-flatten.sol#629) + - sInfo.tsStart = block.timestamp (ServiceStakingToken-flatten.sol#630) + - ServiceStakingBase.mapServiceInfo (ServiceStakingToken-flatten.sol#504) was read at reward += eligibleServiceRewards[i] (ServiceStakingToken-flatten.sol#873) + This variable was written at (after external call): + - delete mapServiceInfo[serviceId] (ServiceStakingToken-flatten.sol#838) + - sInfo.multisig = multisig (ServiceStakingToken-flatten.sol#626) + - sInfo.owner = msg.sender (ServiceStakingToken-flatten.sol#627) + - sInfo.nonce = nonce (ServiceStakingToken-flatten.sol#629) + - sInfo.tsStart = block.timestamp (ServiceStakingToken-flatten.sol#630) + - ServiceStakingBase.mapServiceInfo (ServiceStakingToken-flatten.sol#504) was read at END_IF (ServiceStakingToken-flatten.sol#870-874) + This variable was written at (after external call): + - delete mapServiceInfo[serviceId] (ServiceStakingToken-flatten.sol#838) + - sInfo.multisig = multisig (ServiceStakingToken-flatten.sol#626) + - sInfo.owner = msg.sender (ServiceStakingToken-flatten.sol#627) + - sInfo.nonce = nonce (ServiceStakingToken-flatten.sol#629) + - sInfo.tsStart = block.timestamp (ServiceStakingToken-flatten.sol#630) + - ServiceStakingBase.mapServiceInfo (ServiceStakingToken-flatten.sol#504) was read at BREAK (ServiceStakingToken-flatten.sol#875) + This variable was written at (after external call): + - delete mapServiceInfo[serviceId] (ServiceStakingToken-flatten.sol#838) + - sInfo.multisig = multisig (ServiceStakingToken-flatten.sol#626) + - sInfo.owner = msg.sender (ServiceStakingToken-flatten.sol#627) + - sInfo.nonce = nonce (ServiceStakingToken-flatten.sol#629) + - sInfo.tsStart = block.timestamp (ServiceStakingToken-flatten.sol#630) + - ServiceStakingBase.mapServiceInfo (ServiceStakingToken-flatten.sol#504) was read at END_IF (ServiceStakingToken-flatten.sol#868-876) + This variable was written at (after external call): + - delete mapServiceInfo[serviceId] (ServiceStakingToken-flatten.sol#838) + - sInfo.multisig = multisig (ServiceStakingToken-flatten.sol#626) + - sInfo.owner = msg.sender (ServiceStakingToken-flatten.sol#627) + - sInfo.nonce = nonce (ServiceStakingToken-flatten.sol#629) + - sInfo.tsStart = block.timestamp (ServiceStakingToken-flatten.sol#630) + - ServiceStakingBase.mapServiceInfo (ServiceStakingToken-flatten.sol#504) was read at ++ i (ServiceStakingToken-flatten.sol#867) + This variable was written at (after external call): + - delete mapServiceInfo[serviceId] (ServiceStakingToken-flatten.sol#838) + - sInfo.multisig = multisig (ServiceStakingToken-flatten.sol#626) + - sInfo.owner = msg.sender (ServiceStakingToken-flatten.sol#627) + - sInfo.nonce = nonce (ServiceStakingToken-flatten.sol#629) + - sInfo.tsStart = block.timestamp (ServiceStakingToken-flatten.sol#630) + - ServiceStakingBase.mapServiceInfo (ServiceStakingToken-flatten.sol#504) was read at END_IF (ServiceStakingToken-flatten.sol#865-878) + This variable was written at (after external call): + - delete mapServiceInfo[serviceId] (ServiceStakingToken-flatten.sol#838) + - sInfo.multisig = multisig (ServiceStakingToken-flatten.sol#626) + - sInfo.owner = msg.sender (ServiceStakingToken-flatten.sol#627) + - sInfo.nonce = nonce (ServiceStakingToken-flatten.sol#629) + - sInfo.tsStart = block.timestamp (ServiceStakingToken-flatten.sol#630) + - ServiceStakingBase.setServiceIds (ServiceStakingToken-flatten.sol#506) was read at (lastAvailableRewards,numServices,totalRewards,eligibleServiceIds,eligibleServiceRewards) = _calculateStakingRewards() (ServiceStakingToken-flatten.sol#861-862) + This variable was written at (after external call): + - setServiceIds[idx] = setServiceIds[setServiceIds.length - 1] (ServiceStakingToken-flatten.sol#841) + - setServiceIds.pop() (ServiceStakingToken-flatten.sol#842) + - setServiceIds.push(serviceId) (ServiceStakingToken-flatten.sol#633) + - ServiceStakingBase.setServiceIds (ServiceStakingToken-flatten.sol#506) was read at numServices > 0 (ServiceStakingToken-flatten.sol#865) + This variable was written at (after external call): + - setServiceIds[idx] = setServiceIds[setServiceIds.length - 1] (ServiceStakingToken-flatten.sol#841) + - setServiceIds.pop() (ServiceStakingToken-flatten.sol#842) + - setServiceIds.push(serviceId) (ServiceStakingToken-flatten.sol#633) + - ServiceStakingBase.setServiceIds (ServiceStakingToken-flatten.sol#506) was read at BEGIN_LOOP (ServiceStakingToken-flatten.sol#867-877) + This variable was written at (after external call): + - setServiceIds[idx] = setServiceIds[setServiceIds.length - 1] (ServiceStakingToken-flatten.sol#841) + - setServiceIds.pop() (ServiceStakingToken-flatten.sol#842) + - setServiceIds.push(serviceId) (ServiceStakingToken-flatten.sol#633) + - ServiceStakingBase.setServiceIds (ServiceStakingToken-flatten.sol#506) was read at END_LOOP (ServiceStakingToken-flatten.sol#867-877) + This variable was written at (after external call): + - setServiceIds[idx] = setServiceIds[setServiceIds.length - 1] (ServiceStakingToken-flatten.sol#841) + - setServiceIds.pop() (ServiceStakingToken-flatten.sol#842) + - setServiceIds.push(serviceId) (ServiceStakingToken-flatten.sol#633) + - ServiceStakingBase.setServiceIds (ServiceStakingToken-flatten.sol#506) was read at i = 0 (ServiceStakingToken-flatten.sol#867) + This variable was written at (after external call): + - setServiceIds[idx] = setServiceIds[setServiceIds.length - 1] (ServiceStakingToken-flatten.sol#841) + - setServiceIds.pop() (ServiceStakingToken-flatten.sol#842) + - setServiceIds.push(serviceId) (ServiceStakingToken-flatten.sol#633) + - ServiceStakingBase.setServiceIds (ServiceStakingToken-flatten.sol#506) was read at i < eligibleServiceIds.length (ServiceStakingToken-flatten.sol#867) + This variable was written at (after external call): + - setServiceIds[idx] = setServiceIds[setServiceIds.length - 1] (ServiceStakingToken-flatten.sol#841) + - setServiceIds.pop() (ServiceStakingToken-flatten.sol#842) + - setServiceIds.push(serviceId) (ServiceStakingToken-flatten.sol#633) + - ServiceStakingBase.setServiceIds (ServiceStakingToken-flatten.sol#506) was read at eligibleServiceIds[i] == serviceId (ServiceStakingToken-flatten.sol#868) + This variable was written at (after external call): + - setServiceIds[idx] = setServiceIds[setServiceIds.length - 1] (ServiceStakingToken-flatten.sol#841) + - setServiceIds.pop() (ServiceStakingToken-flatten.sol#842) + - setServiceIds.push(serviceId) (ServiceStakingToken-flatten.sol#633) + - ServiceStakingBase.setServiceIds (ServiceStakingToken-flatten.sol#506) was read at totalRewards > lastAvailableRewards (ServiceStakingToken-flatten.sol#870) + This variable was written at (after external call): + - setServiceIds[idx] = setServiceIds[setServiceIds.length - 1] (ServiceStakingToken-flatten.sol#841) + - setServiceIds.pop() (ServiceStakingToken-flatten.sol#842) + - setServiceIds.push(serviceId) (ServiceStakingToken-flatten.sol#633) + - ServiceStakingBase.setServiceIds (ServiceStakingToken-flatten.sol#506) was read at reward += (eligibleServiceRewards[i] * lastAvailableRewards) / totalRewards (ServiceStakingToken-flatten.sol#871) + This variable was written at (after external call): + - setServiceIds[idx] = setServiceIds[setServiceIds.length - 1] (ServiceStakingToken-flatten.sol#841) + - setServiceIds.pop() (ServiceStakingToken-flatten.sol#842) + - setServiceIds.push(serviceId) (ServiceStakingToken-flatten.sol#633) + - ServiceStakingBase.setServiceIds (ServiceStakingToken-flatten.sol#506) was read at reward += eligibleServiceRewards[i] (ServiceStakingToken-flatten.sol#873) + This variable was written at (after external call): + - setServiceIds[idx] = setServiceIds[setServiceIds.length - 1] (ServiceStakingToken-flatten.sol#841) + - setServiceIds.pop() (ServiceStakingToken-flatten.sol#842) + - setServiceIds.push(serviceId) (ServiceStakingToken-flatten.sol#633) + - ServiceStakingBase.setServiceIds (ServiceStakingToken-flatten.sol#506) was read at END_IF (ServiceStakingToken-flatten.sol#870-874) + This variable was written at (after external call): + - setServiceIds[idx] = setServiceIds[setServiceIds.length - 1] (ServiceStakingToken-flatten.sol#841) + - setServiceIds.pop() (ServiceStakingToken-flatten.sol#842) + - setServiceIds.push(serviceId) (ServiceStakingToken-flatten.sol#633) + - ServiceStakingBase.setServiceIds (ServiceStakingToken-flatten.sol#506) was read at BREAK (ServiceStakingToken-flatten.sol#875) + This variable was written at (after external call): + - setServiceIds[idx] = setServiceIds[setServiceIds.length - 1] (ServiceStakingToken-flatten.sol#841) + - setServiceIds.pop() (ServiceStakingToken-flatten.sol#842) + - setServiceIds.push(serviceId) (ServiceStakingToken-flatten.sol#633) + - ServiceStakingBase.setServiceIds (ServiceStakingToken-flatten.sol#506) was read at END_IF (ServiceStakingToken-flatten.sol#868-876) + This variable was written at (after external call): + - setServiceIds[idx] = setServiceIds[setServiceIds.length - 1] (ServiceStakingToken-flatten.sol#841) + - setServiceIds.pop() (ServiceStakingToken-flatten.sol#842) + - setServiceIds.push(serviceId) (ServiceStakingToken-flatten.sol#633) + - ServiceStakingBase.setServiceIds (ServiceStakingToken-flatten.sol#506) was read at ++ i (ServiceStakingToken-flatten.sol#867) + This variable was written at (after external call): + - setServiceIds[idx] = setServiceIds[setServiceIds.length - 1] (ServiceStakingToken-flatten.sol#841) + - setServiceIds.pop() (ServiceStakingToken-flatten.sol#842) + - setServiceIds.push(serviceId) (ServiceStakingToken-flatten.sol#633) + - ServiceStakingBase.setServiceIds (ServiceStakingToken-flatten.sol#506) was read at END_IF (ServiceStakingToken-flatten.sol#865-878) + This variable was written at (after external call): + - setServiceIds[idx] = setServiceIds[setServiceIds.length - 1] (ServiceStakingToken-flatten.sol#841) + - setServiceIds.pop() (ServiceStakingToken-flatten.sol#842) + - setServiceIds.push(serviceId) (ServiceStakingToken-flatten.sol#633) +Reference: https://github.com/pessimistic-io/slitherin/blob/master/docs/readonly_reentrancy.md + +Notes: False positive. +INFO:Detectors: +IToken (ServiceStakingToken-flatten.sol#885-928) has incorrect ERC721 function interface:IToken.approve(address,uint256) (ServiceStakingToken-flatten.sol#916) +IToken (ServiceStakingToken-flatten.sol#885-928) has incorrect ERC721 function interface:IToken.transferFrom(address,address,uint256) (ServiceStakingToken-flatten.sol#923) +Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#incorrect-erc721-interface + +Notes: False positive. +INFO:Detectors: +ServiceStakingBase.calculateServiceStakingReward(uint256) (ServiceStakingToken-flatten.sol#850-879) uses a dangerous strict equality: + - sInfo.tsStart == 0 (ServiceStakingToken-flatten.sol#856) +Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#dangerous-strict-equalities + +Notes: False positive. See above. +INFO:Detectors: +Reentrancy in ServiceStakingBase.stake(uint256) (ServiceStakingToken-flatten.sol#569-636): + External calls: + - IService(serviceRegistry).safeTransferFrom(msg.sender,address(this),serviceId) (ServiceStakingToken-flatten.sol#622) + State variables written after the call(s): + - setServiceIds.push(serviceId) (ServiceStakingToken-flatten.sol#633) + ServiceStakingBase.setServiceIds (ServiceStakingToken-flatten.sol#506) can be used in cross function reentrancies: + - ServiceStakingBase._calculateStakingRewards() (ServiceStakingToken-flatten.sol#646-717) + - ServiceStakingBase.setServiceIds (ServiceStakingToken-flatten.sol#506) + - ServiceStakingBase.stake(uint256) (ServiceStakingToken-flatten.sol#569-636) + - ServiceStakingBase.unstake(uint256) (ServiceStakingToken-flatten.sol#809-845) +Reentrancy in ServiceStakingBase.unstake(uint256) (ServiceStakingToken-flatten.sol#809-845): + External calls: + - IService(serviceRegistry).safeTransferFrom(address(this),msg.sender,serviceId) (ServiceStakingToken-flatten.sol#829) + State variables written after the call(s): + - delete mapServiceInfo[serviceId] (ServiceStakingToken-flatten.sol#838) + ServiceStakingBase.mapServiceInfo (ServiceStakingToken-flatten.sol#504) can be used in cross function reentrancies: + - ServiceStakingBase._calculateStakingRewards() (ServiceStakingToken-flatten.sol#646-717) + - ServiceStakingBase.calculateServiceStakingReward(uint256) (ServiceStakingToken-flatten.sol#850-879) + - ServiceStakingBase.checkpoint() (ServiceStakingToken-flatten.sol#726-805) + - ServiceStakingBase.mapServiceInfo (ServiceStakingToken-flatten.sol#504) + - ServiceStakingBase.stake(uint256) (ServiceStakingToken-flatten.sol#569-636) + - ServiceStakingBase.unstake(uint256) (ServiceStakingToken-flatten.sol#809-845) + - setServiceIds[idx] = setServiceIds[setServiceIds.length - 1] (ServiceStakingToken-flatten.sol#841) + ServiceStakingBase.setServiceIds (ServiceStakingToken-flatten.sol#506) can be used in cross function reentrancies: + - ServiceStakingBase._calculateStakingRewards() (ServiceStakingToken-flatten.sol#646-717) + - ServiceStakingBase.setServiceIds (ServiceStakingToken-flatten.sol#506) + - ServiceStakingBase.stake(uint256) (ServiceStakingToken-flatten.sol#569-636) + - ServiceStakingBase.unstake(uint256) (ServiceStakingToken-flatten.sol#809-845) + - setServiceIds.pop() (ServiceStakingToken-flatten.sol#842) + ServiceStakingBase.setServiceIds (ServiceStakingToken-flatten.sol#506) can be used in cross function reentrancies: + - ServiceStakingBase._calculateStakingRewards() (ServiceStakingToken-flatten.sol#646-717) + - ServiceStakingBase.setServiceIds (ServiceStakingToken-flatten.sol#506) + - ServiceStakingBase.stake(uint256) (ServiceStakingToken-flatten.sol#569-636) + - ServiceStakingBase.unstake(uint256) (ServiceStakingToken-flatten.sol#809-845) +Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#reentrancy-vulnerabilities-1 + +Notes: False positive. OK by design. +INFO:Detectors: +ServiceStakingBase._calculateStakingRewards().ratio (ServiceStakingToken-flatten.sol#699) is a local variable never initialized +Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#uninitialized-local-variables + +Notes: False positive. OK by design. +INFO:Detectors: +ServiceStakingBase.stake(uint256) (ServiceStakingToken-flatten.sol#569-636) ignores return value by (stakingDeposit,multisig,hash,agentThreshold,maxNumInstances,state) = IService(serviceRegistry).mapServices(serviceId) (ServiceStakingToken-flatten.sol#582-583) +Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#unused-return + +Notes: False positive. OK by design. +INFO:Detectors: +ServiceStakingBase unstake parameter from is not related to msg.sender IService(serviceRegistry).safeTransferFrom(address(this),msg.sender,serviceId) (ServiceStakingToken-flatten.sol#829) +Reference: https://ventral.digital/posts/2022/8/18/sznsdaos-bountyboard-unauthorized-transferfrom-vulnerability + +Notes: False positive. See above. +INFO:Detectors: +Reentrancy in ServiceStakingBase.stake(uint256) (ServiceStakingToken-flatten.sol#569-636): + External calls: + - IService(serviceRegistry).safeTransferFrom(msg.sender,address(this),serviceId) (ServiceStakingToken-flatten.sol#622) + State variables written after the call(s): + - sInfo.multisig = multisig (ServiceStakingToken-flatten.sol#626) + - sInfo.owner = msg.sender (ServiceStakingToken-flatten.sol#627) + - sInfo.nonce = nonce (ServiceStakingToken-flatten.sol#629) + - sInfo.tsStart = block.timestamp (ServiceStakingToken-flatten.sol#630) +Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#reentrancy-vulnerabilities-2 + +Notes: False positive. See above. +INFO:Detectors: +Reentrancy in ServiceStakingBase.stake(uint256) (ServiceStakingToken-flatten.sol#569-636): + External calls: + - IService(serviceRegistry).safeTransferFrom(msg.sender,address(this),serviceId) (ServiceStakingToken-flatten.sol#622) + Event emitted after the call(s): + - ServiceStaked(serviceId,msg.sender,multisig,nonce) (ServiceStakingToken-flatten.sol#635) +Reentrancy in ServiceStakingBase.unstake(uint256) (ServiceStakingToken-flatten.sol#809-845): + External calls: + - IService(serviceRegistry).safeTransferFrom(address(this),msg.sender,serviceId) (ServiceStakingToken-flatten.sol#829) + Event emitted after the call(s): + - ServiceUnstaked(serviceId,msg.sender,sInfo.multisig,sInfo.nonce,sInfo.reward,sInfo.tsStart) (ServiceStakingToken-flatten.sol#844) +Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#reentrancy-vulnerabilities-3 + +Notes: False positive. OK by design. +INFO:Detectors: +ServiceStakingBase._calculateStakingRewards() (ServiceStakingToken-flatten.sol#646-717) uses timestamp for comparisons + Dangerous comparisons: + - block.timestamp - tsCheckpointLast >= livenessPeriod (ServiceStakingToken-flatten.sol#668) + - ts > serviceCheckpoint (ServiceStakingToken-flatten.sol#692) + - ts > 0 (ServiceStakingToken-flatten.sol#701) + - ratio >= livenessRatio (ServiceStakingToken-flatten.sol#706) +ServiceStakingBase.unstake(uint256) (ServiceStakingToken-flatten.sol#809-845) uses timestamp for comparisons + Dangerous comparisons: + - msg.sender != sInfo.owner (ServiceStakingToken-flatten.sol#812) + - sInfo.reward > 0 (ServiceStakingToken-flatten.sol#832) +ServiceStakingBase.calculateServiceStakingReward(uint256) (ServiceStakingToken-flatten.sol#850-879) uses timestamp for comparisons + Dangerous comparisons: + - sInfo.tsStart == 0 (ServiceStakingToken-flatten.sol#856) +Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#block-timestamp + +Notes: False positive. Ignore it. +INFO:Detectors: +SafeTransferLib.safeTransferFrom(address,address,address,uint256) (ServiceStakingToken-flatten.sol#950-981) uses assembly + - INLINE ASM (ServiceStakingToken-flatten.sol#954-976) +SafeTransferLib.safeTransfer(address,address,uint256) (ServiceStakingToken-flatten.sol#992-1022) uses assembly + - INLINE ASM (ServiceStakingToken-flatten.sol#996-1017) +Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#assembly-usage + +Notes: False positive. OK by design +INFO:Detectors: +ERC721._burn(uint256) (ServiceStakingToken-flatten.sol#296-311) is never used and should be removed +ERC721._mint(address,uint256) (ServiceStakingToken-flatten.sol#281-294) is never used and should be removed +ERC721._safeMint(address,uint256) (ServiceStakingToken-flatten.sol#317-326) is never used and should be removed +ERC721._safeMint(address,uint256,bytes) (ServiceStakingToken-flatten.sol#328-341) is never used and should be removed +ServiceStakingBase._checkTokenStakingDeposit(uint256,uint256) (ServiceStakingToken-flatten.sol#555-560) is never used and should be removed +Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#dead-code + +Notes: False positive. OK by design +INFO:Detectors: +Variable ERC721._ownerOf (ServiceStakingToken-flatten.sol#155) is not in mixedCase +Variable ERC721._balanceOf (ServiceStakingToken-flatten.sol#157) is not in mixedCase +Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#conformance-to-solidity-naming-conventions + +Notes: low priority +INFO:Detectors: +Variable ServiceStakingBase.checkpoint().curServiceId_scope_1 (ServiceStakingToken-flatten.sol#774) is too similar to ServiceStakingBase.checkpoint().curServiceId_scope_3 (ServiceStakingToken-flatten.sol#792) +Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#variable-names-too-similar + +Notes: False positive. OK by design +INFO:Detectors: +SafeTransferLib.safeTransferFrom(address,address,address,uint256) (ServiceStakingToken-flatten.sol#950-981) uses literals with too many digits: + - mstore(uint256,uint256)(0,0x23b872dd00000000000000000000000000000000000000000000000000000000) (ServiceStakingToken-flatten.sol#959) +SafeTransferLib.safeTransfer(address,address,uint256) (ServiceStakingToken-flatten.sol#992-1022) uses literals with too many digits: + - mstore(uint256,uint256)(0,0xa9059cbb00000000000000000000000000000000000000000000000000000000) (ServiceStakingToken-flatten.sol#1001) +Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#too-many-digits + +Notes: False positive. OK by design +INFO:Detectors: +ERC721 (ServiceStakingToken-flatten.sol#130-342) does not implement functions: + - ERC721.tokenURI(uint256) (ServiceStakingToken-flatten.sol#149) +Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#unimplemented-functions + +Notes: False positive. OK by design +INFO:Detectors: +Function SafeTransferLib.safeTransferFrom(address,address,address,uint256) (ServiceStakingToken-flatten.sol#950-981) contains magic numbers: 4, 36, 68 +Function SafeTransferLib.safeTransfer(address,address,uint256) (ServiceStakingToken-flatten.sol#992-1022) contains magic numbers: 4, 36 +Function ServiceStakingBase.stake(uint256) (ServiceStakingToken-flatten.sol#569-636) contains magic number: 4 +Reference: https://github.com/pessimistic-io/slitherin/blob/master/docs/magic_number.md + +Notes: False positive. See above. +INFO:Detectors: +Potential vulnerable to readonly-reentrancy function (if read in other function) ServiceStakingBase.calculateServiceStakingReward(uint256) (ServiceStakingBase-flatten.sol#846-875): + State variables read that were written after the external call(s): + - ServiceStakingBase.mapServiceInfo (ServiceStakingBase-flatten.sol#500) was read at sInfo = mapServiceInfo[serviceId] (ServiceStakingBase-flatten.sol#848) + This variable was written at (after external call): + - delete mapServiceInfo[serviceId] (ServiceStakingBase-flatten.sol#834) + - sInfo.multisig = multisig (ServiceStakingBase-flatten.sol#622) + - sInfo.owner = msg.sender (ServiceStakingBase-flatten.sol#623) + - sInfo.nonce = nonce (ServiceStakingBase-flatten.sol#625) + - sInfo.tsStart = block.timestamp (ServiceStakingBase-flatten.sol#626) + - ServiceStakingBase.mapServiceInfo (ServiceStakingBase-flatten.sol#500) was read at reward = sInfo.reward (ServiceStakingBase-flatten.sol#849) + This variable was written at (after external call): + - delete mapServiceInfo[serviceId] (ServiceStakingBase-flatten.sol#834) + - sInfo.multisig = multisig (ServiceStakingBase-flatten.sol#622) + - sInfo.owner = msg.sender (ServiceStakingBase-flatten.sol#623) + - sInfo.nonce = nonce (ServiceStakingBase-flatten.sol#625) + - sInfo.tsStart = block.timestamp (ServiceStakingBase-flatten.sol#626) + - ServiceStakingBase.mapServiceInfo (ServiceStakingBase-flatten.sol#500) was read at sInfo.tsStart == 0 (ServiceStakingBase-flatten.sol#852) + This variable was written at (after external call): + - delete mapServiceInfo[serviceId] (ServiceStakingBase-flatten.sol#834) + - sInfo.multisig = multisig (ServiceStakingBase-flatten.sol#622) + - sInfo.owner = msg.sender (ServiceStakingBase-flatten.sol#623) + - sInfo.nonce = nonce (ServiceStakingBase-flatten.sol#625) + - sInfo.tsStart = block.timestamp (ServiceStakingBase-flatten.sol#626) + - ServiceStakingBase.mapServiceInfo (ServiceStakingBase-flatten.sol#500) was read at revert ServiceNotStaked(uint256)(serviceId) (ServiceStakingBase-flatten.sol#853) + This variable was written at (after external call): + - delete mapServiceInfo[serviceId] (ServiceStakingBase-flatten.sol#834) + - sInfo.multisig = multisig (ServiceStakingBase-flatten.sol#622) + - sInfo.owner = msg.sender (ServiceStakingBase-flatten.sol#623) + - sInfo.nonce = nonce (ServiceStakingBase-flatten.sol#625) + - sInfo.tsStart = block.timestamp (ServiceStakingBase-flatten.sol#626) + - ServiceStakingBase.mapServiceInfo (ServiceStakingBase-flatten.sol#500) was read at END_IF (ServiceStakingBase-flatten.sol#852-854) + This variable was written at (after external call): + - delete mapServiceInfo[serviceId] (ServiceStakingBase-flatten.sol#834) + - sInfo.multisig = multisig (ServiceStakingBase-flatten.sol#622) + - sInfo.owner = msg.sender (ServiceStakingBase-flatten.sol#623) + - sInfo.nonce = nonce (ServiceStakingBase-flatten.sol#625) + - sInfo.tsStart = block.timestamp (ServiceStakingBase-flatten.sol#626) + - ServiceStakingBase.mapServiceInfo (ServiceStakingBase-flatten.sol#500) was read at NEW VARIABLE lastAvailableRewards (ServiceStakingBase-flatten.sol#857) + This variable was written at (after external call): + - delete mapServiceInfo[serviceId] (ServiceStakingBase-flatten.sol#834) + - sInfo.multisig = multisig (ServiceStakingBase-flatten.sol#622) + - sInfo.owner = msg.sender (ServiceStakingBase-flatten.sol#623) + - sInfo.nonce = nonce (ServiceStakingBase-flatten.sol#625) + - sInfo.tsStart = block.timestamp (ServiceStakingBase-flatten.sol#626) + - ServiceStakingBase.mapServiceInfo (ServiceStakingBase-flatten.sol#500) was read at NEW VARIABLE numServices (ServiceStakingBase-flatten.sol#857) + This variable was written at (after external call): + - delete mapServiceInfo[serviceId] (ServiceStakingBase-flatten.sol#834) + - sInfo.multisig = multisig (ServiceStakingBase-flatten.sol#622) + - sInfo.owner = msg.sender (ServiceStakingBase-flatten.sol#623) + - sInfo.nonce = nonce (ServiceStakingBase-flatten.sol#625) + - sInfo.tsStart = block.timestamp (ServiceStakingBase-flatten.sol#626) + - ServiceStakingBase.mapServiceInfo (ServiceStakingBase-flatten.sol#500) was read at NEW VARIABLE totalRewards (ServiceStakingBase-flatten.sol#857) + This variable was written at (after external call): + - delete mapServiceInfo[serviceId] (ServiceStakingBase-flatten.sol#834) + - sInfo.multisig = multisig (ServiceStakingBase-flatten.sol#622) + - sInfo.owner = msg.sender (ServiceStakingBase-flatten.sol#623) + - sInfo.nonce = nonce (ServiceStakingBase-flatten.sol#625) + - sInfo.tsStart = block.timestamp (ServiceStakingBase-flatten.sol#626) + - ServiceStakingBase.mapServiceInfo (ServiceStakingBase-flatten.sol#500) was read at NEW VARIABLE eligibleServiceIds (ServiceStakingBase-flatten.sol#857) + This variable was written at (after external call): + - delete mapServiceInfo[serviceId] (ServiceStakingBase-flatten.sol#834) + - sInfo.multisig = multisig (ServiceStakingBase-flatten.sol#622) + - sInfo.owner = msg.sender (ServiceStakingBase-flatten.sol#623) + - sInfo.nonce = nonce (ServiceStakingBase-flatten.sol#625) + - sInfo.tsStart = block.timestamp (ServiceStakingBase-flatten.sol#626) + - ServiceStakingBase.mapServiceInfo (ServiceStakingBase-flatten.sol#500) was read at NEW VARIABLE eligibleServiceRewards (ServiceStakingBase-flatten.sol#858) + This variable was written at (after external call): + - delete mapServiceInfo[serviceId] (ServiceStakingBase-flatten.sol#834) + - sInfo.multisig = multisig (ServiceStakingBase-flatten.sol#622) + - sInfo.owner = msg.sender (ServiceStakingBase-flatten.sol#623) + - sInfo.nonce = nonce (ServiceStakingBase-flatten.sol#625) + - sInfo.tsStart = block.timestamp (ServiceStakingBase-flatten.sol#626) + - ServiceStakingBase.mapServiceInfo (ServiceStakingBase-flatten.sol#500) was read at (lastAvailableRewards,numServices,totalRewards,eligibleServiceIds,eligibleServiceRewards) = _calculateStakingRewards() (ServiceStakingBase-flatten.sol#857-858) + This variable was written at (after external call): + - delete mapServiceInfo[serviceId] (ServiceStakingBase-flatten.sol#834) + - sInfo.multisig = multisig (ServiceStakingBase-flatten.sol#622) + - sInfo.owner = msg.sender (ServiceStakingBase-flatten.sol#623) + - sInfo.nonce = nonce (ServiceStakingBase-flatten.sol#625) + - sInfo.tsStart = block.timestamp (ServiceStakingBase-flatten.sol#626) + - ServiceStakingBase.mapServiceInfo (ServiceStakingBase-flatten.sol#500) was read at numServices > 0 (ServiceStakingBase-flatten.sol#861) + This variable was written at (after external call): + - delete mapServiceInfo[serviceId] (ServiceStakingBase-flatten.sol#834) + - sInfo.multisig = multisig (ServiceStakingBase-flatten.sol#622) + - sInfo.owner = msg.sender (ServiceStakingBase-flatten.sol#623) + - sInfo.nonce = nonce (ServiceStakingBase-flatten.sol#625) + - sInfo.tsStart = block.timestamp (ServiceStakingBase-flatten.sol#626) + - ServiceStakingBase.mapServiceInfo (ServiceStakingBase-flatten.sol#500) was read at BEGIN_LOOP (ServiceStakingBase-flatten.sol#863-873) + This variable was written at (after external call): + - delete mapServiceInfo[serviceId] (ServiceStakingBase-flatten.sol#834) + - sInfo.multisig = multisig (ServiceStakingBase-flatten.sol#622) + - sInfo.owner = msg.sender (ServiceStakingBase-flatten.sol#623) + - sInfo.nonce = nonce (ServiceStakingBase-flatten.sol#625) + - sInfo.tsStart = block.timestamp (ServiceStakingBase-flatten.sol#626) + - ServiceStakingBase.mapServiceInfo (ServiceStakingBase-flatten.sol#500) was read at END_LOOP (ServiceStakingBase-flatten.sol#863-873) + This variable was written at (after external call): + - delete mapServiceInfo[serviceId] (ServiceStakingBase-flatten.sol#834) + - sInfo.multisig = multisig (ServiceStakingBase-flatten.sol#622) + - sInfo.owner = msg.sender (ServiceStakingBase-flatten.sol#623) + - sInfo.nonce = nonce (ServiceStakingBase-flatten.sol#625) + - sInfo.tsStart = block.timestamp (ServiceStakingBase-flatten.sol#626) + - ServiceStakingBase.mapServiceInfo (ServiceStakingBase-flatten.sol#500) was read at i = 0 (ServiceStakingBase-flatten.sol#863) + This variable was written at (after external call): + - delete mapServiceInfo[serviceId] (ServiceStakingBase-flatten.sol#834) + - sInfo.multisig = multisig (ServiceStakingBase-flatten.sol#622) + - sInfo.owner = msg.sender (ServiceStakingBase-flatten.sol#623) + - sInfo.nonce = nonce (ServiceStakingBase-flatten.sol#625) + - sInfo.tsStart = block.timestamp (ServiceStakingBase-flatten.sol#626) + - ServiceStakingBase.mapServiceInfo (ServiceStakingBase-flatten.sol#500) was read at i < eligibleServiceIds.length (ServiceStakingBase-flatten.sol#863) + This variable was written at (after external call): + - delete mapServiceInfo[serviceId] (ServiceStakingBase-flatten.sol#834) + - sInfo.multisig = multisig (ServiceStakingBase-flatten.sol#622) + - sInfo.owner = msg.sender (ServiceStakingBase-flatten.sol#623) + - sInfo.nonce = nonce (ServiceStakingBase-flatten.sol#625) + - sInfo.tsStart = block.timestamp (ServiceStakingBase-flatten.sol#626) + - ServiceStakingBase.mapServiceInfo (ServiceStakingBase-flatten.sol#500) was read at eligibleServiceIds[i] == serviceId (ServiceStakingBase-flatten.sol#864) + This variable was written at (after external call): + - delete mapServiceInfo[serviceId] (ServiceStakingBase-flatten.sol#834) + - sInfo.multisig = multisig (ServiceStakingBase-flatten.sol#622) + - sInfo.owner = msg.sender (ServiceStakingBase-flatten.sol#623) + - sInfo.nonce = nonce (ServiceStakingBase-flatten.sol#625) + - sInfo.tsStart = block.timestamp (ServiceStakingBase-flatten.sol#626) + - ServiceStakingBase.mapServiceInfo (ServiceStakingBase-flatten.sol#500) was read at totalRewards > lastAvailableRewards (ServiceStakingBase-flatten.sol#866) + This variable was written at (after external call): + - delete mapServiceInfo[serviceId] (ServiceStakingBase-flatten.sol#834) + - sInfo.multisig = multisig (ServiceStakingBase-flatten.sol#622) + - sInfo.owner = msg.sender (ServiceStakingBase-flatten.sol#623) + - sInfo.nonce = nonce (ServiceStakingBase-flatten.sol#625) + - sInfo.tsStart = block.timestamp (ServiceStakingBase-flatten.sol#626) + - ServiceStakingBase.mapServiceInfo (ServiceStakingBase-flatten.sol#500) was read at reward += (eligibleServiceRewards[i] * lastAvailableRewards) / totalRewards (ServiceStakingBase-flatten.sol#867) + This variable was written at (after external call): + - delete mapServiceInfo[serviceId] (ServiceStakingBase-flatten.sol#834) + - sInfo.multisig = multisig (ServiceStakingBase-flatten.sol#622) + - sInfo.owner = msg.sender (ServiceStakingBase-flatten.sol#623) + - sInfo.nonce = nonce (ServiceStakingBase-flatten.sol#625) + - sInfo.tsStart = block.timestamp (ServiceStakingBase-flatten.sol#626) + - ServiceStakingBase.mapServiceInfo (ServiceStakingBase-flatten.sol#500) was read at reward += eligibleServiceRewards[i] (ServiceStakingBase-flatten.sol#869) + This variable was written at (after external call): + - delete mapServiceInfo[serviceId] (ServiceStakingBase-flatten.sol#834) + - sInfo.multisig = multisig (ServiceStakingBase-flatten.sol#622) + - sInfo.owner = msg.sender (ServiceStakingBase-flatten.sol#623) + - sInfo.nonce = nonce (ServiceStakingBase-flatten.sol#625) + - sInfo.tsStart = block.timestamp (ServiceStakingBase-flatten.sol#626) + - ServiceStakingBase.mapServiceInfo (ServiceStakingBase-flatten.sol#500) was read at END_IF (ServiceStakingBase-flatten.sol#866-870) + This variable was written at (after external call): + - delete mapServiceInfo[serviceId] (ServiceStakingBase-flatten.sol#834) + - sInfo.multisig = multisig (ServiceStakingBase-flatten.sol#622) + - sInfo.owner = msg.sender (ServiceStakingBase-flatten.sol#623) + - sInfo.nonce = nonce (ServiceStakingBase-flatten.sol#625) + - sInfo.tsStart = block.timestamp (ServiceStakingBase-flatten.sol#626) + - ServiceStakingBase.mapServiceInfo (ServiceStakingBase-flatten.sol#500) was read at BREAK (ServiceStakingBase-flatten.sol#871) + This variable was written at (after external call): + - delete mapServiceInfo[serviceId] (ServiceStakingBase-flatten.sol#834) + - sInfo.multisig = multisig (ServiceStakingBase-flatten.sol#622) + - sInfo.owner = msg.sender (ServiceStakingBase-flatten.sol#623) + - sInfo.nonce = nonce (ServiceStakingBase-flatten.sol#625) + - sInfo.tsStart = block.timestamp (ServiceStakingBase-flatten.sol#626) + - ServiceStakingBase.mapServiceInfo (ServiceStakingBase-flatten.sol#500) was read at END_IF (ServiceStakingBase-flatten.sol#864-872) + This variable was written at (after external call): + - delete mapServiceInfo[serviceId] (ServiceStakingBase-flatten.sol#834) + - sInfo.multisig = multisig (ServiceStakingBase-flatten.sol#622) + - sInfo.owner = msg.sender (ServiceStakingBase-flatten.sol#623) + - sInfo.nonce = nonce (ServiceStakingBase-flatten.sol#625) + - sInfo.tsStart = block.timestamp (ServiceStakingBase-flatten.sol#626) + - ServiceStakingBase.mapServiceInfo (ServiceStakingBase-flatten.sol#500) was read at ++ i (ServiceStakingBase-flatten.sol#863) + This variable was written at (after external call): + - delete mapServiceInfo[serviceId] (ServiceStakingBase-flatten.sol#834) + - sInfo.multisig = multisig (ServiceStakingBase-flatten.sol#622) + - sInfo.owner = msg.sender (ServiceStakingBase-flatten.sol#623) + - sInfo.nonce = nonce (ServiceStakingBase-flatten.sol#625) + - sInfo.tsStart = block.timestamp (ServiceStakingBase-flatten.sol#626) + - ServiceStakingBase.mapServiceInfo (ServiceStakingBase-flatten.sol#500) was read at END_IF (ServiceStakingBase-flatten.sol#861-874) + This variable was written at (after external call): + - delete mapServiceInfo[serviceId] (ServiceStakingBase-flatten.sol#834) + - sInfo.multisig = multisig (ServiceStakingBase-flatten.sol#622) + - sInfo.owner = msg.sender (ServiceStakingBase-flatten.sol#623) + - sInfo.nonce = nonce (ServiceStakingBase-flatten.sol#625) + - sInfo.tsStart = block.timestamp (ServiceStakingBase-flatten.sol#626) + - ServiceStakingBase.setServiceIds (ServiceStakingBase-flatten.sol#502) was read at (lastAvailableRewards,numServices,totalRewards,eligibleServiceIds,eligibleServiceRewards) = _calculateStakingRewards() (ServiceStakingBase-flatten.sol#857-858) + This variable was written at (after external call): + - setServiceIds[idx] = setServiceIds[setServiceIds.length - 1] (ServiceStakingBase-flatten.sol#837) + - setServiceIds.pop() (ServiceStakingBase-flatten.sol#838) + - setServiceIds.push(serviceId) (ServiceStakingBase-flatten.sol#629) + - ServiceStakingBase.setServiceIds (ServiceStakingBase-flatten.sol#502) was read at numServices > 0 (ServiceStakingBase-flatten.sol#861) + This variable was written at (after external call): + - setServiceIds[idx] = setServiceIds[setServiceIds.length - 1] (ServiceStakingBase-flatten.sol#837) + - setServiceIds.pop() (ServiceStakingBase-flatten.sol#838) + - setServiceIds.push(serviceId) (ServiceStakingBase-flatten.sol#629) + - ServiceStakingBase.setServiceIds (ServiceStakingBase-flatten.sol#502) was read at BEGIN_LOOP (ServiceStakingBase-flatten.sol#863-873) + This variable was written at (after external call): + - setServiceIds[idx] = setServiceIds[setServiceIds.length - 1] (ServiceStakingBase-flatten.sol#837) + - setServiceIds.pop() (ServiceStakingBase-flatten.sol#838) + - setServiceIds.push(serviceId) (ServiceStakingBase-flatten.sol#629) + - ServiceStakingBase.setServiceIds (ServiceStakingBase-flatten.sol#502) was read at END_LOOP (ServiceStakingBase-flatten.sol#863-873) + This variable was written at (after external call): + - setServiceIds[idx] = setServiceIds[setServiceIds.length - 1] (ServiceStakingBase-flatten.sol#837) + - setServiceIds.pop() (ServiceStakingBase-flatten.sol#838) + - setServiceIds.push(serviceId) (ServiceStakingBase-flatten.sol#629) + - ServiceStakingBase.setServiceIds (ServiceStakingBase-flatten.sol#502) was read at i = 0 (ServiceStakingBase-flatten.sol#863) + This variable was written at (after external call): + - setServiceIds[idx] = setServiceIds[setServiceIds.length - 1] (ServiceStakingBase-flatten.sol#837) + - setServiceIds.pop() (ServiceStakingBase-flatten.sol#838) + - setServiceIds.push(serviceId) (ServiceStakingBase-flatten.sol#629) + - ServiceStakingBase.setServiceIds (ServiceStakingBase-flatten.sol#502) was read at i < eligibleServiceIds.length (ServiceStakingBase-flatten.sol#863) + This variable was written at (after external call): + - setServiceIds[idx] = setServiceIds[setServiceIds.length - 1] (ServiceStakingBase-flatten.sol#837) + - setServiceIds.pop() (ServiceStakingBase-flatten.sol#838) + - setServiceIds.push(serviceId) (ServiceStakingBase-flatten.sol#629) + - ServiceStakingBase.setServiceIds (ServiceStakingBase-flatten.sol#502) was read at eligibleServiceIds[i] == serviceId (ServiceStakingBase-flatten.sol#864) + This variable was written at (after external call): + - setServiceIds[idx] = setServiceIds[setServiceIds.length - 1] (ServiceStakingBase-flatten.sol#837) + - setServiceIds.pop() (ServiceStakingBase-flatten.sol#838) + - setServiceIds.push(serviceId) (ServiceStakingBase-flatten.sol#629) + - ServiceStakingBase.setServiceIds (ServiceStakingBase-flatten.sol#502) was read at totalRewards > lastAvailableRewards (ServiceStakingBase-flatten.sol#866) + This variable was written at (after external call): + - setServiceIds[idx] = setServiceIds[setServiceIds.length - 1] (ServiceStakingBase-flatten.sol#837) + - setServiceIds.pop() (ServiceStakingBase-flatten.sol#838) + - setServiceIds.push(serviceId) (ServiceStakingBase-flatten.sol#629) + - ServiceStakingBase.setServiceIds (ServiceStakingBase-flatten.sol#502) was read at reward += (eligibleServiceRewards[i] * lastAvailableRewards) / totalRewards (ServiceStakingBase-flatten.sol#867) + This variable was written at (after external call): + - setServiceIds[idx] = setServiceIds[setServiceIds.length - 1] (ServiceStakingBase-flatten.sol#837) + - setServiceIds.pop() (ServiceStakingBase-flatten.sol#838) + - setServiceIds.push(serviceId) (ServiceStakingBase-flatten.sol#629) + - ServiceStakingBase.setServiceIds (ServiceStakingBase-flatten.sol#502) was read at reward += eligibleServiceRewards[i] (ServiceStakingBase-flatten.sol#869) + This variable was written at (after external call): + - setServiceIds[idx] = setServiceIds[setServiceIds.length - 1] (ServiceStakingBase-flatten.sol#837) + - setServiceIds.pop() (ServiceStakingBase-flatten.sol#838) + - setServiceIds.push(serviceId) (ServiceStakingBase-flatten.sol#629) + - ServiceStakingBase.setServiceIds (ServiceStakingBase-flatten.sol#502) was read at END_IF (ServiceStakingBase-flatten.sol#866-870) + This variable was written at (after external call): + - setServiceIds[idx] = setServiceIds[setServiceIds.length - 1] (ServiceStakingBase-flatten.sol#837) + - setServiceIds.pop() (ServiceStakingBase-flatten.sol#838) + - setServiceIds.push(serviceId) (ServiceStakingBase-flatten.sol#629) + - ServiceStakingBase.setServiceIds (ServiceStakingBase-flatten.sol#502) was read at BREAK (ServiceStakingBase-flatten.sol#871) + This variable was written at (after external call): + - setServiceIds[idx] = setServiceIds[setServiceIds.length - 1] (ServiceStakingBase-flatten.sol#837) + - setServiceIds.pop() (ServiceStakingBase-flatten.sol#838) + - setServiceIds.push(serviceId) (ServiceStakingBase-flatten.sol#629) + - ServiceStakingBase.setServiceIds (ServiceStakingBase-flatten.sol#502) was read at END_IF (ServiceStakingBase-flatten.sol#864-872) + This variable was written at (after external call): + - setServiceIds[idx] = setServiceIds[setServiceIds.length - 1] (ServiceStakingBase-flatten.sol#837) + - setServiceIds.pop() (ServiceStakingBase-flatten.sol#838) + - setServiceIds.push(serviceId) (ServiceStakingBase-flatten.sol#629) + - ServiceStakingBase.setServiceIds (ServiceStakingBase-flatten.sol#502) was read at ++ i (ServiceStakingBase-flatten.sol#863) + This variable was written at (after external call): + - setServiceIds[idx] = setServiceIds[setServiceIds.length - 1] (ServiceStakingBase-flatten.sol#837) + - setServiceIds.pop() (ServiceStakingBase-flatten.sol#838) + - setServiceIds.push(serviceId) (ServiceStakingBase-flatten.sol#629) + - ServiceStakingBase.setServiceIds (ServiceStakingBase-flatten.sol#502) was read at END_IF (ServiceStakingBase-flatten.sol#861-874) + This variable was written at (after external call): + - setServiceIds[idx] = setServiceIds[setServiceIds.length - 1] (ServiceStakingBase-flatten.sol#837) + - setServiceIds.pop() (ServiceStakingBase-flatten.sol#838) + - setServiceIds.push(serviceId) (ServiceStakingBase-flatten.sol#629) +Reference: https://github.com/pessimistic-io/slitherin/blob/master/docs/readonly_reentrancy.md + +Notes: False positive. OK by design +INFO:Detectors: +ServiceStakingBase.calculateServiceStakingReward(uint256) (ServiceStakingBase-flatten.sol#846-875) uses a dangerous strict equality: + - sInfo.tsStart == 0 (ServiceStakingBase-flatten.sol#852) +Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#dangerous-strict-equalities + +Notes: False positive. OK by design +INFO:Detectors: +Reentrancy in ServiceStakingBase.stake(uint256) (ServiceStakingBase-flatten.sol#565-632): + External calls: + - IService(serviceRegistry).safeTransferFrom(msg.sender,address(this),serviceId) (ServiceStakingBase-flatten.sol#618) + State variables written after the call(s): + - setServiceIds.push(serviceId) (ServiceStakingBase-flatten.sol#629) + ServiceStakingBase.setServiceIds (ServiceStakingBase-flatten.sol#502) can be used in cross function reentrancies: + - ServiceStakingBase._calculateStakingRewards() (ServiceStakingBase-flatten.sol#642-713) + - ServiceStakingBase.setServiceIds (ServiceStakingBase-flatten.sol#502) + - ServiceStakingBase.stake(uint256) (ServiceStakingBase-flatten.sol#565-632) + - ServiceStakingBase.unstake(uint256) (ServiceStakingBase-flatten.sol#805-841) +Reentrancy in ServiceStakingBase.unstake(uint256) (ServiceStakingBase-flatten.sol#805-841): + External calls: + - IService(serviceRegistry).safeTransferFrom(address(this),msg.sender,serviceId) (ServiceStakingBase-flatten.sol#825) + State variables written after the call(s): + - delete mapServiceInfo[serviceId] (ServiceStakingBase-flatten.sol#834) + ServiceStakingBase.mapServiceInfo (ServiceStakingBase-flatten.sol#500) can be used in cross function reentrancies: + - ServiceStakingBase._calculateStakingRewards() (ServiceStakingBase-flatten.sol#642-713) + - ServiceStakingBase.calculateServiceStakingReward(uint256) (ServiceStakingBase-flatten.sol#846-875) + - ServiceStakingBase.checkpoint() (ServiceStakingBase-flatten.sol#722-801) + - ServiceStakingBase.mapServiceInfo (ServiceStakingBase-flatten.sol#500) + - ServiceStakingBase.stake(uint256) (ServiceStakingBase-flatten.sol#565-632) + - ServiceStakingBase.unstake(uint256) (ServiceStakingBase-flatten.sol#805-841) + - setServiceIds[idx] = setServiceIds[setServiceIds.length - 1] (ServiceStakingBase-flatten.sol#837) + ServiceStakingBase.setServiceIds (ServiceStakingBase-flatten.sol#502) can be used in cross function reentrancies: + - ServiceStakingBase._calculateStakingRewards() (ServiceStakingBase-flatten.sol#642-713) + - ServiceStakingBase.setServiceIds (ServiceStakingBase-flatten.sol#502) + - ServiceStakingBase.stake(uint256) (ServiceStakingBase-flatten.sol#565-632) + - ServiceStakingBase.unstake(uint256) (ServiceStakingBase-flatten.sol#805-841) + - setServiceIds.pop() (ServiceStakingBase-flatten.sol#838) + ServiceStakingBase.setServiceIds (ServiceStakingBase-flatten.sol#502) can be used in cross function reentrancies: + - ServiceStakingBase._calculateStakingRewards() (ServiceStakingBase-flatten.sol#642-713) + - ServiceStakingBase.setServiceIds (ServiceStakingBase-flatten.sol#502) + - ServiceStakingBase.stake(uint256) (ServiceStakingBase-flatten.sol#565-632) + - ServiceStakingBase.unstake(uint256) (ServiceStakingBase-flatten.sol#805-841) +Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#reentrancy-vulnerabilities-1 + +Notes: False positive. OK by design +INFO:Detectors: +ServiceStakingBase._calculateStakingRewards().ratio (ServiceStakingBase-flatten.sol#695) is a local variable never initialized +Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#uninitialized-local-variables + +Notes: False positive. OK by design +INFO:Detectors: +ServiceStakingBase.stake(uint256) (ServiceStakingBase-flatten.sol#565-632) ignores return value by (stakingDeposit,multisig,hash,agentThreshold,maxNumInstances,state) = IService(serviceRegistry).mapServices(serviceId) (ServiceStakingBase-flatten.sol#578-579) +Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#unused-return +INFO:Detectors: +ServiceStakingBase unstake parameter from is not related to msg.sender IService(serviceRegistry).safeTransferFrom(address(this),msg.sender,serviceId) (ServiceStakingBase-flatten.sol#825) +Reference: https://ventral.digital/posts/2022/8/18/sznsdaos-bountyboard-unauthorized-transferfrom-vulnerability + +Notes: False positive. See above +INFO:Detectors: +Reentrancy in ServiceStakingBase.stake(uint256) (ServiceStakingBase-flatten.sol#565-632): + External calls: + - IService(serviceRegistry).safeTransferFrom(msg.sender,address(this),serviceId) (ServiceStakingBase-flatten.sol#618) + State variables written after the call(s): + - sInfo.multisig = multisig (ServiceStakingBase-flatten.sol#622) + - sInfo.owner = msg.sender (ServiceStakingBase-flatten.sol#623) + - sInfo.nonce = nonce (ServiceStakingBase-flatten.sol#625) + - sInfo.tsStart = block.timestamp (ServiceStakingBase-flatten.sol#626) +Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#reentrancy-vulnerabilities-2 + +Notes: False positive. See above +INFO:Detectors: +Reentrancy in ServiceStakingBase.stake(uint256) (ServiceStakingBase-flatten.sol#565-632): + External calls: + - IService(serviceRegistry).safeTransferFrom(msg.sender,address(this),serviceId) (ServiceStakingBase-flatten.sol#618) + Event emitted after the call(s): + - ServiceStaked(serviceId,msg.sender,multisig,nonce) (ServiceStakingBase-flatten.sol#631) + +Notes: False positive. See above +Reentrancy in ServiceStakingBase.unstake(uint256) (ServiceStakingBase-flatten.sol#805-841): + External calls: + - IService(serviceRegistry).safeTransferFrom(address(this),msg.sender,serviceId) (ServiceStakingBase-flatten.sol#825) + Event emitted after the call(s): + - ServiceUnstaked(serviceId,msg.sender,sInfo.multisig,sInfo.nonce,sInfo.reward,sInfo.tsStart) (ServiceStakingBase-flatten.sol#840) +Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#reentrancy-vulnerabilities-3 + +Notes: False positive. OK by design +INFO:Detectors: +ServiceStakingBase._calculateStakingRewards() (ServiceStakingBase-flatten.sol#642-713) uses timestamp for comparisons + Dangerous comparisons: + - block.timestamp - tsCheckpointLast >= livenessPeriod (ServiceStakingBase-flatten.sol#664) + - ts > serviceCheckpoint (ServiceStakingBase-flatten.sol#688) + - ts > 0 (ServiceStakingBase-flatten.sol#697) + - ratio >= livenessRatio (ServiceStakingBase-flatten.sol#702) +ServiceStakingBase.unstake(uint256) (ServiceStakingBase-flatten.sol#805-841) uses timestamp for comparisons + Dangerous comparisons: + - msg.sender != sInfo.owner (ServiceStakingBase-flatten.sol#808) + - sInfo.reward > 0 (ServiceStakingBase-flatten.sol#828) +ServiceStakingBase.calculateServiceStakingReward(uint256) (ServiceStakingBase-flatten.sol#846-875) uses timestamp for comparisons + Dangerous comparisons: + - sInfo.tsStart == 0 (ServiceStakingBase-flatten.sol#852) +Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#block-timestamp + +Notes: False positive. Ignore it. +INFO:Detectors: +ERC721._burn(uint256) (ServiceStakingBase-flatten.sol#292-307) is never used and should be removed +ERC721._mint(address,uint256) (ServiceStakingBase-flatten.sol#277-290) is never used and should be removed +ERC721._safeMint(address,uint256) (ServiceStakingBase-flatten.sol#313-322) is never used and should be removed +ERC721._safeMint(address,uint256,bytes) (ServiceStakingBase-flatten.sol#324-337) is never used and should be removed +Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#dead-code + +Notes: False positive. Ignore it. +INFO:Detectors: +Variable ERC721._ownerOf (ServiceStakingBase-flatten.sol#151) is not in mixedCase +Variable ERC721._balanceOf (ServiceStakingBase-flatten.sol#153) is not in mixedCase +Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#conformance-to-solidity-naming-conventions + +Notes: low priority +INFO:Detectors: +Variable ServiceStakingBase.checkpoint().curServiceId_scope_1 (ServiceStakingBase-flatten.sol#770) is too similar to ServiceStakingBase.checkpoint().curServiceId_scope_3 (ServiceStakingBase-flatten.sol#788) +Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#variable-names-too-similar + +Notes: False positive. OK by design +INFO:Detectors: +ERC721 (ServiceStakingBase-flatten.sol#126-338) does not implement functions: + - ERC721.tokenURI(uint256) (ServiceStakingBase-flatten.sol#145) +ServiceStakingBase (ServiceStakingBase-flatten.sol#441-876) does not implement functions: + - ServiceStakingBase._withdraw(address,uint256) (ServiceStakingBase-flatten.sol#561) +Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#unimplemented-functions + +Notes: low priority +INFO:Detectors: +Function ServiceStakingBase.stake(uint256) (ServiceStakingBase-flatten.sol#565-632) contains magic number: 4 +Reference: https://github.com/pessimistic-io/slitherin/blob/master/docs/magic_number.md + +Notes: False positive. Wrong. +INFO:Detectors: +ServiceStakingBase.balance (ServiceStakingBase-flatten.sol#492) should be constant +Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#state-variables-that-could-be-declared-constant + +Notes: False positive. +INFO:Detectors: +In a function ServiceStakingBase.stake(uint256) (ServiceStakingBase-flatten.sol#565-632) variable ServiceStakingBase.agentIds (ServiceStakingBase-flatten.sol#498) is read multiple times +In a function ServiceStakingBase.stake(uint256) (ServiceStakingBase-flatten.sol#565-632) variable ServiceStakingBase.serviceRegistry (ServiceStakingBase-flatten.sol#489) is read multiple times +In a function ServiceStakingBase.checkpoint() (ServiceStakingBase-flatten.sol#722-801) variable ServiceStakingBase.mapServiceInfo (ServiceStakingBase-flatten.sol#500) is read multiple times +Reference: https://github.com/pessimistic-io/slitherin/blob/master/docs/multiple_storage_read.md +INFO:Slither:. analyzed (23 contracts with 108 detectors), 89 result(s) found diff --git a/audits/internal4/analysis/slither_function-summary.txt b/audits/internal4/analysis/slither_function-summary.txt new file mode 100644 index 00000000..ff9fb742 --- /dev/null +++ b/audits/internal4/analysis/slither_function-summary.txt @@ -0,0 +1,589 @@ +'solc --version' running +'solc ./ServiceStakingNativeToken-flatten.sol --combined-json abi,ast,bin,bin-runtime,srcmap,srcmap-runtime,userdoc,devdoc,hashes --allow-paths .,/home/andrey/valory/autonolas-registries/audits/internal4/analysis/contracts' running +'solc --version' running +'solc ./ServiceStakingToken-flatten.sol --combined-json abi,ast,bin,bin-runtime,srcmap,srcmap-runtime,userdoc,devdoc,hashes --allow-paths .,/home/andrey/valory/autonolas-registries/audits/internal4/analysis/contracts' running +'solc --version' running +'solc ./ServiceStakingBase-flatten.sol --combined-json abi,ast,bin,bin-runtime,srcmap,srcmap-runtime,userdoc,devdoc,hashes --allow-paths .,/home/andrey/valory/autonolas-registries/audits/internal4/analysis/contracts' running +INFO:Printers: +Contract IErrorsRegistries +Contract vars: [] +Inheritance:: [] + ++----------+------------+-----------+------+-------+----------------+----------------+-----------------------+ +| Function | Visibility | Modifiers | Read | Write | Internal Calls | External Calls | Cyclomatic Complexity | ++----------+------------+-----------+------+-------+----------------+----------------+-----------------------+ ++----------+------------+-----------+------+-------+----------------+----------------+-----------------------+ + ++-----------+------------+------+-------+----------------+----------------+-----------------------+ +| Modifiers | Visibility | Read | Write | Internal Calls | External Calls | Cyclomatic Complexity | ++-----------+------------+------+-------+----------------+----------------+-----------------------+ ++-----------+------------+------+-------+----------------+----------------+-----------------------+ + +INFO:Printers: +Contract ERC721 +Contract vars: ['name', 'symbol', '_ownerOf', '_balanceOf', 'getApproved', 'isApprovedForAll'] +Inheritance:: [] + ++-------------------------------------------------+------------+-----------+-------------------------------------+----------------------------+-------------------------------------------+-----------------------------------------------------------------------------+-----------------------+ +| Function | Visibility | Modifiers | Read | Write | Internal Calls | External Calls | Cyclomatic Complexity | ++-------------------------------------------------+------------+-----------+-------------------------------------+----------------------------+-------------------------------------------+-----------------------------------------------------------------------------+-----------------------+ +| tokenURI(uint256) | public | [] | [] | [] | [] | [] | 2 | +| ownerOf(uint256) | public | [] | ['_ownerOf'] | [] | ['require(bool,string)'] | [] | 1 | +| balanceOf(address) | public | [] | ['_balanceOf'] | [] | ['require(bool,string)'] | [] | 1 | +| constructor(string,string) | internal | [] | [] | ['name', 'symbol'] | [] | [] | 1 | +| approve(address,uint256) | public | [] | ['_ownerOf', 'isApprovedForAll'] | ['getApproved'] | ['require(bool,string)'] | [] | 1 | +| | | | ['msg.sender'] | | | | | +| setApprovalForAll(address,bool) | public | [] | ['msg.sender'] | ['isApprovedForAll'] | [] | [] | 1 | +| transferFrom(address,address,uint256) | public | [] | ['_balanceOf', '_ownerOf'] | ['_balanceOf', '_ownerOf'] | ['require(bool,string)'] | [] | 1 | +| | | | ['getApproved', 'isApprovedForAll'] | ['getApproved'] | | | | +| | | | ['msg.sender'] | | | | | +| safeTransferFrom(address,address,uint256) | public | [] | ['msg.sender'] | [] | ['code(address)', 'require(bool,string)'] | ['ERC721TokenReceiver(to).onERC721Received(msg.sender,from,id,)'] | 2 | +| | | | | | ['transferFrom'] | | | +| safeTransferFrom(address,address,uint256,bytes) | public | [] | ['msg.sender'] | [] | ['code(address)', 'require(bool,string)'] | ['ERC721TokenReceiver(to).onERC721Received(msg.sender,from,id,data)'] | 2 | +| | | | | | ['transferFrom'] | | | +| supportsInterface(bytes4) | public | [] | [] | [] | [] | [] | 1 | +| _mint(address,uint256) | internal | [] | ['_balanceOf', '_ownerOf'] | ['_balanceOf', '_ownerOf'] | ['require(bool,string)'] | [] | 1 | +| _burn(uint256) | internal | [] | ['_balanceOf', '_ownerOf'] | ['_balanceOf', '_ownerOf'] | ['require(bool,string)'] | [] | 1 | +| | | | ['getApproved'] | ['getApproved'] | | | | +| _safeMint(address,uint256) | internal | [] | ['msg.sender'] | [] | ['_mint', 'code(address)'] | ['ERC721TokenReceiver(to).onERC721Received(msg.sender,address(0),id,)'] | 2 | +| | | | | | ['require(bool,string)'] | | | +| _safeMint(address,uint256,bytes) | internal | [] | ['msg.sender'] | [] | ['_mint', 'code(address)'] | ['ERC721TokenReceiver(to).onERC721Received(msg.sender,address(0),id,data)'] | 2 | +| | | | | | ['require(bool,string)'] | | | ++-------------------------------------------------+------------+-----------+-------------------------------------+----------------------------+-------------------------------------------+-----------------------------------------------------------------------------+-----------------------+ + ++-----------+------------+------+-------+----------------+----------------+-----------------------+ +| Modifiers | Visibility | Read | Write | Internal Calls | External Calls | Cyclomatic Complexity | ++-----------+------------+------+-------+----------------+----------------+-----------------------+ ++-----------+------------+------+-------+----------------+----------------+-----------------------+ + +INFO:Printers: +Contract ERC721TokenReceiver +Contract vars: [] +Inheritance:: [] + ++-------------------------------------------------+------------+-----------+------+-------+----------------+----------------+-----------------------+ +| Function | Visibility | Modifiers | Read | Write | Internal Calls | External Calls | Cyclomatic Complexity | ++-------------------------------------------------+------------+-----------+------+-------+----------------+----------------+-----------------------+ +| onERC721Received(address,address,uint256,bytes) | external | [] | [] | [] | [] | [] | 1 | ++-------------------------------------------------+------------+-----------+------+-------+----------------+----------------+-----------------------+ + ++-----------+------------+------+-------+----------------+----------------+-----------------------+ +| Modifiers | Visibility | Read | Write | Internal Calls | External Calls | Cyclomatic Complexity | ++-----------+------------+------+-------+----------------+----------------+-----------------------+ ++-----------+------------+------+-------+----------------+----------------+-----------------------+ + +INFO:Printers: +Contract IMultisig +Contract vars: [] +Inheritance:: [] + ++----------+------------+-----------+------+-------+----------------+----------------+-----------------------+ +| Function | Visibility | Modifiers | Read | Write | Internal Calls | External Calls | Cyclomatic Complexity | ++----------+------------+-----------+------+-------+----------------+----------------+-----------------------+ +| nonce() | external | [] | [] | [] | [] | [] | 2 | ++----------+------------+-----------+------+-------+----------------+----------------+-----------------------+ + ++-----------+------------+------+-------+----------------+----------------+-----------------------+ +| Modifiers | Visibility | Read | Write | Internal Calls | External Calls | Cyclomatic Complexity | ++-----------+------------+------+-------+----------------+----------------+-----------------------+ ++-----------+------------+------+-------+----------------+----------------+-----------------------+ + +INFO:Printers: +Contract IService +Contract vars: [] +Inheritance:: [] + ++------------------------------------------------+------------+-----------+------+-------+----------------+----------------+-----------------------+ +| Function | Visibility | Modifiers | Read | Write | Internal Calls | External Calls | Cyclomatic Complexity | ++------------------------------------------------+------------+-----------+------+-------+----------------+----------------+-----------------------+ +| safeTransferFrom(address,address,uint256) | external | [] | [] | [] | [] | [] | 2 | +| mapServices(uint256) | external | [] | [] | [] | [] | [] | 2 | +| getUnitIdsOfService(IService.UnitType,uint256) | external | [] | [] | [] | [] | [] | 2 | ++------------------------------------------------+------------+-----------+------+-------+----------------+----------------+-----------------------+ + ++-----------+------------+------+-------+----------------+----------------+-----------------------+ +| Modifiers | Visibility | Read | Write | Internal Calls | External Calls | Cyclomatic Complexity | ++-----------+------------+------+-------+----------------+----------------+-----------------------+ ++-----------+------------+------+-------+----------------+----------------+-----------------------+ + +INFO:Printers: +Contract ServiceStakingBase +Contract vars: ['VERSION', 'maxNumServices', 'rewardsPerSecond', 'minStakingDeposit', 'livenessPeriod', 'livenessRatio', 'numAgentInstances', 'threshold', 'configHash', 'serviceRegistry', 'balance', 'availableRewards', 'tsCheckpoint', 'agentIds', 'mapServiceInfo', 'setServiceIds'] +Inheritance:: ['IErrorsRegistries', 'ERC721TokenReceiver'] + ++-------------------------------------------------------+------------+-----------+-----------------------------------------+-------------------------------------------+--------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------+-----------------------+ +| Function | Visibility | Modifiers | Read | Write | Internal Calls | External Calls | Cyclomatic Complexity | ++-------------------------------------------------------+------------+-----------+-----------------------------------------+-------------------------------------------+--------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------+-----------------------+ +| onERC721Received(address,address,uint256,bytes) | external | [] | [] | [] | [] | [] | 1 | +| constructor(ServiceStakingBase.StakingParams,address) | internal | [] | ['agentIds', 'block.timestamp'] | ['agentIds', 'configHash'] | ['revert WrongAgentId(uint256)', 'revert ZeroAddress()'] | ['agentIds.push(agentId)'] | 6 | +| | | | | ['livenessPeriod', 'livenessRatio'] | ['revert ZeroValue()'] | | | +| | | | | ['maxNumServices', 'minStakingDeposit'] | | | | +| | | | | ['numAgentInstances', 'rewardsPerSecond'] | | | | +| | | | | ['serviceRegistry', 'threshold'] | | | | +| | | | | ['tsCheckpoint'] | | | | +| _checkTokenStakingDeposit(uint256,uint256) | internal | [] | ['minStakingDeposit'] | [] | ['revert LowerThan(uint256,uint256)'] | [] | 2 | +| _withdraw(address,uint256) | internal | [] | [] | [] | [] | [] | 2 | +| stake(uint256) | external | [] | ['agentIds', 'availableRewards'] | ['mapServiceInfo', 'setServiceIds'] | ['_checkTokenStakingDeposit', 'revert MaxNumServicesReached(uint256)'] | ['IMultisig(multisig).nonce()', 'IService(serviceRegistry).getUnitIdsOfService(IService.UnitType.Agent,serviceId)'] | 11 | +| | | | ['block.timestamp', 'configHash'] | | ['revert NoRewardsAvailable()', 'revert WrongAgentId(uint256)'] | ['IService(serviceRegistry).mapServices(serviceId)', 'IService(serviceRegistry).safeTransferFrom(msg.sender,address(this),serviceId)'] | | +| | | | ['mapServiceInfo', 'maxNumServices'] | | ['revert WrongServiceConfiguration(uint256)', 'revert WrongServiceState(uint256,uint256)'] | ['setServiceIds.push(serviceId)'] | | +| | | | ['msg.sender', 'numAgentInstances'] | | | | | +| | | | ['serviceRegistry', 'setServiceIds'] | | | | | +| | | | ['this', 'threshold'] | | | | | +| _calculateStakingRewards() | internal | [] | ['availableRewards', 'block.timestamp'] | [] | [] | ['IMultisig(curInfo.multisig).nonce()', 'new uint256[](size)'] | 8 | +| | | | ['livenessPeriod', 'livenessRatio'] | | | ['new uint256[](size)', 'new uint256[](size)'] | | +| | | | ['mapServiceInfo', 'rewardsPerSecond'] | | | ['new uint256[](size)'] | | +| | | | ['setServiceIds', 'tsCheckpoint'] | | | | | +| checkpoint() | public | [] | ['block.timestamp', 'mapServiceInfo'] | ['availableRewards', 'mapServiceInfo'] | ['_calculateStakingRewards'] | [] | 8 | +| | | | | ['tsCheckpoint'] | | | | +| unstake(uint256) | external | [] | ['mapServiceInfo', 'msg.sender'] | ['mapServiceInfo', 'setServiceIds'] | ['_withdraw', 'checkpoint'] | ['IService(serviceRegistry).safeTransferFrom(address(this),msg.sender,serviceId)', 'setServiceIds.pop()'] | 5 | +| | | | ['serviceRegistry', 'setServiceIds'] | | ['revert OwnerOnly(address,address)'] | | | +| | | | ['this'] | | | | | +| calculateServiceStakingReward(uint256) | external | [] | ['mapServiceInfo'] | [] | ['_calculateStakingRewards', 'revert ServiceNotStaked(uint256)'] | [] | 6 | +| slitherConstructorConstantVariables() | internal | [] | [] | ['VERSION'] | [] | [] | 1 | ++-------------------------------------------------------+------------+-----------+-----------------------------------------+-------------------------------------------+--------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------+-----------------------+ + ++-----------+------------+------+-------+----------------+----------------+-----------------------+ +| Modifiers | Visibility | Read | Write | Internal Calls | External Calls | Cyclomatic Complexity | ++-----------+------------+------+-------+----------------+----------------+-----------------------+ ++-----------+------------+------+-------+----------------+----------------+-----------------------+ + +INFO:Printers: +Contract ServiceStakingNativeToken +Contract vars: ['VERSION', 'maxNumServices', 'rewardsPerSecond', 'minStakingDeposit', 'livenessPeriod', 'livenessRatio', 'numAgentInstances', 'threshold', 'configHash', 'serviceRegistry', 'balance', 'availableRewards', 'tsCheckpoint', 'agentIds', 'mapServiceInfo', 'setServiceIds'] +Inheritance:: ['ServiceStakingBase', 'IErrorsRegistries', 'ERC721TokenReceiver'] + ++-------------------------------------------------------+------------+-----------+-----------------------------------------+-------------------------------------------+--------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------+-----------------------+ +| Function | Visibility | Modifiers | Read | Write | Internal Calls | External Calls | Cyclomatic Complexity | ++-------------------------------------------------------+------------+-----------+-----------------------------------------+-------------------------------------------+--------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------+-----------------------+ +| constructor(ServiceStakingBase.StakingParams,address) | internal | [] | ['agentIds', 'block.timestamp'] | ['agentIds', 'configHash'] | ['revert WrongAgentId(uint256)', 'revert ZeroAddress()'] | ['agentIds.push(agentId)'] | 6 | +| | | | | ['livenessPeriod', 'livenessRatio'] | ['revert ZeroValue()'] | | | +| | | | | ['maxNumServices', 'minStakingDeposit'] | | | | +| | | | | ['numAgentInstances', 'rewardsPerSecond'] | | | | +| | | | | ['serviceRegistry', 'threshold'] | | | | +| | | | | ['tsCheckpoint'] | | | | +| _checkTokenStakingDeposit(uint256,uint256) | internal | [] | ['minStakingDeposit'] | [] | ['revert LowerThan(uint256,uint256)'] | [] | 2 | +| _withdraw(address,uint256) | internal | [] | [] | [] | [] | [] | 2 | +| stake(uint256) | external | [] | ['agentIds', 'availableRewards'] | ['mapServiceInfo', 'setServiceIds'] | ['_checkTokenStakingDeposit', 'revert MaxNumServicesReached(uint256)'] | ['IMultisig(multisig).nonce()', 'IService(serviceRegistry).getUnitIdsOfService(IService.UnitType.Agent,serviceId)'] | 11 | +| | | | ['block.timestamp', 'configHash'] | | ['revert NoRewardsAvailable()', 'revert WrongAgentId(uint256)'] | ['IService(serviceRegistry).mapServices(serviceId)', 'IService(serviceRegistry).safeTransferFrom(msg.sender,address(this),serviceId)'] | | +| | | | ['mapServiceInfo', 'maxNumServices'] | | ['revert WrongServiceConfiguration(uint256)', 'revert WrongServiceState(uint256,uint256)'] | ['setServiceIds.push(serviceId)'] | | +| | | | ['msg.sender', 'numAgentInstances'] | | | | | +| | | | ['serviceRegistry', 'setServiceIds'] | | | | | +| | | | ['this', 'threshold'] | | | | | +| _calculateStakingRewards() | internal | [] | ['availableRewards', 'block.timestamp'] | [] | [] | ['IMultisig(curInfo.multisig).nonce()', 'new uint256[](size)'] | 8 | +| | | | ['livenessPeriod', 'livenessRatio'] | | | ['new uint256[](size)', 'new uint256[](size)'] | | +| | | | ['mapServiceInfo', 'rewardsPerSecond'] | | | ['new uint256[](size)'] | | +| | | | ['setServiceIds', 'tsCheckpoint'] | | | | | +| checkpoint() | public | [] | ['block.timestamp', 'mapServiceInfo'] | ['availableRewards', 'mapServiceInfo'] | ['_calculateStakingRewards'] | [] | 8 | +| | | | | ['tsCheckpoint'] | | | | +| unstake(uint256) | external | [] | ['mapServiceInfo', 'msg.sender'] | ['mapServiceInfo', 'setServiceIds'] | ['_withdraw', 'checkpoint'] | ['IService(serviceRegistry).safeTransferFrom(address(this),msg.sender,serviceId)', 'setServiceIds.pop()'] | 5 | +| | | | ['serviceRegistry', 'setServiceIds'] | | ['revert OwnerOnly(address,address)'] | | | +| | | | ['this'] | | | | | +| calculateServiceStakingReward(uint256) | external | [] | ['mapServiceInfo'] | [] | ['_calculateStakingRewards', 'revert ServiceNotStaked(uint256)'] | [] | 6 | +| onERC721Received(address,address,uint256,bytes) | external | [] | [] | [] | [] | [] | 1 | +| constructor(ServiceStakingBase.StakingParams,address) | public | [] | [] | [] | ['constructor'] | [] | 1 | +| _withdraw(address,uint256) | internal | [] | ['balance', 'this'] | ['balance'] | ['revert TransferFailed(address,address,address,uint256)'] | ['to.call{value: amount}()'] | 2 | +| receive() | external | [] | ['availableRewards', 'balance'] | ['availableRewards', 'balance'] | [] | [] | 1 | +| | | | ['msg.sender', 'msg.value'] | | | | | +| slitherConstructorConstantVariables() | internal | [] | [] | ['VERSION'] | [] | [] | 1 | ++-------------------------------------------------------+------------+-----------+-----------------------------------------+-------------------------------------------+--------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------+-----------------------+ + ++-----------+------------+------+-------+----------------+----------------+-----------------------+ +| Modifiers | Visibility | Read | Write | Internal Calls | External Calls | Cyclomatic Complexity | ++-----------+------------+------+-------+----------------+----------------+-----------------------+ ++-----------+------------+------+-------+----------------+----------------+-----------------------+ + +INFO:Printers: +Contract IErrorsRegistries +Contract vars: [] +Inheritance:: [] + ++----------+------------+-----------+------+-------+----------------+----------------+-----------------------+ +| Function | Visibility | Modifiers | Read | Write | Internal Calls | External Calls | Cyclomatic Complexity | ++----------+------------+-----------+------+-------+----------------+----------------+-----------------------+ ++----------+------------+-----------+------+-------+----------------+----------------+-----------------------+ + ++-----------+------------+------+-------+----------------+----------------+-----------------------+ +| Modifiers | Visibility | Read | Write | Internal Calls | External Calls | Cyclomatic Complexity | ++-----------+------------+------+-------+----------------+----------------+-----------------------+ ++-----------+------------+------+-------+----------------+----------------+-----------------------+ + +INFO:Printers: +Contract ERC721 +Contract vars: ['name', 'symbol', '_ownerOf', '_balanceOf', 'getApproved', 'isApprovedForAll'] +Inheritance:: [] + ++-------------------------------------------------+------------+-----------+-------------------------------------+----------------------------+-------------------------------------------+-----------------------------------------------------------------------------+-----------------------+ +| Function | Visibility | Modifiers | Read | Write | Internal Calls | External Calls | Cyclomatic Complexity | ++-------------------------------------------------+------------+-----------+-------------------------------------+----------------------------+-------------------------------------------+-----------------------------------------------------------------------------+-----------------------+ +| tokenURI(uint256) | public | [] | [] | [] | [] | [] | 2 | +| ownerOf(uint256) | public | [] | ['_ownerOf'] | [] | ['require(bool,string)'] | [] | 1 | +| balanceOf(address) | public | [] | ['_balanceOf'] | [] | ['require(bool,string)'] | [] | 1 | +| constructor(string,string) | internal | [] | [] | ['name', 'symbol'] | [] | [] | 1 | +| approve(address,uint256) | public | [] | ['_ownerOf', 'isApprovedForAll'] | ['getApproved'] | ['require(bool,string)'] | [] | 1 | +| | | | ['msg.sender'] | | | | | +| setApprovalForAll(address,bool) | public | [] | ['msg.sender'] | ['isApprovedForAll'] | [] | [] | 1 | +| transferFrom(address,address,uint256) | public | [] | ['_balanceOf', '_ownerOf'] | ['_balanceOf', '_ownerOf'] | ['require(bool,string)'] | [] | 1 | +| | | | ['getApproved', 'isApprovedForAll'] | ['getApproved'] | | | | +| | | | ['msg.sender'] | | | | | +| safeTransferFrom(address,address,uint256) | public | [] | ['msg.sender'] | [] | ['code(address)', 'require(bool,string)'] | ['ERC721TokenReceiver(to).onERC721Received(msg.sender,from,id,)'] | 2 | +| | | | | | ['transferFrom'] | | | +| safeTransferFrom(address,address,uint256,bytes) | public | [] | ['msg.sender'] | [] | ['code(address)', 'require(bool,string)'] | ['ERC721TokenReceiver(to).onERC721Received(msg.sender,from,id,data)'] | 2 | +| | | | | | ['transferFrom'] | | | +| supportsInterface(bytes4) | public | [] | [] | [] | [] | [] | 1 | +| _mint(address,uint256) | internal | [] | ['_balanceOf', '_ownerOf'] | ['_balanceOf', '_ownerOf'] | ['require(bool,string)'] | [] | 1 | +| _burn(uint256) | internal | [] | ['_balanceOf', '_ownerOf'] | ['_balanceOf', '_ownerOf'] | ['require(bool,string)'] | [] | 1 | +| | | | ['getApproved'] | ['getApproved'] | | | | +| _safeMint(address,uint256) | internal | [] | ['msg.sender'] | [] | ['_mint', 'code(address)'] | ['ERC721TokenReceiver(to).onERC721Received(msg.sender,address(0),id,)'] | 2 | +| | | | | | ['require(bool,string)'] | | | +| _safeMint(address,uint256,bytes) | internal | [] | ['msg.sender'] | [] | ['_mint', 'code(address)'] | ['ERC721TokenReceiver(to).onERC721Received(msg.sender,address(0),id,data)'] | 2 | +| | | | | | ['require(bool,string)'] | | | ++-------------------------------------------------+------------+-----------+-------------------------------------+----------------------------+-------------------------------------------+-----------------------------------------------------------------------------+-----------------------+ + ++-----------+------------+------+-------+----------------+----------------+-----------------------+ +| Modifiers | Visibility | Read | Write | Internal Calls | External Calls | Cyclomatic Complexity | ++-----------+------------+------+-------+----------------+----------------+-----------------------+ ++-----------+------------+------+-------+----------------+----------------+-----------------------+ + +INFO:Printers: +Contract ERC721TokenReceiver +Contract vars: [] +Inheritance:: [] + ++-------------------------------------------------+------------+-----------+------+-------+----------------+----------------+-----------------------+ +| Function | Visibility | Modifiers | Read | Write | Internal Calls | External Calls | Cyclomatic Complexity | ++-------------------------------------------------+------------+-----------+------+-------+----------------+----------------+-----------------------+ +| onERC721Received(address,address,uint256,bytes) | external | [] | [] | [] | [] | [] | 1 | ++-------------------------------------------------+------------+-----------+------+-------+----------------+----------------+-----------------------+ + ++-----------+------------+------+-------+----------------+----------------+-----------------------+ +| Modifiers | Visibility | Read | Write | Internal Calls | External Calls | Cyclomatic Complexity | ++-----------+------------+------+-------+----------------+----------------+-----------------------+ ++-----------+------------+------+-------+----------------+----------------+-----------------------+ + +INFO:Printers: +Contract IMultisig +Contract vars: [] +Inheritance:: [] + ++----------+------------+-----------+------+-------+----------------+----------------+-----------------------+ +| Function | Visibility | Modifiers | Read | Write | Internal Calls | External Calls | Cyclomatic Complexity | ++----------+------------+-----------+------+-------+----------------+----------------+-----------------------+ +| nonce() | external | [] | [] | [] | [] | [] | 2 | ++----------+------------+-----------+------+-------+----------------+----------------+-----------------------+ + ++-----------+------------+------+-------+----------------+----------------+-----------------------+ +| Modifiers | Visibility | Read | Write | Internal Calls | External Calls | Cyclomatic Complexity | ++-----------+------------+------+-------+----------------+----------------+-----------------------+ ++-----------+------------+------+-------+----------------+----------------+-----------------------+ + +INFO:Printers: +Contract IService +Contract vars: [] +Inheritance:: [] + ++------------------------------------------------+------------+-----------+------+-------+----------------+----------------+-----------------------+ +| Function | Visibility | Modifiers | Read | Write | Internal Calls | External Calls | Cyclomatic Complexity | ++------------------------------------------------+------------+-----------+------+-------+----------------+----------------+-----------------------+ +| safeTransferFrom(address,address,uint256) | external | [] | [] | [] | [] | [] | 2 | +| mapServices(uint256) | external | [] | [] | [] | [] | [] | 2 | +| getUnitIdsOfService(IService.UnitType,uint256) | external | [] | [] | [] | [] | [] | 2 | ++------------------------------------------------+------------+-----------+------+-------+----------------+----------------+-----------------------+ + ++-----------+------------+------+-------+----------------+----------------+-----------------------+ +| Modifiers | Visibility | Read | Write | Internal Calls | External Calls | Cyclomatic Complexity | ++-----------+------------+------+-------+----------------+----------------+-----------------------+ ++-----------+------------+------+-------+----------------+----------------+-----------------------+ + +INFO:Printers: +Contract ServiceStakingBase +Contract vars: ['VERSION', 'maxNumServices', 'rewardsPerSecond', 'minStakingDeposit', 'livenessPeriod', 'livenessRatio', 'numAgentInstances', 'threshold', 'configHash', 'serviceRegistry', 'balance', 'availableRewards', 'tsCheckpoint', 'agentIds', 'mapServiceInfo', 'setServiceIds'] +Inheritance:: ['IErrorsRegistries', 'ERC721TokenReceiver'] + ++-------------------------------------------------------+------------+-----------+-----------------------------------------+-------------------------------------------+--------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------+-----------------------+ +| Function | Visibility | Modifiers | Read | Write | Internal Calls | External Calls | Cyclomatic Complexity | ++-------------------------------------------------------+------------+-----------+-----------------------------------------+-------------------------------------------+--------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------+-----------------------+ +| onERC721Received(address,address,uint256,bytes) | external | [] | [] | [] | [] | [] | 1 | +| constructor(ServiceStakingBase.StakingParams,address) | internal | [] | ['agentIds', 'block.timestamp'] | ['agentIds', 'configHash'] | ['revert WrongAgentId(uint256)', 'revert ZeroAddress()'] | ['agentIds.push(agentId)'] | 6 | +| | | | | ['livenessPeriod', 'livenessRatio'] | ['revert ZeroValue()'] | | | +| | | | | ['maxNumServices', 'minStakingDeposit'] | | | | +| | | | | ['numAgentInstances', 'rewardsPerSecond'] | | | | +| | | | | ['serviceRegistry', 'threshold'] | | | | +| | | | | ['tsCheckpoint'] | | | | +| _checkTokenStakingDeposit(uint256,uint256) | internal | [] | ['minStakingDeposit'] | [] | ['revert LowerThan(uint256,uint256)'] | [] | 2 | +| _withdraw(address,uint256) | internal | [] | [] | [] | [] | [] | 2 | +| stake(uint256) | external | [] | ['agentIds', 'availableRewards'] | ['mapServiceInfo', 'setServiceIds'] | ['_checkTokenStakingDeposit', 'revert MaxNumServicesReached(uint256)'] | ['IMultisig(multisig).nonce()', 'IService(serviceRegistry).getUnitIdsOfService(IService.UnitType.Agent,serviceId)'] | 11 | +| | | | ['block.timestamp', 'configHash'] | | ['revert NoRewardsAvailable()', 'revert WrongAgentId(uint256)'] | ['IService(serviceRegistry).mapServices(serviceId)', 'IService(serviceRegistry).safeTransferFrom(msg.sender,address(this),serviceId)'] | | +| | | | ['mapServiceInfo', 'maxNumServices'] | | ['revert WrongServiceConfiguration(uint256)', 'revert WrongServiceState(uint256,uint256)'] | ['setServiceIds.push(serviceId)'] | | +| | | | ['msg.sender', 'numAgentInstances'] | | | | | +| | | | ['serviceRegistry', 'setServiceIds'] | | | | | +| | | | ['this', 'threshold'] | | | | | +| _calculateStakingRewards() | internal | [] | ['availableRewards', 'block.timestamp'] | [] | [] | ['IMultisig(curInfo.multisig).nonce()', 'new uint256[](size)'] | 8 | +| | | | ['livenessPeriod', 'livenessRatio'] | | | ['new uint256[](size)', 'new uint256[](size)'] | | +| | | | ['mapServiceInfo', 'rewardsPerSecond'] | | | ['new uint256[](size)'] | | +| | | | ['setServiceIds', 'tsCheckpoint'] | | | | | +| checkpoint() | public | [] | ['block.timestamp', 'mapServiceInfo'] | ['availableRewards', 'mapServiceInfo'] | ['_calculateStakingRewards'] | [] | 8 | +| | | | | ['tsCheckpoint'] | | | | +| unstake(uint256) | external | [] | ['mapServiceInfo', 'msg.sender'] | ['mapServiceInfo', 'setServiceIds'] | ['_withdraw', 'checkpoint'] | ['IService(serviceRegistry).safeTransferFrom(address(this),msg.sender,serviceId)', 'setServiceIds.pop()'] | 5 | +| | | | ['serviceRegistry', 'setServiceIds'] | | ['revert OwnerOnly(address,address)'] | | | +| | | | ['this'] | | | | | +| calculateServiceStakingReward(uint256) | external | [] | ['mapServiceInfo'] | [] | ['_calculateStakingRewards', 'revert ServiceNotStaked(uint256)'] | [] | 6 | +| slitherConstructorConstantVariables() | internal | [] | [] | ['VERSION'] | [] | [] | 1 | ++-------------------------------------------------------+------------+-----------+-----------------------------------------+-------------------------------------------+--------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------+-----------------------+ + ++-----------+------------+------+-------+----------------+----------------+-----------------------+ +| Modifiers | Visibility | Read | Write | Internal Calls | External Calls | Cyclomatic Complexity | ++-----------+------------+------+-------+----------------+----------------+-----------------------+ ++-----------+------------+------+-------+----------------+----------------+-----------------------+ + +INFO:Printers: +Contract IToken +Contract vars: [] +Inheritance:: [] + ++---------------------------------------+------------+-----------+------+-------+----------------+----------------+-----------------------+ +| Function | Visibility | Modifiers | Read | Write | Internal Calls | External Calls | Cyclomatic Complexity | ++---------------------------------------+------------+-----------+------+-------+----------------+----------------+-----------------------+ +| balanceOf(address) | external | [] | [] | [] | [] | [] | 2 | +| ownerOf(uint256) | external | [] | [] | [] | [] | [] | 2 | +| totalSupply() | external | [] | [] | [] | [] | [] | 2 | +| transfer(address,uint256) | external | [] | [] | [] | [] | [] | 2 | +| allowance(address,address) | external | [] | [] | [] | [] | [] | 2 | +| approve(address,uint256) | external | [] | [] | [] | [] | [] | 2 | +| transferFrom(address,address,uint256) | external | [] | [] | [] | [] | [] | 2 | +| decimals() | external | [] | [] | [] | [] | [] | 2 | ++---------------------------------------+------------+-----------+------+-------+----------------+----------------+-----------------------+ + ++-----------+------------+------+-------+----------------+----------------+-----------------------+ +| Modifiers | Visibility | Read | Write | Internal Calls | External Calls | Cyclomatic Complexity | ++-----------+------------+------+-------+----------------+----------------+-----------------------+ ++-----------+------------+------+-------+----------------+----------------+-----------------------+ + +INFO:Printers: +Contract SafeTransferLib +Contract vars: [] +Inheritance:: [] + ++---------------------------------------------------+------------+-----------+----------+-------+-------------------------------------------------------------------------------------+----------------+-----------------------+ +| Function | Visibility | Modifiers | Read | Write | Internal Calls | External Calls | Cyclomatic Complexity | ++---------------------------------------------------+------------+-----------+----------+-------+-------------------------------------------------------------------------------------+----------------+-----------------------+ +| safeTransferFrom(address,address,address,uint256) | internal | [] | [] | [] | ['call(uint256,uint256,uint256,uint256,uint256,uint256,uint256)', 'gas()'] | [] | 2 | +| | | | | | ['mload(uint256)', 'mstore(uint256,uint256)'] | | | +| | | | | | ['returndatasize()', 'revert TokenTransferFailed(address,address,address,uint256)'] | | | +| safeTransfer(address,address,uint256) | internal | [] | ['this'] | [] | ['call(uint256,uint256,uint256,uint256,uint256,uint256,uint256)', 'gas()'] | [] | 2 | +| | | | | | ['mload(uint256)', 'mstore(uint256,uint256)'] | | | +| | | | | | ['returndatasize()', 'revert TokenTransferFailed(address,address,address,uint256)'] | | | ++---------------------------------------------------+------------+-----------+----------+-------+-------------------------------------------------------------------------------------+----------------+-----------------------+ + ++-----------+------------+------+-------+----------------+----------------+-----------------------+ +| Modifiers | Visibility | Read | Write | Internal Calls | External Calls | Cyclomatic Complexity | ++-----------+------------+------+-------+----------------+----------------+-----------------------+ ++-----------+------------+------+-------+----------------+----------------+-----------------------+ + +INFO:Printers: +Contract IServiceTokenUtility +Contract vars: [] +Inheritance:: [] + ++-----------------------------------+------------+-----------+------+-------+----------------+----------------+-----------------------+ +| Function | Visibility | Modifiers | Read | Write | Internal Calls | External Calls | Cyclomatic Complexity | ++-----------------------------------+------------+-----------+------+-------+----------------+----------------+-----------------------+ +| mapServiceIdTokenDeposit(uint256) | external | [] | [] | [] | [] | [] | 2 | ++-----------------------------------+------------+-----------+------+-------+----------------+----------------+-----------------------+ + ++-----------+------------+------+-------+----------------+----------------+-----------------------+ +| Modifiers | Visibility | Read | Write | Internal Calls | External Calls | Cyclomatic Complexity | ++-----------+------------+------+-------+----------------+----------------+-----------------------+ ++-----------+------------+------+-------+----------------+----------------+-----------------------+ + +INFO:Printers: +Contract ServiceStakingToken +Contract vars: ['VERSION', 'maxNumServices', 'rewardsPerSecond', 'minStakingDeposit', 'livenessPeriod', 'livenessRatio', 'numAgentInstances', 'threshold', 'configHash', 'serviceRegistry', 'balance', 'availableRewards', 'tsCheckpoint', 'agentIds', 'mapServiceInfo', 'setServiceIds', 'serviceRegistryTokenUtility', 'stakingToken'] +Inheritance:: ['ServiceStakingBase', 'IErrorsRegistries', 'ERC721TokenReceiver'] + ++-----------------------------------------------------------------------+------------+-----------+------------------------------------------------------+-------------------------------------------------+--------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------+-----------------------+ +| Function | Visibility | Modifiers | Read | Write | Internal Calls | External Calls | Cyclomatic Complexity | ++-----------------------------------------------------------------------+------------+-----------+------------------------------------------------------+-------------------------------------------------+--------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------+-----------------------+ +| constructor(ServiceStakingBase.StakingParams,address) | internal | [] | ['agentIds', 'block.timestamp'] | ['agentIds', 'configHash'] | ['revert WrongAgentId(uint256)', 'revert ZeroAddress()'] | ['agentIds.push(agentId)'] | 6 | +| | | | | ['livenessPeriod', 'livenessRatio'] | ['revert ZeroValue()'] | | | +| | | | | ['maxNumServices', 'minStakingDeposit'] | | | | +| | | | | ['numAgentInstances', 'rewardsPerSecond'] | | | | +| | | | | ['serviceRegistry', 'threshold'] | | | | +| | | | | ['tsCheckpoint'] | | | | +| _checkTokenStakingDeposit(uint256,uint256) | internal | [] | ['minStakingDeposit'] | [] | ['revert LowerThan(uint256,uint256)'] | [] | 2 | +| _withdraw(address,uint256) | internal | [] | [] | [] | [] | [] | 2 | +| stake(uint256) | external | [] | ['agentIds', 'availableRewards'] | ['mapServiceInfo', 'setServiceIds'] | ['_checkTokenStakingDeposit', 'revert MaxNumServicesReached(uint256)'] | ['IMultisig(multisig).nonce()', 'IService(serviceRegistry).getUnitIdsOfService(IService.UnitType.Agent,serviceId)'] | 11 | +| | | | ['block.timestamp', 'configHash'] | | ['revert NoRewardsAvailable()', 'revert WrongAgentId(uint256)'] | ['IService(serviceRegistry).mapServices(serviceId)', 'IService(serviceRegistry).safeTransferFrom(msg.sender,address(this),serviceId)'] | | +| | | | ['mapServiceInfo', 'maxNumServices'] | | ['revert WrongServiceConfiguration(uint256)', 'revert WrongServiceState(uint256,uint256)'] | ['setServiceIds.push(serviceId)'] | | +| | | | ['msg.sender', 'numAgentInstances'] | | | | | +| | | | ['serviceRegistry', 'setServiceIds'] | | | | | +| | | | ['this', 'threshold'] | | | | | +| _calculateStakingRewards() | internal | [] | ['availableRewards', 'block.timestamp'] | [] | [] | ['IMultisig(curInfo.multisig).nonce()', 'new uint256[](size)'] | 8 | +| | | | ['livenessPeriod', 'livenessRatio'] | | | ['new uint256[](size)', 'new uint256[](size)'] | | +| | | | ['mapServiceInfo', 'rewardsPerSecond'] | | | ['new uint256[](size)'] | | +| | | | ['setServiceIds', 'tsCheckpoint'] | | | | | +| checkpoint() | public | [] | ['block.timestamp', 'mapServiceInfo'] | ['availableRewards', 'mapServiceInfo'] | ['_calculateStakingRewards'] | [] | 8 | +| | | | | ['tsCheckpoint'] | | | | +| unstake(uint256) | external | [] | ['mapServiceInfo', 'msg.sender'] | ['mapServiceInfo', 'setServiceIds'] | ['_withdraw', 'checkpoint'] | ['IService(serviceRegistry).safeTransferFrom(address(this),msg.sender,serviceId)', 'setServiceIds.pop()'] | 5 | +| | | | ['serviceRegistry', 'setServiceIds'] | | ['revert OwnerOnly(address,address)'] | | | +| | | | ['this'] | | | | | +| calculateServiceStakingReward(uint256) | external | [] | ['mapServiceInfo'] | [] | ['_calculateStakingRewards', 'revert ServiceNotStaked(uint256)'] | [] | 6 | +| onERC721Received(address,address,uint256,bytes) | external | [] | [] | [] | [] | [] | 1 | +| constructor(ServiceStakingBase.StakingParams,address,address,address) | public | [] | [] | ['serviceRegistryTokenUtility', 'stakingToken'] | ['constructor', 'revert ZeroAddress()'] | [] | 2 | +| _checkTokenStakingDeposit(uint256,uint256) | internal | [] | ['minStakingDeposit', 'serviceRegistryTokenUtility'] | [] | ['revert LowerThan(uint256,uint256)', 'revert WrongStakingToken(address,address)'] | ['IServiceTokenUtility(serviceRegistryTokenUtility).mapServiceIdTokenDeposit(serviceId)'] | 3 | +| | | | ['stakingToken'] | | | | | +| _withdraw(address,uint256) | internal | [] | ['balance', 'stakingToken'] | ['balance'] | [] | ['SafeTransferLib.safeTransfer(stakingToken,to,amount)'] | 1 | +| deposit(uint256) | external | [] | ['availableRewards', 'balance'] | ['availableRewards', 'balance'] | [] | ['SafeTransferLib.safeTransferFrom(stakingToken,msg.sender,address(this),amount)'] | 1 | +| | | | ['msg.sender', 'stakingToken'] | | | | | +| | | | ['this'] | | | | | +| slitherConstructorConstantVariables() | internal | [] | [] | ['VERSION'] | [] | [] | 1 | ++-----------------------------------------------------------------------+------------+-----------+------------------------------------------------------+-------------------------------------------------+--------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------+-----------------------+ + ++-----------+------------+------+-------+----------------+----------------+-----------------------+ +| Modifiers | Visibility | Read | Write | Internal Calls | External Calls | Cyclomatic Complexity | ++-----------+------------+------+-------+----------------+----------------+-----------------------+ ++-----------+------------+------+-------+----------------+----------------+-----------------------+ + +INFO:Printers: +Contract IErrorsRegistries +Contract vars: [] +Inheritance:: [] + ++----------+------------+-----------+------+-------+----------------+----------------+-----------------------+ +| Function | Visibility | Modifiers | Read | Write | Internal Calls | External Calls | Cyclomatic Complexity | ++----------+------------+-----------+------+-------+----------------+----------------+-----------------------+ ++----------+------------+-----------+------+-------+----------------+----------------+-----------------------+ + ++-----------+------------+------+-------+----------------+----------------+-----------------------+ +| Modifiers | Visibility | Read | Write | Internal Calls | External Calls | Cyclomatic Complexity | ++-----------+------------+------+-------+----------------+----------------+-----------------------+ ++-----------+------------+------+-------+----------------+----------------+-----------------------+ + +INFO:Printers: +Contract ERC721 +Contract vars: ['name', 'symbol', '_ownerOf', '_balanceOf', 'getApproved', 'isApprovedForAll'] +Inheritance:: [] + ++-------------------------------------------------+------------+-----------+-------------------------------------+----------------------------+-------------------------------------------+-----------------------------------------------------------------------------+-----------------------+ +| Function | Visibility | Modifiers | Read | Write | Internal Calls | External Calls | Cyclomatic Complexity | ++-------------------------------------------------+------------+-----------+-------------------------------------+----------------------------+-------------------------------------------+-----------------------------------------------------------------------------+-----------------------+ +| tokenURI(uint256) | public | [] | [] | [] | [] | [] | 2 | +| ownerOf(uint256) | public | [] | ['_ownerOf'] | [] | ['require(bool,string)'] | [] | 1 | +| balanceOf(address) | public | [] | ['_balanceOf'] | [] | ['require(bool,string)'] | [] | 1 | +| constructor(string,string) | internal | [] | [] | ['name', 'symbol'] | [] | [] | 1 | +| approve(address,uint256) | public | [] | ['_ownerOf', 'isApprovedForAll'] | ['getApproved'] | ['require(bool,string)'] | [] | 1 | +| | | | ['msg.sender'] | | | | | +| setApprovalForAll(address,bool) | public | [] | ['msg.sender'] | ['isApprovedForAll'] | [] | [] | 1 | +| transferFrom(address,address,uint256) | public | [] | ['_balanceOf', '_ownerOf'] | ['_balanceOf', '_ownerOf'] | ['require(bool,string)'] | [] | 1 | +| | | | ['getApproved', 'isApprovedForAll'] | ['getApproved'] | | | | +| | | | ['msg.sender'] | | | | | +| safeTransferFrom(address,address,uint256) | public | [] | ['msg.sender'] | [] | ['code(address)', 'require(bool,string)'] | ['ERC721TokenReceiver(to).onERC721Received(msg.sender,from,id,)'] | 2 | +| | | | | | ['transferFrom'] | | | +| safeTransferFrom(address,address,uint256,bytes) | public | [] | ['msg.sender'] | [] | ['code(address)', 'require(bool,string)'] | ['ERC721TokenReceiver(to).onERC721Received(msg.sender,from,id,data)'] | 2 | +| | | | | | ['transferFrom'] | | | +| supportsInterface(bytes4) | public | [] | [] | [] | [] | [] | 1 | +| _mint(address,uint256) | internal | [] | ['_balanceOf', '_ownerOf'] | ['_balanceOf', '_ownerOf'] | ['require(bool,string)'] | [] | 1 | +| _burn(uint256) | internal | [] | ['_balanceOf', '_ownerOf'] | ['_balanceOf', '_ownerOf'] | ['require(bool,string)'] | [] | 1 | +| | | | ['getApproved'] | ['getApproved'] | | | | +| _safeMint(address,uint256) | internal | [] | ['msg.sender'] | [] | ['_mint', 'code(address)'] | ['ERC721TokenReceiver(to).onERC721Received(msg.sender,address(0),id,)'] | 2 | +| | | | | | ['require(bool,string)'] | | | +| _safeMint(address,uint256,bytes) | internal | [] | ['msg.sender'] | [] | ['_mint', 'code(address)'] | ['ERC721TokenReceiver(to).onERC721Received(msg.sender,address(0),id,data)'] | 2 | +| | | | | | ['require(bool,string)'] | | | ++-------------------------------------------------+------------+-----------+-------------------------------------+----------------------------+-------------------------------------------+-----------------------------------------------------------------------------+-----------------------+ + ++-----------+------------+------+-------+----------------+----------------+-----------------------+ +| Modifiers | Visibility | Read | Write | Internal Calls | External Calls | Cyclomatic Complexity | ++-----------+------------+------+-------+----------------+----------------+-----------------------+ ++-----------+------------+------+-------+----------------+----------------+-----------------------+ + +INFO:Printers: +Contract ERC721TokenReceiver +Contract vars: [] +Inheritance:: [] + ++-------------------------------------------------+------------+-----------+------+-------+----------------+----------------+-----------------------+ +| Function | Visibility | Modifiers | Read | Write | Internal Calls | External Calls | Cyclomatic Complexity | ++-------------------------------------------------+------------+-----------+------+-------+----------------+----------------+-----------------------+ +| onERC721Received(address,address,uint256,bytes) | external | [] | [] | [] | [] | [] | 1 | ++-------------------------------------------------+------------+-----------+------+-------+----------------+----------------+-----------------------+ + ++-----------+------------+------+-------+----------------+----------------+-----------------------+ +| Modifiers | Visibility | Read | Write | Internal Calls | External Calls | Cyclomatic Complexity | ++-----------+------------+------+-------+----------------+----------------+-----------------------+ ++-----------+------------+------+-------+----------------+----------------+-----------------------+ + +INFO:Printers: +Contract IMultisig +Contract vars: [] +Inheritance:: [] + ++----------+------------+-----------+------+-------+----------------+----------------+-----------------------+ +| Function | Visibility | Modifiers | Read | Write | Internal Calls | External Calls | Cyclomatic Complexity | ++----------+------------+-----------+------+-------+----------------+----------------+-----------------------+ +| nonce() | external | [] | [] | [] | [] | [] | 2 | ++----------+------------+-----------+------+-------+----------------+----------------+-----------------------+ + ++-----------+------------+------+-------+----------------+----------------+-----------------------+ +| Modifiers | Visibility | Read | Write | Internal Calls | External Calls | Cyclomatic Complexity | ++-----------+------------+------+-------+----------------+----------------+-----------------------+ ++-----------+------------+------+-------+----------------+----------------+-----------------------+ + +INFO:Printers: +Contract IService +Contract vars: [] +Inheritance:: [] + ++------------------------------------------------+------------+-----------+------+-------+----------------+----------------+-----------------------+ +| Function | Visibility | Modifiers | Read | Write | Internal Calls | External Calls | Cyclomatic Complexity | ++------------------------------------------------+------------+-----------+------+-------+----------------+----------------+-----------------------+ +| safeTransferFrom(address,address,uint256) | external | [] | [] | [] | [] | [] | 2 | +| mapServices(uint256) | external | [] | [] | [] | [] | [] | 2 | +| getUnitIdsOfService(IService.UnitType,uint256) | external | [] | [] | [] | [] | [] | 2 | ++------------------------------------------------+------------+-----------+------+-------+----------------+----------------+-----------------------+ + ++-----------+------------+------+-------+----------------+----------------+-----------------------+ +| Modifiers | Visibility | Read | Write | Internal Calls | External Calls | Cyclomatic Complexity | ++-----------+------------+------+-------+----------------+----------------+-----------------------+ ++-----------+------------+------+-------+----------------+----------------+-----------------------+ + +INFO:Printers: +Contract ServiceStakingBase +Contract vars: ['VERSION', 'maxNumServices', 'rewardsPerSecond', 'minStakingDeposit', 'livenessPeriod', 'livenessRatio', 'numAgentInstances', 'threshold', 'configHash', 'serviceRegistry', 'balance', 'availableRewards', 'tsCheckpoint', 'agentIds', 'mapServiceInfo', 'setServiceIds'] +Inheritance:: ['IErrorsRegistries', 'ERC721TokenReceiver'] + ++-------------------------------------------------------+------------+-----------+-----------------------------------------+-------------------------------------------+--------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------+-----------------------+ +| Function | Visibility | Modifiers | Read | Write | Internal Calls | External Calls | Cyclomatic Complexity | ++-------------------------------------------------------+------------+-----------+-----------------------------------------+-------------------------------------------+--------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------+-----------------------+ +| onERC721Received(address,address,uint256,bytes) | external | [] | [] | [] | [] | [] | 1 | +| constructor(ServiceStakingBase.StakingParams,address) | internal | [] | ['agentIds', 'block.timestamp'] | ['agentIds', 'configHash'] | ['revert WrongAgentId(uint256)', 'revert ZeroAddress()'] | ['agentIds.push(agentId)'] | 6 | +| | | | | ['livenessPeriod', 'livenessRatio'] | ['revert ZeroValue()'] | | | +| | | | | ['maxNumServices', 'minStakingDeposit'] | | | | +| | | | | ['numAgentInstances', 'rewardsPerSecond'] | | | | +| | | | | ['serviceRegistry', 'threshold'] | | | | +| | | | | ['tsCheckpoint'] | | | | +| _checkTokenStakingDeposit(uint256,uint256) | internal | [] | ['minStakingDeposit'] | [] | ['revert LowerThan(uint256,uint256)'] | [] | 2 | +| _withdraw(address,uint256) | internal | [] | [] | [] | [] | [] | 2 | +| stake(uint256) | external | [] | ['agentIds', 'availableRewards'] | ['mapServiceInfo', 'setServiceIds'] | ['_checkTokenStakingDeposit', 'revert MaxNumServicesReached(uint256)'] | ['IMultisig(multisig).nonce()', 'IService(serviceRegistry).getUnitIdsOfService(IService.UnitType.Agent,serviceId)'] | 11 | +| | | | ['block.timestamp', 'configHash'] | | ['revert NoRewardsAvailable()', 'revert WrongAgentId(uint256)'] | ['IService(serviceRegistry).mapServices(serviceId)', 'IService(serviceRegistry).safeTransferFrom(msg.sender,address(this),serviceId)'] | | +| | | | ['mapServiceInfo', 'maxNumServices'] | | ['revert WrongServiceConfiguration(uint256)', 'revert WrongServiceState(uint256,uint256)'] | ['setServiceIds.push(serviceId)'] | | +| | | | ['msg.sender', 'numAgentInstances'] | | | | | +| | | | ['serviceRegistry', 'setServiceIds'] | | | | | +| | | | ['this', 'threshold'] | | | | | +| _calculateStakingRewards() | internal | [] | ['availableRewards', 'block.timestamp'] | [] | [] | ['IMultisig(curInfo.multisig).nonce()', 'new uint256[](size)'] | 8 | +| | | | ['livenessPeriod', 'livenessRatio'] | | | ['new uint256[](size)', 'new uint256[](size)'] | | +| | | | ['mapServiceInfo', 'rewardsPerSecond'] | | | ['new uint256[](size)'] | | +| | | | ['setServiceIds', 'tsCheckpoint'] | | | | | +| checkpoint() | public | [] | ['block.timestamp', 'mapServiceInfo'] | ['availableRewards', 'mapServiceInfo'] | ['_calculateStakingRewards'] | [] | 8 | +| | | | | ['tsCheckpoint'] | | | | +| unstake(uint256) | external | [] | ['mapServiceInfo', 'msg.sender'] | ['mapServiceInfo', 'setServiceIds'] | ['_withdraw', 'checkpoint'] | ['IService(serviceRegistry).safeTransferFrom(address(this),msg.sender,serviceId)', 'setServiceIds.pop()'] | 5 | +| | | | ['serviceRegistry', 'setServiceIds'] | | ['revert OwnerOnly(address,address)'] | | | +| | | | ['this'] | | | | | +| calculateServiceStakingReward(uint256) | external | [] | ['mapServiceInfo'] | [] | ['_calculateStakingRewards', 'revert ServiceNotStaked(uint256)'] | [] | 6 | +| slitherConstructorConstantVariables() | internal | [] | [] | ['VERSION'] | [] | [] | 1 | ++-------------------------------------------------------+------------+-----------+-----------------------------------------+-------------------------------------------+--------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------+-----------------------+ + ++-----------+------------+------+-------+----------------+----------------+-----------------------+ +| Modifiers | Visibility | Read | Write | Internal Calls | External Calls | Cyclomatic Complexity | ++-----------+------------+------+-------+----------------+----------------+-----------------------+ ++-----------+------------+------+-------+----------------+----------------+-----------------------+ + +INFO:Slither:. analyzed (23 contracts) diff --git a/audits/internal4/analysis/slither_human-summary.txt b/audits/internal4/analysis/slither_human-summary.txt new file mode 100644 index 00000000..e6231e12 --- /dev/null +++ b/audits/internal4/analysis/slither_human-summary.txt @@ -0,0 +1,74 @@ +'solc --version' running +'solc ./ServiceStakingNativeToken-flatten.sol --combined-json abi,ast,bin,bin-runtime,srcmap,srcmap-runtime,userdoc,devdoc,hashes --allow-paths .,/home/andrey/valory/autonolas-registries/audits/internal4/analysis/contracts' running +'solc --version' running +'solc ./ServiceStakingToken-flatten.sol --combined-json abi,ast,bin,bin-runtime,srcmap,srcmap-runtime,userdoc,devdoc,hashes --allow-paths .,/home/andrey/valory/autonolas-registries/audits/internal4/analysis/contracts' running +'solc --version' running +'solc ./ServiceStakingBase-flatten.sol --combined-json abi,ast,bin,bin-runtime,srcmap,srcmap-runtime,userdoc,devdoc,hashes --allow-paths .,/home/andrey/valory/autonolas-registries/audits/internal4/analysis/contracts' running +INFO:Printers: +Compiled with solc +Total number of contracts in source files: 7 +Source lines of code (SLOC) in source files: 473 +Number of assembly lines: 0 +Number of optimization issues: 0 +Number of informational issues: 12 +Number of low issues: 6 +Number of medium issues: 7 +Number of high issues: 2 +ERCs: ERC721, ERC165 + ++---------------------------+-------------+---------------+------------+--------------+--------------------+ +| Name | # functions | ERCS | ERC20 info | Complex code | Features | ++---------------------------+-------------+---------------+------------+--------------+--------------------+ +| ERC721 | 14 | ERC165,ERC721 | | No | | +| IMultisig | 1 | | | No | | +| IService | 3 | | | No | | +| ServiceStakingNativeToken | 13 | | | Yes | Receive ETH | +| | | | | | Send ETH | +| | | | | | Tokens interaction | ++---------------------------+-------------+---------------+------------+--------------+--------------------+ +INFO:Printers: +Compiled with solc +Total number of contracts in source files: 10 +Source lines of code (SLOC) in source files: 550 +Number of assembly lines: 0 +Number of optimization issues: 0 +Number of informational issues: 18 +Number of low issues: 6 +Number of medium issues: 8 +Number of high issues: 1 +ERCs: ERC721, ERC165, ERC20 + ++----------------------+-------------+---------------+--------------------+--------------+--------------------+ +| Name | # functions | ERCS | ERC20 info | Complex code | Features | ++----------------------+-------------+---------------+--------------------+--------------+--------------------+ +| ERC721 | 14 | ERC165,ERC721 | | No | | +| IMultisig | 1 | | | No | | +| IService | 3 | | | No | | +| IToken | 8 | ERC20 | No Minting | No | | +| | | | Approve Race Cond. | | | +| | | | | | | +| SafeTransferLib | 2 | | | No | Assembly | +| IServiceTokenUtility | 1 | | | No | | +| ServiceStakingToken | 14 | | | Yes | Tokens interaction | ++----------------------+-------------+---------------+--------------------+--------------+--------------------+ +INFO:Printers: +Compiled with solc +Total number of contracts in source files: 6 +Source lines of code (SLOC) in source files: 454 +Number of assembly lines: 0 +Number of optimization issues: 4 +Number of informational issues: 12 +Number of low issues: 6 +Number of medium issues: 6 +Number of high issues: 1 +ERCs: ERC721, ERC165 + ++--------------------+-------------+---------------+------------+--------------+--------------------+ +| Name | # functions | ERCS | ERC20 info | Complex code | Features | ++--------------------+-------------+---------------+------------+--------------+--------------------+ +| ERC721 | 14 | ERC165,ERC721 | | No | | +| IMultisig | 1 | | | No | | +| IService | 3 | | | No | | +| ServiceStakingBase | 10 | | | Yes | Tokens interaction | ++--------------------+-------------+---------------+------------+--------------+--------------------+ +INFO:Slither:. analyzed (23 contracts) diff --git a/audits/internal4/analysis/slither_inheritance-graph.txt b/audits/internal4/analysis/slither_inheritance-graph.txt new file mode 100644 index 00000000..7525d84a --- /dev/null +++ b/audits/internal4/analysis/slither_inheritance-graph.txt @@ -0,0 +1,13 @@ +'solc --version' running +'solc ./ServiceStakingNativeToken-flatten.sol --combined-json abi,ast,bin,bin-runtime,srcmap,srcmap-runtime,userdoc,devdoc,hashes --allow-paths .,/home/andrey/valory/autonolas-registries/audits/internal4/analysis/contracts' running +'solc --version' running +'solc ./ServiceStakingToken-flatten.sol --combined-json abi,ast,bin,bin-runtime,srcmap,srcmap-runtime,userdoc,devdoc,hashes --allow-paths .,/home/andrey/valory/autonolas-registries/audits/internal4/analysis/contracts' running +'solc --version' running +'solc ./ServiceStakingBase-flatten.sol --combined-json abi,ast,bin,bin-runtime,srcmap,srcmap-runtime,userdoc,devdoc,hashes --allow-paths .,/home/andrey/valory/autonolas-registries/audits/internal4/analysis/contracts' running +INFO:Printers:Inheritance Graph: ./ServiceStakingNativeToken-flatten.sol.inheritance-graph.dot + +INFO:Printers:Inheritance Graph: ./ServiceStakingToken-flatten.sol.inheritance-graph.dot + +INFO:Printers:Inheritance Graph: ./ServiceStakingBase-flatten.sol.inheritance-graph.dot + +INFO:Slither:. analyzed (23 contracts) diff --git a/audits/internal4/analysis/slither_inheritance.txt b/audits/internal4/analysis/slither_inheritance.txt new file mode 100644 index 00000000..6287d58f --- /dev/null +++ b/audits/internal4/analysis/slither_inheritance.txt @@ -0,0 +1,136 @@ +'solc --version' running +'solc ./ServiceStakingNativeToken-flatten.sol --combined-json abi,ast,bin,bin-runtime,srcmap,srcmap-runtime,userdoc,devdoc,hashes --allow-paths .,/home/andrey/valory/autonolas-registries/audits/internal4/analysis/contracts' running +'solc --version' running +'solc ./ServiceStakingToken-flatten.sol --combined-json abi,ast,bin,bin-runtime,srcmap,srcmap-runtime,userdoc,devdoc,hashes --allow-paths .,/home/andrey/valory/autonolas-registries/audits/internal4/analysis/contracts' running +'solc --version' running +'solc ./ServiceStakingBase-flatten.sol --combined-json abi,ast,bin,bin-runtime,srcmap,srcmap-runtime,userdoc,devdoc,hashes --allow-paths .,/home/andrey/valory/autonolas-registries/audits/internal4/analysis/contracts' running +INFO:Printers:Inheritance +Child_Contract -> Immediate_Base_Contracts [Not_Immediate_Base_Contracts] ++ IErrorsRegistries + ++ ERC721 + ++ ERC721TokenReceiver + ++ IMultisig + ++ IService + ++ ServiceStakingBase + -> ERC721TokenReceiver, IErrorsRegistries + ++ ServiceStakingNativeToken + -> ServiceStakingBase +, [IErrorsRegistries, ERC721TokenReceiver] + + +Base_Contract -> Immediate_Child_Contracts + [Not_Immediate_Child_Contracts] + ++ IErrorsRegistries + -> ServiceStakingBase +, [ServiceStakingNativeToken] + ++ ERC721 + ++ ERC721TokenReceiver + -> ServiceStakingBase +, [ServiceStakingNativeToken] + ++ IMultisig + ++ IService + ++ ServiceStakingBase + -> ServiceStakingNativeToken + ++ ServiceStakingNativeToken + +INFO:Printers:Inheritance +Child_Contract -> Immediate_Base_Contracts [Not_Immediate_Base_Contracts] ++ IErrorsRegistries + ++ ERC721 + ++ ERC721TokenReceiver + ++ IMultisig + ++ IService + ++ ServiceStakingBase + -> ERC721TokenReceiver, IErrorsRegistries + ++ IToken + ++ SafeTransferLib + ++ IServiceTokenUtility + ++ ServiceStakingToken + -> ServiceStakingBase +, [IErrorsRegistries, ERC721TokenReceiver] + + +Base_Contract -> Immediate_Child_Contracts + [Not_Immediate_Child_Contracts] + ++ IErrorsRegistries + -> ServiceStakingBase +, [ServiceStakingToken] + ++ ERC721 + ++ ERC721TokenReceiver + -> ServiceStakingBase +, [ServiceStakingToken] + ++ IMultisig + ++ IService + ++ ServiceStakingBase + -> ServiceStakingToken + ++ IToken + ++ SafeTransferLib + ++ IServiceTokenUtility + ++ ServiceStakingToken + +INFO:Printers:Inheritance +Child_Contract -> Immediate_Base_Contracts [Not_Immediate_Base_Contracts] ++ IErrorsRegistries + ++ ERC721 + ++ ERC721TokenReceiver + ++ IMultisig + ++ IService + ++ ServiceStakingBase + -> ERC721TokenReceiver, IErrorsRegistries + + +Base_Contract -> Immediate_Child_Contracts + [Not_Immediate_Child_Contracts] + ++ IErrorsRegistries + -> ServiceStakingBase + ++ ERC721 + ++ ERC721TokenReceiver + -> ServiceStakingBase + ++ IMultisig + ++ IService + ++ ServiceStakingBase + +INFO:Slither:. analyzed (23 contracts) diff --git a/audits/internal4/analysis/slither_modifiers.txt b/audits/internal4/analysis/slither_modifiers.txt new file mode 100644 index 00000000..a09d6be7 --- /dev/null +++ b/audits/internal4/analysis/slither_modifiers.txt @@ -0,0 +1,199 @@ +'solc --version' running +'solc ./ServiceStakingNativeToken-flatten.sol --combined-json abi,ast,bin,bin-runtime,srcmap,srcmap-runtime,userdoc,devdoc,hashes --allow-paths .,/home/andrey/valory/autonolas-registries/audits/internal4/analysis/contracts' running +'solc --version' running +'solc ./ServiceStakingToken-flatten.sol --combined-json abi,ast,bin,bin-runtime,srcmap,srcmap-runtime,userdoc,devdoc,hashes --allow-paths .,/home/andrey/valory/autonolas-registries/audits/internal4/analysis/contracts' running +'solc --version' running +'solc ./ServiceStakingBase-flatten.sol --combined-json abi,ast,bin,bin-runtime,srcmap,srcmap-runtime,userdoc,devdoc,hashes --allow-paths .,/home/andrey/valory/autonolas-registries/audits/internal4/analysis/contracts' running +INFO:Printers: +Contract ERC721 ++-------------------+-----------+ +| Function | Modifiers | ++-------------------+-----------+ +| tokenURI | [] | +| ownerOf | [] | +| balanceOf | [] | +| constructor | [] | +| approve | [] | +| setApprovalForAll | [] | +| transferFrom | [] | +| safeTransferFrom | [] | +| safeTransferFrom | [] | +| supportsInterface | [] | +| _mint | [] | +| _burn | [] | +| _safeMint | [] | +| _safeMint | [] | ++-------------------+-----------+ +INFO:Printers: +Contract IMultisig ++----------+-----------+ +| Function | Modifiers | ++----------+-----------+ +| nonce | [] | ++----------+-----------+ +INFO:Printers: +Contract IService ++---------------------+-----------+ +| Function | Modifiers | ++---------------------+-----------+ +| safeTransferFrom | [] | +| mapServices | [] | +| getUnitIdsOfService | [] | ++---------------------+-----------+ +INFO:Printers: +Contract ServiceStakingNativeToken ++-------------------------------------+-----------+ +| Function | Modifiers | ++-------------------------------------+-----------+ +| constructor | [] | +| _checkTokenStakingDeposit | [] | +| _withdraw | [] | +| stake | [] | +| _calculateStakingRewards | [] | +| checkpoint | [] | +| unstake | [] | +| calculateServiceStakingReward | [] | +| onERC721Received | [] | +| constructor | [] | +| _withdraw | [] | +| receive | [] | +| slitherConstructorConstantVariables | [] | ++-------------------------------------+-----------+ +INFO:Printers: +Contract ERC721 ++-------------------+-----------+ +| Function | Modifiers | ++-------------------+-----------+ +| tokenURI | [] | +| ownerOf | [] | +| balanceOf | [] | +| constructor | [] | +| approve | [] | +| setApprovalForAll | [] | +| transferFrom | [] | +| safeTransferFrom | [] | +| safeTransferFrom | [] | +| supportsInterface | [] | +| _mint | [] | +| _burn | [] | +| _safeMint | [] | +| _safeMint | [] | ++-------------------+-----------+ +INFO:Printers: +Contract IMultisig ++----------+-----------+ +| Function | Modifiers | ++----------+-----------+ +| nonce | [] | ++----------+-----------+ +INFO:Printers: +Contract IService ++---------------------+-----------+ +| Function | Modifiers | ++---------------------+-----------+ +| safeTransferFrom | [] | +| mapServices | [] | +| getUnitIdsOfService | [] | ++---------------------+-----------+ +INFO:Printers: +Contract IToken ++--------------+-----------+ +| Function | Modifiers | ++--------------+-----------+ +| balanceOf | [] | +| ownerOf | [] | +| totalSupply | [] | +| transfer | [] | +| allowance | [] | +| approve | [] | +| transferFrom | [] | +| decimals | [] | ++--------------+-----------+ +INFO:Printers: +Contract SafeTransferLib ++------------------+-----------+ +| Function | Modifiers | ++------------------+-----------+ +| safeTransferFrom | [] | +| safeTransfer | [] | ++------------------+-----------+ +INFO:Printers: +Contract IServiceTokenUtility ++--------------------------+-----------+ +| Function | Modifiers | ++--------------------------+-----------+ +| mapServiceIdTokenDeposit | [] | ++--------------------------+-----------+ +INFO:Printers: +Contract ServiceStakingToken ++-------------------------------------+-----------+ +| Function | Modifiers | ++-------------------------------------+-----------+ +| constructor | [] | +| _checkTokenStakingDeposit | [] | +| _withdraw | [] | +| stake | [] | +| _calculateStakingRewards | [] | +| checkpoint | [] | +| unstake | [] | +| calculateServiceStakingReward | [] | +| onERC721Received | [] | +| constructor | [] | +| _checkTokenStakingDeposit | [] | +| _withdraw | [] | +| deposit | [] | +| slitherConstructorConstantVariables | [] | ++-------------------------------------+-----------+ +INFO:Printers: +Contract ERC721 ++-------------------+-----------+ +| Function | Modifiers | ++-------------------+-----------+ +| tokenURI | [] | +| ownerOf | [] | +| balanceOf | [] | +| constructor | [] | +| approve | [] | +| setApprovalForAll | [] | +| transferFrom | [] | +| safeTransferFrom | [] | +| safeTransferFrom | [] | +| supportsInterface | [] | +| _mint | [] | +| _burn | [] | +| _safeMint | [] | +| _safeMint | [] | ++-------------------+-----------+ +INFO:Printers: +Contract IMultisig ++----------+-----------+ +| Function | Modifiers | ++----------+-----------+ +| nonce | [] | ++----------+-----------+ +INFO:Printers: +Contract IService ++---------------------+-----------+ +| Function | Modifiers | ++---------------------+-----------+ +| safeTransferFrom | [] | +| mapServices | [] | +| getUnitIdsOfService | [] | ++---------------------+-----------+ +INFO:Printers: +Contract ServiceStakingBase ++-------------------------------------+-----------+ +| Function | Modifiers | ++-------------------------------------+-----------+ +| onERC721Received | [] | +| constructor | [] | +| _checkTokenStakingDeposit | [] | +| _withdraw | [] | +| stake | [] | +| _calculateStakingRewards | [] | +| checkpoint | [] | +| unstake | [] | +| calculateServiceStakingReward | [] | +| slitherConstructorConstantVariables | [] | ++-------------------------------------+-----------+ +INFO:Slither:. analyzed (23 contracts) diff --git a/audits/internal4/analysis/slither_require.txt b/audits/internal4/analysis/slither_require.txt new file mode 100644 index 00000000..066efefc --- /dev/null +++ b/audits/internal4/analysis/slither_require.txt @@ -0,0 +1,238 @@ +'solc --version' running +'solc ./ServiceStakingNativeToken-flatten.sol --combined-json abi,ast,bin,bin-runtime,srcmap,srcmap-runtime,userdoc,devdoc,hashes --allow-paths .,/home/andrey/valory/autonolas-registries/audits/internal4/analysis/contracts' running +'solc --version' running +'solc ./ServiceStakingToken-flatten.sol --combined-json abi,ast,bin,bin-runtime,srcmap,srcmap-runtime,userdoc,devdoc,hashes --allow-paths .,/home/andrey/valory/autonolas-registries/audits/internal4/analysis/contracts' running +'solc --version' running +'solc ./ServiceStakingBase-flatten.sol --combined-json abi,ast,bin,bin-runtime,srcmap,srcmap-runtime,userdoc,devdoc,hashes --allow-paths .,/home/andrey/valory/autonolas-registries/audits/internal4/analysis/contracts' running +INFO:Printers: +Contract ERC721 ++-------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| Function | require or assert | ++-------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| tokenURI | | +| ownerOf | require(bool,string)((owner = _ownerOf[id]) != address(0),NOT_MINTED) | +| balanceOf | require(bool,string)(owner != address(0),ZERO_ADDRESS) | +| constructor | | +| approve | require(bool,string)(msg.sender == owner || isApprovedForAll[owner][msg.sender],NOT_AUTHORIZED) | +| setApprovalForAll | | +| transferFrom | require(bool,string)(from == _ownerOf[id],WRONG_FROM) | +| | require(bool,string)(msg.sender == from || isApprovedForAll[from][msg.sender] || msg.sender == getApproved[id],NOT_AUTHORIZED) | +| | require(bool,string)(to != address(0),INVALID_RECIPIENT) | +| safeTransferFrom | require(bool,string)(ERC721TokenReceiver(to).onERC721Received(msg.sender,from,id,) == ERC721TokenReceiver.onERC721Received.selector,UNSAFE_RECIPIENT) | +| | require(bool,string)(from == _ownerOf[id],WRONG_FROM) | +| | require(bool,string)(msg.sender == from || isApprovedForAll[from][msg.sender] || msg.sender == getApproved[id],NOT_AUTHORIZED) | +| | require(bool,string)(to != address(0),INVALID_RECIPIENT) | +| safeTransferFrom | require(bool,string)(ERC721TokenReceiver(to).onERC721Received(msg.sender,from,id,data) == ERC721TokenReceiver.onERC721Received.selector,UNSAFE_RECIPIENT) | +| | require(bool,string)(from == _ownerOf[id],WRONG_FROM) | +| | require(bool,string)(msg.sender == from || isApprovedForAll[from][msg.sender] || msg.sender == getApproved[id],NOT_AUTHORIZED) | +| | require(bool,string)(to != address(0),INVALID_RECIPIENT) | +| supportsInterface | | +| _mint | require(bool,string)(_ownerOf[id] == address(0),ALREADY_MINTED) | +| | require(bool,string)(to != address(0),INVALID_RECIPIENT) | +| _burn | require(bool,string)(owner != address(0),NOT_MINTED) | +| _safeMint | require(bool,string)(ERC721TokenReceiver(to).onERC721Received(msg.sender,address(0),id,) == ERC721TokenReceiver.onERC721Received.selector,UNSAFE_RECIPIENT) | +| | require(bool,string)(_ownerOf[id] == address(0),ALREADY_MINTED) | +| | require(bool,string)(to != address(0),INVALID_RECIPIENT) | +| _safeMint | require(bool,string)(ERC721TokenReceiver(to).onERC721Received(msg.sender,address(0),id,data) == ERC721TokenReceiver.onERC721Received.selector,UNSAFE_RECIPIENT) | +| | require(bool,string)(_ownerOf[id] == address(0),ALREADY_MINTED) | +| | require(bool,string)(to != address(0),INVALID_RECIPIENT) | ++-------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------+ +INFO:Printers: +Contract IMultisig ++----------+-------------------+ +| Function | require or assert | ++----------+-------------------+ +| nonce | | ++----------+-------------------+ +INFO:Printers: +Contract IService ++---------------------+-------------------+ +| Function | require or assert | ++---------------------+-------------------+ +| safeTransferFrom | | +| mapServices | | +| getUnitIdsOfService | | ++---------------------+-------------------+ +INFO:Printers: +Contract ServiceStakingNativeToken ++-------------------------------------+-------------------+ +| Function | require or assert | ++-------------------------------------+-------------------+ +| constructor | | +| _checkTokenStakingDeposit | | +| _withdraw | | +| stake | | +| _calculateStakingRewards | | +| checkpoint | | +| unstake | | +| calculateServiceStakingReward | | +| onERC721Received | | +| constructor | | +| _withdraw | | +| receive | | +| slitherConstructorConstantVariables | | ++-------------------------------------+-------------------+ +INFO:Printers: +Contract ERC721 ++-------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| Function | require or assert | ++-------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| tokenURI | | +| ownerOf | require(bool,string)((owner = _ownerOf[id]) != address(0),NOT_MINTED) | +| balanceOf | require(bool,string)(owner != address(0),ZERO_ADDRESS) | +| constructor | | +| approve | require(bool,string)(msg.sender == owner || isApprovedForAll[owner][msg.sender],NOT_AUTHORIZED) | +| setApprovalForAll | | +| transferFrom | require(bool,string)(from == _ownerOf[id],WRONG_FROM) | +| | require(bool,string)(msg.sender == from || isApprovedForAll[from][msg.sender] || msg.sender == getApproved[id],NOT_AUTHORIZED) | +| | require(bool,string)(to != address(0),INVALID_RECIPIENT) | +| safeTransferFrom | require(bool,string)(ERC721TokenReceiver(to).onERC721Received(msg.sender,from,id,) == ERC721TokenReceiver.onERC721Received.selector,UNSAFE_RECIPIENT) | +| | require(bool,string)(from == _ownerOf[id],WRONG_FROM) | +| | require(bool,string)(msg.sender == from || isApprovedForAll[from][msg.sender] || msg.sender == getApproved[id],NOT_AUTHORIZED) | +| | require(bool,string)(to != address(0),INVALID_RECIPIENT) | +| safeTransferFrom | require(bool,string)(ERC721TokenReceiver(to).onERC721Received(msg.sender,from,id,data) == ERC721TokenReceiver.onERC721Received.selector,UNSAFE_RECIPIENT) | +| | require(bool,string)(from == _ownerOf[id],WRONG_FROM) | +| | require(bool,string)(msg.sender == from || isApprovedForAll[from][msg.sender] || msg.sender == getApproved[id],NOT_AUTHORIZED) | +| | require(bool,string)(to != address(0),INVALID_RECIPIENT) | +| supportsInterface | | +| _mint | require(bool,string)(_ownerOf[id] == address(0),ALREADY_MINTED) | +| | require(bool,string)(to != address(0),INVALID_RECIPIENT) | +| _burn | require(bool,string)(owner != address(0),NOT_MINTED) | +| _safeMint | require(bool,string)(ERC721TokenReceiver(to).onERC721Received(msg.sender,address(0),id,) == ERC721TokenReceiver.onERC721Received.selector,UNSAFE_RECIPIENT) | +| | require(bool,string)(_ownerOf[id] == address(0),ALREADY_MINTED) | +| | require(bool,string)(to != address(0),INVALID_RECIPIENT) | +| _safeMint | require(bool,string)(ERC721TokenReceiver(to).onERC721Received(msg.sender,address(0),id,data) == ERC721TokenReceiver.onERC721Received.selector,UNSAFE_RECIPIENT) | +| | require(bool,string)(_ownerOf[id] == address(0),ALREADY_MINTED) | +| | require(bool,string)(to != address(0),INVALID_RECIPIENT) | ++-------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------+ +INFO:Printers: +Contract IMultisig ++----------+-------------------+ +| Function | require or assert | ++----------+-------------------+ +| nonce | | ++----------+-------------------+ +INFO:Printers: +Contract IService ++---------------------+-------------------+ +| Function | require or assert | ++---------------------+-------------------+ +| safeTransferFrom | | +| mapServices | | +| getUnitIdsOfService | | ++---------------------+-------------------+ +INFO:Printers: +Contract IToken ++--------------+-------------------+ +| Function | require or assert | ++--------------+-------------------+ +| balanceOf | | +| ownerOf | | +| totalSupply | | +| transfer | | +| allowance | | +| approve | | +| transferFrom | | +| decimals | | ++--------------+-------------------+ +INFO:Printers: +Contract SafeTransferLib ++------------------+-------------------+ +| Function | require or assert | ++------------------+-------------------+ +| safeTransferFrom | | +| safeTransfer | | ++------------------+-------------------+ +INFO:Printers: +Contract IServiceTokenUtility ++--------------------------+-------------------+ +| Function | require or assert | ++--------------------------+-------------------+ +| mapServiceIdTokenDeposit | | ++--------------------------+-------------------+ +INFO:Printers: +Contract ServiceStakingToken ++-------------------------------------+-------------------+ +| Function | require or assert | ++-------------------------------------+-------------------+ +| constructor | | +| _checkTokenStakingDeposit | | +| _withdraw | | +| stake | | +| _calculateStakingRewards | | +| checkpoint | | +| unstake | | +| calculateServiceStakingReward | | +| onERC721Received | | +| constructor | | +| _checkTokenStakingDeposit | | +| _withdraw | | +| deposit | | +| slitherConstructorConstantVariables | | ++-------------------------------------+-------------------+ +INFO:Printers: +Contract ERC721 ++-------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| Function | require or assert | ++-------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| tokenURI | | +| ownerOf | require(bool,string)((owner = _ownerOf[id]) != address(0),NOT_MINTED) | +| balanceOf | require(bool,string)(owner != address(0),ZERO_ADDRESS) | +| constructor | | +| approve | require(bool,string)(msg.sender == owner || isApprovedForAll[owner][msg.sender],NOT_AUTHORIZED) | +| setApprovalForAll | | +| transferFrom | require(bool,string)(from == _ownerOf[id],WRONG_FROM) | +| | require(bool,string)(msg.sender == from || isApprovedForAll[from][msg.sender] || msg.sender == getApproved[id],NOT_AUTHORIZED) | +| | require(bool,string)(to != address(0),INVALID_RECIPIENT) | +| safeTransferFrom | require(bool,string)(ERC721TokenReceiver(to).onERC721Received(msg.sender,from,id,) == ERC721TokenReceiver.onERC721Received.selector,UNSAFE_RECIPIENT) | +| | require(bool,string)(from == _ownerOf[id],WRONG_FROM) | +| | require(bool,string)(msg.sender == from || isApprovedForAll[from][msg.sender] || msg.sender == getApproved[id],NOT_AUTHORIZED) | +| | require(bool,string)(to != address(0),INVALID_RECIPIENT) | +| safeTransferFrom | require(bool,string)(ERC721TokenReceiver(to).onERC721Received(msg.sender,from,id,data) == ERC721TokenReceiver.onERC721Received.selector,UNSAFE_RECIPIENT) | +| | require(bool,string)(from == _ownerOf[id],WRONG_FROM) | +| | require(bool,string)(msg.sender == from || isApprovedForAll[from][msg.sender] || msg.sender == getApproved[id],NOT_AUTHORIZED) | +| | require(bool,string)(to != address(0),INVALID_RECIPIENT) | +| supportsInterface | | +| _mint | require(bool,string)(_ownerOf[id] == address(0),ALREADY_MINTED) | +| | require(bool,string)(to != address(0),INVALID_RECIPIENT) | +| _burn | require(bool,string)(owner != address(0),NOT_MINTED) | +| _safeMint | require(bool,string)(ERC721TokenReceiver(to).onERC721Received(msg.sender,address(0),id,) == ERC721TokenReceiver.onERC721Received.selector,UNSAFE_RECIPIENT) | +| | require(bool,string)(_ownerOf[id] == address(0),ALREADY_MINTED) | +| | require(bool,string)(to != address(0),INVALID_RECIPIENT) | +| _safeMint | require(bool,string)(ERC721TokenReceiver(to).onERC721Received(msg.sender,address(0),id,data) == ERC721TokenReceiver.onERC721Received.selector,UNSAFE_RECIPIENT) | +| | require(bool,string)(_ownerOf[id] == address(0),ALREADY_MINTED) | +| | require(bool,string)(to != address(0),INVALID_RECIPIENT) | ++-------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------+ +INFO:Printers: +Contract IMultisig ++----------+-------------------+ +| Function | require or assert | ++----------+-------------------+ +| nonce | | ++----------+-------------------+ +INFO:Printers: +Contract IService ++---------------------+-------------------+ +| Function | require or assert | ++---------------------+-------------------+ +| safeTransferFrom | | +| mapServices | | +| getUnitIdsOfService | | ++---------------------+-------------------+ +INFO:Printers: +Contract ServiceStakingBase ++-------------------------------------+-------------------+ +| Function | require or assert | ++-------------------------------------+-------------------+ +| onERC721Received | | +| constructor | | +| _checkTokenStakingDeposit | | +| _withdraw | | +| stake | | +| _calculateStakingRewards | | +| checkpoint | | +| unstake | | +| calculateServiceStakingReward | | +| slitherConstructorConstantVariables | | ++-------------------------------------+-------------------+ +INFO:Slither:. analyzed (23 contracts) diff --git a/audits/internal4/analysis/slither_variable-order.txt b/audits/internal4/analysis/slither_variable-order.txt new file mode 100644 index 00000000..b35fccf6 --- /dev/null +++ b/audits/internal4/analysis/slither_variable-order.txt @@ -0,0 +1,136 @@ +'solc --version' running +'solc ./ServiceStakingNativeToken-flatten.sol --combined-json abi,ast,bin,bin-runtime,srcmap,srcmap-runtime,userdoc,devdoc,hashes --allow-paths .,/home/andrey/valory/autonolas-registries/audits/internal4/analysis/contracts' running +'solc --version' running +'solc ./ServiceStakingToken-flatten.sol --combined-json abi,ast,bin,bin-runtime,srcmap,srcmap-runtime,userdoc,devdoc,hashes --allow-paths .,/home/andrey/valory/autonolas-registries/audits/internal4/analysis/contracts' running +'solc --version' running +'solc ./ServiceStakingBase-flatten.sol --combined-json abi,ast,bin,bin-runtime,srcmap,srcmap-runtime,userdoc,devdoc,hashes --allow-paths .,/home/andrey/valory/autonolas-registries/audits/internal4/analysis/contracts' running +INFO:Printers: +ERC721: ++-------------------------+----------------------------------------------+------+--------+ +| Name | Type | Slot | Offset | ++-------------------------+----------------------------------------------+------+--------+ +| ERC721.name | string | 0 | 0 | +| ERC721.symbol | string | 1 | 0 | +| ERC721._ownerOf | mapping(uint256 => address) | 2 | 0 | +| ERC721._balanceOf | mapping(address => uint256) | 3 | 0 | +| ERC721.getApproved | mapping(uint256 => address) | 4 | 0 | +| ERC721.isApprovedForAll | mapping(address => mapping(address => bool)) | 5 | 0 | ++-------------------------+----------------------------------------------+------+--------+ + +IMultisig: ++------+------+------+--------+ +| Name | Type | Slot | Offset | ++------+------+------+--------+ ++------+------+------+--------+ + +IService: ++------+------+------+--------+ +| Name | Type | Slot | Offset | ++------+------+------+--------+ ++------+------+------+--------+ + +ServiceStakingNativeToken: ++-------------------------------------+---------------------------------+------+--------+ +| Name | Type | Slot | Offset | ++-------------------------------------+---------------------------------+------+--------+ +| ServiceStakingBase.balance | uint256 | 0 | 0 | +| ServiceStakingBase.availableRewards | uint256 | 1 | 0 | +| ServiceStakingBase.tsCheckpoint | uint256 | 2 | 0 | +| ServiceStakingBase.agentIds | uint256[] | 3 | 0 | +| ServiceStakingBase.mapServiceInfo | mapping(uint256 => ServiceInfo) | 4 | 0 | +| ServiceStakingBase.setServiceIds | uint256[] | 5 | 0 | ++-------------------------------------+---------------------------------+------+--------+ + +INFO:Printers: +ERC721: ++-------------------------+----------------------------------------------+------+--------+ +| Name | Type | Slot | Offset | ++-------------------------+----------------------------------------------+------+--------+ +| ERC721.name | string | 0 | 0 | +| ERC721.symbol | string | 1 | 0 | +| ERC721._ownerOf | mapping(uint256 => address) | 2 | 0 | +| ERC721._balanceOf | mapping(address => uint256) | 3 | 0 | +| ERC721.getApproved | mapping(uint256 => address) | 4 | 0 | +| ERC721.isApprovedForAll | mapping(address => mapping(address => bool)) | 5 | 0 | ++-------------------------+----------------------------------------------+------+--------+ + +IMultisig: ++------+------+------+--------+ +| Name | Type | Slot | Offset | ++------+------+------+--------+ ++------+------+------+--------+ + +IService: ++------+------+------+--------+ +| Name | Type | Slot | Offset | ++------+------+------+--------+ ++------+------+------+--------+ + +IToken: ++------+------+------+--------+ +| Name | Type | Slot | Offset | ++------+------+------+--------+ ++------+------+------+--------+ + +SafeTransferLib: ++------+------+------+--------+ +| Name | Type | Slot | Offset | ++------+------+------+--------+ ++------+------+------+--------+ + +IServiceTokenUtility: ++------+------+------+--------+ +| Name | Type | Slot | Offset | ++------+------+------+--------+ ++------+------+------+--------+ + +ServiceStakingToken: ++-------------------------------------+---------------------------------+------+--------+ +| Name | Type | Slot | Offset | ++-------------------------------------+---------------------------------+------+--------+ +| ServiceStakingBase.balance | uint256 | 0 | 0 | +| ServiceStakingBase.availableRewards | uint256 | 1 | 0 | +| ServiceStakingBase.tsCheckpoint | uint256 | 2 | 0 | +| ServiceStakingBase.agentIds | uint256[] | 3 | 0 | +| ServiceStakingBase.mapServiceInfo | mapping(uint256 => ServiceInfo) | 4 | 0 | +| ServiceStakingBase.setServiceIds | uint256[] | 5 | 0 | ++-------------------------------------+---------------------------------+------+--------+ + +INFO:Printers: +ERC721: ++-------------------------+----------------------------------------------+------+--------+ +| Name | Type | Slot | Offset | ++-------------------------+----------------------------------------------+------+--------+ +| ERC721.name | string | 0 | 0 | +| ERC721.symbol | string | 1 | 0 | +| ERC721._ownerOf | mapping(uint256 => address) | 2 | 0 | +| ERC721._balanceOf | mapping(address => uint256) | 3 | 0 | +| ERC721.getApproved | mapping(uint256 => address) | 4 | 0 | +| ERC721.isApprovedForAll | mapping(address => mapping(address => bool)) | 5 | 0 | ++-------------------------+----------------------------------------------+------+--------+ + +IMultisig: ++------+------+------+--------+ +| Name | Type | Slot | Offset | ++------+------+------+--------+ ++------+------+------+--------+ + +IService: ++------+------+------+--------+ +| Name | Type | Slot | Offset | ++------+------+------+--------+ ++------+------+------+--------+ + +ServiceStakingBase: ++-------------------------------------+---------------------------------+------+--------+ +| Name | Type | Slot | Offset | ++-------------------------------------+---------------------------------+------+--------+ +| ServiceStakingBase.balance | uint256 | 0 | 0 | +| ServiceStakingBase.availableRewards | uint256 | 1 | 0 | +| ServiceStakingBase.tsCheckpoint | uint256 | 2 | 0 | +| ServiceStakingBase.agentIds | uint256[] | 3 | 0 | +| ServiceStakingBase.mapServiceInfo | mapping(uint256 => ServiceInfo) | 4 | 0 | +| ServiceStakingBase.setServiceIds | uint256[] | 5 | 0 | ++-------------------------------------+---------------------------------+------+--------+ + +INFO:Slither:. analyzed (23 contracts) diff --git a/audits/internal4/analysis/slither_vars-and-auth.txt b/audits/internal4/analysis/slither_vars-and-auth.txt new file mode 100644 index 00000000..fdaa13be --- /dev/null +++ b/audits/internal4/analysis/slither_vars-and-auth.txt @@ -0,0 +1,273 @@ +'solc --version' running +'solc ./ServiceStakingNativeToken-flatten.sol --combined-json abi,ast,bin,bin-runtime,srcmap,srcmap-runtime,userdoc,devdoc,hashes --allow-paths .,/home/andrey/valory/autonolas-registries/audits/internal4/analysis/contracts' running +'solc --version' running +'solc ./ServiceStakingToken-flatten.sol --combined-json abi,ast,bin,bin-runtime,srcmap,srcmap-runtime,userdoc,devdoc,hashes --allow-paths .,/home/andrey/valory/autonolas-registries/audits/internal4/analysis/contracts' running +'solc --version' running +'solc ./ServiceStakingBase-flatten.sol --combined-json abi,ast,bin,bin-runtime,srcmap,srcmap-runtime,userdoc,devdoc,hashes --allow-paths .,/home/andrey/valory/autonolas-registries/audits/internal4/analysis/contracts' running +INFO:Printers: +Contract IErrorsRegistries ++----------+-------------------------+--------------------------+ +| Function | State variables written | Conditions on msg.sender | ++----------+-------------------------+--------------------------+ ++----------+-------------------------+--------------------------+ + +Contract ERC721 ++-------------------+-------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| Function | State variables written | Conditions on msg.sender | ++-------------------+-------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| tokenURI | [] | [] | +| ownerOf | [] | [] | +| balanceOf | [] | [] | +| constructor | ['name', 'symbol'] | [] | +| approve | ['getApproved'] | ['require(bool,string)(msg.sender == owner || isApprovedForAll[owner][msg.sender],NOT_AUTHORIZED)'] | +| setApprovalForAll | ['isApprovedForAll'] | [] | +| transferFrom | ['_balanceOf', '_ownerOf', 'getApproved'] | ['require(bool,string)(msg.sender == from || isApprovedForAll[from][msg.sender] || msg.sender == getApproved[id],NOT_AUTHORIZED)'] | +| safeTransferFrom | ['_balanceOf', '_ownerOf', 'getApproved'] | ['require(bool,string)(ERC721TokenReceiver(to).onERC721Received(msg.sender,from,id,) == ERC721TokenReceiver.onERC721Received.selector,UNSAFE_RECIPIENT)', 'require(bool,string)(msg.sender == from || isApprovedForAll[from][msg.sender] || msg.sender == getApproved[id],NOT_AUTHORIZED)'] | +| safeTransferFrom | ['_balanceOf', '_ownerOf', 'getApproved'] | ['require(bool,string)(ERC721TokenReceiver(to).onERC721Received(msg.sender,from,id,data) == ERC721TokenReceiver.onERC721Received.selector,UNSAFE_RECIPIENT)', 'require(bool,string)(msg.sender == from || isApprovedForAll[from][msg.sender] || msg.sender == getApproved[id],NOT_AUTHORIZED)'] | +| supportsInterface | [] | [] | +| _mint | ['_balanceOf', '_ownerOf'] | [] | +| _burn | ['_balanceOf', '_ownerOf', 'getApproved'] | [] | +| _safeMint | ['_balanceOf', '_ownerOf'] | ['require(bool,string)(ERC721TokenReceiver(to).onERC721Received(msg.sender,address(0),id,) == ERC721TokenReceiver.onERC721Received.selector,UNSAFE_RECIPIENT)'] | +| _safeMint | ['_balanceOf', '_ownerOf'] | ['require(bool,string)(ERC721TokenReceiver(to).onERC721Received(msg.sender,address(0),id,data) == ERC721TokenReceiver.onERC721Received.selector,UNSAFE_RECIPIENT)'] | ++-------------------+-------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ + +Contract ERC721TokenReceiver ++------------------+-------------------------+--------------------------+ +| Function | State variables written | Conditions on msg.sender | ++------------------+-------------------------+--------------------------+ +| onERC721Received | [] | [] | ++------------------+-------------------------+--------------------------+ + +Contract IMultisig ++----------+-------------------------+--------------------------+ +| Function | State variables written | Conditions on msg.sender | ++----------+-------------------------+--------------------------+ +| nonce | [] | [] | ++----------+-------------------------+--------------------------+ + +Contract IService ++---------------------+-------------------------+--------------------------+ +| Function | State variables written | Conditions on msg.sender | ++---------------------+-------------------------+--------------------------+ +| safeTransferFrom | [] | [] | +| mapServices | [] | [] | +| getUnitIdsOfService | [] | [] | ++---------------------+-------------------------+--------------------------+ + +Contract ServiceStakingBase ++-------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------+ +| Function | State variables written | Conditions on msg.sender | ++-------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------+ +| onERC721Received | [] | [] | +| constructor | ['agentIds', 'configHash', 'livenessPeriod', 'livenessRatio', 'maxNumServices', 'minStakingDeposit', 'numAgentInstances', 'rewardsPerSecond', 'serviceRegistry', 'threshold', 'tsCheckpoint'] | [] | +| _checkTokenStakingDeposit | [] | [] | +| _withdraw | [] | [] | +| stake | ['mapServiceInfo', 'setServiceIds'] | [] | +| _calculateStakingRewards | [] | [] | +| checkpoint | ['availableRewards', 'mapServiceInfo', 'tsCheckpoint'] | [] | +| unstake | ['availableRewards', 'mapServiceInfo', 'setServiceIds', 'tsCheckpoint'] | ['msg.sender != sInfo.owner'] | +| calculateServiceStakingReward | [] | [] | +| slitherConstructorConstantVariables | ['VERSION'] | [] | ++-------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------+ + +Contract ServiceStakingNativeToken ++-------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------+ +| Function | State variables written | Conditions on msg.sender | ++-------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------+ +| constructor | ['agentIds', 'configHash', 'livenessPeriod', 'livenessRatio', 'maxNumServices', 'minStakingDeposit', 'numAgentInstances', 'rewardsPerSecond', 'serviceRegistry', 'threshold', 'tsCheckpoint'] | [] | +| _checkTokenStakingDeposit | [] | [] | +| _withdraw | [] | [] | +| stake | ['mapServiceInfo', 'setServiceIds'] | [] | +| _calculateStakingRewards | [] | [] | +| checkpoint | ['availableRewards', 'mapServiceInfo', 'tsCheckpoint'] | [] | +| unstake | ['availableRewards', 'balance', 'mapServiceInfo', 'setServiceIds', 'tsCheckpoint'] | ['msg.sender != sInfo.owner'] | +| calculateServiceStakingReward | [] | [] | +| onERC721Received | [] | [] | +| constructor | ['agentIds', 'configHash', 'livenessPeriod', 'livenessRatio', 'maxNumServices', 'minStakingDeposit', 'numAgentInstances', 'rewardsPerSecond', 'serviceRegistry', 'threshold', 'tsCheckpoint'] | [] | +| _withdraw | ['balance'] | [] | +| receive | ['availableRewards', 'balance'] | [] | +| slitherConstructorConstantVariables | ['VERSION'] | [] | ++-------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------+ + +INFO:Printers: +Contract IErrorsRegistries ++----------+-------------------------+--------------------------+ +| Function | State variables written | Conditions on msg.sender | ++----------+-------------------------+--------------------------+ ++----------+-------------------------+--------------------------+ + +Contract ERC721 ++-------------------+-------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| Function | State variables written | Conditions on msg.sender | ++-------------------+-------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| tokenURI | [] | [] | +| ownerOf | [] | [] | +| balanceOf | [] | [] | +| constructor | ['name', 'symbol'] | [] | +| approve | ['getApproved'] | ['require(bool,string)(msg.sender == owner || isApprovedForAll[owner][msg.sender],NOT_AUTHORIZED)'] | +| setApprovalForAll | ['isApprovedForAll'] | [] | +| transferFrom | ['_balanceOf', '_ownerOf', 'getApproved'] | ['require(bool,string)(msg.sender == from || isApprovedForAll[from][msg.sender] || msg.sender == getApproved[id],NOT_AUTHORIZED)'] | +| safeTransferFrom | ['_balanceOf', '_ownerOf', 'getApproved'] | ['require(bool,string)(ERC721TokenReceiver(to).onERC721Received(msg.sender,from,id,) == ERC721TokenReceiver.onERC721Received.selector,UNSAFE_RECIPIENT)', 'require(bool,string)(msg.sender == from || isApprovedForAll[from][msg.sender] || msg.sender == getApproved[id],NOT_AUTHORIZED)'] | +| safeTransferFrom | ['_balanceOf', '_ownerOf', 'getApproved'] | ['require(bool,string)(ERC721TokenReceiver(to).onERC721Received(msg.sender,from,id,data) == ERC721TokenReceiver.onERC721Received.selector,UNSAFE_RECIPIENT)', 'require(bool,string)(msg.sender == from || isApprovedForAll[from][msg.sender] || msg.sender == getApproved[id],NOT_AUTHORIZED)'] | +| supportsInterface | [] | [] | +| _mint | ['_balanceOf', '_ownerOf'] | [] | +| _burn | ['_balanceOf', '_ownerOf', 'getApproved'] | [] | +| _safeMint | ['_balanceOf', '_ownerOf'] | ['require(bool,string)(ERC721TokenReceiver(to).onERC721Received(msg.sender,address(0),id,) == ERC721TokenReceiver.onERC721Received.selector,UNSAFE_RECIPIENT)'] | +| _safeMint | ['_balanceOf', '_ownerOf'] | ['require(bool,string)(ERC721TokenReceiver(to).onERC721Received(msg.sender,address(0),id,data) == ERC721TokenReceiver.onERC721Received.selector,UNSAFE_RECIPIENT)'] | ++-------------------+-------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ + +Contract ERC721TokenReceiver ++------------------+-------------------------+--------------------------+ +| Function | State variables written | Conditions on msg.sender | ++------------------+-------------------------+--------------------------+ +| onERC721Received | [] | [] | ++------------------+-------------------------+--------------------------+ + +Contract IMultisig ++----------+-------------------------+--------------------------+ +| Function | State variables written | Conditions on msg.sender | ++----------+-------------------------+--------------------------+ +| nonce | [] | [] | ++----------+-------------------------+--------------------------+ + +Contract IService ++---------------------+-------------------------+--------------------------+ +| Function | State variables written | Conditions on msg.sender | ++---------------------+-------------------------+--------------------------+ +| safeTransferFrom | [] | [] | +| mapServices | [] | [] | +| getUnitIdsOfService | [] | [] | ++---------------------+-------------------------+--------------------------+ + +Contract ServiceStakingBase ++-------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------+ +| Function | State variables written | Conditions on msg.sender | ++-------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------+ +| onERC721Received | [] | [] | +| constructor | ['agentIds', 'configHash', 'livenessPeriod', 'livenessRatio', 'maxNumServices', 'minStakingDeposit', 'numAgentInstances', 'rewardsPerSecond', 'serviceRegistry', 'threshold', 'tsCheckpoint'] | [] | +| _checkTokenStakingDeposit | [] | [] | +| _withdraw | [] | [] | +| stake | ['mapServiceInfo', 'setServiceIds'] | [] | +| _calculateStakingRewards | [] | [] | +| checkpoint | ['availableRewards', 'mapServiceInfo', 'tsCheckpoint'] | [] | +| unstake | ['availableRewards', 'mapServiceInfo', 'setServiceIds', 'tsCheckpoint'] | ['msg.sender != sInfo.owner'] | +| calculateServiceStakingReward | [] | [] | +| slitherConstructorConstantVariables | ['VERSION'] | [] | ++-------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------+ + +Contract IToken ++--------------+-------------------------+--------------------------+ +| Function | State variables written | Conditions on msg.sender | ++--------------+-------------------------+--------------------------+ +| balanceOf | [] | [] | +| ownerOf | [] | [] | +| totalSupply | [] | [] | +| transfer | [] | [] | +| allowance | [] | [] | +| approve | [] | [] | +| transferFrom | [] | [] | +| decimals | [] | [] | ++--------------+-------------------------+--------------------------+ + +Contract SafeTransferLib ++------------------+-------------------------+--------------------------+ +| Function | State variables written | Conditions on msg.sender | ++------------------+-------------------------+--------------------------+ +| safeTransferFrom | [] | [] | +| safeTransfer | [] | [] | ++------------------+-------------------------+--------------------------+ + +Contract IServiceTokenUtility ++--------------------------+-------------------------+--------------------------+ +| Function | State variables written | Conditions on msg.sender | ++--------------------------+-------------------------+--------------------------+ +| mapServiceIdTokenDeposit | [] | [] | ++--------------------------+-------------------------+--------------------------+ + +Contract ServiceStakingToken ++-------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------+ +| Function | State variables written | Conditions on msg.sender | ++-------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------+ +| constructor | ['agentIds', 'configHash', 'livenessPeriod', 'livenessRatio', 'maxNumServices', 'minStakingDeposit', 'numAgentInstances', 'rewardsPerSecond', 'serviceRegistry', 'threshold', 'tsCheckpoint'] | [] | +| _checkTokenStakingDeposit | [] | [] | +| _withdraw | [] | [] | +| stake | ['mapServiceInfo', 'setServiceIds'] | [] | +| _calculateStakingRewards | [] | [] | +| checkpoint | ['availableRewards', 'mapServiceInfo', 'tsCheckpoint'] | [] | +| unstake | ['availableRewards', 'balance', 'mapServiceInfo', 'setServiceIds', 'tsCheckpoint'] | ['msg.sender != sInfo.owner'] | +| calculateServiceStakingReward | [] | [] | +| onERC721Received | [] | [] | +| constructor | ['agentIds', 'configHash', 'livenessPeriod', 'livenessRatio', 'maxNumServices', 'minStakingDeposit', 'numAgentInstances', 'rewardsPerSecond', 'serviceRegistry', 'serviceRegistryTokenUtility', 'stakingToken', 'threshold', 'tsCheckpoint'] | [] | +| _checkTokenStakingDeposit | [] | [] | +| _withdraw | ['balance'] | [] | +| deposit | ['availableRewards', 'balance'] | [] | +| slitherConstructorConstantVariables | ['VERSION'] | [] | ++-------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------+ + +INFO:Printers: +Contract IErrorsRegistries ++----------+-------------------------+--------------------------+ +| Function | State variables written | Conditions on msg.sender | ++----------+-------------------------+--------------------------+ ++----------+-------------------------+--------------------------+ + +Contract ERC721 ++-------------------+-------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| Function | State variables written | Conditions on msg.sender | ++-------------------+-------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| tokenURI | [] | [] | +| ownerOf | [] | [] | +| balanceOf | [] | [] | +| constructor | ['name', 'symbol'] | [] | +| approve | ['getApproved'] | ['require(bool,string)(msg.sender == owner || isApprovedForAll[owner][msg.sender],NOT_AUTHORIZED)'] | +| setApprovalForAll | ['isApprovedForAll'] | [] | +| transferFrom | ['_balanceOf', '_ownerOf', 'getApproved'] | ['require(bool,string)(msg.sender == from || isApprovedForAll[from][msg.sender] || msg.sender == getApproved[id],NOT_AUTHORIZED)'] | +| safeTransferFrom | ['_balanceOf', '_ownerOf', 'getApproved'] | ['require(bool,string)(ERC721TokenReceiver(to).onERC721Received(msg.sender,from,id,) == ERC721TokenReceiver.onERC721Received.selector,UNSAFE_RECIPIENT)', 'require(bool,string)(msg.sender == from || isApprovedForAll[from][msg.sender] || msg.sender == getApproved[id],NOT_AUTHORIZED)'] | +| safeTransferFrom | ['_balanceOf', '_ownerOf', 'getApproved'] | ['require(bool,string)(ERC721TokenReceiver(to).onERC721Received(msg.sender,from,id,data) == ERC721TokenReceiver.onERC721Received.selector,UNSAFE_RECIPIENT)', 'require(bool,string)(msg.sender == from || isApprovedForAll[from][msg.sender] || msg.sender == getApproved[id],NOT_AUTHORIZED)'] | +| supportsInterface | [] | [] | +| _mint | ['_balanceOf', '_ownerOf'] | [] | +| _burn | ['_balanceOf', '_ownerOf', 'getApproved'] | [] | +| _safeMint | ['_balanceOf', '_ownerOf'] | ['require(bool,string)(ERC721TokenReceiver(to).onERC721Received(msg.sender,address(0),id,) == ERC721TokenReceiver.onERC721Received.selector,UNSAFE_RECIPIENT)'] | +| _safeMint | ['_balanceOf', '_ownerOf'] | ['require(bool,string)(ERC721TokenReceiver(to).onERC721Received(msg.sender,address(0),id,data) == ERC721TokenReceiver.onERC721Received.selector,UNSAFE_RECIPIENT)'] | ++-------------------+-------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ + +Contract ERC721TokenReceiver ++------------------+-------------------------+--------------------------+ +| Function | State variables written | Conditions on msg.sender | ++------------------+-------------------------+--------------------------+ +| onERC721Received | [] | [] | ++------------------+-------------------------+--------------------------+ + +Contract IMultisig ++----------+-------------------------+--------------------------+ +| Function | State variables written | Conditions on msg.sender | ++----------+-------------------------+--------------------------+ +| nonce | [] | [] | ++----------+-------------------------+--------------------------+ + +Contract IService ++---------------------+-------------------------+--------------------------+ +| Function | State variables written | Conditions on msg.sender | ++---------------------+-------------------------+--------------------------+ +| safeTransferFrom | [] | [] | +| mapServices | [] | [] | +| getUnitIdsOfService | [] | [] | ++---------------------+-------------------------+--------------------------+ + +Contract ServiceStakingBase ++-------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------+ +| Function | State variables written | Conditions on msg.sender | ++-------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------+ +| onERC721Received | [] | [] | +| constructor | ['agentIds', 'configHash', 'livenessPeriod', 'livenessRatio', 'maxNumServices', 'minStakingDeposit', 'numAgentInstances', 'rewardsPerSecond', 'serviceRegistry', 'threshold', 'tsCheckpoint'] | [] | +| _checkTokenStakingDeposit | [] | [] | +| _withdraw | [] | [] | +| stake | ['mapServiceInfo', 'setServiceIds'] | [] | +| _calculateStakingRewards | [] | [] | +| checkpoint | ['availableRewards', 'mapServiceInfo', 'tsCheckpoint'] | [] | +| unstake | ['availableRewards', 'mapServiceInfo', 'setServiceIds', 'tsCheckpoint'] | ['msg.sender != sInfo.owner'] | +| calculateServiceStakingReward | [] | [] | +| slitherConstructorConstantVariables | ['VERSION'] | [] | ++-------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------+ + +INFO:Slither:. analyzed (23 contracts)