Include Checkpointing library from Aragon's Staking app

pull/1917/head
David Núñez 2020-04-18 01:54:54 +02:00
parent eafb57cf17
commit dd14b55804
4 changed files with 126 additions and 2 deletions

View File

@ -41,6 +41,7 @@ class SolidityCompiler:
__compiled_contracts_dir = 'contracts'
__zeppelin_library_dir = 'zeppelin'
__aragon_library_dir = 'aragon'
optimization_runs = 200
@ -154,9 +155,11 @@ class SolidityCompiler:
# Compile with remappings: https://github.com/ethereum/py-solc
zeppelin_dir = os.path.join(root_source_dir, self.__zeppelin_library_dir)
aragon_dir = os.path.join(root_source_dir, self.__aragon_library_dir)
remappings = ("contracts={}".format(contracts_dir),
"zeppelin={}".format(zeppelin_dir),
"aragon={}".format(aragon_dir),
)
self.log.info("Compiling with import remappings {}".format(", ".join(remappings)))

View File

@ -0,0 +1,119 @@
pragma solidity ^0.4.24;
library Checkpointing {
uint256 private constant MAX_UINT192 = uint256(uint192(-1));
uint256 private constant MAX_UINT64 = uint256(uint64(-1));
string private constant ERROR_PAST_CHECKPOINT = "CHECKPOINT_PAST_CHECKPOINT";
string private constant ERROR_TIME_TOO_BIG = "CHECKPOINT_TIME_TOO_BIG";
string private constant ERROR_VALUE_TOO_BIG = "CHECKPOINT_VALUE_TOO_BIG";
struct Checkpoint {
uint64 time;
uint192 value;
}
struct History {
Checkpoint[] history;
}
function add(History storage self, uint256 time, uint256 value) internal {
require(time <= MAX_UINT64, ERROR_TIME_TOO_BIG);
require(value <= MAX_UINT192, ERROR_VALUE_TOO_BIG);
add192(self, uint64(time), uint192(value));
}
function add64(History storage self, uint64 time, uint256 value) internal {
require(value <= MAX_UINT192, ERROR_VALUE_TOO_BIG);
add192(self, time, uint192(value));
}
function get(History storage self, uint256 time) internal view returns (uint256) {
require(time <= MAX_UINT64, ERROR_TIME_TOO_BIG);
return uint256(get192(self, uint64(time)));
}
function get64(History storage self, uint64 time) internal view returns (uint256) {
return uint256(get192(self, time));
}
function lastUpdated(History storage self) internal view returns (uint256) {
uint256 length = self.history.length;
if (length > 0) {
return uint256(self.history[length - 1].time);
}
return 0;
}
function getLatestValue(History storage self) internal view returns (uint256) {
uint256 length = self.history.length;
if (length > 0) {
return uint256(self.history[length - 1].value);
}
return 0;
}
function add192(History storage self, uint64 time, uint192 value) internal {
uint256 length = self.history.length;
if (length == 0) {
self.history.push(Checkpoint(time, value));
} else {
Checkpoint storage currentCheckpoint = self.history[length - 1];
uint64 currentCheckpointTime = currentCheckpoint.time;
if (time > currentCheckpointTime) {
self.history.push(Checkpoint(time, value));
} else if (time == currentCheckpointTime) {
currentCheckpoint.value = value;
} else { // ensure list ordering
revert(ERROR_PAST_CHECKPOINT);
}
}
}
function get192(History storage self, uint64 time) internal view returns (uint192) {
uint256 length = self.history.length;
if (length == 0) {
return 0;
}
uint256 lastIndex = length - 1;
// short-circuit
Checkpoint storage lastCheckpoint = self.history[lastIndex];
if (time >= lastCheckpoint.time) {
return lastCheckpoint.value;
}
if (time < self.history[0].time) {
return 0;
}
uint256 low = 0;
uint256 high = lastIndex;
while (high > low) {
uint256 mid = (high + low + 1) / 2; // average, ceil round
Checkpoint storage checkpoint = self.history[mid];
uint64 midTime = checkpoint.time;
if (time > midTime) {
low = mid;
} else if (time < midTime) {
high = mid - 1;
} else { // time == midTime
return checkpoint.value;
}
}
return self.history[low].value;
}
}

View File

@ -1,6 +1,6 @@
pragma solidity ^0.6.5;
import "aragon/staking/Checkpointing.sol";
import "contracts/Issuer.sol";
import "contracts/lib/Bits.sol";
import "zeppelin/math/SafeMath.sol";

View File

@ -118,7 +118,9 @@ PACKAGE_DATA = ['network/templates/basic_status.j2',
'blockchain/eth/sol/source/zeppelin/math/*',
'blockchain/eth/sol/source/zeppelin/utils/*',
'blockchain/eth/sol/source/zeppelin/ownership/*',
'blockchain/eth/sol/source/zeppelin/token/ERC20/*']
'blockchain/eth/sol/source/zeppelin/token/ERC20/*',
'blockchain/eth/sol/source/aragon/staking/*'
]
setup(name=ABOUT['__title__'],
url=ABOUT['__url__'],