Update contracts to use 256 bit math
This commit is contained in:
@@ -50,7 +50,6 @@ contract Staking is
|
||||
MixinExchangeFees,
|
||||
MixinDelegatedStake
|
||||
{
|
||||
|
||||
// this contract can receive ETH
|
||||
// solhint-disable no-empty-blocks
|
||||
function ()
|
||||
|
@@ -33,8 +33,10 @@ contract StakingProxy is
|
||||
/// @param _stakingContract Staking contract to delegate calls to.
|
||||
constructor(address _stakingContract)
|
||||
public
|
||||
MixinStorage(_stakingContract)
|
||||
{}
|
||||
MixinStorage()
|
||||
{
|
||||
stakingContract = _stakingContract;
|
||||
}
|
||||
|
||||
/// @dev Delegates calls to the staking contract, if it is set.
|
||||
// solhint-disable no-complex-fallback
|
||||
|
@@ -54,7 +54,6 @@ contract MixinExchangeFees is
|
||||
MixinTimeLockedStake,
|
||||
MixinStakeBalances
|
||||
{
|
||||
|
||||
using LibSafeMath for uint256;
|
||||
|
||||
/// @dev Pays a protocol fee in ETH.
|
||||
|
@@ -35,7 +35,6 @@ contract MixinExchangeManager is
|
||||
MixinConstants,
|
||||
MixinStorage
|
||||
{
|
||||
|
||||
/// @dev Asserts that the call is coming from a valid exchange.
|
||||
modifier onlyExchange() {
|
||||
if (!isValidExchangeAddress(msg.sender)) {
|
||||
|
@@ -36,9 +36,9 @@ interface IStakingEvents {
|
||||
/// @param startTimeInSeconds The start time of the epoch.
|
||||
/// @param earliestEndTimeInSeconds The earliest this epoch can end.
|
||||
event EpochChanged(
|
||||
uint64 epoch,
|
||||
uint64 startTimeInSeconds,
|
||||
uint64 earliestEndTimeInSeconds
|
||||
uint256 epoch,
|
||||
uint256 startTimeInSeconds,
|
||||
uint256 earliestEndTimeInSeconds
|
||||
);
|
||||
|
||||
/// @dev Emitted by MixinScheduler when the timeLock period is changed.
|
||||
@@ -46,9 +46,9 @@ interface IStakingEvents {
|
||||
/// @param startEpoch The epoch this period started.
|
||||
/// @param endEpoch The epoch this period ends.
|
||||
event TimeLockPeriodChanged(
|
||||
uint64 timeLockPeriod,
|
||||
uint64 startEpoch,
|
||||
uint64 endEpoch
|
||||
uint256 timeLockPeriod,
|
||||
uint256 startEpoch,
|
||||
uint256 endEpoch
|
||||
);
|
||||
|
||||
/// @dev Emitted by MixinExchangeFees when rewards are paid out.
|
||||
|
@@ -90,9 +90,9 @@ library LibStakingRichErrors {
|
||||
bytes4 internal constant WITHDRAW_AMOUNT_EXCEEDS_MEMBER_BALANCE_ERROR_SELECTOR =
|
||||
0xfc9c065f;
|
||||
|
||||
// bytes4(keccak256("BlockTimestampTooLowError(uint64,uint64)"))
|
||||
// bytes4(keccak256("BlockTimestampTooLowError(uint256,uint256)"))
|
||||
bytes4 internal constant BLOCK_TIMESTAMP_TOO_LOW_ERROR_SELECTOR =
|
||||
0x887225f7;
|
||||
0xa6bcde47;
|
||||
|
||||
// bytes4(keccak256("OnlyCallableByStakingContractError(address)"))
|
||||
bytes4 internal constant ONLY_CALLABLE_BY_STAKING_CONTRACT_ERROR_SELECTOR =
|
||||
@@ -358,8 +358,8 @@ library LibStakingRichErrors {
|
||||
}
|
||||
|
||||
function BlockTimestampTooLowError(
|
||||
uint64 epochEndTime,
|
||||
uint64 currentBlockTimestamp
|
||||
uint256 epochEndTime,
|
||||
uint256 currentBlockTimestamp
|
||||
)
|
||||
internal
|
||||
pure
|
||||
|
@@ -88,7 +88,6 @@ contract MixinStake is
|
||||
MixinTimeLockedStake,
|
||||
MixinStakeBalances
|
||||
{
|
||||
|
||||
using LibSafeMath for uint256;
|
||||
|
||||
/// @dev Deposit Zrx. This mints stake for the sender that is in the "Deactivated & Withdrawable" state.
|
||||
|
@@ -37,7 +37,6 @@ contract MixinStakeBalances is
|
||||
MixinScheduler,
|
||||
MixinTimeLockedStake
|
||||
{
|
||||
|
||||
using LibSafeMath for uint256;
|
||||
|
||||
/// @dev Returns the total activated stake across all owners.
|
||||
|
@@ -84,9 +84,8 @@ contract MixinTimeLockedStake is
|
||||
MixinStorage,
|
||||
MixinScheduler
|
||||
{
|
||||
|
||||
using LibSafeDowncast for uint256;
|
||||
using LibSafeMath for uint256;
|
||||
using LibSafeDowncast for uint256;
|
||||
|
||||
/// @dev Forces the timeLock data structure to sync to state.
|
||||
/// This is not necessary but may optimize some subsequent calls.
|
||||
@@ -105,8 +104,8 @@ contract MixinTimeLockedStake is
|
||||
internal
|
||||
{
|
||||
(IStructs.TimeLock memory ownerTimeLock,) = _getSynchronizedTimeLock(owner);
|
||||
uint96 downcastAmount = amount.downcastToUint96();
|
||||
ownerTimeLock.total += downcastAmount;
|
||||
uint256 total = uint256(ownerTimeLock.total);
|
||||
ownerTimeLock.total = total.safeAdd(amount).downcastToUint96();
|
||||
timeLockedStakeByOwner[owner] = ownerTimeLock;
|
||||
}
|
||||
|
||||
@@ -132,14 +131,15 @@ contract MixinTimeLockedStake is
|
||||
bool isOutOfSync
|
||||
)
|
||||
{
|
||||
uint64 currentTimeLockPeriod = getCurrentTimeLockPeriod();
|
||||
uint256 currentTimeLockPeriod = getCurrentTimeLockPeriod();
|
||||
ownerTimeLock = timeLockedStakeByOwner[owner];
|
||||
isOutOfSync = false;
|
||||
if (currentTimeLockPeriod == ownerTimeLock.lockedAt.safeAdd(1)) {
|
||||
uint256 ownerLockedAt = uint256(ownerTimeLock.lockedAt);
|
||||
if (currentTimeLockPeriod == ownerLockedAt.safeAdd(1)) {
|
||||
// shift n periods
|
||||
ownerTimeLock.pending = ownerTimeLock.total;
|
||||
isOutOfSync = true;
|
||||
} else if (currentTimeLockPeriod > ownerTimeLock.lockedAt) {
|
||||
} else if (currentTimeLockPeriod > ownerLockedAt) {
|
||||
// TimeLock has expired - zero out
|
||||
ownerTimeLock.lockedAt = 0;
|
||||
ownerTimeLock.total = 0;
|
||||
|
@@ -61,7 +61,6 @@ contract MixinStakingPool is
|
||||
MixinStorage,
|
||||
MixinStakingPoolRewardVault
|
||||
{
|
||||
|
||||
using LibSafeMath for uint256;
|
||||
|
||||
/// @dev Asserts that the sender is the operator of the input pool.
|
||||
|
@@ -21,8 +21,6 @@ pragma solidity ^0.5.9;
|
||||
import "@0x/contracts-utils/contracts/src/LibRichErrors.sol";
|
||||
import "@0x/contracts-utils/contracts/src/LibSafeMath.sol";
|
||||
import "../libs/LibStakingRichErrors.sol";
|
||||
import "../libs/LibSafeMath64.sol";
|
||||
import "../libs/LibSafeDowncast.sol";
|
||||
import "../immutable/MixinConstants.sol";
|
||||
import "../immutable/MixinStorage.sol";
|
||||
import "../interfaces/IStructs.sol";
|
||||
@@ -41,17 +39,14 @@ contract MixinScheduler is
|
||||
MixinConstants,
|
||||
MixinStorage
|
||||
{
|
||||
|
||||
using LibSafeDowncast for uint256;
|
||||
using LibSafeMath for uint256;
|
||||
using LibSafeMath64 for uint64;
|
||||
|
||||
/// @dev Returns the current epoch.
|
||||
/// @return Epoch.
|
||||
function getCurrentEpoch()
|
||||
public
|
||||
view
|
||||
returns (uint64)
|
||||
returns (uint256)
|
||||
{
|
||||
return currentEpoch;
|
||||
}
|
||||
@@ -62,7 +57,7 @@ contract MixinScheduler is
|
||||
function getEpochDurationInSeconds()
|
||||
public
|
||||
pure
|
||||
returns (uint64)
|
||||
returns (uint256)
|
||||
{
|
||||
return EPOCH_DURATION_IN_SECONDS;
|
||||
}
|
||||
@@ -73,7 +68,7 @@ contract MixinScheduler is
|
||||
function getCurrentEpochStartTimeInSeconds()
|
||||
public
|
||||
view
|
||||
returns (uint64)
|
||||
returns (uint256)
|
||||
{
|
||||
return currentEpochStartTimeInSeconds;
|
||||
}
|
||||
@@ -85,7 +80,7 @@ contract MixinScheduler is
|
||||
function getCurrentEpochEarliestEndTimeInSeconds()
|
||||
public
|
||||
view
|
||||
returns (uint64)
|
||||
returns (uint256)
|
||||
{
|
||||
return getCurrentEpochStartTimeInSeconds().safeAdd(getEpochDurationInSeconds());
|
||||
}
|
||||
@@ -95,7 +90,7 @@ contract MixinScheduler is
|
||||
function getCurrentTimeLockPeriod()
|
||||
public
|
||||
view
|
||||
returns (uint64)
|
||||
returns (uint256)
|
||||
{
|
||||
return currentTimeLockPeriod;
|
||||
}
|
||||
@@ -106,7 +101,7 @@ contract MixinScheduler is
|
||||
function getTimeLockDurationInEpochs()
|
||||
public
|
||||
pure
|
||||
returns (uint64)
|
||||
returns (uint256)
|
||||
{
|
||||
return TIMELOCK_DURATION_IN_EPOCHS;
|
||||
}
|
||||
@@ -117,7 +112,7 @@ contract MixinScheduler is
|
||||
function getCurrentTimeLockPeriodStartEpoch()
|
||||
public
|
||||
view
|
||||
returns (uint64)
|
||||
returns (uint256)
|
||||
{
|
||||
return currentTimeLockPeriodStartEpoch;
|
||||
}
|
||||
@@ -128,7 +123,7 @@ contract MixinScheduler is
|
||||
function getCurrentTimeLockPeriodEndEpoch()
|
||||
public
|
||||
view
|
||||
returns (uint64)
|
||||
returns (uint256)
|
||||
{
|
||||
return getCurrentTimeLockPeriodStartEpoch().safeAdd(getTimeLockDurationInEpochs());
|
||||
}
|
||||
@@ -141,10 +136,10 @@ contract MixinScheduler is
|
||||
{
|
||||
// get current timestamp
|
||||
// solhint-disable-next-line not-rely-on-time
|
||||
uint64 currentBlockTimestamp = block.timestamp.downcastToUint64();
|
||||
uint256 currentBlockTimestamp = block.timestamp;
|
||||
|
||||
// validate that we can increment the current epoch
|
||||
uint64 epochEndTime = getCurrentEpochEarliestEndTimeInSeconds();
|
||||
uint256 epochEndTime = getCurrentEpochEarliestEndTimeInSeconds();
|
||||
if (epochEndTime > currentBlockTimestamp) {
|
||||
LibRichErrors.rrevert(LibStakingRichErrors.BlockTimestampTooLowError(
|
||||
epochEndTime,
|
||||
@@ -153,10 +148,10 @@ contract MixinScheduler is
|
||||
}
|
||||
|
||||
// incremment epoch
|
||||
uint64 nextEpoch = currentEpoch.safeAdd(1);
|
||||
uint256 nextEpoch = currentEpoch.safeAdd(1);
|
||||
currentEpoch = nextEpoch;
|
||||
currentEpochStartTimeInSeconds = currentBlockTimestamp;
|
||||
uint64 earliestEndTimeInSeconds = currentEpochStartTimeInSeconds.safeAdd(getEpochDurationInSeconds());
|
||||
uint256 earliestEndTimeInSeconds = currentEpochStartTimeInSeconds.safeAdd(getEpochDurationInSeconds());
|
||||
|
||||
// notify of epoch change
|
||||
emit EpochChanged(
|
||||
@@ -169,7 +164,7 @@ contract MixinScheduler is
|
||||
if (getCurrentTimeLockPeriodEndEpoch() <= nextEpoch) {
|
||||
currentTimeLockPeriod = currentTimeLockPeriod.safeAdd(1);
|
||||
currentTimeLockPeriodStartEpoch = currentEpoch;
|
||||
uint64 endEpoch = currentEpoch.safeAdd(getTimeLockDurationInEpochs());
|
||||
uint256 endEpoch = currentEpoch.safeAdd(getTimeLockDurationInEpochs());
|
||||
|
||||
// notify
|
||||
emit TimeLockPeriodChanged(
|
||||
|
@@ -18,11 +18,11 @@
|
||||
|
||||
pragma solidity ^0.5.9;
|
||||
|
||||
import "@0x/contracts-exchange-libs/contracts/src/LibMath.sol";
|
||||
import "@0x/contracts-utils/contracts/src/LibRichErrors.sol";
|
||||
import "@0x/contracts-utils/contracts/src/LibSafeMath.sol";
|
||||
import "../libs/LibSafeDowncast.sol";
|
||||
import "../libs/LibSafeMath96.sol";
|
||||
import "../libs/LibStakingRichErrors.sol";
|
||||
import "../libs/LibSafeDowncast.sol";
|
||||
import "./MixinVaultCore.sol";
|
||||
import "../interfaces/IStakingPoolRewardVault.sol";
|
||||
import "../immutable/MixinConstants.sol";
|
||||
@@ -44,10 +44,8 @@ contract StakingPoolRewardVault is
|
||||
MixinConstants,
|
||||
MixinVaultCore
|
||||
{
|
||||
|
||||
using LibSafeDowncast for uint256;
|
||||
using LibSafeMath for uint256;
|
||||
using LibSafeMath96 for uint96;
|
||||
using LibSafeDowncast for uint256;
|
||||
|
||||
// mapping from Pool to Reward Balance in ETH
|
||||
mapping (bytes32 => Balance) internal balanceByPoolId;
|
||||
@@ -109,7 +107,8 @@ contract StakingPoolRewardVault is
|
||||
onlyStakingContract
|
||||
{
|
||||
// sanity check - sufficient balance?
|
||||
if (amount > balanceByPoolId[poolId].operatorBalance) {
|
||||
uint256 operatorBalance = uint256(balanceByPoolId[poolId].operatorBalance);
|
||||
if (amount > operatorBalance) {
|
||||
LibRichErrors.rrevert(LibStakingRichErrors.AmountExceedsBalanceOfPoolError(
|
||||
amount,
|
||||
balanceByPoolId[poolId].operatorBalance
|
||||
@@ -117,7 +116,7 @@ contract StakingPoolRewardVault is
|
||||
}
|
||||
|
||||
// update balance and transfer `amount` in ETH to staking contract
|
||||
balanceByPoolId[poolId].operatorBalance -= amount.downcastToUint96();
|
||||
balanceByPoolId[poolId].operatorBalance = operatorBalance.safeSub(amount).downcastToUint96();
|
||||
stakingContractAddress.transfer(amount);
|
||||
|
||||
// notify
|
||||
@@ -134,7 +133,8 @@ contract StakingPoolRewardVault is
|
||||
onlyStakingContract
|
||||
{
|
||||
// sanity check - sufficient balance?
|
||||
if (amount > balanceByPoolId[poolId].membersBalance) {
|
||||
uint256 membersBalance = uint256(balanceByPoolId[poolId].membersBalance);
|
||||
if (amount > membersBalance) {
|
||||
LibRichErrors.rrevert(LibStakingRichErrors.AmountExceedsBalanceOfPoolError(
|
||||
amount,
|
||||
balanceByPoolId[poolId].membersBalance
|
||||
@@ -142,7 +142,7 @@ contract StakingPoolRewardVault is
|
||||
}
|
||||
|
||||
// update balance and transfer `amount` in ETH to staking contract
|
||||
balanceByPoolId[poolId].membersBalance -= amount.downcastToUint96();
|
||||
balanceByPoolId[poolId].membersBalance = membersBalance.safeSub(amount).downcastToUint96();
|
||||
stakingContractAddress.transfer(amount);
|
||||
|
||||
// notify
|
||||
@@ -221,20 +221,22 @@ contract StakingPoolRewardVault is
|
||||
/// @dev Increments a balance struct, splitting the input amount between the
|
||||
/// pool operator and members of the pool based on the pool operator's share.
|
||||
/// @param balance Balance struct to increment.
|
||||
/// @param amount256Bit Amount to add to balance.
|
||||
function _incrementBalanceStruct(Balance memory balance, uint256 amount256Bit)
|
||||
/// @param amount Amount to add to balance.
|
||||
function _incrementBalanceStruct(Balance memory balance, uint256 amount)
|
||||
private
|
||||
pure
|
||||
{
|
||||
// balances are stored as uint96; safely downscale.
|
||||
uint96 amount = amount256Bit.downcastToUint96();
|
||||
|
||||
// compute portions. One of the two must round down: the operator always receives the leftover from rounding.
|
||||
uint96 operatorPortion = amount._computePercentageCeil(balance.operatorShare);
|
||||
uint96 poolPortion = amount.safeSub(operatorPortion);
|
||||
uint256 operatorPortion = LibMath.getPartialAmountCeil(
|
||||
uint256(balance.operatorShare), // Operator share out of 100
|
||||
100,
|
||||
amount
|
||||
);
|
||||
|
||||
uint256 poolPortion = amount.safeSub(operatorPortion);
|
||||
|
||||
// update balances
|
||||
balance.operatorBalance = balance.operatorBalance.safeAdd(operatorPortion);
|
||||
balance.membersBalance = balance.membersBalance.safeAdd(poolPortion);
|
||||
balance.operatorBalance = uint256(balance.operatorBalance).safeAdd(operatorPortion).downcastToUint96();
|
||||
balance.membersBalance = uint256(balance.membersBalance).safeAdd(poolPortion).downcastToUint96();
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user