Description:
Multi-signature wallet contract requiring multiple confirmations for transaction execution.
Blockchain: Ethereum
Source Code: View Code On The Blockchain
Solidity Source Code:
{{
"language": "Solidity",
"sources": {
"lib/ve-governance/src/curve/LinearIncreasingCurve.sol": {
"content": "/// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;
// interfaces
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {IDAO} from "@aragon/osx-commons-contracts/src/dao/IDAO.sol";
import {
IVotingEscrowIncreasingV1_2_0 as IVotingEscrow
} from "@escrow/IVotingEscrowIncreasing_v1_2_0.sol";
import {
IEscrowCurveIncreasingV1_2_0 as IEscrowCurve,
IEscrowCurveGlobal,
IEscrowCurveCore,
IEscrowCurveTokenV1_2_0 as IEscrowCurveToken
} from "@curve/IEscrowCurveIncreasing_v1_2_0.sol";
import {IClockUser, IClockV1_2_0 as IClock} from "@clock/IClock_v1_2_0.sol";
// libraries
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import {SafeCast} from "@openzeppelin/contracts/utils/math/SafeCast.sol";
import {SignedFixedPointMath} from "@libs/SignedFixedPointMathLib.sol";
import {CurveConstantLib} from "@libs/CurveConstantLib.sol";
// contracts
import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
import {
ReentrancyGuardUpgradeable as ReentrancyGuard
} from "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol";
import {
DaoAuthorizableUpgradeable as DaoAuthorizable
} from "@aragon/osx-commons-contracts/src/permission/auth/DaoAuthorizableUpgradeable.sol";
/// @title Linear Increasing Escrow Curve
contract LinearIncreasingCurve is
IEscrowCurve,
IClockUser,
ReentrancyGuard,
DaoAuthorizable,
UUPSUpgradeable
{
using SafeERC20 for IERC20;
using SafeCast for int256;
using SafeCast for uint256;
using SignedFixedPointMath for int256;
/// @notice Administrator role for the contract
bytes32 public constant CURVE_ADMIN_ROLE = keccak256("CURVE_ADMIN_ROLE");
/// @notice The VotingEscrow contract address
address public escrow;
/// @notice The Clock contract address
address public clock;
/// @notice tokenId => latest index: incremented on a per-tokenId basis
/// @custom:oz-renamed-from tokenPointIntervals
mapping(uint256 => uint256) public tokenPointLatestIndex;
/// @notice The warmup period for the curve
/// @dev Deprecated in this version, but kept for backwards compatibility.
uint48 public warmupPeriod;
/// @dev tokenId => tokenPointIntervals => TokenPoint
/// @dev The Array is fixed so we can write to it in the future
/// This implementation means that very short intervals may be challenging
mapping(uint256 => TokenPoint[1_000_000_000]) internal _tokenPointHistory;
/*//////////////////////////////////////////////////////////////
MATH
//////////////////////////////////////////////////////////////*/
/// @custom:oz-upgrades-unsafe-allow state-variable-immutable
int256 private immutable SHARED_QUADRATIC_COEFFICIENT;
/// @custom:oz-upgrades-unsafe-allow state-variable-immutable
int256 private immutable SHARED_LINEAR_COEFFICIENT;
/// @custom:oz-upgrades-unsafe-allow state-variable-immutable
int256 private immutable SHARED_CONSTANT_COEFFICIENT;
/// @custom:oz-upgrades-unsafe-allow state-variable-immutable
uint256 private immutable MAX_EPOCHS;
/*//////////////////////////////////////////////////////////////
ADDED: TOTAL SUPPLY(1.2.0)
//////////////////////////////////////////////////////////////*/
/// @dev The latest global point index.
uint256 public globalPointLatestIndex;
// endTime => summed up slopes at that endTime
mapping(uint256 => int256) public slopeChanges;
/// @dev The global point history
mapping(uint256 => GlobalPoint) internal _globalPointHistory;
/*//////////////////////////////////////////////////////////////
INITIALIZATION
//////////////////////////////////////////////////////////////*/
/// @custom:oz-upgrades-unsafe-allow constructor
constructor(int256[3] memory _coefficients, uint256 _maxEpochs) {
SHARED_CONSTANT_COEFFICIENT = _coefficients[0];
SHARED_LINEAR_COEFFICIENT = _coefficients[1];
SHARED_QUADRATIC_COEFFICIENT = _coefficients[2];
MAX_EPOCHS = _maxEpochs;
_disableInitializers();
}
/// @param _escrow VotingEscrow contract address
function initialize(address _escrow, address _dao, address _clock) external initializer {
escrow = _escrow;
clock = _clock;
__ReentrancyGuard_init();
__DaoAuthorizableUpgradeable_init(IDAO(_dao));
// other initializers are empty
}
/*//////////////////////////////////////////////////////////////
CURVE COEFFICIENTS
//////////////////////////////////////////////////////////////*/
/// @return The coefficient for the curve's linear term, for the given amount
function _getLinearCoeff(uint256 amount) internal view virtual returns (int256) {
return amount.toInt256() * SHARED_LINEAR_COEFFICIENT;
}
/// @return The constant coefficient of the increasing curve, for the given amount
/// @dev In this case, the constant term is 1 so we just case the amount
function _getConstantCoeff(uint256 amount) internal view virtual returns (int256) {
return amount.toInt256() * SHARED_CONSTANT_COEFFICIENT;
}
/// @return The coefficients of the quadratic curve, for the given amount
/// @dev The coefficients are returned in the order [constant, linear, quadratic]
function _getCoefficients(uint256 amount) internal view virtual returns (int256[3] memory) {
return [_getConstantCoeff(amount), _getLinearCoeff(amount), 0];
}
/// @return The coefficients of the quadratic curve, for the given amount
/// @dev The coefficients are returned in the order [constant, linear, quadratic]
/// and are converted to regular 256-bit signed integers instead of their fixed-point representation
function getCoefficients(uint256 amount) public view virtual returns (int256[3] memory) {
int256[3] memory coefficients = _getCoefficients(amount);
return [
coefficients[0] / 1e18, // amount
coefficients[1] / 1e18, // slope
0
];
}
/*//////////////////////////////////////////////////////////////
CURVE BIAS
//////////////////////////////////////////////////////////////*/
/// @notice Rounds `_elapsed` to maxTime if it's greater, otherwise returns `_elapsed`.
function boundElapsedMaxTime(uint256 _elapsed) private view returns (uint256) {
uint256 MAX_TIME = maxTime();
return _elapsed > MAX_TIME ? MAX_TIME : _elapsed;
}
/// @notice Returns the bias for the given time elapsed and amount, up to the maximum time
function getBias(uint256 timeElapsed, uint256 amount) public view returns (uint256) {
int256[3] memory coefficients = _getCoefficients(amount);
uint256 bias = _getBias(boundElapsedMaxTime(timeElapsed), coefficients[0], coefficients[1]);
return bias / 1e18;
}
/// @notice Returns the bias for the given time elapsed and amount, up to the maximum time
/// @dev Returned values from these functions are in fixed point representation
/// which is not the case in `getBias`.
function _getBias(
uint256 _timeElapsed,
int256 _constantCoeff,
int256 _linearCoeff
) internal pure returns (uint256) {
int256 bias = _linearCoeff * int256(_timeElapsed) + _constantCoeff;
if (bias < 0) bias = 0;
return bias.toUint256();
}
function _getBiasAndSlope(
uint256 _timeElapsed,
uint256 _amount
) public view returns (int256, int256) {
int256 slope = _getLinearCoeff(_amount);
uint256 bias = _getBias(
boundElapsedMaxTime(_timeElapsed),
_getConstantCoeff(_amount),
slope
);
return (int256(bias), slope);
}
function maxTime() public view virtual returns (uint256) {
return IClock(clock).epochDuration() * MAX_EPOCHS;
}
function previewMaxBias(uint256 amount) external view returns (uint256) {
return getBias(maxTime(), amount);
}
/*//////////////////////////////////////////////////////////////
BALANCE
//////////////////////////////////////////////////////////////*/
/// @inheritdoc IEscrowCurveToken
function tokenPointHistory(
uint256 _tokenId,
uint256 _index
) external view returns (TokenPoint memory point) {
point = _tokenPointHistory[_tokenId][_index];
/// bind for backwards compatibility
point.bias = uint(point.coefficients[0]) / 1e18;
}
/// @inheritdoc IEscrowCurveGlobal
function globalPointHistory(uint256 _index) public view returns (GlobalPoint memory) {
return _globalPointHistory[_index];
}
/// @inheritdoc IEscrowCurveToken
function tokenPointIntervals(uint256 _tokenId) external view returns (uint256) {
return tokenPointLatestIndex[_tokenId];
}
/// @inheritdoc IEscrowCurveCore
function votingPowerAt(uint256 _tokenId, uint256 _t) external view returns (uint256) {
uint256 interval = _getPastTokenPointInterval(_tokenId, _t);
// epoch 0 is an empty point
if (interval == 0) return 0;
// Note that very first point is saved at index 1.
// Grab original point(the very first point for `_tokenId`).
TokenPoint memory originalPoint = _tokenPointHistory[_tokenId][1];
// Grab last point before `_t`.
TokenPoint memory lastPoint = _tokenPointHistory[_tokenId][interval];
int256 bias = lastPoint.coefficients[0];
int256 slope = lastPoint.coefficients[1];
uint256 end = originalPoint.checkpointTs + maxTime();
// If the point was created before the upgrade:
// it will have `checkpointTs` greater than `writtenTs`.
// bias would have been stored as just the amount(without bonus).
// In such case, we make writtenTs equal to avoid checkpointTs greater.
// This ensures that behaviour after and before upgrade are same.
if (lastPoint.checkpointTs > lastPoint.writtenTs) {
lastPoint.writtenTs = lastPoint.checkpointTs;
if (_t < lastPoint.writtenTs) return 0;
}
uint256 elapsed = _t - lastPoint.writtenTs;
uint256 timeTillMaxTime = 0;
if (end > lastPoint.writtenTs) {
timeTillMaxTime = end - lastPoint.writtenTs;
}
if (elapsed >= timeTillMaxTime) {
elapsed = timeTillMaxTime;
}
return _getBias(elapsed, bias, slope) / 1e18;
}
/// @inheritdoc IEscrowCurveCore
function supplyAt(uint256 _timestamp) external view returns (uint256) {
return _supplyAt(_timestamp);
}
/*//////////////////////////////////////////////////////////////
CHECKPOINT
//////////////////////////////////////////////////////////////*/
/// @notice A checkpoint can be called by the VotingEscrow contract to snapshot the user's voting power
function checkpoint(
uint256 _tokenId,
IVotingEscrow.LockedBalance memory _oldLocked,
IVotingEscrow.LockedBalance memory _newLocked
) external nonReentrant {
if (msg.sender != escrow) revert OnlyEscrow();
_checkpoint(_tokenId, _oldLocked, _newLocked);
}
/// @notice Record user data to checkpoints. Used by VotingEscrow system.
/// @param _tokenId NFT token ID.
/// @param _fromLocked The locked from which we're moving.
/// @param _newLocked New locked amount / end lock time for the user
function _checkpoint(
uint256 _tokenId,
IVotingEscrow.LockedBalance memory _fromLocked,
IVotingEscrow.LockedBalance memory _newLocked
) internal {
// this implementation doesn't yet support manual checkpointing
if (_tokenId == 0) revert InvalidTokenId();
if (_newLocked.start < _fromLocked.start) {
revert InvalidCheckpoint();
}
uint256 _globalPointLatestIndex = globalPointLatestIndex;
// Get the slope and bias for `_newLocked`...
(int256 newLockBias, int256 newLockSlope) = _getBiasAndSlope(
block.timestamp - _newLocked.start,
_newLocked.amount
);
GlobalPoint memory lastPoint = GlobalPoint({
bias: 0,
slope: 0,
writtenTs: uint48(block.timestamp)
});
if (_globalPointLatestIndex > 0) {
lastPoint = _globalPointHistory[_globalPointLatestIndex];
}
{
uint256 checkpointInterval = IClock(clock).checkpointInterval();
// For safety reasons, we don't allow checkpoints
// on the exact checkpointInterval.
if (block.timestamp % checkpointInterval == 0) {
revert CheckpointOnDepositIntervalNotAllowed();
}
uint256 lastPointCheckpoint = lastPoint.writtenTs;
uint256 t_i = (lastPointCheckpoint / checkpointInterval) * checkpointInterval;
for (uint256 i = 0; i < 255; ++i) {
t_i += checkpointInterval;
int256 dSlope;
if (t_i > block.timestamp) {
t_i = block.timestamp;
} else {
dSlope = slopeChanges[t_i];
}
lastPoint.bias += lastPoint.slope * int256(t_i - lastPointCheckpoint);
lastPoint.slope -= dSlope;
if (lastPoint.slope < 0) lastPoint.slope = 0;
if (lastPoint.bias < 0) lastPoint.bias = 0;
lastPointCheckpoint = t_i;
lastPoint.writtenTs = uint48(t_i);
_globalPointLatestIndex += 1;
if (t_i == block.timestamp) {
break;
} else {
_globalPointHistory[_globalPointLatestIndex] = lastPoint;
}
}
}
uint256 _maxTime = maxTime();
uint256 newLockedEnd = _newLocked.start + _maxTime;
uint256 fromLockedEnd = _fromLocked.start + _maxTime;
// The following condition is true if merging non-mature locks with different start dates.
// current version of ve-governance is built around the assumption that merge can only
// occur if tokens are either mature or have the same start dates. Even though `escrow`
// does this check before calling `checkpoint` on curve, it's still a safety measure to repeat
// the check in case the code of checkpoint might be called by another contract in the future.
if (
_fromLocked.start != 0 &&
_newLocked.start != 0 &&
_fromLocked.start != _newLocked.start &&
(newLockedEnd >= block.timestamp || fromLockedEnd >= block.timestamp)
) {
revert InvalidLocks(_tokenId, _fromLocked, _newLocked);
}
// newLocked could be ended in case of merge, when
// a token is already mature.
if (newLockedEnd <= block.timestamp) {
newLockSlope = 0;
}
(int256 oldLockBias, int256 oldLockSlope) = (0, 0);
if (_fromLocked.amount > 0) {
(oldLockBias, oldLockSlope) = _getBiasAndSlope(
block.timestamp - _fromLocked.start,
_fromLocked.amount
);
// In case fromLocked already ended, its slope would already
// be subtracted from `lastPoint.slope` in the above for loop.
// So we make this 0 to not subtract double times.
if (fromLockedEnd <= block.timestamp) {
oldLockSlope = 0;
}
}
lastPoint.bias += (newLockBias - oldLockBias);
lastPoint.slope += (newLockSlope - oldLockSlope);
if (lastPoint.slope < 0) lastPoint.slope = 0;
if (lastPoint.bias < 0) lastPoint.bias = 0;
uint256 tokenLatestIndex = tokenPointLatestIndex[_tokenId];
// The token point already exists..
if (tokenLatestIndex > 0) {
if (fromLockedEnd > block.timestamp) {
slopeChanges[fromLockedEnd] -= oldLockSlope;
}
}
// store new slope change
slopeChanges[newLockedEnd] += newLockSlope;
// Record the latest global point.
_storeLatestGlobalPoint(lastPoint, _globalPointLatestIndex);
// Create new token point and store.
TokenPoint memory tNew;
tNew.writtenTs = uint128(block.timestamp);
tNew.checkpointTs = _newLocked.start;
tNew.coefficients = [newLockBias, newLockSlope, 0];
// Record the latest token point.
_storeLatestTokenPoint(tNew, _tokenId, tokenLatestIndex);
}
/// @dev The private helper function to either store latest global point on a new index or overwrite it.
/// In case of overwriting, the latest global point index is not incremented.
function _storeLatestGlobalPoint(GlobalPoint memory _p, uint256 _index) private {
// If the timestamp of last stored global point is the same as
// current timestamp, overwrite it, otherwise store a new one
// to reduce unnecessary global points in the history for
// gas costs and binary search efficiency.
if (_index != 1 && _globalPointHistory[_index - 1].writtenTs == block.timestamp) {
_globalPointHistory[_index - 1] = _p;
} else {
globalPointLatestIndex = _index;
_globalPointHistory[_index] = _p;
}
}
/// @dev The private helper function to either store latest token point on a new index or overwrite it.
/// In case of overwriting, the latest token point index is not incremented.
function _storeLatestTokenPoint(
TokenPoint memory _p,
uint256 _tokenId,
uint256 _index
) private {
// If the timestamp of last stored token point is the same as
// current timestamp, overwrite it, otherwise store a new one
// to reduce unnecessary global points in the history for
// gas costs and binary search efficiency.
if (_index != 0 && _tokenPointHistory[_tokenId][_index].writtenTs == block.timestamp) {
_tokenPointHistory[_tokenId][_index] = _p;
} else {
tokenPointLatestIndex[_tokenId] = ++_index;
_tokenPointHistory[_tokenId][_index] = _p;
}
}
/*///////////////////////////////////////////////////////////////
Total Supply and Voting Power Calculations
//////////////////////////////////////////////////////////////*/
/// @notice Binary search to get the token point interval for a token id at or prior to a given timestamp
/// Once we have the point , we can apply the bias calculation to get the voting power.
/// @dev If a token point does not exist prior to the timestamp, this will return 0.
function _getPastTokenPointInterval(
uint256 _tokenId,
uint256 _timestamp
) internal view returns (uint256) {
uint256 tokenInterval = tokenPointLatestIndex[_tokenId];
if (tokenInterval == 0) return 0;
// if the most recent point is before the timestamp, return it
if (_tokenPointHistory[_tokenId][tokenInterval].writtenTs <= _timestamp)
return (tokenInterval);
// Check if the first balance is after the timestamp
// this means that the first epoch has yet to start
if (_tokenPointHistory[_tokenId][1].writtenTs > _timestamp) return 0;
uint256 lower = 0;
uint256 upper = tokenInterval;
while (upper > lower) {
uint256 center = upper - (upper - lower) / 2; // ceil, avoiding overflow
TokenPoint storage tokenPoint = _tokenPointHistory[_tokenId][center];
if (tokenPoint.writtenTs == _timestamp) {
return center;
} else if (tokenPoint.writtenTs < _timestamp) {
lower = center;
} else {
upper = center - 1;
}
}
return lower;
}
/// @notice Binary search to get the global point index at or prior to a given timestamp
/// @dev If a checkpoint does not exist prior to the timestamp, this will return 0.
/// @param _timestamp The timestamp to get a checkpoint at.
/// @return Global point index
function getPastGlobalPointIndex(uint256 _timestamp) internal view returns (uint256) {
if (globalPointLatestIndex == 0) return 0;
// First check most recent balance
if (_globalPointHistory[globalPointLatestIndex].writtenTs <= _timestamp)
return (globalPointLatestIndex);
// Next check implicit zero balance
if (_globalPointHistory[1].writtenTs > _timestamp) return 0;
uint256 lower = 0;
uint256 upper = globalPointLatestIndex;
while (upper > lower) {
uint256 center = upper - (upper - lower) / 2; // ceil, avoiding overflow
GlobalPoint storage globalPoint = _globalPointHistory[center];
if (globalPoint.writtenTs == _timestamp) {
return center;
} else if (globalPoint.writtenTs < _timestamp) {
lower = center;
} else {
upper = center - 1;
}
}
return lower;
}
/// @notice Calculate total voting power at some point in the past
/// @param _timestamp Time to calculate the total voting power at
/// @return Total voting power at that time
function _supplyAt(uint256 _timestamp) internal view returns (uint256) {
uint256 epoch_ = getPastGlobalPointIndex(_timestamp);
// epoch 0 is an empty point
if (epoch_ == 0) return 0;
GlobalPoint memory _point = _globalPointHistory[epoch_];
int256 bias = _point.bias;
int256 slope = _point.slope;
uint256 ts = _point.writtenTs; // changes in for loop.
uint256 checkpointInterval = IClock(clock).checkpointInterval();
uint256 t_i = (ts / checkpointInterval) * checkpointInterval;
for (uint256 i = 0; i < 255; ++i) {
t_i += checkpointInterval;
int256 dSlope = 0;
if (t_i > _timestamp) {
t_i = _timestamp;
} else {
dSlope = slopeChanges[t_i];
}
bias += slope * int256(t_i - ts);
if (t_i == _timestamp) {
break;
}
slope -= dSlope;
ts = t_i;
}
if (bias < 0) bias = 0;
return uint256(bias / 1e18);
}
/*///////////////////////////////////////////////////////////////
UUPS Upgrade
//////////////////////////////////////////////////////////////*/
/// @notice Returns the address of the implementation contract in the [proxy storage slot](https://eips.ethereum.org/EIPS/eip-1967) slot the [UUPS proxy](https://eips.ethereum.org/EIPS/eip-1822) is pointing to.
/// @return The address of the implementation contract.
function implementation() public view returns (address) {
return _getImplementation();
}
/// @notice Internal method authorizing the upgrade of the contract via the [upgradeability mechanism for UUPS proxies](https://docs.openzeppelin.com/contracts/4.x/api/proxy#UUPSUpgradeable) (see [ERC-1822](https://eips.ethereum.org/EIPS/eip-1822)).
function _authorizeUpgrade(address) internal virtual override auth(CURVE_ADMIN_ROLE) {}
/// @dev Reserved storage space to allow for layout changes in the future.
uint256[42] private __gap;
/*//////////////////////////////////////////////////////////////
DEPRECATED: Warmup
//////////////////////////////////////////////////////////////*/
function setWarmupPeriod(uint48) external pure {
revert Deprecated();
}
/// @notice Returns whether the NFT is warm
/// @dev In this version, warm functionality has been deprecated.
/// For backwards compatibility, always return true.
function isWarm(uint256) public pure virtual returns (bool) {
return true;
}
/// @notice Returns whether the NFT is warm at the specified timestamp(`_ts`)
/// @dev In this version, warm functionality has been deprecated.
/// For backwards compatibility, always return true.
function isWarm(uint256, uint48) public pure virtual returns (bool) {
return true;
}
}
"
},
"lib/token-voting-plugin/lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol": {
"content": "// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `from` to `to` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address from, address to, uint256 amount) external returns (bool);
}
"
},
"lib/ve-governance/lib/osx-commons/contracts/src/dao/IDAO.sol": {
"content": "// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity ^0.8.8;
/// @title IDAO
/// @author Aragon X - 2022-2024
/// @notice The interface required for DAOs within the Aragon App DAO framework.
/// @custom:security-contact sirt@aragon.org
interface IDAO {
/// @notice Checks if an address has permission on a contract via a permission identifier and considers if `ANY_ADDRESS` was used in the granting process.
/// @param _where The address of the contract.
/// @param _who The address of a EOA or contract to give the permissions.
/// @param _permissionId The permission identifier.
/// @param _data The optional data passed to the `PermissionCondition` registered.
/// @return Returns true if the address has permission, false if not.
function hasPermission(
address _where,
address _who,
bytes32 _permissionId,
bytes memory _data
) external view returns (bool);
/// @notice Updates the DAO metadata (e.g., an IPFS hash).
/// @param _metadata The IPFS hash of the new metadata object.
function setMetadata(bytes calldata _metadata) external;
/// @notice Emitted when the DAO metadata is updated.
/// @param metadata The IPFS hash of the new metadata object.
event MetadataSet(bytes metadata);
/// @notice Emitted when a standard callback is registered.
/// @param interfaceId The ID of the interface.
/// @param callbackSelector The selector of the callback function.
/// @param magicNumber The magic number to be registered for the callback function selector.
event StandardCallbackRegistered(
bytes4 interfaceId,
bytes4 callbackSelector,
bytes4 magicNumber
);
/// @notice Deposits (native) tokens to the DAO contract with a reference string.
/// @param _token The address of the token or address(0) in case of the native token.
/// @param _amount The amount of tokens to deposit.
/// @param _reference The reference describing the deposit reason.
function deposit(address _token, uint256 _amount, string calldata _reference) external payable;
/// @notice Emitted when a token deposit has been made to the DAO.
/// @param sender The address of the sender.
/// @param token The address of the deposited token.
/// @param amount The amount of tokens deposited.
/// @param _reference The reference describing the deposit reason.
event Deposited(
address indexed sender,
address indexed token,
uint256 amount,
string _reference
);
/// @notice Emitted when a native token deposit has been made to the DAO.
/// @dev This event is intended to be emitted in the `receive` function and is therefore bound by the gas limitations for `send`/`transfer` calls introduced by [ERC-2929](https://eips.ethereum.org/EIPS/eip-2929).
/// @param sender The address of the sender.
/// @param amount The amount of native tokens deposited.
event NativeTokenDeposited(address sender, uint256 amount);
/// @notice Setter for the trusted forwarder verifying the meta transaction.
/// @param _trustedForwarder The trusted forwarder address.
function setTrustedForwarder(address _trustedForwarder) external;
/// @notice Getter for the trusted forwarder verifying the meta transaction.
/// @return The trusted forwarder address.
function getTrustedForwarder() external view returns (address);
/// @notice Emitted when a new TrustedForwarder is set on the DAO.
/// @param forwarder the new forwarder address.
event TrustedForwarderSet(address forwarder);
/// @notice Checks whether a signature is valid for a provided hash according to [ERC-1271](https://eips.ethereum.org/EIPS/eip-1271).
/// @param _hash The hash of the data to be signed.
/// @param _signature The signature byte array associated with `_hash`.
/// @return Returns the `bytes4` magic value `0x1626ba7e` if the signature is valid and `0xffffffff` if not.
function isValidSignature(bytes32 _hash, bytes memory _signature) external returns (bytes4);
/// @notice Registers an ERC standard having a callback by registering its [ERC-165](https://eips.ethereum.org/EIPS/eip-165) interface ID and callback function signature.
/// @param _interfaceId The ID of the interface.
/// @param _callbackSelector The selector of the callback function.
/// @param _magicNumber The magic number to be registered for the function signature.
function registerStandardCallback(
bytes4 _interfaceId,
bytes4 _callbackSelector,
bytes4 _magicNumber
) external;
/// @notice Removed function being left here to not corrupt the IDAO interface ID. Any call will revert.
/// @dev Introduced in v1.0.0. Removed in v1.4.0.
function setSignatureValidator(address) external;
}
"
},
"lib/ve-governance/src/escrow/IVotingEscrowIncreasing_v1_2_0.sol": {
"content": "/// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "./IVotingEscrowIncreasing.sol";
import {IEscrowIVotesAdapter, IDelegateUpdateVotingPower} from "@delegation/IEscrowIVotesAdapter.sol";
interface IVotingEscrowExiting {
/// @notice How much amount has been exiting.
/// @return total The total amount for which beginWithdrawal has been called
/// but withdraw has not yet been executed.
function currentExitingAmount() external view returns (uint256);
}
interface IMergeEventsAndErrors {
event Merged(
address indexed _sender,
uint256 indexed _from,
uint256 indexed _to,
uint208 _amountFrom,
uint208 _amountTo,
uint208 _amountFinal
);
error CannotMerge(uint256 _from, uint256 _to);
error SameNFT();
}
interface IMerge is ILockedBalanceIncreasing, IMergeEventsAndErrors {
/// @notice Merge two tokens - i.e `from` into `_to`.
/// @param _from The token id from which merge is occuring
/// @param _to The token id to which `_from` is merging
function merge(uint256 _from, uint256 _to) external;
/// @notice Whether 2 tokens can be merged.
/// @param _from The token id from which merge should occur.
/// @param _to The token id to which `_from` should merge.
function canMerge(
LockedBalance memory _from,
LockedBalance memory _to
) external view returns (bool);
}
interface ISplitEventsAndErrors {
event Split(
uint256 indexed _from,
uint256 indexed newTokenId,
address _sender,
uint208 _splitAmount1,
uint208 _splitAmount2
);
event SplitWhitelistSet(address indexed account, bool status);
error SplitNotWhitelisted();
error SplitAmountTooBig();
}
interface ISplit is ISplitEventsAndErrors {
/// @notice Split token into two new, separate tokens.
/// @param _from The token id that should be split
/// @param _value The amount that determines how token is split
/// @return _newTokenId The new token id after split.
function split(
uint256 _from,
uint256 _value
) external returns (uint256 _newTokenId);
}
interface IDelegateMoveVoteCaller {
/// @notice After a token transfer, decreases `_from`'s voting power and increases `_to`'s voting power.
/// @dev Called upon a token transfer.
/// @param _from The current delegatee of `_tokenId`.
/// @param _to The new delegatee of `_tokenId`
/// @param _tokenId The token id that is being transferred.
function moveDelegateVotes(
address _from,
address _to,
uint256 _tokenId
) external;
}
interface IVotingEscrowIncreasingV1_2_0 is
IVotingEscrowIncreasing,
IVotingEscrowExiting,
IMerge,
ISplit,
IDelegateUpdateVotingPower,
IDelegateMoveVoteCaller
{}
"
},
"lib/ve-governance/src/curve/IEscrowCurveIncreasing_v1_2_0.sol": {
"content": "/// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "./IEscrowCurveIncreasing.sol";
import "../IDeprecated.sol";
/*///////////////////////////////////////////////////////////////
Global Curve
//////////////////////////////////////////////////////////////*/
interface IEscrowCurveGlobalStorage {
/// @notice Captures the shape of the aggregate voting curve at a specific point in time
/// @param bias The y intercept of the aggregate voting curve at the given time
/// @param slope The slope of the aggregate voting curve at the given time
/// @param writtenTs The timestamp at which the we last updated the aggregate voting curve
struct GlobalPoint {
int256 bias;
int256 slope;
uint48 writtenTs;
}
}
interface IEscrowCurveGlobal is IEscrowCurveGlobalStorage {
/// @notice Returns the global point at the passed epoch
/// @param _index The index in an array to return the point for
function globalPointHistory(uint256 _index) external view returns (GlobalPoint memory);
}
/*///////////////////////////////////////////////////////////////
Token Curve
//////////////////////////////////////////////////////////////*/
interface IEscrowCurveTokenV1_2_0 is IEscrowCurveTokenStorage {
/// @notice Returns the latest index of the tokenId which can be used
/// to retrive token point from `tokenPointHistory` function.
/// @dev This has been renamed to `tokenPointLatestIndex` in the latest upgrade, but
/// for backwards-compatibility, the function still stays in the contract.
/// Note that we treat it as deprecated, So use `tokenPointLatestIndex` instead.
/// @return The latest index of the token id.
function tokenPointIntervals(uint256 _tokenId) external view returns (uint256);
/// @notice Returns the latest index of the tokenId which can be used
/// to retrive token point from `tokenPointHistory` function.
/// @param _tokenId The NFT to return the latest token point index
/// @return The latest index of the token id.
function tokenPointLatestIndex(uint256 _tokenId) external view returns (uint256);
/// @notice Returns the TokenPoint at the passed `_index`.
/// @param _tokenId The NFT to return the TokenPoint for
/// @param _index The index to return the TokenPoint at.
function tokenPointHistory(
uint256 _tokenId,
uint256 _index
) external view returns (TokenPoint memory);
}
interface IEscrowCurveMaxTime is IEscrowCurveErrorsAndEvents {
/// @return The max time allowed for the lock duration.
function maxTime() external view returns (uint256);
}
/*///////////////////////////////////////////////////////////////
INCREASING CURVE
//////////////////////////////////////////////////////////////*/
interface IEscrowCurveIncreasingV1_2_0 is
IEscrowCurveCore,
IEscrowCurveMath,
IEscrowCurveTokenV1_2_0,
IEscrowCurveMaxTime,
IEscrowCurveGlobal,
IDeprecated
{}
interface IEscrowCurveIncreasingV1_2_0_NoSupply is
IEscrowCurveCore,
IEscrowCurveMath,
IEscrowCurveTokenV1_2_0,
IEscrowCurveMaxTime,
IDeprecated
{}
"
},
"lib/ve-governance/src/clock/IClock_v1_2_0.sol": {
"content": "/// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "./IClock.sol";
interface IClockV1_2_0 is IClock {
function epochPrevCheckpointTs() external view returns (uint256);
function resolveEpochPrevCheckpointTs(uint256 timestamp) external pure returns (uint256);
}
"
},
"lib/token-voting-plugin/lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol": {
"content": "// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)
pragma solidity ^0.8.0;
import "../IERC20.sol";
import "../extensions/IERC20Permit.sol";
import "../../../utils/Address.sol";
/**
* @title SafeERC20
* @dev Wrappers around ERC20 operations that throw on failure (when the token
* contract returns false). Tokens that return no value (and instead revert or
* throw on failure) are also supported, non-reverting calls are assumed to be
* successful.
* To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
*/
library SafeERC20 {
using Address for address;
/**
* @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeTransfer(IERC20 token, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
/**
* @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the
* calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.
*/
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
}
/**
* @dev Deprecated. This function has issues similar to the ones found in
* {IERC20-approve}, and its usage is discouraged.
*
* Whenever possible, use {safeIncreaseAllowance} and
* {safeDecreaseAllowance} instead.
*/
function safeApprove(IERC20 token, address spender, uint256 value) internal {
// safeApprove should only be called when setting an initial allowance,
// or when resetting it to zero. To increase and decrease it, use
// 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
require(
(value == 0) || (token.allowance(address(this), spender) == 0),
"SafeERC20: approve from non-zero to non-zero allowance"
);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
/**
* @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 oldAllowance = token.allowance(address(this), spender);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));
}
/**
* @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
unchecked {
uint256 oldAllowance = token.allowance(address(this), spender);
require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));
}
}
/**
* @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval
* to be set to zero before setting it to a non-zero value, such as USDT.
*/
function forceApprove(IERC20 token, address spender, uint256 value) internal {
bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);
if (!_callOptionalReturnBool(token, approvalCall)) {
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));
_callOptionalReturn(token, approvalCall);
}
}
/**
* @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.
* Revert on invalid signature.
*/
function safePermit(
IERC20Permit token,
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) internal {
uint256 nonceBefore = token.nonces(owner);
token.permit(owner, spender, value, deadline, v, r, s);
uint256 nonceAfter = token.nonces(owner);
require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed");
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*/
function _callOptionalReturn(IERC20 token, bytes memory data) private {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that
// the target address contains contract code and also asserts for success in the low-level call.
bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
require(returndata.length == 0 || abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*
* This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.
*/
function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false
// and not revert is the subcall reverts.
(bool success, bytes memory returndata) = address(token).call(data);
return
success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));
}
}
"
},
"lib/token-voting-plugin/lib/openzeppelin-contracts/contracts/utils/math/SafeCast.sol": {
"content": "// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)
// This file was procedurally generated from scripts/generate/templates/SafeCast.js.
pragma solidity ^0.8.0;
/**
* @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow
* checks.
*
* Downcasting from uint256/int256 in Solidity does not revert on overflow. This can
* easily result in undesired exploitation or bugs, since developers usually
* assume that overflows raise errors. `SafeCast` restores this intuition by
* reverting the transaction when such an operation overflows.
*
* Using this library instead of the unchecked operations eliminates an entire
* class of bugs, so it's recommended to use it always.
*
* Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing
* all math on `uint256` and `int256` and then downcasting.
*/
library SafeCast {
/**
* @dev Returns the downcasted uint248 from uint256, reverting on
* overflow (when the input is greater than largest uint248).
*
* Counterpart to Solidity's `uint248` operator.
*
* Requirements:
*
* - input must fit into 248 bits
*
* _Available since v4.7._
*/
function toUint248(uint256 value) internal pure returns (uint248) {
require(value <= type(uint248).max, "SafeCast: value doesn't fit in 248 bits");
return uint248(value);
}
/**
* @dev Returns the downcasted uint240 from uint256, reverting on
* overflow (when the input is greater than largest uint240).
*
* Counterpart to Solidity's `uint240` operator.
*
* Requirements:
*
* - input must fit into 240 bits
*
* _Available since v4.7._
*/
function toUint240(uint256 value) internal pure returns (uint240) {
require(value <= type(uint240).max, "SafeCast: value doesn't fit in 240 bits");
return uint240(value);
}
/**
* @dev Returns the downcasted uint232 from uint256, reverting on
* overflow (when the input is greater than largest uint232).
*
* Counterpart to Solidity's `uint232` operator.
*
* Requirements:
*
* - input must fit into 232 bits
*
* _Available since v4.7._
*/
function toUint232(uint256 value) internal pure returns (uint232) {
require(value <= type(uint232).max, "SafeCast: value doesn't fit in 232 bits");
return uint232(value);
}
/**
* @dev Returns the downcasted uint224 from uint256, reverting on
* overflow (when the input is greater than largest uint224).
*
* Counterpart to Solidity's `uint224` operator.
*
* Requirements:
*
* - input must fit into 224 bits
*
* _Available since v4.2._
*/
function toUint224(uint256 value) internal pure returns (uint224) {
require(value <= type(uint224).max, "SafeCast: value doesn't fit in 224 bits");
return uint224(value);
}
/**
* @dev Returns the downcasted uint216 from uint256, reverting on
* overflow (when the input is greater than largest uint216).
*
* Counterpart to Solidity's `uint216` operator.
*
* Requirements:
*
* - input must fit into 216 bits
*
* _Available since v4.7._
*/
function toUint216(uint256 value) internal pure returns (uint216) {
require(value <= type(uint216).max, "SafeCast: value doesn't fit in 216 bits");
return uint216(value);
}
/**
* @dev Returns the downcasted uint208 from uint256, reverting on
* overflow (when the input is greater than largest uint208).
*
* Counterpart to Solidity's `uint208` operator.
*
* Requirements:
*
* - input must fit into 208 bits
*
* _Available since v4.7._
*/
function toUint208(uint256 value) internal pure returns (uint208) {
require(value <= type(uint208).max, "SafeCast: value doesn't fit in 208 bits");
return uint208(value);
}
/**
* @dev Returns the downcasted uint200 from uint256, reverting on
* overflow (when the input is greater than largest uint200).
*
* Counterpart to Solidity's `uint200` operator.
*
* Requirements:
*
* - input must fit into 200 bits
*
* _Available since v4.7._
*/
function toUint200(uint256 value) internal pure returns (uint200) {
require(value <= type(uint200).max, "SafeCast: value doesn't fit in 200 bits");
return uint200(value);
}
/**
* @dev Returns the downcasted uint192 from uint256, reverting on
* overflow (when the input is greater than largest uint192).
*
* Counterpart to Solidity's `uint192` operator.
*
* Requirements:
*
* - input must fit into 192 bits
*
* _Available since v4.7._
*/
function toUint192(uint256 value) internal pure returns (uint192) {
require(value <= type(uint192).max, "SafeCast: value doesn't fit in 192 bits");
return uint192(value);
}
/**
* @dev Returns the downcasted uint184 from uint256, reverting on
* overflow (when the input is greater than largest uint184).
*
* Counterpart to Solidity's `uint184` operator.
*
* Requirements:
*
* - input must fit into 184 bits
*
* _Available since v4.7._
*/
function toUint184(uint256 value) internal pure returns (uint184) {
require(value <= type(uint184).max, "SafeCast: value doesn't fit in 184 bits");
return uint184(value);
}
/**
* @dev Returns the downcasted uint176 from uint256, reverting on
* overflow (when the input is greater than largest uint176).
*
* Counterpart to Solidity's `uint176` operator.
*
* Requirements:
*
* - input must fit into 176 bits
*
* _Available since v4.7._
*/
function toUint176(uint256 value) internal pure returns (uint176) {
require(value <= type(uint176).max, "SafeCast: value doesn't fit in 176 bits");
return uint176(value);
}
/**
* @dev Returns the downcasted uint168 from uint256, reverting on
* overflow (when the input is greater than largest uint168).
*
* Counterpart to Solidity's `uint168` operator.
*
* Requirements:
*
* - input must fit into 168 bits
*
* _Available since v4.7._
*/
function toUint168(uint256 value) internal pure returns (uint168) {
require(value <= type(uint168).max, "SafeCast: value doesn't fit in 168 bits");
return uint168(value);
}
/**
* @dev Returns the downcasted uint160 from uint256, reverting on
* overflow (when the input is greater than largest uint160).
*
* Counterpart to Solidity's `uint160` operator.
*
* Requirements:
*
* - input must fit into 160 bits
*
* _Available since v4.7._
*/
function toUint160(uint256 value) internal pure returns (uint160) {
require(value <= type(uint160).max, "SafeCast: value doesn't fit in 160 bits");
return uint160(value);
}
/**
* @dev Returns the downcasted uint152 from uint256, reverting on
* overflow (when the input is greater than largest uint152).
*
* Counterpart to Solidity's `uint152` operator.
*
* Requirements:
*
* - input must fit into 152 bits
*
* _Available since v4.7._
*/
function toUint152(uint256 value) internal pure returns (uint152) {
require(value <= type(uint152).max, "SafeCast: value doesn't fit in 152 bits");
return uint152(value);
}
/**
* @dev Returns the downcasted uint144 from uint256, reverting on
* overflow (when the input is greater than largest uint144).
*
* Counterpart to Solidity's `uint144` operator.
*
* Requirements:
*
* - input must fit into 144 bits
*
* _Available since v4.7._
*/
function toUint144(uint256 value) internal pure returns (uint144) {
require(value <= type(uint144).max, "SafeCast: value doesn't fit in 144 bits");
return uint144(value);
}
/**
* @dev Returns the downcasted uint136 from uint256, reverting on
* overflow (when the input is greater than largest uint136).
*
* Counterpart to Solidity's `uint136` operator.
*
* Requirements:
*
* - input must fit into 136 bits
*
* _Available since v4.7._
*/
function toUint136(uint256 value) internal pure returns (uint136) {
require(value <= type(uint136).max, "SafeCast: value doesn't fit in 136 bits");
return uint136(value);
}
/**
* @dev Returns the downcasted uint128 from uint256, reverting on
* overflow (when the input is greater than largest uint128).
*
* Counterpart to Solidity's `uint128` operator.
*
* Requirements:
*
* - input must fit into 128 bits
*
* _Available since v2.5._
*/
function toUint128(uint256 value) internal pure returns (uint128) {
require(value <= type(uint128).max, "SafeCast: value doesn't fit in 128 bits");
return uint128(value);
}
/**
* @dev Returns the downcasted uint120 from uint256, reverting on
* overflow (when the input is greater than largest uint120).
*
* Counterpart to Solidity's `uint120` operator.
*
* Requirements:
*
* - input must fit into 120 bits
*
* _Available since v4.7._
*/
function toUint120(uint256 value) internal pure returns (uint120) {
require(value <= type(uint120).max, "SafeCast: value doesn't fit in 120 bits");
return uint120(value);
}
/**
* @dev Returns the downcasted uint112 from uint256, reverting on
* overflow (when the input is greater than largest uint112).
*
* Counterpart to Solidity's `uint112` operator.
*
* Requirements:
*
* - input must fit into 112 bits
*
* _Available since v4.7._
*/
function toUint112(uint256 value) internal pure returns (uint112) {
require(value <= type(uint112).max, "SafeCast: value doesn't fit in 112 bits");
return uint112(value);
}
/**
* @dev Returns the downcasted uint104 from uint256, reverting on
* overflow (when the input is greater than largest uint104).
*
* Counterpart to Solidity's `uint104` operator.
*
* Requirements:
*
* - input must fit into 104 bits
*
* _Available since v4.7._
*/
function toUint104(uint256 value) internal pure returns (uint104) {
require(value <= type(uint104).max, "SafeCast: value doesn't fit in 104 bits");
return uint104(value);
}
/**
* @dev Returns the downcasted uint96 from uint256, reverting on
* overflow (when the input is greater than largest uint96).
*
* Counterpart to Solidity's `uint96` operator.
*
* Requirements:
*
* - input must fit into 96 bits
*
* _Available since v4.2._
*/
function toUint96(uint256 value) internal pure returns (uint96) {
require(value <= type(uint96).max, "SafeCast: value doesn't fit in 96 bits");
return uint96(value);
}
/**
* @dev Returns the downcasted uint88 from uint256, reverting on
* overflow (when the input is greater than largest uint88).
*
* Counterpart to Solidity's `uint88` operator.
*
* Requirements:
*
* - input must fit into 88 bits
*
* _Available since v4.7._
*/
function toUint88(uint256 value) internal pure returns (uint88) {
require(value <= type(uint88).max, "SafeCast: value doesn't fit in 88 bits");
return uint88(value);
}
/**
* @dev Returns the downcasted uint80 from uint256, reverting on
* overflow (when the input is greater than largest uint80).
*
* Counterpart to Solidity's `uint80` operator.
*
* Requirements:
*
* - input must fit into 80 bits
*
* _Available since v4.7._
*/
function toUint80(uint256 value) internal pure returns (uint80) {
require(value <= type(uint80).max, "SafeCast: value doesn't fit in 80 bits");
return uint80(value);
}
/**
* @dev Returns the downcasted uint72 from uint256, reverting on
* overflow (when the input is greater than largest uint72).
*
* Counterpart to Solidity's `uint72` operator.
*
* Requirements:
*
* - input must fit into 72 bits
*
* _Available since v4.7._
*/
function toUint72(uint256 value) internal pure returns (uint72) {
require(value <= type(uint72).max, "SafeCast: value doesn't fit in 72 bits");
return uint72(value);
}
/**
* @dev Returns the downcasted uint64 from uint256, reverting on
* overflow (when the input is greater than largest uint64).
*
* Counterpart to Solidity's `uint64` operator.
*
* Requirements:
*
* - input must fit into 64 bits
*
* _Available since v2.5._
*/
function toUint64(uint256 value) internal pure returns (uint64) {
require(value <= type(uint64).max, "SafeCast: value doesn't fit in 64 bits");
return uint64(value);
}
/**
* @dev Returns the downcasted uint56 from uint256, reverting on
* overflow (when the input is greater than largest uint56).
*
* Counterpart to Solidity's `uint56` operator.
*
* Requirements:
*
* - input must fit into 56 bits
*
* _Available since v4.7._
*/
function toUint56(uint256 value) internal pure returns (uint56) {
require(value <= type(uint56).max, "SafeCast: value doesn't fit in 56 bits");
return uint56(value);
}
/**
* @dev Returns the downcasted uint48 from uint256, reverting on
* overflow (when the input is greater than largest uint48).
*
* Counterpart to Solidity's `uint48` operator.
*
* Requirements:
*
* - input must fit into 48 bits
*
* _Available since v4.7._
*/
function toUint48(uint256 value) internal pure returns (uint48) {
require(value <= type(uint48).max, "SafeCast: value doesn't fit in 48 bits");
return uint48(value);
}
/**
* @dev Returns the downcasted uint40 from uint256, reverting on
* overflow (when the input is greater than largest uint40).
*
* Counterpart to Solidity's `uint40` operator.
*
* Requirements:
*
* - input must fit into 40 bits
*
* _Available since v4.7._
*/
function toUint40(uint256 value) internal pure returns (uint40) {
require(value <= type(uint40).max, "SafeCast: value doesn't fit in 40 bits");
return uint40(value);
}
/**
* @dev Returns the downcasted uint32 from uint256, reverting on
* overflow (when the input is greater than largest uint32).
*
* Counterpart to Solidity's `uint32` operator.
*
* Requirements:
*
* - input must fit into 32 bits
*
* _Available since v2.5._
*/
function toUint32(uint256 value) internal pure returns (uint32) {
require(value <= type(uint32).max, "SafeCast: value doesn't fit in 32 bits");
return uint32(value);
}
/**
* @dev Returns the downcasted uint24 from uint256, reverting on
* overflow (when the input is greater than largest uint24).
*
* Counterpart to Solidity's `uint24` operator.
*
* Requirements:
*
* - input must fit into 24 bits
*
* _Available since v4.7._
*/
function toUint24(uint256 value) internal pure returns (uint24) {
require(value <= type(uint24).max, "SafeCast: value doesn't fit in 24 bits");
return uint24(value);
}
/**
* @dev Returns the downcasted uint16 from uint256, reverting on
* overflow (when the input is greater than largest uint16).
*
* Counterpart to Solidity's `uint16` operator.
*
* Requirements:
*
* - input must fit into 16 bits
*
* _Available since v2.5._
*/
function toUint16(uint256 value) internal pure returns (uint16) {
require(value <= type(uint16).max, "SafeCast: value doesn't fit in 16 bits");
return uint16(value);
}
/**
* @dev Returns the downcasted uint8 from uint256, reverting on
* overflow (when the input is greater than largest uint8).
*
* Counterpart to Solidity's `uint8` operator.
*
* Requirements:
*
* - input must fit into 8 bits
*
* _Available since v2.5._
*/
function toUint8(uint256 value) internal pure returns (uint8) {
require(value <= type(uint8).max, "SafeCast: value doesn't fit in 8 bits");
return uint8(value);
}
/**
* @dev Converts a signed int256 into an unsigned uint256.
*
* Requirements:
*
* - input must be greater than or equal to 0.
*
* _Available since v3.0._
*/
function toUint256(int256 value) internal pure returns (uint256) {
Submitted on: 2025-11-07 20:50:11
Comments
Log in to comment.
No comments yet.