diff --git a/audits/internal12/README.md b/audits/internal12/README.md index 0959b9b..d4b2161 100644 --- a/audits/internal12/README.md +++ b/audits/internal12/README.md @@ -166,4 +166,21 @@ https://github.com/trailofbits/publications/blob/master/reviews/CurveDAO.pdf ``` [x] noted and added as a comment +# re-audit. 21.05.24 +# autonolas-governance-audit +The review has been performed based on the contract code in the following repository:
+`https://github.com/valory-xyz/autonolas-governance`
+commit: `9df1f95ec7e51eacb985aece56654b8d2506e29f` or `tag: v1.2.1-pre-internal-audit`
+ +### Flatten version +Flatten version of contracts. [contracts](https://github.com/valory-xyz/autonolas-governance/blob/main/audits/internal12/analysis2/contracts) + +### Coverage +Hardhat coverage has been performed before the audit and can be found here: +```sh +--------------------------------------|----------|----------|----------|----------|----------------| +File | % Stmts | % Branch | % Funcs | % Lines |Uncovered Lines | +--------------------------------------|----------|----------|----------|----------|----------------| + VoteWeighting.sol | 100 | 100 | 100 | 100 | | +``` diff --git a/audits/internal12/analysis2/contracts/VoteWeighting-flatten.sol b/audits/internal12/analysis2/contracts/VoteWeighting-flatten.sol new file mode 100644 index 0000000..a981ad1 --- /dev/null +++ b/audits/internal12/analysis2/contracts/VoteWeighting-flatten.sol @@ -0,0 +1,809 @@ +// Sources flattened with hardhat v2.22.4 https://hardhat.org + +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.25; + +// Dispenser interface +interface IDispenser { + /// @dev Records nominee addition in dispenser. + /// @param nomineeHash Nominee hash. + function addNominee(bytes32 nomineeHash) external; + + /// @dev Records nominee removal. + /// @param nomineeHash Nominee hash. + function removeNominee(bytes32 nomineeHash) external; +} + +// veOLAS interface +interface IVEOLAS { + // Structure for voting escrow points + // The struct size is two storage slots of 2 * uint256 (128 + 128 + 64 + 64 + 128) + struct PointVoting { + // w(i) = at + b (bias) + int128 bias; + // dw / dt = a (slope) + int128 slope; + // Timestamp. It will never practically be bigger than 2^64 - 1 + uint64 ts; + // Block number. It will not be bigger than the timestamp + uint64 blockNumber; + // Token amount. It will never practically be bigger. Initial OLAS cap is 1 bn tokens, or 1e27. + // After 10 years, the inflation rate is 2% per year. It would take 1340+ years to reach 2^128 - 1 + uint128 balance; + } + + /// @dev Gets the `account`'s lock end time. + /// @param account Account address. + /// @return unlockTime Lock end time. + function lockedEnd(address account) external view returns (uint256 unlockTime); + + /// @dev Gets the most recently recorded user point for `account`. + /// @param account Account address. + /// @return pv Last checkpoint. + function getLastUserPoint(address account) external view returns (PointVoting memory pv); +} + +/// @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 Provided zero address. +error ZeroAddress(); + +/// @dev Zero value when it has to be different from zero. +error ZeroValue(); + +/// @dev Wrong length of two arrays. +/// @param numValues1 Number of values in a first array. +/// @param numValues2 Number of values in a second array. +error WrongArrayLength(uint256 numValues1, uint256 numValues2); + +/// @dev Value overflow. +/// @param provided Overflow value. +/// @param max Maximum possible value. +error Overflow(uint256 provided, uint256 max); + +/// @dev Underflow value. +/// @param provided Provided value. +/// @param expected Minimum expected value. +error Underflow(uint256 provided, uint256 expected); + +/// @dev Nominee does not exist. +/// @param account Nominee account address. +/// @param chainId Nominee chain Id. +error NomineeDoesNotExist(bytes32 account, uint256 chainId); + +/// @dev Nominee already exists. +/// @param account Nominee account address. +/// @param chainId Nominee chain Id. +error NomineeAlreadyExists(bytes32 account, uint256 chainId); + +/// @dev Value lock is expired. +/// @param account Address that is checked for the locked value. +/// @param deadline The lock expiration deadline. +/// @param curTime Current timestamp. +error LockExpired(address account, uint256 deadline, uint256 curTime); + +/// @dev Violated a negative slope value. +/// @param account Account address. +/// @param slope Negative slope. +error NegativeSlope(address account, int128 slope); + +/// @dev The vote has been performed already. +/// @param voter Voter address. +/// @param curTime Current time. +/// @param nextAllowedVotingTime Next allowed voting time. +error VoteTooOften(address voter, uint256 curTime, uint256 nextAllowedVotingTime); + +/// @dev Nominee is not in the removed nominee map. +/// @param account Nominee account address. +/// @param chainId Nominee chain Id. +error NomineeNotRemoved(bytes32 account, uint256 chainId); + +/// @dev Nominee is in the removed nominee map. +/// @param account Nominee account address. +/// @param chainId Nominee chain Id. +error NomineeRemoved(bytes32 account, uint256 chainId); + +// Point struct +struct Point { + uint256 bias; + uint256 slope; +} + +// Voted slope struct +struct VotedSlope { + uint256 slope; + uint256 power; + uint256 end; +} + +// Nominee struct +struct Nominee { + bytes32 account; + uint256 chainId; +} + + +/// @title VoteWeighting - Smart contract for Vote Weighting with specific nominees composed of address and chain Id +/// @notice Inspired by https://github.com/curvefi/curve-dao-contracts/blob/master/contracts/GaugeController.vy +/// @author Aleksandr Kuperman - +/// @author Andrey Lebedev - +/// @author Mariapia Moscatiello - +contract VoteWeighting { + event OwnerUpdated(address indexed owner); + event DispenserUpdated(address indexed dispenser); + event Checkpoint(address indexed sender, uint256 sumBias); + event CheckpointNominee(address indexed sender, bytes32 indexed nomineeAccount, uint256 chainId, + uint256 nomineeWeight, uint256 totalSum); + event NomineeRelativeWeightWrite(address indexed sender, bytes32 indexed nomineeAccount, uint256 chainId, + uint256 nomineeWeight, uint256 totalSum, uint256 relativeWeight); + event VoteForNominee(address indexed user, bytes32 indexed nominee, uint256 chainId, uint256 weight); + event AddNominee(bytes32 indexed account, uint256 chainId, uint256 id); + event RemoveNominee(bytes32 indexed account, uint256 chainId, uint256 newSum); + + // 7 * 86400 seconds - all future times are rounded by week + uint256 public constant WEEK = 604_800; + // Cannot change weight votes more often than once in 10 days + // For explanation about the delay consult the official audit report: https://github.com/trailofbits/publications/blob/master/reviews/CurveDAO.pdf + uint256 public constant WEIGHT_VOTE_DELAY = 864_000; + // Max number of weeks for checkpoints + // The number corresponds to slightly more than a year time, that is more than enough to have at least one vote + // Also, in line with our tokenomics that cannot have epochs longer than a year + // The suggested maximum amount of weeks results in checkpoint calculation that always fit in the block, + // although in practice it is unlikely that there is no single checkpoint for the maximum amount of weeks + // For gas concerns regarding checkpoint calculations, see the internal audit and the official audit report: https://github.com/trailofbits/publications/blob/master/reviews/CurveDAO.pdf + uint256 public constant MAX_NUM_WEEKS = 53; + // Max weight amount + uint256 public constant MAX_WEIGHT = 10_000; + // Maximum chain Id as per EVM specs + uint256 public constant MAX_EVM_CHAIN_ID = type(uint64).max / 2 - 36; + // veOLAS contract address + address public immutable ve; + // Contract owner address + address public owner; + // Dispenser contract + address public dispenser; + + // Set of Nominee structs + Nominee[] public setNominees; + // Set of removed Nominee structs + Nominee[] public setRemovedNominees; + // Mapping of hash(Nominee struct) => nominee Id + mapping(bytes32 => uint256) public mapNomineeIds; + // Mapping of hash(Nominee struct) => removed nominee Id + mapping(bytes32 => uint256) public mapRemovedNominees; + + // user -> hash(Nominee struct) -> VotedSlope + mapping(address => mapping(bytes32 => VotedSlope)) public voteUserSlopes; + // Total vote power used by user + mapping(address => uint256) public voteUserPower; + // Last user vote's timestamp for each hash(Nominee struct) + mapping(address => mapping(bytes32 => uint256)) public lastUserVote; + + // Past and scheduled points for nominee weight, sum of weights per type, total weight + // Point is for bias+slope + // changes_* are for changes in slope + // time_* are for the last change timestamp + // timestamps are rounded to whole weeks + + // hash(Nominee struct) -> time -> Point + mapping(bytes32 => mapping(uint256 => Point)) public pointsWeight; + // hash(Nominee struct) -> time -> slope + mapping(bytes32 => mapping(uint256 => uint256)) public changesWeight; + // hash(Nominee struct) -> last scheduled time (next week) + mapping(bytes32 => uint256) public timeWeight; + + // time -> Point + mapping(uint256 => Point) public pointsSum; + // time -> slope + mapping(uint256 => uint256) public changesSum; + // last scheduled time (next week) + uint256 public timeSum; + + /// @dev Contract constructor. + /// @param _ve Voting Escrow contract address. + constructor(address _ve) { + // Check for the zero address + if (_ve == address(0)) { + revert ZeroAddress(); + } + + // Set initial parameters + owner = msg.sender; + ve = _ve; + timeSum = block.timestamp / WEEK * WEEK; + // Push empty element to the zero-th index + setNominees.push(Nominee(0, 0)); + // For symmetry, push empty element to the zero-th index in the removed Nominee set as well + setRemovedNominees.push(Nominee(0, 0)); + } + + /// @dev Fill sum of nominee weights for the same type week-over-week for missed checkins and return the sum for the future week. + /// @return Sum of nominee weights. + function _getSum() internal returns (uint256) { + // t is always > 0 as it is set in the constructor + uint256 t = timeSum; + Point memory pt = pointsSum[t]; + for (uint256 i = 0; i < MAX_NUM_WEEKS; i++) { + if (t > block.timestamp) { + break; + } + t += WEEK; + uint256 dBias = pt.slope * WEEK; + if (pt.bias > dBias) { + pt.bias -= dBias; + uint256 dSlope = changesSum[t]; + pt.slope -= dSlope; + } else { + pt.bias = 0; + pt.slope = 0; + } + + pointsSum[t] = pt; + if (t > block.timestamp) { + timeSum = t; + } + } + return pt.bias; + } + + /// @dev Fill historic nominee weights week-over-week for missed checkins and return the total for the future week. + /// @param account Nominee account address in bytes32 form. + /// @param chainId Nominee chain Id. + /// @return Nominee weight. + function _getWeight(bytes32 account, uint256 chainId) internal returns (uint256) { + // Construct the nominee struct + Nominee memory nominee = Nominee(account, chainId); + + // Check that the nominee exists or has been removed + bytes32 nomineeHash = keccak256(abi.encode(nominee)); + if (mapRemovedNominees[nomineeHash] == 0 && mapNomineeIds[nomineeHash] == 0) { + revert NomineeDoesNotExist(account, chainId); + } + + // t is always > 0 as it is set during the addNominee() call + uint256 t = timeWeight[nomineeHash]; + Point memory pt = pointsWeight[nomineeHash][t]; + for (uint256 i = 0; i < MAX_NUM_WEEKS; i++) { + if (t > block.timestamp) { + break; + } + t += WEEK; + uint256 dBias = pt.slope * WEEK; + if (pt.bias > dBias) { + pt.bias -= dBias; + uint256 dSlope = changesWeight[nomineeHash][t]; + pt.slope -= dSlope; + } else { + pt.bias = 0; + pt.slope = 0; + } + + pointsWeight[nomineeHash][t] = pt; + if (t > block.timestamp) { + timeWeight[nomineeHash] = t; + } + } + return pt.bias; + } + + /// @dev Add nominee address along with the chain Id. + /// @param nominee Nominee account address and chainId. + function _addNominee(Nominee memory nominee) internal { + // Check for the nominee existence + bytes32 nomineeHash = keccak256(abi.encode(nominee)); + if (mapNomineeIds[nomineeHash] > 0) { + revert NomineeAlreadyExists(nominee.account, nominee.chainId); + } + + // Check for the previously removed nominee + if (mapRemovedNominees[nomineeHash] > 0) { + revert NomineeRemoved(nominee.account, nominee.chainId); + } + + uint256 id = setNominees.length; + mapNomineeIds[nomineeHash] = id; + // Push the nominee into the list + setNominees.push(nominee); + + uint256 nextTime = (block.timestamp + WEEK) / WEEK * WEEK; + timeWeight[nomineeHash] = nextTime; + + // Enable nominee in dispenser, if applicable + address localDispenser = dispenser; + if (localDispenser != address(0)) { + IDispenser(localDispenser).addNominee(nomineeHash); + } + + emit AddNominee(nominee.account, nominee.chainId, id); + } + + /// @dev Add EVM nominee address along with the chain Id. + /// @param account Address of the nominee. + /// @param chainId Chain Id. + function addNomineeEVM(address account, uint256 chainId) external { + // Check for the zero address + if (account == address(0)) { + revert ZeroAddress(); + } + + // Check for zero chain Id + if (chainId == 0) { + revert ZeroValue(); + } + + // Check for the chain Id overflow + if (chainId > MAX_EVM_CHAIN_ID) { + revert Overflow(chainId, MAX_EVM_CHAIN_ID); + } + + Nominee memory nominee = Nominee(bytes32(uint256(uint160(account))), chainId); + + // Record nominee instance + _addNominee(nominee); + } + + /// @dev Add Non-EVM nominee address along with the chain Id. + /// @param account Address of the nominee in byte32 standard. + /// @param chainId Chain Id. + function addNomineeNonEVM(bytes32 account, uint256 chainId) external { + // Check for the zero address + if (account == bytes32(0)) { + revert ZeroAddress(); + } + + // Check for the chain Id underflow + if (MAX_EVM_CHAIN_ID >= chainId) { + revert Underflow(chainId, MAX_EVM_CHAIN_ID + 1); + } + + Nominee memory nominee = Nominee(account, chainId); + + // Record nominee instance + _addNominee(nominee); + } + + /// @dev Changes the owner address. + /// @param newOwner Address of a new owner. + function changeOwner(address newOwner) external { + // Check for the contract ownership + if (msg.sender != owner) { + revert OwnerOnly(msg.sender, owner); + } + + // Check for the zero address + if (newOwner == address(0)) { + revert ZeroAddress(); + } + + owner = newOwner; + emit OwnerUpdated(newOwner); + } + + /// @dev Changes the dispenser contract address. + /// @notice Dispenser can be set to a zero address if the contract needs to serve a general purpose. + /// @param newDispenser New dispenser contract address. + function changeDispenser(address newDispenser) external { + // Check for the contract ownership + if (msg.sender != owner) { + revert OwnerOnly(msg.sender, owner); + } + + dispenser = newDispenser; + emit DispenserUpdated(newDispenser); + } + + /// @dev Checkpoints to fill data common for all nominees. + function checkpoint() external { + uint256 totalSum = _getSum(); + + emit Checkpoint(msg.sender, totalSum); + } + + /// @dev Checkpoints to fill data for both a specific nominee and common for all nominees. + /// @param account Address of the nominee. + /// @param chainId Chain Id. + function checkpointNominee(bytes32 account, uint256 chainId) external { + uint256 nomineeWeight = _getWeight(account, chainId); + uint256 totalSum = _getSum(); + + emit CheckpointNominee(msg.sender, account, chainId, nomineeWeight, totalSum); + } + + /// @dev Gets Nominee relative weight (not more than 1.0) normalized to 1e18 (e.g. 1.0 == 1e18) and a sum of weights. + /// @param account Address of the nominee in byte32 standard. + /// @param chainId Chain Id. + /// @param time Timestamp in the past or present. + /// @return weight Value of relative weight normalized to 1e18. + /// @return totalSum Sum of nominee weights. + function _nomineeRelativeWeight( + bytes32 account, + uint256 chainId, + uint256 time + ) internal view returns (uint256 weight, uint256 totalSum) { + uint256 t = time / WEEK * WEEK; + totalSum = pointsSum[t].bias; + + Nominee memory nominee = Nominee(account, chainId); + bytes32 nomineeHash = keccak256(abi.encode(nominee)); + + if (totalSum > 0) { + uint256 nomineeWeight = pointsWeight[nomineeHash][t].bias; + weight = 1e18 * nomineeWeight / totalSum; + } + } + + /// @dev Gets Nominee relative weight (not more than 1.0) normalized to 1e18 (e.g. 1.0 == 1e18) and a sum of weights. + /// @param account Address of the nominee in bytes32 form. + /// @param chainId Chain Id. + /// @param time Relative weight at the specified timestamp in the past or present. + /// @return relativeWeight Value of nominee relative weight normalized to 1e18. + /// @return totalSum Sum of nominee weights. + function nomineeRelativeWeight( + bytes32 account, + uint256 chainId, + uint256 time + ) external view returns (uint256 relativeWeight, uint256 totalSum) { + (relativeWeight, totalSum) = _nomineeRelativeWeight(account, chainId, time); + } + + /// @dev Checkpoints and gets nominee weight normalized to 1e18, and the total sum of all the nominee weights. + /// @notice Nothing is recorded if the values are already filled. + /// @param account Address of the nominee in bytes32 form. + /// @param chainId Chain Id. + /// @param time Relative weight at the specified timestamp in the past or present. + /// @return relativeWeight Value of nominee relative weight normalized to 1e18. + /// @return totalSum Sum of nominee weights. + function nomineeRelativeWeightWrite( + bytes32 account, + uint256 chainId, + uint256 time + ) external returns (uint256 relativeWeight, uint256 totalSum) { + uint256 nomineeWeight = _getWeight(account, chainId); + _getSum(); + (relativeWeight, totalSum) = _nomineeRelativeWeight(account, chainId, time); + + emit NomineeRelativeWeightWrite(msg.sender, account, chainId, nomineeWeight, totalSum, relativeWeight); + } + + /// @dev Allocates voting power for changing pool weights. + /// @param account Address of the nominee the `msg.sender` votes for in bytes32 form. + /// @param chainId Chain Id. + /// @param weight Weight for a nominee in bps (units of 0.01%). Minimal is 0.01%. Ignored if 0. + function voteForNomineeWeights(bytes32 account, uint256 chainId, uint256 weight) public { + // Get the nominee hash + bytes32 nomineeHash = keccak256(abi.encode(Nominee(account, chainId))); + + // Check for the previously removed nominee + if (mapRemovedNominees[nomineeHash] > 0) { + revert NomineeRemoved(account, chainId); + } + + // Get user veOLAS slope and check its value + int128 userSlope = IVEOLAS(ve).getLastUserPoint(msg.sender).slope; + if (userSlope < 0) { + revert NegativeSlope(msg.sender, userSlope); + } + + uint256 lockEnd = IVEOLAS(ve).lockedEnd(msg.sender); + uint256 nextTime = (block.timestamp + WEEK) / WEEK * WEEK; + + // Check for the lock end expiration + if (nextTime >= lockEnd) { + revert LockExpired(msg.sender, lockEnd, nextTime); + } + + // Check for the weight number + if (weight > MAX_WEIGHT) { + revert Overflow(weight, MAX_WEIGHT); + } + + // Check for the last voting time + uint256 nextAllowedVotingTime = lastUserVote[msg.sender][nomineeHash] + WEIGHT_VOTE_DELAY; + if (nextAllowedVotingTime > block.timestamp) { + revert VoteTooOften(msg.sender, block.timestamp, nextAllowedVotingTime); + } + + // Prepare old and new slopes and biases + VotedSlope memory oldSlope = voteUserSlopes[msg.sender][nomineeHash]; + uint256 oldBias; + if (oldSlope.end > nextTime) { + oldBias = oldSlope.slope * (oldSlope.end - nextTime); + } + + VotedSlope memory newSlope = VotedSlope({ + slope: uint256(uint128(userSlope)) * weight / MAX_WEIGHT, + end: lockEnd, + power: weight + }); + + uint256 newBias = newSlope.slope * (lockEnd - nextTime); + + uint256 powerUsed = voteUserPower[msg.sender]; + powerUsed = powerUsed + newSlope.power - oldSlope.power; + voteUserPower[msg.sender] = powerUsed; + if (powerUsed > MAX_WEIGHT) { + revert Overflow(powerUsed, MAX_WEIGHT); + } + + // Remove old and schedule new slope changes + // Remove slope changes for old slopes + // Schedule recording of initial slope for nextTime + pointsWeight[nomineeHash][nextTime].bias = _maxAndSub(_getWeight(account, chainId) + newBias, oldBias); + pointsSum[nextTime].bias = _maxAndSub(_getSum() + newBias, oldBias); + if (oldSlope.end > nextTime) { + pointsWeight[nomineeHash][nextTime].slope = + _maxAndSub(pointsWeight[nomineeHash][nextTime].slope + newSlope.slope, oldSlope.slope); + pointsSum[nextTime].slope = _maxAndSub(pointsSum[nextTime].slope + newSlope.slope, oldSlope.slope); + } else { + pointsWeight[nomineeHash][nextTime].slope += newSlope.slope; + pointsSum[nextTime].slope += newSlope.slope; + } + if (oldSlope.end > block.timestamp) { + // Cancel old slope changes if they still didn't happen + changesWeight[nomineeHash][oldSlope.end] -= oldSlope.slope; + changesSum[oldSlope.end] -= oldSlope.slope; + } + // Add slope changes for new slopes + changesWeight[nomineeHash][newSlope.end] += newSlope.slope; + changesSum[newSlope.end] += newSlope.slope; + + voteUserSlopes[msg.sender][nomineeHash] = newSlope; + + // Record last action time + lastUserVote[msg.sender][nomineeHash] = block.timestamp; + + emit VoteForNominee(msg.sender, account, chainId, weight); + } + + /// @dev Allocates voting power for changing pool weights in a batch set. + /// @param accounts Set of nominee addresses in bytes32 form the `msg.sender` votes for. + /// @param chainIds Set of corresponding chain Ids. + /// @param weights Weights for a nominees in bps (units of 0.01%). Minimal is 0.01%. Ignored if 0. + function voteForNomineeWeightsBatch( + bytes32[] memory accounts, + uint256[] memory chainIds, + uint256[] memory weights + ) external { + if (accounts.length != chainIds.length || accounts.length != weights.length) { + revert WrongArrayLength(accounts.length, weights.length); + } + + // Traverse all accounts and weights + for (uint256 i = 0; i < accounts.length; ++i) { + voteForNomineeWeights(accounts[i], chainIds[i], weights[i]); + } + } + + function _maxAndSub(uint256 a, uint256 b) internal pure returns (uint256) { + return a > b ? a - b : 0; + } + + /// @dev Removes nominee from the contract and zeros its weight. + /// @notice The last nominee in the set of nominees is going to change its Id at the end of this function call. + /// @param account Address of the nominee in bytes32 form. + /// @param chainId Chain Id. + function removeNominee(bytes32 account, uint256 chainId) external { + // Check for the contract ownership + if (msg.sender != owner) { + revert OwnerOnly(owner, msg.sender); + } + + // Get the nominee struct and hash + Nominee memory nominee = Nominee(account, chainId); + bytes32 nomineeHash = keccak256(abi.encode(nominee)); + + // Get the nominee id in the nominee set + uint256 id = mapNomineeIds[nomineeHash]; + if (id == 0) { + revert NomineeDoesNotExist(account, chainId); + } + + // Set nominee weight to zero + uint256 oldWeight = _getWeight(account, chainId); + uint256 oldSum = _getSum(); + uint256 nextTime = (block.timestamp + WEEK) / WEEK * WEEK; + pointsWeight[nomineeHash][nextTime].bias = 0; + timeWeight[nomineeHash] = nextTime; + + // Account for the the sum weight change + uint256 newSum = oldSum - oldWeight; + pointsSum[nextTime].bias = newSum; + timeSum = nextTime; + + // Add to the removed nominee map and set + mapRemovedNominees[nomineeHash] = setRemovedNominees.length; + setRemovedNominees.push(nominee); + + // Remove nominee from the map + mapNomineeIds[nomineeHash] = 0; + + // Shuffle the current last nominee id in the set to be placed to the removed one + nominee = setNominees[setNominees.length - 1]; + bytes32 replacedNomineeHash = keccak256(abi.encode(nominee)); + mapNomineeIds[replacedNomineeHash] = id; + setNominees[id] = nominee; + // Pop the last element from the set + setNominees.pop(); + + // Remove nominee in dispenser, if applicable + address localDispenser = dispenser; + if (localDispenser != address(0)) { + IDispenser(localDispenser).removeNominee(nomineeHash); + } + + emit RemoveNominee(account, chainId, newSum); + } + + /// @dev Retrieves user voting power from a removed nominee. + /// @param account Address of the nominee in bytes32 form. + /// @param chainId Chain Id. + function retrieveRemovedNomineeVotingPower(bytes32 account, uint256 chainId) external { + // Get the nominee struct and hash + Nominee memory nominee = Nominee(account, chainId); + bytes32 nomineeHash = keccak256(abi.encode(nominee)); + + // Check that the nominee is removed + if (mapRemovedNominees[nomineeHash] == 0) { + revert NomineeNotRemoved(account, chainId); + } + + // Get the user old slope + VotedSlope memory oldSlope = voteUserSlopes[msg.sender][nomineeHash]; + if (oldSlope.power == 0) { + revert ZeroValue(); + } + + // Cancel old slope changes if they still didn't happen + if (oldSlope.end > block.timestamp) { + changesWeight[nomineeHash][oldSlope.end] -= oldSlope.slope; + changesSum[oldSlope.end] -= oldSlope.slope; + } + + // Update the voting power + uint256 powerUsed = voteUserPower[msg.sender]; + powerUsed = powerUsed - oldSlope.power; + voteUserPower[msg.sender] = powerUsed; + delete voteUserSlopes[msg.sender][nomineeHash]; + } + + /// @dev Get current nominee weight. + /// @param account Address of the nominee in bytes32 form. + /// @param chainId Chain Id. + /// @return Nominee weight. + function getNomineeWeight(bytes32 account, uint256 chainId) external view returns (uint256) { + // Get the nominee struct and hash + Nominee memory nominee = Nominee(account, chainId); + bytes32 nomineeHash = keccak256(abi.encode(nominee)); + + return pointsWeight[nomineeHash][timeWeight[nomineeHash]].bias; + } + + /// @dev Get sum of nominee weights. + /// @return Sum of nominee weights. + function getWeightsSum() external view returns (uint256) { + return pointsSum[timeSum].bias; + } + + /// @dev Get the total number of nominees. + /// @notice The zero-th default nominee Id with id == 0 does not count. + /// @return Total number of nominees. + function getNumNominees() external view returns (uint256) { + return setNominees.length - 1; + } + + /// @dev Get the total number of removed nominees. + /// @notice The zero-th default nominee Id with id == 0 does not count. + /// @return Total number of removed nominees. + function getNumRemovedNominees() external view returns (uint256) { + return setRemovedNominees.length - 1; + } + + /// @dev Gets a full set of nominees. + /// @notice The returned set includes the zero-th empty nominee instance. + /// @return Set of all the nominees in the contract. + function getAllNominees() external view returns (Nominee[] memory) { + return setNominees; + } + + /// @dev Gets a full set of removed nominees. + /// @notice The returned set includes the zero-th empty nominee instance. + /// @return Set of all the removed nominees in the contract. + function getAllRemovedNominees() external view returns (Nominee[] memory) { + return setRemovedNominees; + } + + /// @dev Gets the nominee Id in the global nominees set. + /// @param account Nominee address in bytes32 form. + /// @param chainId Chain Id. + /// @return Nominee Id in the global set of Nominee struct values. + function getNomineeId(bytes32 account, uint256 chainId) external view returns (uint256) { + // Get the nominee struct and hash + Nominee memory nominee = Nominee(account, chainId); + bytes32 nomineeHash = keccak256(abi.encode(nominee)); + + return mapNomineeIds[nomineeHash]; + } + + /// @dev Gets the removed nominee Id in the global removed nominees set. + /// @param account Nominee address in bytes32 form. + /// @param chainId Chain Id. + /// @return Removed nominee Id in the global set of Nominee struct values. + function getRemovedNomineeId(bytes32 account, uint256 chainId) external view returns (uint256) { + // Get the nominee struct and hash + Nominee memory nominee = Nominee(account, chainId); + bytes32 nomineeHash = keccak256(abi.encode(nominee)); + + return mapRemovedNominees[nomineeHash]; + } + + /// @dev Gets the nominee address and its corresponding chain Id. + /// @notice The zero-th default nominee Id with id == 0 does not count. + /// @param id Nominee Id in the global set of Nominee struct values. + /// @return Nominee address in bytes32 form and chain Id. + function getNominee(uint256 id) external view returns (Nominee memory) { + // Get the total number of nominees in the contract + uint256 totalNumNominees = setNominees.length - 1; + // Check for the zero id or the overflow + if (id == 0) { + revert ZeroValue(); + } else if (id > totalNumNominees) { + revert Overflow(id, totalNumNominees); + } + + return setNominees[id]; + } + + /// @dev Gets the removed nominee address and its corresponding chain Id. + /// @notice The zero-th default removed nominee Id with id == 0 does not count. + /// @param id Removed nominee Id in the global set of Nominee struct values. + /// @return Removed nominee address in bytes32 form and chain Id. + function getRemovedNominee(uint256 id) external view returns (Nominee memory) { + // Get the total number of nominees in the contract + uint256 totalNumRemovedNominees = setRemovedNominees.length - 1; + // Check for the zero id or the overflow + if (id == 0) { + revert ZeroValue(); + } else if (id > totalNumRemovedNominees) { + revert Overflow(id, totalNumRemovedNominees); + } + + return setRemovedNominees[id]; + } + + /// @dev Gets next allowed voting time for selected nominees and voters. + /// @notice The function does not check for repeated nominees and voters. + /// @param accounts Set of nominee account addresses. + /// @param chainIds Corresponding set of chain Ids. + /// @param voters Corresponding set of voters for specified nominees. + function getNextAllowedVotingTimes( + bytes32[] memory accounts, + uint256[] memory chainIds, + address[] memory voters + ) external view returns (uint256[] memory nextAllowedVotingTimes) { + // Check array lengths + if (accounts.length != chainIds.length || accounts.length != voters.length) { + revert WrongArrayLength(accounts.length, chainIds.length); + } + + // Allocate the times array + nextAllowedVotingTimes = new uint256[](accounts.length); + + // Traverse nominees and get next available voting times + for (uint256 i = 0; i < accounts.length; ++i) { + // Get the nominee struct and hash + Nominee memory nominee = Nominee(accounts[i], chainIds[i]); + bytes32 nomineeHash = keccak256(abi.encode(nominee)); + + // Check for nominee existence + if (mapNomineeIds[nomineeHash] == 0) { + revert NomineeDoesNotExist(accounts[i], chainIds[i]); + } + + // Calculate next allowed voting times + nextAllowedVotingTimes[i] = lastUserVote[voters[i]][nomineeHash] + WEIGHT_VOTE_DELAY; + } + } +} diff --git a/audits/internal12/analysis2/contracts/script.sh b/audits/internal12/analysis2/contracts/script.sh new file mode 100755 index 0000000..286784b --- /dev/null +++ b/audits/internal12/analysis2/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/internal12/analysis2/slither_VoteWeighting-flatten.sol.IDispenser.call-graph.png b/audits/internal12/analysis2/slither_VoteWeighting-flatten.sol.IDispenser.call-graph.png new file mode 100644 index 0000000..68ad698 Binary files /dev/null and b/audits/internal12/analysis2/slither_VoteWeighting-flatten.sol.IDispenser.call-graph.png differ diff --git a/audits/internal12/analysis2/slither_VoteWeighting-flatten.sol.IVEOLAS.call-graph.png b/audits/internal12/analysis2/slither_VoteWeighting-flatten.sol.IVEOLAS.call-graph.png new file mode 100644 index 0000000..86a6346 Binary files /dev/null and b/audits/internal12/analysis2/slither_VoteWeighting-flatten.sol.IVEOLAS.call-graph.png differ diff --git a/audits/internal12/analysis2/slither_VoteWeighting-flatten.sol.VoteWeighting.call-graph.png b/audits/internal12/analysis2/slither_VoteWeighting-flatten.sol.VoteWeighting.call-graph.png new file mode 100644 index 0000000..58482b1 Binary files /dev/null and b/audits/internal12/analysis2/slither_VoteWeighting-flatten.sol.VoteWeighting.call-graph.png differ diff --git a/audits/internal12/analysis2/slither_VoteWeighting-flatten.sol.all_contracts.call-graph.png b/audits/internal12/analysis2/slither_VoteWeighting-flatten.sol.all_contracts.call-graph.png new file mode 100644 index 0000000..6f55f90 Binary files /dev/null and b/audits/internal12/analysis2/slither_VoteWeighting-flatten.sol.all_contracts.call-graph.png differ diff --git a/audits/internal12/analysis2/slither_VoteWeighting-flatten.sol.inheritance-graph.png b/audits/internal12/analysis2/slither_VoteWeighting-flatten.sol.inheritance-graph.png new file mode 100644 index 0000000..08604e0 Binary files /dev/null and b/audits/internal12/analysis2/slither_VoteWeighting-flatten.sol.inheritance-graph.png differ diff --git a/audits/internal12/analysis2/slither_call-graph.txt b/audits/internal12/analysis2/slither_call-graph.txt new file mode 100644 index 0000000..14dba8c --- /dev/null +++ b/audits/internal12/analysis2/slither_call-graph.txt @@ -0,0 +1,8 @@ +'solc --version' running +'solc ./VoteWeighting-flatten.sol --combined-json abi,ast,bin,bin-runtime,srcmap,srcmap-runtime,userdoc,devdoc,hashes --allow-paths .,/home/andrey/valory/autonolas-governance/audits/internal12/analysis2/contracts' running +INFO:Printers:Call Graph: ./VoteWeighting-flatten.sol.all_contracts.call-graph.dot +Call Graph: ./VoteWeighting-flatten.sol.IDispenser.call-graph.dot +Call Graph: ./VoteWeighting-flatten.sol.IVEOLAS.call-graph.dot +Call Graph: ./VoteWeighting-flatten.sol.VoteWeighting.call-graph.dot + +INFO:Slither:. analyzed (3 contracts) diff --git a/audits/internal12/analysis2/slither_constructor-calls.txt b/audits/internal12/analysis2/slither_constructor-calls.txt new file mode 100644 index 0000000..a5d2060 --- /dev/null +++ b/audits/internal12/analysis2/slither_constructor-calls.txt @@ -0,0 +1,31 @@ +'solc --version' running +'solc ./VoteWeighting-flatten.sol --combined-json abi,ast,bin,bin-runtime,srcmap,srcmap-runtime,userdoc,devdoc,hashes --allow-paths .,/home/andrey/valory/autonolas-governance/audits/internal12/analysis2/contracts' running +INFO:Printers: +############################# +####### VoteWeighting ####### +############################# + +## Constructor Call Sequence + - VoteWeighting + +## Constructor Definitions + +### VoteWeighting + + constructor(address _ve) { + // Check for the zero address + if (_ve == address(0)) { + revert ZeroAddress(); + } + + // Set initial parameters + owner = msg.sender; + ve = _ve; + timeSum = block.timestamp / WEEK * WEEK; + // Push empty element to the zero-th index + setNominees.push(Nominee(0, 0)); + // For symmetry, push empty element to the zero-th index in the removed Nominee set as well + setRemovedNominees.push(Nominee(0, 0)); + } + +INFO:Slither:. analyzed (3 contracts) diff --git a/audits/internal12/analysis2/slither_contract-summary.txt b/audits/internal12/analysis2/slither_contract-summary.txt new file mode 100644 index 0000000..8d8e3ee --- /dev/null +++ b/audits/internal12/analysis2/slither_contract-summary.txt @@ -0,0 +1,46 @@ +'solc --version' running +'solc ./VoteWeighting-flatten.sol --combined-json abi,ast,bin,bin-runtime,srcmap,srcmap-runtime,userdoc,devdoc,hashes --allow-paths .,/home/andrey/valory/autonolas-governance/audits/internal12/analysis2/contracts' running +INFO:Printers: ++ Contract IDispenser (Most derived contract) + - From IDispenser + - addNominee(bytes32) (external) + - removeNominee(bytes32) (external) + ++ Contract IVEOLAS (Most derived contract) + - From IVEOLAS + - getLastUserPoint(address) (external) + - lockedEnd(address) (external) + ++ Contract VoteWeighting (Most derived contract) + - From VoteWeighting + - _addNominee(Nominee) (internal) + - _getSum() (internal) + - _getWeight(bytes32,uint256) (internal) + - _maxAndSub(uint256,uint256) (internal) + - _nomineeRelativeWeight(bytes32,uint256,uint256) (internal) + - addNomineeEVM(address,uint256) (external) + - addNomineeNonEVM(bytes32,uint256) (external) + - changeDispenser(address) (external) + - changeOwner(address) (external) + - checkpoint() (external) + - checkpointNominee(bytes32,uint256) (external) + - constructor(address) (public) + - getAllNominees() (external) + - getAllRemovedNominees() (external) + - getNextAllowedVotingTimes(bytes32[],uint256[],address[]) (external) + - getNominee(uint256) (external) + - getNomineeId(bytes32,uint256) (external) + - getNomineeWeight(bytes32,uint256) (external) + - getNumNominees() (external) + - getNumRemovedNominees() (external) + - getRemovedNominee(uint256) (external) + - getRemovedNomineeId(bytes32,uint256) (external) + - getWeightsSum() (external) + - nomineeRelativeWeight(bytes32,uint256,uint256) (external) + - nomineeRelativeWeightWrite(bytes32,uint256,uint256) (external) + - removeNominee(bytes32,uint256) (external) + - retrieveRemovedNomineeVotingPower(bytes32,uint256) (external) + - voteForNomineeWeights(bytes32,uint256,uint256) (public) + - voteForNomineeWeightsBatch(bytes32[],uint256[],uint256[]) (external) + +INFO:Slither:. analyzed (3 contracts) diff --git a/audits/internal12/analysis2/slither_data-dependency.txt b/audits/internal12/analysis2/slither_data-dependency.txt new file mode 100644 index 0000000..775fa8a --- /dev/null +++ b/audits/internal12/analysis2/slither_data-dependency.txt @@ -0,0 +1,1032 @@ +'solc --version' running +'solc ./VoteWeighting-flatten.sol --combined-json abi,ast,bin,bin-runtime,srcmap,srcmap-runtime,userdoc,devdoc,hashes --allow-paths .,/home/andrey/valory/autonolas-governance/audits/internal12/analysis2/contracts' running +INFO:Printers: +Contract IDispenser ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ ++----------+--------------+ + +Function addNominee(bytes32) ++-------------+--------------+ +| Variable | Dependencies | ++-------------+--------------+ +| nomineeHash | [] | ++-------------+--------------+ +Function removeNominee(bytes32) ++-------------+--------------+ +| Variable | Dependencies | ++-------------+--------------+ +| nomineeHash | [] | ++-------------+--------------+ +INFO:Printers: +Contract IDispenser ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ ++----------+--------------+ + +Function addNominee(bytes32) ++-------------+--------------+ +| Variable | Dependencies | ++-------------+--------------+ +| nomineeHash | [] | ++-------------+--------------+ +Function removeNominee(bytes32) ++-------------+--------------+ +| Variable | Dependencies | ++-------------+--------------+ +| nomineeHash | [] | ++-------------+--------------+ +Contract IVEOLAS ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ ++----------+--------------+ + +Function lockedEnd(address) ++------------+--------------+ +| Variable | Dependencies | ++------------+--------------+ +| account | [] | +| unlockTime | [] | ++------------+--------------+ +Function getLastUserPoint(address) ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ +| account | [] | +| pv | [] | ++----------+--------------+ +INFO:Printers: +Contract IDispenser ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ ++----------+--------------+ + +Function addNominee(bytes32) ++-------------+--------------+ +| Variable | Dependencies | ++-------------+--------------+ +| nomineeHash | [] | ++-------------+--------------+ +Function removeNominee(bytes32) ++-------------+--------------+ +| Variable | Dependencies | ++-------------+--------------+ +| nomineeHash | [] | ++-------------+--------------+ +Contract IVEOLAS ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ ++----------+--------------+ + +Function lockedEnd(address) ++------------+--------------+ +| Variable | Dependencies | ++------------+--------------+ +| account | [] | +| unlockTime | [] | ++------------+--------------+ +Function getLastUserPoint(address) ++----------+--------------+ +| Variable | Dependencies | ++----------+--------------+ +| account | [] | +| pv | [] | ++----------+--------------+ +Contract VoteWeighting ++--------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| Variable | Dependencies | ++--------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| WEEK | ['WEEK'] | +| WEIGHT_VOTE_DELAY | ['WEIGHT_VOTE_DELAY'] | +| MAX_NUM_WEEKS | ['MAX_NUM_WEEKS'] | +| MAX_WEIGHT | ['MAX_WEIGHT'] | +| MAX_EVM_CHAIN_ID | ['MAX_EVM_CHAIN_ID'] | +| ve | ['_ve', 've'] | +| owner | ['msg.sender', 'newOwner', 'owner'] | +| dispenser | ['dispenser', 'newDispenser'] | +| setNominees | ['account', 'chainId', 'nominee', 'setNominees'] | +| setRemovedNominees | ['account', 'chainId', 'nominee', 'setRemovedNominees'] | +| mapNomineeIds | ['account', 'chainId', 'id', 'mapNomineeIds', 'nominee', 'setNominees'] | +| mapRemovedNominees | ['mapRemovedNominees', 'setRemovedNominees'] | +| voteUserSlopes | ['voteUserSlopes'] | +| voteUserPower | ['MAX_WEIGHT', '_ve', 'lockEnd', 'msg.sender', 'newSlope', 'oldSlope', 'powerUsed', 'userSlope', 've', 'voteUserPower', 'voteUserSlopes', 'weight', 'weights'] | +| lastUserVote | ['lastUserVote'] | +| pointsWeight | ['pointsWeight'] | +| changesWeight | ['changesWeight'] | +| timeWeight | ['WEEK', 'block.timestamp', 'nextTime', 't', 'timeWeight'] | +| pointsSum | ['MAX_WEIGHT', 'WEEK', '_ve', 'changesSum', 'dBias', 'dSlope', 'lockEnd', 'msg.sender', 'newSlope', 'oldSlope', 'pointsSum', 'pt', 'userSlope', 've', 'voteUserSlopes', 'weight', 'weights'] | +| changesSum | ['MAX_WEIGHT', '_ve', 'changesSum', 'lockEnd', 'msg.sender', 'newSlope', 'oldSlope', 'userSlope', 've', 'voteUserSlopes', 'weight', 'weights'] | +| timeSum | ['WEEK', 'block.timestamp', 'nextTime', 't', 'timeSum'] | ++--------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ + +Function constructor(address) ++----------------------------------+-----------------------------+ +| Variable | Dependencies | ++----------------------------------+-----------------------------+ +| _ve | [] | +| VoteWeighting.WEEK | ['WEEK'] | +| VoteWeighting.WEIGHT_VOTE_DELAY | [] | +| VoteWeighting.MAX_NUM_WEEKS | [] | +| VoteWeighting.MAX_WEIGHT | [] | +| VoteWeighting.MAX_EVM_CHAIN_ID | [] | +| VoteWeighting.ve | ['_ve'] | +| VoteWeighting.owner | ['msg.sender'] | +| VoteWeighting.dispenser | [] | +| VoteWeighting.setNominees | ['setNominees'] | +| VoteWeighting.setRemovedNominees | ['setRemovedNominees'] | +| VoteWeighting.mapNomineeIds | [] | +| VoteWeighting.mapRemovedNominees | [] | +| VoteWeighting.voteUserSlopes | [] | +| VoteWeighting.voteUserPower | [] | +| VoteWeighting.lastUserVote | [] | +| VoteWeighting.pointsWeight | [] | +| VoteWeighting.changesWeight | [] | +| VoteWeighting.timeWeight | [] | +| VoteWeighting.pointsSum | [] | +| VoteWeighting.changesSum | [] | +| VoteWeighting.timeSum | ['WEEK', 'block.timestamp'] | ++----------------------------------+-----------------------------+ +Function _getSum() ++----------------------------------+--------------------------------------------------------------+ +| Variable | Dependencies | ++----------------------------------+--------------------------------------------------------------+ +| | [] | +| t | ['WEEK', 't', 'timeSum'] | +| pt | ['WEEK', 'changesSum', 'dBias', 'dSlope', 'pointsSum', 'pt'] | +| i | ['i'] | +| dBias | ['WEEK', 'changesSum', 'dSlope', 'pointsSum', 'pt'] | +| dSlope | ['changesSum'] | +| VoteWeighting.WEEK | ['WEEK'] | +| VoteWeighting.WEIGHT_VOTE_DELAY | [] | +| VoteWeighting.MAX_NUM_WEEKS | ['MAX_NUM_WEEKS'] | +| VoteWeighting.MAX_WEIGHT | [] | +| VoteWeighting.MAX_EVM_CHAIN_ID | [] | +| VoteWeighting.ve | [] | +| VoteWeighting.owner | [] | +| VoteWeighting.dispenser | [] | +| VoteWeighting.setNominees | [] | +| VoteWeighting.setRemovedNominees | [] | +| VoteWeighting.mapNomineeIds | [] | +| VoteWeighting.mapRemovedNominees | [] | +| VoteWeighting.voteUserSlopes | [] | +| VoteWeighting.voteUserPower | [] | +| VoteWeighting.lastUserVote | [] | +| VoteWeighting.pointsWeight | [] | +| VoteWeighting.changesWeight | [] | +| VoteWeighting.timeWeight | [] | +| VoteWeighting.pointsSum | ['WEEK', 'changesSum', 'dBias', 'dSlope', 'pointsSum', 'pt'] | +| VoteWeighting.changesSum | ['changesSum'] | +| VoteWeighting.timeSum | ['WEEK', 't', 'timeSum'] | ++----------------------------------+--------------------------------------------------------------+ +Function _getWeight(bytes32,uint256) ++----------------------------------+--------------------------------------------------------------------+ +| Variable | Dependencies | ++----------------------------------+--------------------------------------------------------------------+ +| account | ['account'] | +| chainId | ['chainId'] | +| | [] | +| nominee | ['account', 'chainId'] | +| nomineeHash | ['account', 'chainId', 'nominee'] | +| t | ['WEEK', 't', 'timeWeight'] | +| pt | ['WEEK', 'changesWeight', 'dBias', 'dSlope', 'pointsWeight', 'pt'] | +| i | ['i'] | +| dBias | ['WEEK', 'pointsWeight', 'pt'] | +| dSlope | ['changesWeight'] | +| VoteWeighting.WEEK | ['WEEK'] | +| VoteWeighting.WEIGHT_VOTE_DELAY | [] | +| VoteWeighting.MAX_NUM_WEEKS | ['MAX_NUM_WEEKS'] | +| VoteWeighting.MAX_WEIGHT | [] | +| VoteWeighting.MAX_EVM_CHAIN_ID | [] | +| VoteWeighting.ve | [] | +| VoteWeighting.owner | [] | +| VoteWeighting.dispenser | [] | +| VoteWeighting.setNominees | [] | +| VoteWeighting.setRemovedNominees | [] | +| VoteWeighting.mapNomineeIds | ['mapNomineeIds'] | +| VoteWeighting.mapRemovedNominees | ['mapRemovedNominees'] | +| VoteWeighting.voteUserSlopes | [] | +| VoteWeighting.voteUserPower | [] | +| VoteWeighting.lastUserVote | [] | +| VoteWeighting.pointsWeight | ['pointsWeight'] | +| VoteWeighting.changesWeight | ['changesWeight'] | +| VoteWeighting.timeWeight | ['WEEK', 't', 'timeWeight'] | +| VoteWeighting.pointsSum | [] | +| VoteWeighting.changesSum | [] | +| VoteWeighting.timeSum | [] | ++----------------------------------+--------------------------------------------------------------------+ +Function _addNominee(Nominee) ++----------------------------------+-------------------------------------------------------+ +| Variable | Dependencies | ++----------------------------------+-------------------------------------------------------+ +| nominee | ['nominee'] | +| nomineeHash | ['nominee'] | +| id | ['nominee', 'setNominees'] | +| nextTime | ['WEEK', 'block.timestamp'] | +| localDispenser | ['dispenser'] | +| VoteWeighting.WEEK | ['WEEK'] | +| VoteWeighting.WEIGHT_VOTE_DELAY | [] | +| VoteWeighting.MAX_NUM_WEEKS | [] | +| VoteWeighting.MAX_WEIGHT | [] | +| VoteWeighting.MAX_EVM_CHAIN_ID | [] | +| VoteWeighting.ve | [] | +| VoteWeighting.owner | [] | +| VoteWeighting.dispenser | ['dispenser'] | +| VoteWeighting.setNominees | ['nominee', 'setNominees'] | +| VoteWeighting.setRemovedNominees | [] | +| VoteWeighting.mapNomineeIds | ['id', 'mapNomineeIds', 'nominee', 'setNominees'] | +| VoteWeighting.mapRemovedNominees | ['mapRemovedNominees'] | +| VoteWeighting.voteUserSlopes | [] | +| VoteWeighting.voteUserPower | [] | +| VoteWeighting.lastUserVote | [] | +| VoteWeighting.pointsWeight | [] | +| VoteWeighting.changesWeight | [] | +| VoteWeighting.timeWeight | ['WEEK', 'block.timestamp', 'nextTime', 'timeWeight'] | +| VoteWeighting.pointsSum | [] | +| VoteWeighting.changesSum | [] | +| VoteWeighting.timeSum | [] | ++----------------------------------+-------------------------------------------------------+ +Function addNomineeEVM(address,uint256) ++----------------------------------+------------------------+ +| Variable | Dependencies | ++----------------------------------+------------------------+ +| account | [] | +| chainId | [] | +| nominee | ['account', 'chainId'] | +| VoteWeighting.WEEK | [] | +| VoteWeighting.WEIGHT_VOTE_DELAY | [] | +| VoteWeighting.MAX_NUM_WEEKS | [] | +| VoteWeighting.MAX_WEIGHT | [] | +| VoteWeighting.MAX_EVM_CHAIN_ID | ['MAX_EVM_CHAIN_ID'] | +| VoteWeighting.ve | [] | +| VoteWeighting.owner | [] | +| VoteWeighting.dispenser | [] | +| VoteWeighting.setNominees | [] | +| VoteWeighting.setRemovedNominees | [] | +| VoteWeighting.mapNomineeIds | [] | +| VoteWeighting.mapRemovedNominees | [] | +| VoteWeighting.voteUserSlopes | [] | +| VoteWeighting.voteUserPower | [] | +| VoteWeighting.lastUserVote | [] | +| VoteWeighting.pointsWeight | [] | +| VoteWeighting.changesWeight | [] | +| VoteWeighting.timeWeight | [] | +| VoteWeighting.pointsSum | [] | +| VoteWeighting.changesSum | [] | +| VoteWeighting.timeSum | [] | ++----------------------------------+------------------------+ +Function addNomineeNonEVM(bytes32,uint256) ++----------------------------------+------------------------+ +| Variable | Dependencies | ++----------------------------------+------------------------+ +| account | [] | +| chainId | [] | +| nominee | ['account', 'chainId'] | +| VoteWeighting.WEEK | [] | +| VoteWeighting.WEIGHT_VOTE_DELAY | [] | +| VoteWeighting.MAX_NUM_WEEKS | [] | +| VoteWeighting.MAX_WEIGHT | [] | +| VoteWeighting.MAX_EVM_CHAIN_ID | ['MAX_EVM_CHAIN_ID'] | +| VoteWeighting.ve | [] | +| VoteWeighting.owner | [] | +| VoteWeighting.dispenser | [] | +| VoteWeighting.setNominees | [] | +| VoteWeighting.setRemovedNominees | [] | +| VoteWeighting.mapNomineeIds | [] | +| VoteWeighting.mapRemovedNominees | [] | +| VoteWeighting.voteUserSlopes | [] | +| VoteWeighting.voteUserPower | [] | +| VoteWeighting.lastUserVote | [] | +| VoteWeighting.pointsWeight | [] | +| VoteWeighting.changesWeight | [] | +| VoteWeighting.timeWeight | [] | +| VoteWeighting.pointsSum | [] | +| VoteWeighting.changesSum | [] | +| VoteWeighting.timeSum | [] | ++----------------------------------+------------------------+ +Function changeOwner(address) ++----------------------------------+-----------------------+ +| Variable | Dependencies | ++----------------------------------+-----------------------+ +| newOwner | [] | +| VoteWeighting.WEEK | [] | +| VoteWeighting.WEIGHT_VOTE_DELAY | [] | +| VoteWeighting.MAX_NUM_WEEKS | [] | +| VoteWeighting.MAX_WEIGHT | [] | +| VoteWeighting.MAX_EVM_CHAIN_ID | [] | +| VoteWeighting.ve | [] | +| VoteWeighting.owner | ['newOwner', 'owner'] | +| VoteWeighting.dispenser | [] | +| VoteWeighting.setNominees | [] | +| VoteWeighting.setRemovedNominees | [] | +| VoteWeighting.mapNomineeIds | [] | +| VoteWeighting.mapRemovedNominees | [] | +| VoteWeighting.voteUserSlopes | [] | +| VoteWeighting.voteUserPower | [] | +| VoteWeighting.lastUserVote | [] | +| VoteWeighting.pointsWeight | [] | +| VoteWeighting.changesWeight | [] | +| VoteWeighting.timeWeight | [] | +| VoteWeighting.pointsSum | [] | +| VoteWeighting.changesSum | [] | +| VoteWeighting.timeSum | [] | ++----------------------------------+-----------------------+ +Function changeDispenser(address) ++----------------------------------+------------------+ +| Variable | Dependencies | ++----------------------------------+------------------+ +| newDispenser | [] | +| VoteWeighting.WEEK | [] | +| VoteWeighting.WEIGHT_VOTE_DELAY | [] | +| VoteWeighting.MAX_NUM_WEEKS | [] | +| VoteWeighting.MAX_WEIGHT | [] | +| VoteWeighting.MAX_EVM_CHAIN_ID | [] | +| VoteWeighting.ve | [] | +| VoteWeighting.owner | ['owner'] | +| VoteWeighting.dispenser | ['newDispenser'] | +| VoteWeighting.setNominees | [] | +| VoteWeighting.setRemovedNominees | [] | +| VoteWeighting.mapNomineeIds | [] | +| VoteWeighting.mapRemovedNominees | [] | +| VoteWeighting.voteUserSlopes | [] | +| VoteWeighting.voteUserPower | [] | +| VoteWeighting.lastUserVote | [] | +| VoteWeighting.pointsWeight | [] | +| VoteWeighting.changesWeight | [] | +| VoteWeighting.timeWeight | [] | +| VoteWeighting.pointsSum | [] | +| VoteWeighting.changesSum | [] | +| VoteWeighting.timeSum | [] | ++----------------------------------+------------------+ +Function checkpoint() ++----------------------------------+--------------+ +| Variable | Dependencies | ++----------------------------------+--------------+ +| totalSum | [] | +| VoteWeighting.WEEK | [] | +| VoteWeighting.WEIGHT_VOTE_DELAY | [] | +| VoteWeighting.MAX_NUM_WEEKS | [] | +| VoteWeighting.MAX_WEIGHT | [] | +| VoteWeighting.MAX_EVM_CHAIN_ID | [] | +| VoteWeighting.ve | [] | +| VoteWeighting.owner | [] | +| VoteWeighting.dispenser | [] | +| VoteWeighting.setNominees | [] | +| VoteWeighting.setRemovedNominees | [] | +| VoteWeighting.mapNomineeIds | [] | +| VoteWeighting.mapRemovedNominees | [] | +| VoteWeighting.voteUserSlopes | [] | +| VoteWeighting.voteUserPower | [] | +| VoteWeighting.lastUserVote | [] | +| VoteWeighting.pointsWeight | [] | +| VoteWeighting.changesWeight | [] | +| VoteWeighting.timeWeight | [] | +| VoteWeighting.pointsSum | [] | +| VoteWeighting.changesSum | [] | +| VoteWeighting.timeSum | [] | ++----------------------------------+--------------+ +Function checkpointNominee(bytes32,uint256) ++----------------------------------+--------------+ +| Variable | Dependencies | ++----------------------------------+--------------+ +| account | [] | +| chainId | [] | +| nomineeWeight | [] | +| totalSum | [] | +| VoteWeighting.WEEK | [] | +| VoteWeighting.WEIGHT_VOTE_DELAY | [] | +| VoteWeighting.MAX_NUM_WEEKS | [] | +| VoteWeighting.MAX_WEIGHT | [] | +| VoteWeighting.MAX_EVM_CHAIN_ID | [] | +| VoteWeighting.ve | [] | +| VoteWeighting.owner | [] | +| VoteWeighting.dispenser | [] | +| VoteWeighting.setNominees | [] | +| VoteWeighting.setRemovedNominees | [] | +| VoteWeighting.mapNomineeIds | [] | +| VoteWeighting.mapRemovedNominees | [] | +| VoteWeighting.voteUserSlopes | [] | +| VoteWeighting.voteUserPower | [] | +| VoteWeighting.lastUserVote | [] | +| VoteWeighting.pointsWeight | [] | +| VoteWeighting.changesWeight | [] | +| VoteWeighting.timeWeight | [] | +| VoteWeighting.pointsSum | [] | +| VoteWeighting.changesSum | [] | +| VoteWeighting.timeSum | [] | ++----------------------------------+--------------+ +Function _nomineeRelativeWeight(bytes32,uint256,uint256) ++----------------------------------+------------------------------------------------------------+ +| Variable | Dependencies | ++----------------------------------+------------------------------------------------------------+ +| account | ['account'] | +| chainId | ['chainId'] | +| time | ['time'] | +| weight | ['nomineeWeight', 'pointsSum', 'pointsWeight', 'totalSum'] | +| totalSum | ['pointsSum'] | +| t | ['WEEK', 'time'] | +| nominee | ['account', 'chainId'] | +| nomineeHash | ['account', 'chainId', 'nominee'] | +| nomineeWeight | ['pointsWeight'] | +| VoteWeighting.WEEK | ['WEEK'] | +| VoteWeighting.WEIGHT_VOTE_DELAY | [] | +| VoteWeighting.MAX_NUM_WEEKS | [] | +| VoteWeighting.MAX_WEIGHT | [] | +| VoteWeighting.MAX_EVM_CHAIN_ID | [] | +| VoteWeighting.ve | [] | +| VoteWeighting.owner | [] | +| VoteWeighting.dispenser | [] | +| VoteWeighting.setNominees | [] | +| VoteWeighting.setRemovedNominees | [] | +| VoteWeighting.mapNomineeIds | [] | +| VoteWeighting.mapRemovedNominees | [] | +| VoteWeighting.voteUserSlopes | [] | +| VoteWeighting.voteUserPower | [] | +| VoteWeighting.lastUserVote | [] | +| VoteWeighting.pointsWeight | ['pointsWeight'] | +| VoteWeighting.changesWeight | [] | +| VoteWeighting.timeWeight | [] | +| VoteWeighting.pointsSum | ['pointsSum'] | +| VoteWeighting.changesSum | [] | +| VoteWeighting.timeSum | [] | ++----------------------------------+------------------------------------------------------------+ +Function nomineeRelativeWeight(bytes32,uint256,uint256) ++----------------------------------+--------------+ +| Variable | Dependencies | ++----------------------------------+--------------+ +| account | [] | +| chainId | [] | +| time | [] | +| relativeWeight | ['TUPLE_0'] | +| totalSum | ['TUPLE_0'] | +| VoteWeighting.WEEK | [] | +| VoteWeighting.WEIGHT_VOTE_DELAY | [] | +| VoteWeighting.MAX_NUM_WEEKS | [] | +| VoteWeighting.MAX_WEIGHT | [] | +| VoteWeighting.MAX_EVM_CHAIN_ID | [] | +| VoteWeighting.ve | [] | +| VoteWeighting.owner | [] | +| VoteWeighting.dispenser | [] | +| VoteWeighting.setNominees | [] | +| VoteWeighting.setRemovedNominees | [] | +| VoteWeighting.mapNomineeIds | [] | +| VoteWeighting.mapRemovedNominees | [] | +| VoteWeighting.voteUserSlopes | [] | +| VoteWeighting.voteUserPower | [] | +| VoteWeighting.lastUserVote | [] | +| VoteWeighting.pointsWeight | [] | +| VoteWeighting.changesWeight | [] | +| VoteWeighting.timeWeight | [] | +| VoteWeighting.pointsSum | [] | +| VoteWeighting.changesSum | [] | +| VoteWeighting.timeSum | [] | ++----------------------------------+--------------+ +Function nomineeRelativeWeightWrite(bytes32,uint256,uint256) ++----------------------------------+--------------+ +| Variable | Dependencies | ++----------------------------------+--------------+ +| account | [] | +| chainId | [] | +| time | [] | +| relativeWeight | ['TUPLE_1'] | +| totalSum | ['TUPLE_1'] | +| nomineeWeight | [] | +| VoteWeighting.WEEK | [] | +| VoteWeighting.WEIGHT_VOTE_DELAY | [] | +| VoteWeighting.MAX_NUM_WEEKS | [] | +| VoteWeighting.MAX_WEIGHT | [] | +| VoteWeighting.MAX_EVM_CHAIN_ID | [] | +| VoteWeighting.ve | [] | +| VoteWeighting.owner | [] | +| VoteWeighting.dispenser | [] | +| VoteWeighting.setNominees | [] | +| VoteWeighting.setRemovedNominees | [] | +| VoteWeighting.mapNomineeIds | [] | +| VoteWeighting.mapRemovedNominees | [] | +| VoteWeighting.voteUserSlopes | [] | +| VoteWeighting.voteUserPower | [] | +| VoteWeighting.lastUserVote | [] | +| VoteWeighting.pointsWeight | [] | +| VoteWeighting.changesWeight | [] | +| VoteWeighting.timeWeight | [] | +| VoteWeighting.pointsSum | [] | +| VoteWeighting.changesSum | [] | +| VoteWeighting.timeSum | [] | ++----------------------------------+--------------+ +Function voteForNomineeWeights(bytes32,uint256,uint256) ++----------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------+ +| Variable | Dependencies | ++----------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------+ +| account | [] | +| chainId | [] | +| weight | [] | +| nomineeHash | ['account', 'chainId'] | +| userSlope | ['msg.sender', 've'] | +| lockEnd | ['msg.sender', 've'] | +| nextTime | ['WEEK', 'block.timestamp'] | +| nextAllowedVotingTime | ['WEIGHT_VOTE_DELAY', 'lastUserVote'] | +| oldSlope | ['oldSlope', 'voteUserSlopes'] | +| oldBias | ['WEEK', 'block.timestamp', 'nextTime', 'oldBias', 'oldSlope', 'voteUserSlopes'] | +| newSlope | ['MAX_WEIGHT', 'lockEnd', 'msg.sender', 'newSlope', 'userSlope', 've', 'weight'] | +| newBias | ['MAX_WEIGHT', 'WEEK', 'block.timestamp', 'lockEnd', 'msg.sender', 'newSlope', 'nextTime', 'userSlope', 've', 'weight'] | +| powerUsed | ['MAX_WEIGHT', 'lockEnd', 'msg.sender', 'newSlope', 'oldSlope', 'powerUsed', 'userSlope', 've', 'voteUserPower', 'voteUserSlopes', 'weight'] | +| VoteWeighting.WEEK | ['WEEK'] | +| VoteWeighting.WEIGHT_VOTE_DELAY | ['WEIGHT_VOTE_DELAY'] | +| VoteWeighting.MAX_NUM_WEEKS | [] | +| VoteWeighting.MAX_WEIGHT | ['MAX_WEIGHT'] | +| VoteWeighting.MAX_EVM_CHAIN_ID | [] | +| VoteWeighting.ve | ['ve'] | +| VoteWeighting.owner | [] | +| VoteWeighting.dispenser | [] | +| VoteWeighting.setNominees | [] | +| VoteWeighting.setRemovedNominees | [] | +| VoteWeighting.mapNomineeIds | [] | +| VoteWeighting.mapRemovedNominees | ['mapRemovedNominees'] | +| VoteWeighting.voteUserSlopes | ['voteUserSlopes'] | +| VoteWeighting.voteUserPower | ['MAX_WEIGHT', 'lockEnd', 'msg.sender', 'newSlope', 'oldSlope', 'powerUsed', 'userSlope', 've', 'voteUserPower', 'voteUserSlopes', 'weight'] | +| VoteWeighting.lastUserVote | ['lastUserVote'] | +| VoteWeighting.pointsWeight | ['pointsWeight'] | +| VoteWeighting.changesWeight | ['changesWeight'] | +| VoteWeighting.timeWeight | [] | +| VoteWeighting.pointsSum | ['pointsSum'] | +| VoteWeighting.changesSum | ['MAX_WEIGHT', 'changesSum', 'lockEnd', 'msg.sender', 'newSlope', 'oldSlope', 'userSlope', 've', 'voteUserSlopes', 'weight'] | +| VoteWeighting.timeSum | [] | ++----------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------+ +Function voteForNomineeWeightsBatch(bytes32[],uint256[],uint256[]) ++----------------------------------+--------------+ +| Variable | Dependencies | ++----------------------------------+--------------+ +| accounts | ['accounts'] | +| chainIds | ['chainIds'] | +| weights | ['weights'] | +| i | ['i'] | +| VoteWeighting.WEEK | [] | +| VoteWeighting.WEIGHT_VOTE_DELAY | [] | +| VoteWeighting.MAX_NUM_WEEKS | [] | +| VoteWeighting.MAX_WEIGHT | [] | +| VoteWeighting.MAX_EVM_CHAIN_ID | [] | +| VoteWeighting.ve | [] | +| VoteWeighting.owner | [] | +| VoteWeighting.dispenser | [] | +| VoteWeighting.setNominees | [] | +| VoteWeighting.setRemovedNominees | [] | +| VoteWeighting.mapNomineeIds | [] | +| VoteWeighting.mapRemovedNominees | [] | +| VoteWeighting.voteUserSlopes | [] | +| VoteWeighting.voteUserPower | [] | +| VoteWeighting.lastUserVote | [] | +| VoteWeighting.pointsWeight | [] | +| VoteWeighting.changesWeight | [] | +| VoteWeighting.timeWeight | [] | +| VoteWeighting.pointsSum | [] | +| VoteWeighting.changesSum | [] | +| VoteWeighting.timeSum | [] | ++----------------------------------+--------------+ +Function _maxAndSub(uint256,uint256) ++----------------------------------+--------------+ +| Variable | Dependencies | ++----------------------------------+--------------+ +| a | [] | +| b | ['oldBias'] | +| | [] | +| VoteWeighting.WEEK | [] | +| VoteWeighting.WEIGHT_VOTE_DELAY | [] | +| VoteWeighting.MAX_NUM_WEEKS | [] | +| VoteWeighting.MAX_WEIGHT | [] | +| VoteWeighting.MAX_EVM_CHAIN_ID | [] | +| VoteWeighting.ve | [] | +| VoteWeighting.owner | [] | +| VoteWeighting.dispenser | [] | +| VoteWeighting.setNominees | [] | +| VoteWeighting.setRemovedNominees | [] | +| VoteWeighting.mapNomineeIds | [] | +| VoteWeighting.mapRemovedNominees | [] | +| VoteWeighting.voteUserSlopes | [] | +| VoteWeighting.voteUserPower | [] | +| VoteWeighting.lastUserVote | [] | +| VoteWeighting.pointsWeight | [] | +| VoteWeighting.changesWeight | [] | +| VoteWeighting.timeWeight | [] | +| VoteWeighting.pointsSum | [] | +| VoteWeighting.changesSum | [] | +| VoteWeighting.timeSum | [] | ++----------------------------------+--------------+ +Function removeNominee(bytes32,uint256) ++----------------------------------+---------------------------------------------------------+ +| Variable | Dependencies | ++----------------------------------+---------------------------------------------------------+ +| account | [] | +| chainId | [] | +| nominee | ['account', 'chainId', 'setNominees'] | +| nomineeHash | ['account', 'chainId', 'nominee'] | +| id | ['mapNomineeIds'] | +| oldWeight | [] | +| oldSum | [] | +| nextTime | ['WEEK', 'block.timestamp'] | +| newSum | ['oldSum', 'oldWeight'] | +| replacedNomineeHash | ['nominee', 'setNominees'] | +| localDispenser | ['dispenser'] | +| VoteWeighting.WEEK | ['WEEK'] | +| VoteWeighting.WEIGHT_VOTE_DELAY | [] | +| VoteWeighting.MAX_NUM_WEEKS | [] | +| VoteWeighting.MAX_WEIGHT | [] | +| VoteWeighting.MAX_EVM_CHAIN_ID | [] | +| VoteWeighting.ve | [] | +| VoteWeighting.owner | ['owner'] | +| VoteWeighting.dispenser | ['dispenser'] | +| VoteWeighting.setNominees | ['nominee', 'setNominees'] | +| VoteWeighting.setRemovedNominees | ['account', 'chainId', 'nominee', 'setRemovedNominees'] | +| VoteWeighting.mapNomineeIds | ['id', 'mapNomineeIds'] | +| VoteWeighting.mapRemovedNominees | ['mapRemovedNominees', 'setRemovedNominees'] | +| VoteWeighting.voteUserSlopes | [] | +| VoteWeighting.voteUserPower | [] | +| VoteWeighting.lastUserVote | [] | +| VoteWeighting.pointsWeight | ['pointsWeight'] | +| VoteWeighting.changesWeight | [] | +| VoteWeighting.timeWeight | ['WEEK', 'block.timestamp', 'nextTime', 'timeWeight'] | +| VoteWeighting.pointsSum | ['pointsSum'] | +| VoteWeighting.changesSum | [] | +| VoteWeighting.timeSum | ['WEEK', 'block.timestamp', 'nextTime'] | ++----------------------------------+---------------------------------------------------------+ +Function retrieveRemovedNomineeVotingPower(bytes32,uint256) ++----------------------------------+--------------------------------------------------------------+ +| Variable | Dependencies | ++----------------------------------+--------------------------------------------------------------+ +| account | [] | +| chainId | [] | +| nominee | ['account', 'chainId'] | +| nomineeHash | ['account', 'chainId', 'nominee'] | +| oldSlope | ['oldSlope', 'voteUserSlopes'] | +| powerUsed | ['oldSlope', 'powerUsed', 'voteUserPower', 'voteUserSlopes'] | +| VoteWeighting.WEEK | [] | +| VoteWeighting.WEIGHT_VOTE_DELAY | [] | +| VoteWeighting.MAX_NUM_WEEKS | [] | +| VoteWeighting.MAX_WEIGHT | [] | +| VoteWeighting.MAX_EVM_CHAIN_ID | [] | +| VoteWeighting.ve | [] | +| VoteWeighting.owner | [] | +| VoteWeighting.dispenser | [] | +| VoteWeighting.setNominees | [] | +| VoteWeighting.setRemovedNominees | [] | +| VoteWeighting.mapNomineeIds | [] | +| VoteWeighting.mapRemovedNominees | ['mapRemovedNominees'] | +| VoteWeighting.voteUserSlopes | ['voteUserSlopes'] | +| VoteWeighting.voteUserPower | ['oldSlope', 'powerUsed', 'voteUserPower', 'voteUserSlopes'] | +| VoteWeighting.lastUserVote | [] | +| VoteWeighting.pointsWeight | [] | +| VoteWeighting.changesWeight | ['changesWeight'] | +| VoteWeighting.timeWeight | [] | +| VoteWeighting.pointsSum | [] | +| VoteWeighting.changesSum | ['changesSum', 'oldSlope', 'voteUserSlopes'] | +| VoteWeighting.timeSum | [] | ++----------------------------------+--------------------------------------------------------------+ +Function getNomineeWeight(bytes32,uint256) ++----------------------------------+-----------------------------------+ +| Variable | Dependencies | ++----------------------------------+-----------------------------------+ +| account | [] | +| chainId | [] | +| | [] | +| nominee | ['account', 'chainId'] | +| nomineeHash | ['account', 'chainId', 'nominee'] | +| VoteWeighting.WEEK | [] | +| VoteWeighting.WEIGHT_VOTE_DELAY | [] | +| VoteWeighting.MAX_NUM_WEEKS | [] | +| VoteWeighting.MAX_WEIGHT | [] | +| VoteWeighting.MAX_EVM_CHAIN_ID | [] | +| VoteWeighting.ve | [] | +| VoteWeighting.owner | [] | +| VoteWeighting.dispenser | [] | +| VoteWeighting.setNominees | [] | +| VoteWeighting.setRemovedNominees | [] | +| VoteWeighting.mapNomineeIds | [] | +| VoteWeighting.mapRemovedNominees | [] | +| VoteWeighting.voteUserSlopes | [] | +| VoteWeighting.voteUserPower | [] | +| VoteWeighting.lastUserVote | [] | +| VoteWeighting.pointsWeight | ['pointsWeight'] | +| VoteWeighting.changesWeight | [] | +| VoteWeighting.timeWeight | ['timeWeight'] | +| VoteWeighting.pointsSum | [] | +| VoteWeighting.changesSum | [] | +| VoteWeighting.timeSum | [] | ++----------------------------------+-----------------------------------+ +Function getWeightsSum() ++----------------------------------+---------------+ +| Variable | Dependencies | ++----------------------------------+---------------+ +| | [] | +| VoteWeighting.WEEK | [] | +| VoteWeighting.WEIGHT_VOTE_DELAY | [] | +| VoteWeighting.MAX_NUM_WEEKS | [] | +| VoteWeighting.MAX_WEIGHT | [] | +| VoteWeighting.MAX_EVM_CHAIN_ID | [] | +| VoteWeighting.ve | [] | +| VoteWeighting.owner | [] | +| VoteWeighting.dispenser | [] | +| VoteWeighting.setNominees | [] | +| VoteWeighting.setRemovedNominees | [] | +| VoteWeighting.mapNomineeIds | [] | +| VoteWeighting.mapRemovedNominees | [] | +| VoteWeighting.voteUserSlopes | [] | +| VoteWeighting.voteUserPower | [] | +| VoteWeighting.lastUserVote | [] | +| VoteWeighting.pointsWeight | [] | +| VoteWeighting.changesWeight | [] | +| VoteWeighting.timeWeight | [] | +| VoteWeighting.pointsSum | ['pointsSum'] | +| VoteWeighting.changesSum | [] | +| VoteWeighting.timeSum | ['timeSum'] | ++----------------------------------+---------------+ +Function getNumNominees() ++----------------------------------+-----------------+ +| Variable | Dependencies | ++----------------------------------+-----------------+ +| | [] | +| VoteWeighting.WEEK | [] | +| VoteWeighting.WEIGHT_VOTE_DELAY | [] | +| VoteWeighting.MAX_NUM_WEEKS | [] | +| VoteWeighting.MAX_WEIGHT | [] | +| VoteWeighting.MAX_EVM_CHAIN_ID | [] | +| VoteWeighting.ve | [] | +| VoteWeighting.owner | [] | +| VoteWeighting.dispenser | [] | +| VoteWeighting.setNominees | ['setNominees'] | +| VoteWeighting.setRemovedNominees | [] | +| VoteWeighting.mapNomineeIds | [] | +| VoteWeighting.mapRemovedNominees | [] | +| VoteWeighting.voteUserSlopes | [] | +| VoteWeighting.voteUserPower | [] | +| VoteWeighting.lastUserVote | [] | +| VoteWeighting.pointsWeight | [] | +| VoteWeighting.changesWeight | [] | +| VoteWeighting.timeWeight | [] | +| VoteWeighting.pointsSum | [] | +| VoteWeighting.changesSum | [] | +| VoteWeighting.timeSum | [] | ++----------------------------------+-----------------+ +Function getNumRemovedNominees() ++----------------------------------+------------------------+ +| Variable | Dependencies | ++----------------------------------+------------------------+ +| | [] | +| VoteWeighting.WEEK | [] | +| VoteWeighting.WEIGHT_VOTE_DELAY | [] | +| VoteWeighting.MAX_NUM_WEEKS | [] | +| VoteWeighting.MAX_WEIGHT | [] | +| VoteWeighting.MAX_EVM_CHAIN_ID | [] | +| VoteWeighting.ve | [] | +| VoteWeighting.owner | [] | +| VoteWeighting.dispenser | [] | +| VoteWeighting.setNominees | [] | +| VoteWeighting.setRemovedNominees | ['setRemovedNominees'] | +| VoteWeighting.mapNomineeIds | [] | +| VoteWeighting.mapRemovedNominees | [] | +| VoteWeighting.voteUserSlopes | [] | +| VoteWeighting.voteUserPower | [] | +| VoteWeighting.lastUserVote | [] | +| VoteWeighting.pointsWeight | [] | +| VoteWeighting.changesWeight | [] | +| VoteWeighting.timeWeight | [] | +| VoteWeighting.pointsSum | [] | +| VoteWeighting.changesSum | [] | +| VoteWeighting.timeSum | [] | ++----------------------------------+------------------------+ +Function getAllNominees() ++----------------------------------+-----------------+ +| Variable | Dependencies | ++----------------------------------+-----------------+ +| | [] | +| VoteWeighting.WEEK | [] | +| VoteWeighting.WEIGHT_VOTE_DELAY | [] | +| VoteWeighting.MAX_NUM_WEEKS | [] | +| VoteWeighting.MAX_WEIGHT | [] | +| VoteWeighting.MAX_EVM_CHAIN_ID | [] | +| VoteWeighting.ve | [] | +| VoteWeighting.owner | [] | +| VoteWeighting.dispenser | [] | +| VoteWeighting.setNominees | ['setNominees'] | +| VoteWeighting.setRemovedNominees | [] | +| VoteWeighting.mapNomineeIds | [] | +| VoteWeighting.mapRemovedNominees | [] | +| VoteWeighting.voteUserSlopes | [] | +| VoteWeighting.voteUserPower | [] | +| VoteWeighting.lastUserVote | [] | +| VoteWeighting.pointsWeight | [] | +| VoteWeighting.changesWeight | [] | +| VoteWeighting.timeWeight | [] | +| VoteWeighting.pointsSum | [] | +| VoteWeighting.changesSum | [] | +| VoteWeighting.timeSum | [] | ++----------------------------------+-----------------+ +Function getAllRemovedNominees() ++----------------------------------+------------------------+ +| Variable | Dependencies | ++----------------------------------+------------------------+ +| | [] | +| VoteWeighting.WEEK | [] | +| VoteWeighting.WEIGHT_VOTE_DELAY | [] | +| VoteWeighting.MAX_NUM_WEEKS | [] | +| VoteWeighting.MAX_WEIGHT | [] | +| VoteWeighting.MAX_EVM_CHAIN_ID | [] | +| VoteWeighting.ve | [] | +| VoteWeighting.owner | [] | +| VoteWeighting.dispenser | [] | +| VoteWeighting.setNominees | [] | +| VoteWeighting.setRemovedNominees | ['setRemovedNominees'] | +| VoteWeighting.mapNomineeIds | [] | +| VoteWeighting.mapRemovedNominees | [] | +| VoteWeighting.voteUserSlopes | [] | +| VoteWeighting.voteUserPower | [] | +| VoteWeighting.lastUserVote | [] | +| VoteWeighting.pointsWeight | [] | +| VoteWeighting.changesWeight | [] | +| VoteWeighting.timeWeight | [] | +| VoteWeighting.pointsSum | [] | +| VoteWeighting.changesSum | [] | +| VoteWeighting.timeSum | [] | ++----------------------------------+------------------------+ +Function getNomineeId(bytes32,uint256) ++----------------------------------+-----------------------------------+ +| Variable | Dependencies | ++----------------------------------+-----------------------------------+ +| account | [] | +| chainId | [] | +| | [] | +| nominee | ['account', 'chainId'] | +| nomineeHash | ['account', 'chainId', 'nominee'] | +| VoteWeighting.WEEK | [] | +| VoteWeighting.WEIGHT_VOTE_DELAY | [] | +| VoteWeighting.MAX_NUM_WEEKS | [] | +| VoteWeighting.MAX_WEIGHT | [] | +| VoteWeighting.MAX_EVM_CHAIN_ID | [] | +| VoteWeighting.ve | [] | +| VoteWeighting.owner | [] | +| VoteWeighting.dispenser | [] | +| VoteWeighting.setNominees | [] | +| VoteWeighting.setRemovedNominees | [] | +| VoteWeighting.mapNomineeIds | ['mapNomineeIds'] | +| VoteWeighting.mapRemovedNominees | [] | +| VoteWeighting.voteUserSlopes | [] | +| VoteWeighting.voteUserPower | [] | +| VoteWeighting.lastUserVote | [] | +| VoteWeighting.pointsWeight | [] | +| VoteWeighting.changesWeight | [] | +| VoteWeighting.timeWeight | [] | +| VoteWeighting.pointsSum | [] | +| VoteWeighting.changesSum | [] | +| VoteWeighting.timeSum | [] | ++----------------------------------+-----------------------------------+ +Function getRemovedNomineeId(bytes32,uint256) ++----------------------------------+-----------------------------------+ +| Variable | Dependencies | ++----------------------------------+-----------------------------------+ +| account | [] | +| chainId | [] | +| | [] | +| nominee | ['account', 'chainId'] | +| nomineeHash | ['account', 'chainId', 'nominee'] | +| VoteWeighting.WEEK | [] | +| VoteWeighting.WEIGHT_VOTE_DELAY | [] | +| VoteWeighting.MAX_NUM_WEEKS | [] | +| VoteWeighting.MAX_WEIGHT | [] | +| VoteWeighting.MAX_EVM_CHAIN_ID | [] | +| VoteWeighting.ve | [] | +| VoteWeighting.owner | [] | +| VoteWeighting.dispenser | [] | +| VoteWeighting.setNominees | [] | +| VoteWeighting.setRemovedNominees | [] | +| VoteWeighting.mapNomineeIds | [] | +| VoteWeighting.mapRemovedNominees | ['mapRemovedNominees'] | +| VoteWeighting.voteUserSlopes | [] | +| VoteWeighting.voteUserPower | [] | +| VoteWeighting.lastUserVote | [] | +| VoteWeighting.pointsWeight | [] | +| VoteWeighting.changesWeight | [] | +| VoteWeighting.timeWeight | [] | +| VoteWeighting.pointsSum | [] | +| VoteWeighting.changesSum | [] | +| VoteWeighting.timeSum | [] | ++----------------------------------+-----------------------------------+ +Function getNominee(uint256) ++----------------------------------+-----------------+ +| Variable | Dependencies | ++----------------------------------+-----------------+ +| id | [] | +| | [] | +| totalNumNominees | ['setNominees'] | +| VoteWeighting.WEEK | [] | +| VoteWeighting.WEIGHT_VOTE_DELAY | [] | +| VoteWeighting.MAX_NUM_WEEKS | [] | +| VoteWeighting.MAX_WEIGHT | [] | +| VoteWeighting.MAX_EVM_CHAIN_ID | [] | +| VoteWeighting.ve | [] | +| VoteWeighting.owner | [] | +| VoteWeighting.dispenser | [] | +| VoteWeighting.setNominees | ['setNominees'] | +| VoteWeighting.setRemovedNominees | [] | +| VoteWeighting.mapNomineeIds | [] | +| VoteWeighting.mapRemovedNominees | [] | +| VoteWeighting.voteUserSlopes | [] | +| VoteWeighting.voteUserPower | [] | +| VoteWeighting.lastUserVote | [] | +| VoteWeighting.pointsWeight | [] | +| VoteWeighting.changesWeight | [] | +| VoteWeighting.timeWeight | [] | +| VoteWeighting.pointsSum | [] | +| VoteWeighting.changesSum | [] | +| VoteWeighting.timeSum | [] | ++----------------------------------+-----------------+ +Function getRemovedNominee(uint256) ++----------------------------------+------------------------+ +| Variable | Dependencies | ++----------------------------------+------------------------+ +| id | [] | +| | [] | +| totalNumRemovedNominees | ['setRemovedNominees'] | +| VoteWeighting.WEEK | [] | +| VoteWeighting.WEIGHT_VOTE_DELAY | [] | +| VoteWeighting.MAX_NUM_WEEKS | [] | +| VoteWeighting.MAX_WEIGHT | [] | +| VoteWeighting.MAX_EVM_CHAIN_ID | [] | +| VoteWeighting.ve | [] | +| VoteWeighting.owner | [] | +| VoteWeighting.dispenser | [] | +| VoteWeighting.setNominees | [] | +| VoteWeighting.setRemovedNominees | ['setRemovedNominees'] | +| VoteWeighting.mapNomineeIds | [] | +| VoteWeighting.mapRemovedNominees | [] | +| VoteWeighting.voteUserSlopes | [] | +| VoteWeighting.voteUserPower | [] | +| VoteWeighting.lastUserVote | [] | +| VoteWeighting.pointsWeight | [] | +| VoteWeighting.changesWeight | [] | +| VoteWeighting.timeWeight | [] | +| VoteWeighting.pointsSum | [] | +| VoteWeighting.changesSum | [] | +| VoteWeighting.timeSum | [] | ++----------------------------------+------------------------+ +Function getNextAllowedVotingTimes(bytes32[],uint256[],address[]) ++----------------------------------+-----------------------------------------------------------------------------+ +| Variable | Dependencies | ++----------------------------------+-----------------------------------------------------------------------------+ +| accounts | ['accounts'] | +| chainIds | ['chainIds'] | +| voters | ['voters'] | +| nextAllowedVotingTimes | ['WEIGHT_VOTE_DELAY', 'accounts', 'lastUserVote', 'nextAllowedVotingTimes'] | +| i | ['i'] | +| nominee | ['accounts', 'chainIds'] | +| nomineeHash | ['accounts', 'chainIds', 'nominee'] | +| VoteWeighting.WEEK | [] | +| VoteWeighting.WEIGHT_VOTE_DELAY | ['WEIGHT_VOTE_DELAY'] | +| VoteWeighting.MAX_NUM_WEEKS | [] | +| VoteWeighting.MAX_WEIGHT | [] | +| VoteWeighting.MAX_EVM_CHAIN_ID | [] | +| VoteWeighting.ve | [] | +| VoteWeighting.owner | [] | +| VoteWeighting.dispenser | [] | +| VoteWeighting.setNominees | [] | +| VoteWeighting.setRemovedNominees | [] | +| VoteWeighting.mapNomineeIds | ['mapNomineeIds'] | +| VoteWeighting.mapRemovedNominees | [] | +| VoteWeighting.voteUserSlopes | [] | +| VoteWeighting.voteUserPower | [] | +| VoteWeighting.lastUserVote | ['lastUserVote'] | +| VoteWeighting.pointsWeight | [] | +| VoteWeighting.changesWeight | [] | +| VoteWeighting.timeWeight | [] | +| VoteWeighting.pointsSum | [] | +| VoteWeighting.changesSum | [] | +| VoteWeighting.timeSum | [] | ++----------------------------------+-----------------------------------------------------------------------------+ +Function slitherConstructorConstantVariables() ++----------------------------------+--------------+ +| Variable | Dependencies | ++----------------------------------+--------------+ +| VoteWeighting.WEEK | [] | +| VoteWeighting.WEIGHT_VOTE_DELAY | [] | +| VoteWeighting.MAX_NUM_WEEKS | [] | +| VoteWeighting.MAX_WEIGHT | [] | +| VoteWeighting.MAX_EVM_CHAIN_ID | [] | +| VoteWeighting.ve | [] | +| VoteWeighting.owner | [] | +| VoteWeighting.dispenser | [] | +| VoteWeighting.setNominees | [] | +| VoteWeighting.setRemovedNominees | [] | +| VoteWeighting.mapNomineeIds | [] | +| VoteWeighting.mapRemovedNominees | [] | +| VoteWeighting.voteUserSlopes | [] | +| VoteWeighting.voteUserPower | [] | +| VoteWeighting.lastUserVote | [] | +| VoteWeighting.pointsWeight | [] | +| VoteWeighting.changesWeight | [] | +| VoteWeighting.timeWeight | [] | +| VoteWeighting.pointsSum | [] | +| VoteWeighting.changesSum | [] | +| VoteWeighting.timeSum | [] | ++----------------------------------+--------------+ +INFO:Slither:. analyzed (3 contracts) diff --git a/audits/internal12/analysis2/slither_full.txt b/audits/internal12/analysis2/slither_full.txt new file mode 100644 index 0000000..038ecb1 --- /dev/null +++ b/audits/internal12/analysis2/slither_full.txt @@ -0,0 +1,78 @@ +'solc --version' running +'solc ./VoteWeighting-flatten.sol --combined-json abi,ast,bin,bin-runtime,srcmap,srcmap-runtime,userdoc,devdoc,hashes --allow-paths .,/home/andrey/valory/autonolas-governance/audits/internal12/analysis2/contracts' running +INFO:Detectors: +VoteWeighting.constructor(address) (VoteWeighting-flatten.sol#207-221) performs a multiplication on the result of a division: + - timeSum = block.timestamp / WEEK * WEEK (VoteWeighting-flatten.sol#216) +VoteWeighting._addNominee(Nominee) (VoteWeighting-flatten.sol#294-321) performs a multiplication on the result of a division: + - nextTime = (block.timestamp + WEEK) / WEEK * WEEK (VoteWeighting-flatten.sol#311) +VoteWeighting._nomineeRelativeWeight(bytes32,uint256,uint256) (VoteWeighting-flatten.sol#421-436) performs a multiplication on the result of a division: + - t = time / WEEK * WEEK (VoteWeighting-flatten.sol#426) +VoteWeighting.voteForNomineeWeights(bytes32,uint256,uint256) (VoteWeighting-flatten.sol#475-559) performs a multiplication on the result of a division: + - nextTime = (block.timestamp + WEEK) / WEEK * WEEK (VoteWeighting-flatten.sol#491) +VoteWeighting.removeNominee(bytes32,uint256) (VoteWeighting-flatten.sol#588-638) performs a multiplication on the result of a division: + - nextTime = (block.timestamp + WEEK) / WEEK * WEEK (VoteWeighting-flatten.sol#607) +Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#divide-before-multiply +INFO:Detectors: +VoteWeighting.voteForNomineeWeights(bytes32,uint256,uint256).oldBias (VoteWeighting-flatten.sol#511) is a local variable never initialized +Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#uninitialized-local-variables +INFO:Detectors: +Dubious typecast in VoteWeighting.voteForNomineeWeights(bytes32,uint256,uint256) (VoteWeighting-flatten.sol#475-559): + int128 => uint128 casting occurs in newSlope = VotedSlope(uint256(uint128(userSlope)) * weight / MAX_WEIGHT,lockEnd,weight) (VoteWeighting-flatten.sol#516-520) +Reference: https://github.com/pessimistic-io/slitherin/blob/master/docs/dubious_typecast.md +INFO:Detectors: +VoteWeighting.changeDispenser(address).newDispenser (VoteWeighting-flatten.sol#388) lacks a zero-check on : + - dispenser = newDispenser (VoteWeighting-flatten.sol#394) +Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#missing-zero-address-validation +INFO:Detectors: +VoteWeighting.voteForNomineeWeights(bytes32,uint256,uint256) (VoteWeighting-flatten.sol#475-559) has external calls inside a loop: userSlope = IVEOLAS(ve).getLastUserPoint(msg.sender).slope (VoteWeighting-flatten.sol#485) +VoteWeighting.voteForNomineeWeights(bytes32,uint256,uint256) (VoteWeighting-flatten.sol#475-559) has external calls inside a loop: lockEnd = IVEOLAS(ve).lockedEnd(msg.sender) (VoteWeighting-flatten.sol#490) +Reference: https://github.com/crytic/slither/wiki/Detector-Documentation/#calls-inside-a-loop +INFO:Detectors: +Reentrancy in VoteWeighting._addNominee(Nominee) (VoteWeighting-flatten.sol#294-321): + External calls: + - IDispenser(localDispenser).addNominee(nomineeHash) (VoteWeighting-flatten.sol#317) + Event emitted after the call(s): + - AddNominee(nominee.account,nominee.chainId,id) (VoteWeighting-flatten.sol#320) +Reentrancy in VoteWeighting.removeNominee(bytes32,uint256) (VoteWeighting-flatten.sol#588-638): + External calls: + - IDispenser(localDispenser).removeNominee(nomineeHash) (VoteWeighting-flatten.sol#634) + Event emitted after the call(s): + - RemoveNominee(account,chainId,newSum) (VoteWeighting-flatten.sol#637) +Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#reentrancy-vulnerabilities-3 +INFO:Detectors: +VoteWeighting._getSum() (VoteWeighting-flatten.sol#225-250) uses timestamp for comparisons + Dangerous comparisons: + - t > block.timestamp (VoteWeighting-flatten.sol#230) + - t > block.timestamp (VoteWeighting-flatten.sol#245) +VoteWeighting._getWeight(bytes32,uint256) (VoteWeighting-flatten.sol#256-290) uses timestamp for comparisons + Dangerous comparisons: + - t > block.timestamp (VoteWeighting-flatten.sol#270) + - t > block.timestamp (VoteWeighting-flatten.sol#285) +VoteWeighting.voteForNomineeWeights(bytes32,uint256,uint256) (VoteWeighting-flatten.sol#475-559) uses timestamp for comparisons + Dangerous comparisons: + - nextTime >= lockEnd (VoteWeighting-flatten.sol#494) + - nextAllowedVotingTime > block.timestamp (VoteWeighting-flatten.sol#505) + - oldSlope.end > nextTime (VoteWeighting-flatten.sol#512) + - oldSlope.end > nextTime (VoteWeighting-flatten.sol#536) + - oldSlope.end > block.timestamp (VoteWeighting-flatten.sol#544) +VoteWeighting._maxAndSub(uint256,uint256) (VoteWeighting-flatten.sol#580-582) uses timestamp for comparisons + Dangerous comparisons: + - a > b (VoteWeighting-flatten.sol#581) +VoteWeighting.retrieveRemovedNomineeVotingPower(bytes32,uint256) (VoteWeighting-flatten.sol#643-670) uses timestamp for comparisons + Dangerous comparisons: + - oldSlope.end > block.timestamp (VoteWeighting-flatten.sol#660) +Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#block-timestamp +INFO:Detectors: +VoteWeighting._getSum() (VoteWeighting-flatten.sol#225-250) has costly operations inside a loop: + - timeSum = t (VoteWeighting-flatten.sol#246) +Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#costly-operations-inside-a-loop +INFO:Detectors: +Pragma version^0.8.25 (VoteWeighting-flatten.sol#4) necessitates a version too recent to be trusted. Consider deploying with 0.8.18. +solc-0.8.25 is not recommended for deployment +Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#incorrect-versions-of-solidity +INFO:Detectors: +In a function VoteWeighting.voteForNomineeWeights(bytes32,uint256,uint256) (VoteWeighting-flatten.sol#475-559) variable VoteWeighting.MAX_WEIGHT (VoteWeighting-flatten.sol#159) is read multiple times +In a function VoteWeighting.voteForNomineeWeights(bytes32,uint256,uint256) (VoteWeighting-flatten.sol#475-559) variable VoteWeighting.pointsSum (VoteWeighting-flatten.sol#199) is read multiple times +In a function VoteWeighting.voteForNomineeWeights(bytes32,uint256,uint256) (VoteWeighting-flatten.sol#475-559) variable VoteWeighting.pointsWeight (VoteWeighting-flatten.sol#192) is read multiple times +Reference: https://github.com/pessimistic-io/slitherin/blob/master/docs/multiple_storage_read.md +INFO:Slither:. analyzed (3 contracts with 108 detectors), 23 result(s) found diff --git a/audits/internal12/analysis2/slither_function-summary.txt b/audits/internal12/analysis2/slither_function-summary.txt new file mode 100644 index 0000000..8438e87 --- /dev/null +++ b/audits/internal12/analysis2/slither_function-summary.txt @@ -0,0 +1,111 @@ +'solc --version' running +'solc ./VoteWeighting-flatten.sol --combined-json abi,ast,bin,bin-runtime,srcmap,srcmap-runtime,userdoc,devdoc,hashes --allow-paths .,/home/andrey/valory/autonolas-governance/audits/internal12/analysis2/contracts' running +INFO:Printers: +Contract IDispenser +Contract vars: [] +Inheritance:: [] + ++------------------------+------------+-----------+------+-------+----------------+----------------+-----------------------+ +| Function | Visibility | Modifiers | Read | Write | Internal Calls | External Calls | Cyclomatic Complexity | ++------------------------+------------+-----------+------+-------+----------------+----------------+-----------------------+ +| addNominee(bytes32) | external | [] | [] | [] | [] | [] | 2 | +| removeNominee(bytes32) | external | [] | [] | [] | [] | [] | 2 | ++------------------------+------------+-----------+------+-------+----------------+----------------+-----------------------+ + ++-----------+------------+------+-------+----------------+----------------+-----------------------+ +| Modifiers | Visibility | Read | Write | Internal Calls | External Calls | Cyclomatic Complexity | ++-----------+------------+------+-------+----------------+----------------+-----------------------+ ++-----------+------------+------+-------+----------------+----------------+-----------------------+ + +INFO:Printers: +Contract IVEOLAS +Contract vars: [] +Inheritance:: [] + ++---------------------------+------------+-----------+------+-------+----------------+----------------+-----------------------+ +| Function | Visibility | Modifiers | Read | Write | Internal Calls | External Calls | Cyclomatic Complexity | ++---------------------------+------------+-----------+------+-------+----------------+----------------+-----------------------+ +| lockedEnd(address) | external | [] | [] | [] | [] | [] | 2 | +| getLastUserPoint(address) | external | [] | [] | [] | [] | [] | 2 | ++---------------------------+------------+-----------+------+-------+----------------+----------------+-----------------------+ + ++-----------+------------+------+-------+----------------+----------------+-----------------------+ +| Modifiers | Visibility | Read | Write | Internal Calls | External Calls | Cyclomatic Complexity | ++-----------+------------+------+-------+----------------+----------------+-----------------------+ ++-----------+------------+------+-------+----------------+----------------+-----------------------+ + +INFO:Printers: +Contract VoteWeighting +Contract vars: ['WEEK', 'WEIGHT_VOTE_DELAY', 'MAX_NUM_WEEKS', 'MAX_WEIGHT', 'MAX_EVM_CHAIN_ID', 've', 'owner', 'dispenser', 'setNominees', 'setRemovedNominees', 'mapNomineeIds', 'mapRemovedNominees', 'voteUserSlopes', 'voteUserPower', 'lastUserVote', 'pointsWeight', 'changesWeight', 'timeWeight', 'pointsSum', 'changesSum', 'timeSum'] +Inheritance:: [] + ++-----------------------------------------------------------+------------+-----------+------------------------------------------+-----------------------------------------+---------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+-----------------------+ +| Function | Visibility | Modifiers | Read | Write | Internal Calls | External Calls | Cyclomatic Complexity | ++-----------------------------------------------------------+------------+-----------+------------------------------------------+-----------------------------------------+---------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+-----------------------+ +| constructor(address) | public | [] | ['WEEK', 'block.timestamp'] | ['owner', 'setNominees'] | ['revert ZeroAddress()'] | ['setNominees.push(Nominee(0,0))', 'setRemovedNominees.push(Nominee(0,0))'] | 2 | +| | | | ['msg.sender', 'setNominees'] | ['setRemovedNominees', 'timeSum'] | | | | +| | | | ['setRemovedNominees'] | ['ve'] | | | | +| _getSum() | internal | [] | ['MAX_NUM_WEEKS', 'WEEK'] | ['pointsSum', 'timeSum'] | [] | [] | 5 | +| | | | ['block.timestamp', 'changesSum'] | | | | | +| | | | ['pointsSum', 'timeSum'] | | | | | +| _getWeight(bytes32,uint256) | internal | [] | ['MAX_NUM_WEEKS', 'WEEK'] | ['pointsWeight', 'timeWeight'] | ['abi.encode()', 'keccak256(bytes)'] | ['abi.encode(nominee)'] | 6 | +| | | | ['block.timestamp', 'changesWeight'] | | ['revert NomineeDoesNotExist(bytes32,uint256)'] | | | +| | | | ['mapNomineeIds', 'mapRemovedNominees'] | | | | | +| | | | ['pointsWeight', 'timeWeight'] | | | | | +| _addNominee(Nominee) | internal | [] | ['WEEK', 'block.timestamp'] | ['mapNomineeIds', 'setNominees'] | ['abi.encode()', 'keccak256(bytes)'] | ['IDispenser(localDispenser).addNominee(nomineeHash)', 'abi.encode(nominee)'] | 4 | +| | | | ['dispenser', 'mapNomineeIds'] | ['timeWeight'] | ['revert NomineeAlreadyExists(bytes32,uint256)', 'revert NomineeRemoved(bytes32,uint256)'] | ['setNominees.push(nominee)'] | | +| | | | ['mapRemovedNominees', 'setNominees'] | | | | | +| addNomineeEVM(address,uint256) | external | [] | ['MAX_EVM_CHAIN_ID'] | [] | ['_addNominee', 'revert Overflow(uint256,uint256)'] | [] | 4 | +| | | | | | ['revert ZeroAddress()', 'revert ZeroValue()'] | | | +| addNomineeNonEVM(bytes32,uint256) | external | [] | ['MAX_EVM_CHAIN_ID'] | [] | ['_addNominee', 'revert Underflow(uint256,uint256)'] | [] | 3 | +| | | | | | ['revert ZeroAddress()'] | | | +| changeOwner(address) | external | [] | ['msg.sender', 'owner'] | ['owner'] | ['revert OwnerOnly(address,address)', 'revert ZeroAddress()'] | [] | 3 | +| changeDispenser(address) | external | [] | ['msg.sender', 'owner'] | ['dispenser'] | ['revert OwnerOnly(address,address)'] | [] | 2 | +| checkpoint() | external | [] | ['msg.sender'] | [] | ['_getSum'] | [] | 1 | +| checkpointNominee(bytes32,uint256) | external | [] | ['msg.sender'] | [] | ['_getSum', '_getWeight'] | [] | 1 | +| _nomineeRelativeWeight(bytes32,uint256,uint256) | internal | [] | ['WEEK', 'pointsSum'] | [] | ['abi.encode()', 'keccak256(bytes)'] | ['abi.encode(nominee)'] | 2 | +| | | | ['pointsWeight'] | | | | | +| nomineeRelativeWeight(bytes32,uint256,uint256) | external | [] | [] | [] | ['_nomineeRelativeWeight'] | [] | 1 | +| nomineeRelativeWeightWrite(bytes32,uint256,uint256) | external | [] | ['msg.sender'] | [] | ['_getSum', '_getWeight'] | [] | 1 | +| | | | | | ['_nomineeRelativeWeight'] | | | +| voteForNomineeWeights(bytes32,uint256,uint256) | public | [] | ['MAX_WEIGHT', 'WEEK'] | ['changesSum', 'changesWeight'] | ['_getSum', '_getWeight'] | ['IVEOLAS(ve).getLastUserPoint(msg.sender)', 'IVEOLAS(ve).lockedEnd(msg.sender)'] | 10 | +| | | | ['WEIGHT_VOTE_DELAY', 'block.timestamp'] | ['lastUserVote', 'pointsSum'] | ['_maxAndSub', 'abi.encode()'] | ['abi.encode(Nominee(account,chainId))'] | | +| | | | ['changesSum', 'changesWeight'] | ['pointsWeight', 'voteUserPower'] | ['keccak256(bytes)', 'revert LockExpired(address,uint256,uint256)'] | | | +| | | | ['lastUserVote', 'mapRemovedNominees'] | ['voteUserSlopes'] | ['revert NegativeSlope(address,int128)', 'revert NomineeRemoved(bytes32,uint256)'] | | | +| | | | ['msg.sender', 'pointsSum'] | | ['revert Overflow(uint256,uint256)', 'revert VoteTooOften(address,uint256,uint256)'] | | | +| | | | ['pointsWeight', 've'] | | | | | +| | | | ['voteUserPower', 'voteUserSlopes'] | | | | | +| voteForNomineeWeightsBatch(bytes32[],uint256[],uint256[]) | external | [] | [] | [] | ['revert WrongArrayLength(uint256,uint256)', 'voteForNomineeWeights'] | [] | 3 | +| _maxAndSub(uint256,uint256) | internal | [] | [] | [] | [] | [] | 1 | +| removeNominee(bytes32,uint256) | external | [] | ['WEEK', 'block.timestamp'] | ['mapNomineeIds', 'mapRemovedNominees'] | ['_getSum', '_getWeight'] | ['IDispenser(localDispenser).removeNominee(nomineeHash)', 'abi.encode(nominee)'] | 4 | +| | | | ['dispenser', 'mapNomineeIds'] | ['pointsSum', 'pointsWeight'] | ['abi.encode()', 'keccak256(bytes)'] | ['abi.encode(nominee)', 'setNominees.pop()'] | | +| | | | ['msg.sender', 'owner'] | ['setNominees', 'setRemovedNominees'] | ['revert NomineeDoesNotExist(bytes32,uint256)', 'revert OwnerOnly(address,address)'] | ['setRemovedNominees.push(nominee)'] | | +| | | | ['pointsSum', 'pointsWeight'] | ['timeSum', 'timeWeight'] | | | | +| | | | ['setNominees', 'setRemovedNominees'] | | | | | +| retrieveRemovedNomineeVotingPower(bytes32,uint256) | external | [] | ['block.timestamp', 'changesSum'] | ['changesSum', 'changesWeight'] | ['abi.encode()', 'keccak256(bytes)'] | ['abi.encode(nominee)'] | 4 | +| | | | ['changesWeight', 'mapRemovedNominees'] | ['voteUserPower', 'voteUserSlopes'] | ['revert NomineeNotRemoved(bytes32,uint256)', 'revert ZeroValue()'] | | | +| | | | ['msg.sender', 'voteUserPower'] | | | | | +| | | | ['voteUserSlopes'] | | | | | +| getNomineeWeight(bytes32,uint256) | external | [] | ['pointsWeight', 'timeWeight'] | [] | ['abi.encode()', 'keccak256(bytes)'] | ['abi.encode(nominee)'] | 1 | +| getWeightsSum() | external | [] | ['pointsSum', 'timeSum'] | [] | [] | [] | 1 | +| getNumNominees() | external | [] | ['setNominees'] | [] | [] | [] | 1 | +| getNumRemovedNominees() | external | [] | ['setRemovedNominees'] | [] | [] | [] | 1 | +| getAllNominees() | external | [] | ['setNominees'] | [] | [] | [] | 1 | +| getAllRemovedNominees() | external | [] | ['setRemovedNominees'] | [] | [] | [] | 1 | +| getNomineeId(bytes32,uint256) | external | [] | ['mapNomineeIds'] | [] | ['abi.encode()', 'keccak256(bytes)'] | ['abi.encode(nominee)'] | 1 | +| getRemovedNomineeId(bytes32,uint256) | external | [] | ['mapRemovedNominees'] | [] | ['abi.encode()', 'keccak256(bytes)'] | ['abi.encode(nominee)'] | 1 | +| getNominee(uint256) | external | [] | ['setNominees'] | [] | ['revert Overflow(uint256,uint256)', 'revert ZeroValue()'] | [] | 3 | +| getRemovedNominee(uint256) | external | [] | ['setRemovedNominees'] | [] | ['revert Overflow(uint256,uint256)', 'revert ZeroValue()'] | [] | 3 | +| getNextAllowedVotingTimes(bytes32[],uint256[],address[]) | external | [] | ['WEIGHT_VOTE_DELAY', 'lastUserVote'] | [] | ['abi.encode()', 'keccak256(bytes)'] | ['abi.encode(nominee)', 'new uint256[](accounts.length)'] | 4 | +| | | | ['mapNomineeIds'] | | ['revert NomineeDoesNotExist(bytes32,uint256)', 'revert WrongArrayLength(uint256,uint256)'] | | | +| slitherConstructorConstantVariables() | internal | [] | [] | ['MAX_EVM_CHAIN_ID', 'MAX_NUM_WEEKS'] | [] | [] | 1 | +| | | | | ['MAX_WEIGHT', 'WEEK'] | | | | +| | | | | ['WEIGHT_VOTE_DELAY'] | | | | ++-----------------------------------------------------------+------------+-----------+------------------------------------------+-----------------------------------------+---------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+-----------------------+ + ++-----------+------------+------+-------+----------------+----------------+-----------------------+ +| Modifiers | Visibility | Read | Write | Internal Calls | External Calls | Cyclomatic Complexity | ++-----------+------------+------+-------+----------------+----------------+-----------------------+ ++-----------+------------+------+-------+----------------+----------------+-----------------------+ + +INFO:Slither:. analyzed (3 contracts) diff --git a/audits/internal12/analysis2/slither_human-summary.txt b/audits/internal12/analysis2/slither_human-summary.txt new file mode 100644 index 0000000..be3dc8c --- /dev/null +++ b/audits/internal12/analysis2/slither_human-summary.txt @@ -0,0 +1,22 @@ +'solc --version' running +'solc ./VoteWeighting-flatten.sol --combined-json abi,ast,bin,bin-runtime,srcmap,srcmap-runtime,userdoc,devdoc,hashes --allow-paths .,/home/andrey/valory/autonolas-governance/audits/internal12/analysis2/contracts' running +INFO:Printers: +Compiled with solc +Total number of contracts in source files: 3 +Source lines of code (SLOC) in source files: 427 +Number of assembly lines: 0 +Number of optimization issues: 3 +Number of informational issues: 3 +Number of low issues: 10 +Number of medium issues: 7 +Number of high issues: 0 + + ++---------------+-------------+------+------------+--------------+----------+ +| Name | # functions | ERCS | ERC20 info | Complex code | Features | ++---------------+-------------+------+------------+--------------+----------+ +| IDispenser | 2 | | | No | | +| IVEOLAS | 2 | | | No | | +| VoteWeighting | 30 | | | Yes | | ++---------------+-------------+------+------------+--------------+----------+ +INFO:Slither:. analyzed (3 contracts) diff --git a/audits/internal12/analysis2/slither_inheritance-graph.txt b/audits/internal12/analysis2/slither_inheritance-graph.txt new file mode 100644 index 0000000..9ff00cf --- /dev/null +++ b/audits/internal12/analysis2/slither_inheritance-graph.txt @@ -0,0 +1,5 @@ +'solc --version' running +'solc ./VoteWeighting-flatten.sol --combined-json abi,ast,bin,bin-runtime,srcmap,srcmap-runtime,userdoc,devdoc,hashes --allow-paths .,/home/andrey/valory/autonolas-governance/audits/internal12/analysis2/contracts' running +INFO:Printers:Inheritance Graph: ./VoteWeighting-flatten.sol.inheritance-graph.dot + +INFO:Slither:. analyzed (3 contracts) diff --git a/audits/internal12/analysis2/slither_inheritance.txt b/audits/internal12/analysis2/slither_inheritance.txt new file mode 100644 index 0000000..4d042c9 --- /dev/null +++ b/audits/internal12/analysis2/slither_inheritance.txt @@ -0,0 +1,21 @@ +'solc --version' running +'solc ./VoteWeighting-flatten.sol --combined-json abi,ast,bin,bin-runtime,srcmap,srcmap-runtime,userdoc,devdoc,hashes --allow-paths .,/home/andrey/valory/autonolas-governance/audits/internal12/analysis2/contracts' running +INFO:Printers:Inheritance +Child_Contract -> Immediate_Base_Contracts [Not_Immediate_Base_Contracts] ++ IDispenser + ++ IVEOLAS + ++ VoteWeighting + + +Base_Contract -> Immediate_Child_Contracts + [Not_Immediate_Child_Contracts] + ++ IDispenser + ++ IVEOLAS + ++ VoteWeighting + +INFO:Slither:. analyzed (3 contracts) diff --git a/audits/internal12/analysis2/slither_modifiers.txt b/audits/internal12/analysis2/slither_modifiers.txt new file mode 100644 index 0000000..dbe7600 --- /dev/null +++ b/audits/internal12/analysis2/slither_modifiers.txt @@ -0,0 +1,55 @@ +'solc --version' running +'solc ./VoteWeighting-flatten.sol --combined-json abi,ast,bin,bin-runtime,srcmap,srcmap-runtime,userdoc,devdoc,hashes --allow-paths .,/home/andrey/valory/autonolas-governance/audits/internal12/analysis2/contracts' running +INFO:Printers: +Contract IDispenser ++---------------+-----------+ +| Function | Modifiers | ++---------------+-----------+ +| addNominee | [] | +| removeNominee | [] | ++---------------+-----------+ +INFO:Printers: +Contract IVEOLAS ++------------------+-----------+ +| Function | Modifiers | ++------------------+-----------+ +| lockedEnd | [] | +| getLastUserPoint | [] | ++------------------+-----------+ +INFO:Printers: +Contract VoteWeighting ++-------------------------------------+-----------+ +| Function | Modifiers | ++-------------------------------------+-----------+ +| constructor | [] | +| _getSum | [] | +| _getWeight | [] | +| _addNominee | [] | +| addNomineeEVM | [] | +| addNomineeNonEVM | [] | +| changeOwner | [] | +| changeDispenser | [] | +| checkpoint | [] | +| checkpointNominee | [] | +| _nomineeRelativeWeight | [] | +| nomineeRelativeWeight | [] | +| nomineeRelativeWeightWrite | [] | +| voteForNomineeWeights | [] | +| voteForNomineeWeightsBatch | [] | +| _maxAndSub | [] | +| removeNominee | [] | +| retrieveRemovedNomineeVotingPower | [] | +| getNomineeWeight | [] | +| getWeightsSum | [] | +| getNumNominees | [] | +| getNumRemovedNominees | [] | +| getAllNominees | [] | +| getAllRemovedNominees | [] | +| getNomineeId | [] | +| getRemovedNomineeId | [] | +| getNominee | [] | +| getRemovedNominee | [] | +| getNextAllowedVotingTimes | [] | +| slitherConstructorConstantVariables | [] | ++-------------------------------------+-----------+ +INFO:Slither:. analyzed (3 contracts) diff --git a/audits/internal12/analysis2/slither_require.txt b/audits/internal12/analysis2/slither_require.txt new file mode 100644 index 0000000..b7d365d --- /dev/null +++ b/audits/internal12/analysis2/slither_require.txt @@ -0,0 +1,55 @@ +'solc --version' running +'solc ./VoteWeighting-flatten.sol --combined-json abi,ast,bin,bin-runtime,srcmap,srcmap-runtime,userdoc,devdoc,hashes --allow-paths .,/home/andrey/valory/autonolas-governance/audits/internal12/analysis2/contracts' running +INFO:Printers: +Contract IDispenser ++---------------+-------------------+ +| Function | require or assert | ++---------------+-------------------+ +| addNominee | | +| removeNominee | | ++---------------+-------------------+ +INFO:Printers: +Contract IVEOLAS ++------------------+-------------------+ +| Function | require or assert | ++------------------+-------------------+ +| lockedEnd | | +| getLastUserPoint | | ++------------------+-------------------+ +INFO:Printers: +Contract VoteWeighting ++-------------------------------------+-------------------+ +| Function | require or assert | ++-------------------------------------+-------------------+ +| constructor | | +| _getSum | | +| _getWeight | | +| _addNominee | | +| addNomineeEVM | | +| addNomineeNonEVM | | +| changeOwner | | +| changeDispenser | | +| checkpoint | | +| checkpointNominee | | +| _nomineeRelativeWeight | | +| nomineeRelativeWeight | | +| nomineeRelativeWeightWrite | | +| voteForNomineeWeights | | +| voteForNomineeWeightsBatch | | +| _maxAndSub | | +| removeNominee | | +| retrieveRemovedNomineeVotingPower | | +| getNomineeWeight | | +| getWeightsSum | | +| getNumNominees | | +| getNumRemovedNominees | | +| getAllNominees | | +| getAllRemovedNominees | | +| getNomineeId | | +| getRemovedNomineeId | | +| getNominee | | +| getRemovedNominee | | +| getNextAllowedVotingTimes | | +| slitherConstructorConstantVariables | | ++-------------------------------------+-------------------+ +INFO:Slither:. analyzed (3 contracts) diff --git a/audits/internal12/analysis2/slither_variable-order.txt b/audits/internal12/analysis2/slither_variable-order.txt new file mode 100644 index 0000000..c4d9481 --- /dev/null +++ b/audits/internal12/analysis2/slither_variable-order.txt @@ -0,0 +1,37 @@ +'solc --version' running +'solc ./VoteWeighting-flatten.sol --combined-json abi,ast,bin,bin-runtime,srcmap,srcmap-runtime,userdoc,devdoc,hashes --allow-paths .,/home/andrey/valory/autonolas-governance/audits/internal12/analysis2/contracts' running +INFO:Printers: +IDispenser: ++------+------+------+--------+ +| Name | Type | Slot | Offset | ++------+------+------+--------+ ++------+------+------+--------+ + +IVEOLAS: ++------+------+------+--------+ +| Name | Type | Slot | Offset | ++------+------+------+--------+ ++------+------+------+--------+ + +VoteWeighting: ++----------------------------------+----------------------------------------------------+------+--------+ +| Name | Type | Slot | Offset | ++----------------------------------+----------------------------------------------------+------+--------+ +| VoteWeighting.owner | address | 0 | 0 | +| VoteWeighting.dispenser | address | 1 | 0 | +| VoteWeighting.setNominees | Nominee[] | 2 | 0 | +| VoteWeighting.setRemovedNominees | Nominee[] | 3 | 0 | +| VoteWeighting.mapNomineeIds | mapping(bytes32 => uint256) | 4 | 0 | +| VoteWeighting.mapRemovedNominees | mapping(bytes32 => uint256) | 5 | 0 | +| VoteWeighting.voteUserSlopes | mapping(address => mapping(bytes32 => VotedSlope)) | 6 | 0 | +| VoteWeighting.voteUserPower | mapping(address => uint256) | 7 | 0 | +| VoteWeighting.lastUserVote | mapping(address => mapping(bytes32 => uint256)) | 8 | 0 | +| VoteWeighting.pointsWeight | mapping(bytes32 => mapping(uint256 => Point)) | 9 | 0 | +| VoteWeighting.changesWeight | mapping(bytes32 => mapping(uint256 => uint256)) | 10 | 0 | +| VoteWeighting.timeWeight | mapping(bytes32 => uint256) | 11 | 0 | +| VoteWeighting.pointsSum | mapping(uint256 => Point) | 12 | 0 | +| VoteWeighting.changesSum | mapping(uint256 => uint256) | 13 | 0 | +| VoteWeighting.timeSum | uint256 | 14 | 0 | ++----------------------------------+----------------------------------------------------+------+--------+ + +INFO:Slither:. analyzed (3 contracts) diff --git a/audits/internal12/analysis2/slither_vars-and-auth.txt b/audits/internal12/analysis2/slither_vars-and-auth.txt new file mode 100644 index 0000000..2231088 --- /dev/null +++ b/audits/internal12/analysis2/slither_vars-and-auth.txt @@ -0,0 +1,56 @@ +'solc --version' running +'solc ./VoteWeighting-flatten.sol --combined-json abi,ast,bin,bin-runtime,srcmap,srcmap-runtime,userdoc,devdoc,hashes --allow-paths .,/home/andrey/valory/autonolas-governance/audits/internal12/analysis2/contracts' running +INFO:Printers: +Contract IDispenser ++---------------+-------------------------+--------------------------+ +| Function | State variables written | Conditions on msg.sender | ++---------------+-------------------------+--------------------------+ +| addNominee | [] | [] | +| removeNominee | [] | [] | ++---------------+-------------------------+--------------------------+ + +Contract IVEOLAS ++------------------+-------------------------+--------------------------+ +| Function | State variables written | Conditions on msg.sender | ++------------------+-------------------------+--------------------------+ +| lockedEnd | [] | [] | +| getLastUserPoint | [] | [] | ++------------------+-------------------------+--------------------------+ + +Contract VoteWeighting ++-------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------+--------------------------+ +| Function | State variables written | Conditions on msg.sender | ++-------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------+--------------------------+ +| constructor | ['owner', 'setNominees', 'setRemovedNominees', 'timeSum', 've'] | [] | +| _getSum | ['pointsSum', 'timeSum'] | [] | +| _getWeight | ['pointsWeight', 'timeWeight'] | [] | +| _addNominee | ['mapNomineeIds', 'setNominees', 'timeWeight'] | [] | +| addNomineeEVM | ['mapNomineeIds', 'setNominees', 'timeWeight'] | [] | +| addNomineeNonEVM | ['mapNomineeIds', 'setNominees', 'timeWeight'] | [] | +| changeOwner | ['owner'] | ['msg.sender != owner'] | +| changeDispenser | ['dispenser'] | ['msg.sender != owner'] | +| checkpoint | ['pointsSum', 'timeSum'] | [] | +| checkpointNominee | ['pointsSum', 'pointsWeight', 'timeSum', 'timeWeight'] | [] | +| _nomineeRelativeWeight | [] | [] | +| nomineeRelativeWeight | [] | [] | +| nomineeRelativeWeightWrite | ['pointsSum', 'pointsWeight', 'timeSum', 'timeWeight'] | [] | +| voteForNomineeWeights | ['changesSum', 'changesWeight', 'lastUserVote', 'pointsSum', 'pointsWeight', 'timeSum', 'timeWeight', 'voteUserPower', 'voteUserSlopes'] | [] | +| voteForNomineeWeightsBatch | ['changesSum', 'changesWeight', 'lastUserVote', 'pointsSum', 'pointsWeight', 'timeSum', 'timeWeight', 'voteUserPower', 'voteUserSlopes'] | [] | +| _maxAndSub | [] | [] | +| removeNominee | ['mapNomineeIds', 'mapRemovedNominees', 'pointsSum', 'pointsWeight', 'setNominees', 'setRemovedNominees', 'timeSum', 'timeWeight'] | ['msg.sender != owner'] | +| retrieveRemovedNomineeVotingPower | ['changesSum', 'changesWeight', 'voteUserPower', 'voteUserSlopes'] | [] | +| getNomineeWeight | [] | [] | +| getWeightsSum | [] | [] | +| getNumNominees | [] | [] | +| getNumRemovedNominees | [] | [] | +| getAllNominees | [] | [] | +| getAllRemovedNominees | [] | [] | +| getNomineeId | [] | [] | +| getRemovedNomineeId | [] | [] | +| getNominee | [] | [] | +| getRemovedNominee | [] | [] | +| getNextAllowedVotingTimes | [] | [] | +| slitherConstructorConstantVariables | ['MAX_EVM_CHAIN_ID', 'MAX_NUM_WEEKS', 'MAX_WEIGHT', 'WEEK', 'WEIGHT_VOTE_DELAY'] | [] | ++-------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------+--------------------------+ + +INFO:Slither:. analyzed (3 contracts)