Update contracts to use 256 bit math

This commit is contained in:
Amir Bandeali
2019-08-27 22:31:40 -07:00
parent 3a096ff0b4
commit e7c4d2171f
12 changed files with 54 additions and 61 deletions

View File

@@ -50,7 +50,6 @@ contract Staking is
MixinExchangeFees,
MixinDelegatedStake
{
// this contract can receive ETH
// solhint-disable no-empty-blocks
function ()

View File

@@ -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

View File

@@ -54,7 +54,6 @@ contract MixinExchangeFees is
MixinTimeLockedStake,
MixinStakeBalances
{
using LibSafeMath for uint256;
/// @dev Pays a protocol fee in ETH.

View File

@@ -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)) {

View File

@@ -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.

View File

@@ -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

View File

@@ -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.

View File

@@ -37,7 +37,6 @@ contract MixinStakeBalances is
MixinScheduler,
MixinTimeLockedStake
{
using LibSafeMath for uint256;
/// @dev Returns the total activated stake across all owners.

View File

@@ -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;

View File

@@ -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.

View File

@@ -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(

View File

@@ -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();
}
}