编译器
0.8.19+commit.7dd6d404
文件 1 的 13:AccessControl.sol
pragma solidity ^0.8.0;
import "./IAccessControl.sol";
import "../utils/Context.sol";
import "../utils/Strings.sol";
import "../utils/introspection/ERC165.sol";
abstract contract AccessControl is Context, IAccessControl, ERC165 {
struct RoleData {
mapping(address => bool) members;
bytes32 adminRole;
}
mapping(bytes32 => RoleData) private _roles;
bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;
modifier onlyRole(bytes32 role) {
_checkRole(role);
_;
}
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);
}
function hasRole(bytes32 role, address account) public view virtual override returns (bool) {
return _roles[role].members[account];
}
function _checkRole(bytes32 role) internal view virtual {
_checkRole(role, _msgSender());
}
function _checkRole(bytes32 role, address account) internal view virtual {
if (!hasRole(role, account)) {
revert(
string(
abi.encodePacked(
"AccessControl: account ",
Strings.toHexString(account),
" is missing role ",
Strings.toHexString(uint256(role), 32)
)
)
);
}
}
function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {
return _roles[role].adminRole;
}
function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
_grantRole(role, account);
}
function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
_revokeRole(role, account);
}
function renounceRole(bytes32 role, address account) public virtual override {
require(account == _msgSender(), "AccessControl: can only renounce roles for self");
_revokeRole(role, account);
}
function _setupRole(bytes32 role, address account) internal virtual {
_grantRole(role, account);
}
function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
bytes32 previousAdminRole = getRoleAdmin(role);
_roles[role].adminRole = adminRole;
emit RoleAdminChanged(role, previousAdminRole, adminRole);
}
function _grantRole(bytes32 role, address account) internal virtual {
if (!hasRole(role, account)) {
_roles[role].members[account] = true;
emit RoleGranted(role, account, _msgSender());
}
}
function _revokeRole(bytes32 role, address account) internal virtual {
if (hasRole(role, account)) {
_roles[role].members[account] = false;
emit RoleRevoked(role, account, _msgSender());
}
}
}
文件 2 的 13:ChunkProof.sol
pragma solidity ^0.8.19;
library BMTChunk {
uint256 public constant MAX_CHUNK_PAYLOAD_SIZE = 4096;
uint256 public constant SEGMENT_SIZE = 32;
function reverseUint64(uint64 _b) public pure returns (uint64) {
uint256 v = _b;
v =
((v >> 8) & 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |
((v & 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) << 8);
v =
((v >> 16) & 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |
((v & 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) << 16);
v =
((v >> 32) & 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |
((v & 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) << 32);
return uint64(v);
}
function rootHashFromInclusionProof(
bytes32[] memory _proofSegments,
bytes32 _proveSegment,
uint256 _proveSegmentIndex
) internal pure returns (bytes32 _calculatedHash) {
_calculatedHash = _proveSegment;
for (uint256 i = 0; i < _proofSegments.length; i++) {
bool mergeFromRight = _proveSegmentIndex % 2 == 0;
_calculatedHash = mergeSegment(_calculatedHash, _proofSegments[i], mergeFromRight);
_proveSegmentIndex >>= 1;
}
return _calculatedHash;
}
function chunkAddressFromInclusionProof(
bytes32[] memory _proofSegments,
bytes32 _proveSegment,
uint256 _proveSegmentIndex,
uint64 _chunkSpan
) internal pure returns (bytes32) {
bytes32 rootHash = rootHashFromInclusionProof(_proofSegments, _proveSegment, _proveSegmentIndex);
return keccak256(abi.encodePacked(reverseUint64(_chunkSpan), rootHash));
}
function mergeSegment(
bytes32 _calculatedHash,
bytes32 _proofSegment,
bool mergeFromRight
) internal pure returns (bytes32 res) {
if (mergeFromRight) {
res = keccak256(abi.encode(_calculatedHash, _proofSegment));
} else {
res = keccak256(abi.encode(_proofSegment, _calculatedHash));
}
return res;
}
}
文件 3 的 13:Context.sol
pragma solidity ^0.8.0;
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
文件 4 的 13:ERC165.sol
pragma solidity ^0.8.0;
import "./IERC165.sol";
abstract contract ERC165 is IERC165 {
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}
文件 5 的 13:IAccessControl.sol
pragma solidity ^0.8.0;
interface IAccessControl {
event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);
event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);
event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);
function hasRole(bytes32 role, address account) external view returns (bool);
function getRoleAdmin(bytes32 role) external view returns (bytes32);
function grantRole(bytes32 role, address account) external;
function revokeRole(bytes32 role, address account) external;
function renounceRole(bytes32 role, address account) external;
}
文件 6 的 13:IERC165.sol
pragma solidity ^0.8.0;
interface IERC165 {
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
文件 7 的 13:IPostageStamp.sol
pragma solidity ^0.8.19;
interface IPostageStamp {
function withdraw(address beneficiary) external;
function setPrice(uint256 _price) external;
function validChunkCount() external view returns (uint256);
function batchOwner(bytes32 _batchId) external view returns (address);
function batchDepth(bytes32 _batchId) external view returns (uint8);
function batchBucketDepth(bytes32 _batchId) external view returns (uint8);
function remainingBalance(bytes32 _batchId) external view returns (uint256);
function minimumInitialBalancePerChunk() external view returns (uint256);
function batches(
bytes32
)
external
view
returns (
address owner,
uint8 depth,
uint8 bucketDepth,
bool immutableFlag,
uint256 normalisedBalance,
uint256 lastUpdatedBlockNumber
);
}
文件 8 的 13:Math.sol
pragma solidity ^0.8.0;
library Math {
enum Rounding {
Down,
Up,
Zero
}
function max(uint256 a, uint256 b) internal pure returns (uint256) {
return a > b ? a : b;
}
function min(uint256 a, uint256 b) internal pure returns (uint256) {
return a < b ? a : b;
}
function average(uint256 a, uint256 b) internal pure returns (uint256) {
return (a & b) + (a ^ b) / 2;
}
function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
return a == 0 ? 0 : (a - 1) / b + 1;
}
function mulDiv(
uint256 x,
uint256 y,
uint256 denominator
) internal pure returns (uint256 result) {
unchecked {
uint256 prod0;
uint256 prod1;
assembly {
let mm := mulmod(x, y, not(0))
prod0 := mul(x, y)
prod1 := sub(sub(mm, prod0), lt(mm, prod0))
}
if (prod1 == 0) {
return prod0 / denominator;
}
require(denominator > prod1);
uint256 remainder;
assembly {
remainder := mulmod(x, y, denominator)
prod1 := sub(prod1, gt(remainder, prod0))
prod0 := sub(prod0, remainder)
}
uint256 twos = denominator & (~denominator + 1);
assembly {
denominator := div(denominator, twos)
prod0 := div(prod0, twos)
twos := add(div(sub(0, twos), twos), 1)
}
prod0 |= prod1 * twos;
uint256 inverse = (3 * denominator) ^ 2;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
result = prod0 * inverse;
return result;
}
}
function mulDiv(
uint256 x,
uint256 y,
uint256 denominator,
Rounding rounding
) internal pure returns (uint256) {
uint256 result = mulDiv(x, y, denominator);
if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {
result += 1;
}
return result;
}
function sqrt(uint256 a) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
uint256 result = 1 << (log2(a) >> 1);
unchecked {
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
return min(result, a / result);
}
}
function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = sqrt(a);
return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);
}
}
function log2(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 128;
}
if (value >> 64 > 0) {
value >>= 64;
result += 64;
}
if (value >> 32 > 0) {
value >>= 32;
result += 32;
}
if (value >> 16 > 0) {
value >>= 16;
result += 16;
}
if (value >> 8 > 0) {
value >>= 8;
result += 8;
}
if (value >> 4 > 0) {
value >>= 4;
result += 4;
}
if (value >> 2 > 0) {
value >>= 2;
result += 2;
}
if (value >> 1 > 0) {
result += 1;
}
}
return result;
}
function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log2(value);
return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);
}
}
function log10(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >= 10**64) {
value /= 10**64;
result += 64;
}
if (value >= 10**32) {
value /= 10**32;
result += 32;
}
if (value >= 10**16) {
value /= 10**16;
result += 16;
}
if (value >= 10**8) {
value /= 10**8;
result += 8;
}
if (value >= 10**4) {
value /= 10**4;
result += 4;
}
if (value >= 10**2) {
value /= 10**2;
result += 2;
}
if (value >= 10**1) {
result += 1;
}
}
return result;
}
function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log10(value);
return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0);
}
}
function log256(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 16;
}
if (value >> 64 > 0) {
value >>= 64;
result += 8;
}
if (value >> 32 > 0) {
value >>= 32;
result += 4;
}
if (value >> 16 > 0) {
value >>= 16;
result += 2;
}
if (value >> 8 > 0) {
result += 1;
}
}
return result;
}
function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log256(value);
return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0);
}
}
}
文件 9 的 13:Pausable.sol
pragma solidity ^0.8.0;
import "../utils/Context.sol";
abstract contract Pausable is Context {
event Paused(address account);
event Unpaused(address account);
bool private _paused;
constructor() {
_paused = false;
}
modifier whenNotPaused() {
_requireNotPaused();
_;
}
modifier whenPaused() {
_requirePaused();
_;
}
function paused() public view virtual returns (bool) {
return _paused;
}
function _requireNotPaused() internal view virtual {
require(!paused(), "Pausable: paused");
}
function _requirePaused() internal view virtual {
require(paused(), "Pausable: not paused");
}
function _pause() internal virtual whenNotPaused {
_paused = true;
emit Paused(_msgSender());
}
function _unpause() internal virtual whenPaused {
_paused = false;
emit Unpaused(_msgSender());
}
}
文件 10 的 13:Redistribution.sol
pragma solidity ^0.8.19;
import "@openzeppelin/contracts/access/AccessControl.sol";
import "@openzeppelin/contracts/security/Pausable.sol";
import "./Util/TransformedChunkProof.sol";
import "./Util/ChunkProof.sol";
import "./Util/Signatures.sol";
import "./interface/IPostageStamp.sol";
interface IPriceOracle {
function adjustPrice(uint16 redundancy) external returns (bool);
}
interface IStakeRegistry {
struct Stake {
bytes32 overlay;
uint256 stakeAmount;
uint256 lastUpdatedBlockNumber;
}
function freezeDeposit(address _owner, uint256 _time) external;
function lastUpdatedBlockNumberOfAddress(address _owner) external view returns (uint256);
function overlayOfAddress(address _owner) external view returns (bytes32);
function heightOfAddress(address _owner) external view returns (uint8);
function nodeEffectiveStake(address _owner) external view returns (uint256);
}
contract Redistribution is AccessControl, Pausable {
struct Commit {
bytes32 overlay;
address owner;
bool revealed;
uint8 height;
uint256 stake;
bytes32 obfuscatedHash;
uint256 revealIndex;
}
struct Reveal {
bytes32 overlay;
address owner;
uint8 depth;
uint256 stake;
uint256 stakeDensity;
bytes32 hash;
}
struct ChunkInclusionProof {
bytes32[] proofSegments;
bytes32 proveSegment;
bytes32[] proofSegments2;
bytes32 proveSegment2;
uint64 chunkSpan;
bytes32[] proofSegments3;
PostageProof postageProof;
SOCProof[] socProof;
}
struct SOCProof {
address signer;
bytes signature;
bytes32 identifier;
bytes32 chunkAddr;
}
struct PostageProof {
bytes signature;
bytes32 postageId;
uint64 index;
uint64 timeStamp;
}
IPostageStamp public PostageContract;
IPriceOracle public OracleContract;
IStakeRegistry public Stakes;
Commit[] public currentCommits;
Reveal[] public currentReveals;
bytes32 private currentRevealRoundAnchor;
bytes32 private seed;
uint64 public currentCommitRound;
uint64 public currentRevealRound;
uint64 public currentClaimRound;
uint8 private penaltyMultiplierDisagreement = 1;
uint8 private penaltyMultiplierNonRevealed = 2;
uint8 private penaltyRandomFactor = 100;
uint256 private sampleMaxValue = 1284401000000000000000000000000000000000000000000000000000000000000000000;
Reveal public winner;
uint256 private constant ROUND_LENGTH = 152;
bytes32 private constant MAX_H = 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff;
event WinnerSelected(Reveal winner);
event TruthSelected(bytes32 hash, uint8 depth);
event CountCommits(uint256 _count);
event CountReveals(uint256 _count);
event Committed(uint256 roundNumber, bytes32 overlay, uint8 height);
event ChunkCount(uint256 validChunkCount);
event CurrentRevealAnchor(uint256 roundNumber, bytes32 anchor);
event PriceAdjustmentSkipped(uint16 redundancyCount);
event WithdrawFailed(address owner);
event Revealed(
uint256 roundNumber,
bytes32 overlay,
uint256 stake,
uint256 stakeDensity,
bytes32 reserveCommitment,
uint8 depth
);
event transformedChunkAddressFromInclusionProof(uint256 indexInRC, bytes32 chunkAddress);
error NotCommitPhase();
error NoCommitsReceived();
error PhaseLastBlock();
error CommitRoundOver();
error CommitRoundNotStarted();
error NotMatchingOwner();
error MustStake2Rounds();
error NotStaked();
error WrongPhase();
error AlreadyCommitted();
error NotRevealPhase();
error OutOfDepthReveal(bytes32);
error OutOfDepthClaim(uint8);
error OutOfDepth();
error AlreadyRevealed();
error NoMatchingCommit();
error NotClaimPhase();
error NoReveals();
error FirstRevealDone();
error AlreadyClaimed();
error NotAdmin();
error OnlyPauser();
error SocVerificationFailed(bytes32);
error SocCalcNotMatching(bytes32);
error IndexOutsideSet(bytes32);
error SigRecoveryFailed(bytes32);
error BatchDoesNotExist(bytes32);
error BucketDiffers(bytes32);
error InclusionProofFailed(uint8, bytes32);
error RandomElementCheckFailed();
error LastElementCheckFailed();
error ReserveCheckFailed(bytes32 trALast);
constructor(address staking, address postageContract, address oracleContract) {
Stakes = IStakeRegistry(staking);
PostageContract = IPostageStamp(postageContract);
OracleContract = IPriceOracle(oracleContract);
_setupRole(DEFAULT_ADMIN_ROLE, msg.sender);
}
function commit(bytes32 _obfuscatedHash, uint64 _roundNumber) external whenNotPaused {
uint64 cr = currentRound();
bytes32 _overlay = Stakes.overlayOfAddress(msg.sender);
uint256 _stake = Stakes.nodeEffectiveStake(msg.sender);
uint256 _lastUpdate = Stakes.lastUpdatedBlockNumberOfAddress(msg.sender);
uint8 _height = Stakes.heightOfAddress(msg.sender);
if (!currentPhaseCommit()) {
revert NotCommitPhase();
}
if (block.number % ROUND_LENGTH == (ROUND_LENGTH / 4) - 1) {
revert PhaseLastBlock();
}
if (cr > _roundNumber) {
revert CommitRoundOver();
}
if (cr < _roundNumber) {
revert CommitRoundNotStarted();
}
if (_lastUpdate == 0) {
revert NotStaked();
}
if (_lastUpdate >= block.number - 2 * ROUND_LENGTH) {
revert MustStake2Rounds();
}
if (cr != currentCommitRound) {
delete currentCommits;
currentCommitRound = cr;
}
uint256 commitsArrayLength = currentCommits.length;
for (uint256 i = 0; i < commitsArrayLength; ) {
if (currentCommits[i].overlay == _overlay) {
revert AlreadyCommitted();
}
unchecked {
++i;
}
}
currentCommits.push(
Commit({
overlay: _overlay,
owner: msg.sender,
revealed: false,
height: _height,
stake: _stake,
obfuscatedHash: _obfuscatedHash,
revealIndex: 0
})
);
emit Committed(_roundNumber, _overlay, _height);
}
function reveal(uint8 _depth, bytes32 _hash, bytes32 _revealNonce) external whenNotPaused {
uint64 cr = currentRound();
bytes32 _overlay = Stakes.overlayOfAddress(msg.sender);
if (_depth < currentMinimumDepth()) {
revert OutOfDepth();
}
if (!currentPhaseReveal()) {
revert NotRevealPhase();
}
if (cr != currentCommitRound) {
revert NoCommitsReceived();
}
if (cr != currentRevealRound) {
currentRevealRoundAnchor = currentRoundAnchor();
delete currentReveals;
currentRevealRound = cr;
emit CurrentRevealAnchor(cr, currentRevealRoundAnchor);
updateRandomness();
}
bytes32 obfuscatedHash = wrapCommit(_overlay, _depth, _hash, _revealNonce);
uint256 id = findCommit(_overlay, obfuscatedHash);
Commit memory revealedCommit = currentCommits[id];
uint8 depthResponsibility = _depth - revealedCommit.height;
if (!inProximity(revealedCommit.overlay, currentRevealRoundAnchor, depthResponsibility)) {
revert OutOfDepthReveal(currentRevealRoundAnchor);
}
if (revealedCommit.revealed) {
revert AlreadyRevealed();
}
currentCommits[id].revealed = true;
currentCommits[id].revealIndex = currentReveals.length;
currentReveals.push(
Reveal({
overlay: revealedCommit.overlay,
owner: revealedCommit.owner,
depth: _depth,
stake: revealedCommit.stake,
stakeDensity: revealedCommit.stake * uint256(2 ** depthResponsibility),
hash: _hash
})
);
emit Revealed(
cr,
revealedCommit.overlay,
revealedCommit.stake,
revealedCommit.stake * uint256(2 ** depthResponsibility),
_hash,
_depth
);
}
function claim(
ChunkInclusionProof calldata entryProof1,
ChunkInclusionProof calldata entryProof2,
ChunkInclusionProof calldata entryProofLast
) external whenNotPaused {
winnerSelection();
Reveal memory winnerSelected = winner;
uint256 indexInRC1;
uint256 indexInRC2;
bytes32 _currentRevealRoundAnchor = currentRevealRoundAnchor;
bytes32 _seed = seed;
indexInRC1 = uint256(_seed) % 15;
indexInRC2 = uint256(_seed) % 14;
if (indexInRC2 >= indexInRC1) {
indexInRC2++;
}
if (!inProximity(entryProofLast.proveSegment, _currentRevealRoundAnchor, winnerSelected.depth)) {
revert OutOfDepthClaim(3);
}
inclusionFunction(entryProofLast, 30);
stampFunction(entryProofLast);
socFunction(entryProofLast);
if (!inProximity(entryProof1.proveSegment, _currentRevealRoundAnchor, winnerSelected.depth)) {
revert OutOfDepthClaim(2);
}
inclusionFunction(entryProof1, indexInRC1 * 2);
stampFunction(entryProof1);
socFunction(entryProof1);
if (!inProximity(entryProof2.proveSegment, _currentRevealRoundAnchor, winnerSelected.depth)) {
revert OutOfDepthClaim(1);
}
inclusionFunction(entryProof2, indexInRC2 * 2);
stampFunction(entryProof2);
socFunction(entryProof2);
checkOrder(
indexInRC1,
indexInRC2,
entryProof1.proofSegments[0],
entryProof2.proofSegments[0],
entryProofLast.proofSegments[0]
);
estimateSize(entryProofLast.proofSegments[0]);
(bool success, ) = address(PostageContract).call(
abi.encodeWithSignature("withdraw(address)", winnerSelected.owner)
);
if (!success) {
emit WithdrawFailed(winnerSelected.owner);
}
emit WinnerSelected(winnerSelected);
emit ChunkCount(PostageContract.validChunkCount());
}
function winnerSelection() internal {
uint64 cr = currentRound();
if (!currentPhaseClaim()) {
revert NotClaimPhase();
}
if (cr != currentRevealRound) {
revert NoReveals();
}
if (cr <= currentClaimRound) {
revert AlreadyClaimed();
}
uint256 currentWinnerSelectionSum = 0;
uint256 redundancyCount = 0;
bytes32 randomNumber;
uint256 randomNumberTrunc;
bytes32 truthRevealedHash;
uint8 truthRevealedDepth;
uint256 currentCommitsLength = currentCommits.length;
emit CountCommits(currentCommitsLength);
emit CountReveals(currentReveals.length);
(truthRevealedHash, truthRevealedDepth) = getCurrentTruth();
emit TruthSelected(truthRevealedHash, truthRevealedDepth);
string memory winnerSelectionAnchor = currentWinnerSelectionAnchor();
for (uint256 i = 0; i < currentCommitsLength; ) {
Commit memory currentCommit = currentCommits[i];
uint256 revIndex = currentCommit.revealIndex;
Reveal memory currentReveal = currentReveals[revIndex];
if (
currentCommit.revealed &&
truthRevealedHash == currentReveal.hash &&
truthRevealedDepth == currentReveal.depth
) {
currentWinnerSelectionSum += currentReveal.stakeDensity;
randomNumber = keccak256(abi.encodePacked(winnerSelectionAnchor, redundancyCount));
randomNumberTrunc = uint256(randomNumber & MAX_H);
if (randomNumberTrunc * currentWinnerSelectionSum < currentReveal.stakeDensity * (uint256(MAX_H) + 1)) {
winner = currentReveal;
}
redundancyCount++;
}
if (
currentCommit.revealed &&
(truthRevealedHash != currentReveal.hash || truthRevealedDepth != currentReveal.depth) &&
(block.prevrandao % 100 < penaltyRandomFactor)
) {
Stakes.freezeDeposit(
currentReveal.owner,
penaltyMultiplierDisagreement * ROUND_LENGTH * uint256(2 ** truthRevealedDepth)
);
}
if (!currentCommit.revealed) {
Stakes.freezeDeposit(
currentCommit.owner,
penaltyMultiplierNonRevealed * ROUND_LENGTH * uint256(2 ** truthRevealedDepth)
);
}
unchecked {
++i;
}
}
bool success = OracleContract.adjustPrice(uint16(redundancyCount));
if (!success) {
emit PriceAdjustmentSkipped(uint16(redundancyCount));
}
currentClaimRound = cr;
}
function inclusionFunction(ChunkInclusionProof calldata entryProof, uint256 indexInRC) internal {
uint256 randomChunkSegmentIndex = uint256(seed) % 128;
bytes32 calculatedTransformedAddr = TransformedBMTChunk.transformedChunkAddressFromInclusionProof(
entryProof.proofSegments3,
entryProof.proveSegment2,
randomChunkSegmentIndex,
entryProof.chunkSpan,
currentRevealRoundAnchor
);
emit transformedChunkAddressFromInclusionProof(indexInRC, calculatedTransformedAddr);
if (
winner.hash !=
BMTChunk.chunkAddressFromInclusionProof(
entryProof.proofSegments,
entryProof.proveSegment,
indexInRC,
32 * 32
)
) {
revert InclusionProofFailed(1, calculatedTransformedAddr);
}
if (entryProof.proofSegments2[0] != entryProof.proofSegments3[0]) {
revert InclusionProofFailed(2, calculatedTransformedAddr);
}
bytes32 originalAddress = entryProof.socProof.length > 0
? entryProof.socProof[0].chunkAddr
: entryProof.proveSegment;
if (
originalAddress !=
BMTChunk.chunkAddressFromInclusionProof(
entryProof.proofSegments2,
entryProof.proveSegment2,
randomChunkSegmentIndex,
entryProof.chunkSpan
)
) {
revert InclusionProofFailed(3, calculatedTransformedAddr);
}
if (entryProof.socProof.length > 0) {
calculatedTransformedAddr = keccak256(
abi.encode(
entryProof.proveSegment,
calculatedTransformedAddr
)
);
}
if (entryProof.proofSegments[0] != calculatedTransformedAddr) {
revert InclusionProofFailed(4, calculatedTransformedAddr);
}
}
function setFreezingParams(
uint8 _penaltyMultiplierDisagreement,
uint8 _penaltyMultiplierNonRevealed,
uint8 _penaltyRandomFactor
) external {
if (!hasRole(DEFAULT_ADMIN_ROLE, msg.sender)) {
revert NotAdmin();
}
penaltyMultiplierDisagreement = _penaltyMultiplierDisagreement;
penaltyMultiplierNonRevealed = _penaltyMultiplierNonRevealed;
penaltyRandomFactor = _penaltyRandomFactor;
}
function setSampleMaxValue(uint256 _sampleMaxValue) external {
if (!hasRole(DEFAULT_ADMIN_ROLE, msg.sender)) {
revert NotAdmin();
}
sampleMaxValue = _sampleMaxValue;
}
function updateRandomness() private {
seed = keccak256(abi.encode(seed, block.prevrandao));
}
function pause() public {
if (!hasRole(DEFAULT_ADMIN_ROLE, msg.sender)) {
revert OnlyPauser();
}
_pause();
}
function unPause() public {
if (!hasRole(DEFAULT_ADMIN_ROLE, msg.sender)) {
revert OnlyPauser();
}
_unpause();
}
function currentSeed() public view returns (bytes32) {
uint64 cr = currentRound();
bytes32 currentSeedValue = seed;
if (cr > currentRevealRound + 1) {
uint256 difference = cr - currentRevealRound - 1;
currentSeedValue = keccak256(abi.encodePacked(currentSeedValue, difference));
}
return currentSeedValue;
}
function nextSeed() public view returns (bytes32) {
uint64 cr = currentRound() + 1;
bytes32 currentSeedValue = seed;
if (cr > currentRevealRound + 1) {
uint256 difference = cr - currentRevealRound - 1;
currentSeedValue = keccak256(abi.encodePacked(currentSeedValue, difference));
}
return currentSeedValue;
}
function currentTruthSelectionAnchor() private view returns (string memory) {
if (!currentPhaseClaim()) {
revert NotClaimPhase();
}
uint64 cr = currentRound();
if (cr != currentRevealRound) {
revert NoReveals();
}
return string(abi.encodePacked(seed, "0"));
}
function currentWinnerSelectionAnchor() private view returns (string memory) {
if (!currentPhaseClaim()) {
revert NotClaimPhase();
}
uint64 cr = currentRound();
if (cr != currentRevealRound) {
revert NoReveals();
}
return string(abi.encodePacked(seed, "1"));
}
function currentRoundAnchor() public view returns (bytes32 returnVal) {
if (currentPhaseCommit() || (currentRound() > currentRevealRound && !currentPhaseClaim())) {
return currentSeed();
}
if (currentPhaseClaim()) {
return nextSeed();
}
if (currentPhaseReveal() && currentRound() == currentRevealRound) {
revert FirstRevealDone();
}
}
function inProximity(bytes32 A, bytes32 B, uint8 minimum) public pure returns (bool) {
if (minimum == 0) {
return true;
}
return uint256(A ^ B) < uint256(2 ** (256 - minimum));
}
function currentRound() public view returns (uint64) {
return uint64(block.number / ROUND_LENGTH);
}
function currentPhaseCommit() public view returns (bool) {
if (block.number % ROUND_LENGTH < ROUND_LENGTH / 4) {
return true;
}
return false;
}
function isParticipatingInUpcomingRound(address _owner, uint8 _depth) public view returns (bool) {
uint256 _lastUpdate = Stakes.lastUpdatedBlockNumberOfAddress(_owner);
uint8 _depthResponsibility = _depth - Stakes.heightOfAddress(_owner);
if (currentPhaseReveal()) {
revert WrongPhase();
}
if (_lastUpdate == 0) {
revert NotStaked();
}
if (_lastUpdate >= block.number - 2 * ROUND_LENGTH) {
revert MustStake2Rounds();
}
return inProximity(Stakes.overlayOfAddress(_owner), currentRoundAnchor(), _depthResponsibility);
}
function currentMinimumDepth() public view returns (uint8) {
uint256 difference = currentCommitRound - currentClaimRound;
uint8 skippedRounds = uint8(difference > 254 ? 254 : difference) + 1;
uint8 lastWinnerDepth = winner.depth;
return skippedRounds >= lastWinnerDepth ? 0 : lastWinnerDepth - skippedRounds;
}
function findCommit(bytes32 _overlay, bytes32 _obfuscatedHash) internal view returns (uint256) {
for (uint256 i = 0; i < currentCommits.length; ) {
if (currentCommits[i].overlay == _overlay && _obfuscatedHash == currentCommits[i].obfuscatedHash) {
return i;
}
unchecked {
++i;
}
}
revert NoMatchingCommit();
}
function wrapCommit(
bytes32 _overlay,
uint8 _depth,
bytes32 _hash,
bytes32 revealNonce
) public pure returns (bytes32) {
return keccak256(abi.encodePacked(_overlay, _depth, _hash, revealNonce));
}
function currentPhaseReveal() public view returns (bool) {
uint256 number = block.number % ROUND_LENGTH;
if (number >= ROUND_LENGTH / 4 && number < ROUND_LENGTH / 2) {
return true;
}
return false;
}
function currentRoundReveals() public view returns (Reveal[] memory) {
if (!currentPhaseClaim()) {
revert NotClaimPhase();
}
uint64 cr = currentRound();
if (cr != currentRevealRound) {
revert NoReveals();
}
return currentReveals;
}
function currentPhaseClaim() public view returns (bool) {
if (block.number % ROUND_LENGTH >= ROUND_LENGTH / 2) {
return true;
}
return false;
}
function getCurrentTruth() internal view returns (bytes32 Hash, uint8 Depth) {
uint256 currentSum;
bytes32 randomNumber;
uint256 randomNumberTrunc;
bytes32 truthRevealedHash;
uint8 truthRevealedDepth;
uint256 revIndex;
string memory truthSelectionAnchor = currentTruthSelectionAnchor();
uint256 commitsArrayLength = currentCommits.length;
for (uint256 i = 0; i < commitsArrayLength; ) {
if (currentCommits[i].revealed) {
revIndex = currentCommits[i].revealIndex;
currentSum += currentReveals[revIndex].stakeDensity;
randomNumber = keccak256(abi.encodePacked(truthSelectionAnchor, i));
randomNumberTrunc = uint256(randomNumber & MAX_H);
if (randomNumberTrunc * currentSum < currentReveals[revIndex].stakeDensity * (uint256(MAX_H) + 1)) {
truthRevealedHash = currentReveals[revIndex].hash;
truthRevealedDepth = currentReveals[revIndex].depth;
}
}
unchecked {
++i;
}
}
return (truthRevealedHash, truthRevealedDepth);
}
function isWinner(bytes32 _overlay) public view returns (bool) {
if (!currentPhaseClaim()) {
revert NotClaimPhase();
}
uint64 cr = currentRound();
if (cr != currentRevealRound) {
revert NoReveals();
}
if (cr <= currentClaimRound) {
revert AlreadyClaimed();
}
uint256 currentWinnerSelectionSum;
bytes32 winnerIs;
bytes32 randomNumber;
uint256 randomNumberTrunc;
bytes32 truthRevealedHash;
uint8 truthRevealedDepth;
uint256 revIndex;
string memory winnerSelectionAnchor = currentWinnerSelectionAnchor();
uint256 redundancyCount = 0;
(truthRevealedHash, truthRevealedDepth) = getCurrentTruth();
uint256 commitsArrayLength = currentCommits.length;
for (uint256 i = 0; i < commitsArrayLength; ) {
revIndex = currentCommits[i].revealIndex;
if (
currentCommits[i].revealed &&
truthRevealedHash == currentReveals[revIndex].hash &&
truthRevealedDepth == currentReveals[revIndex].depth
) {
currentWinnerSelectionSum += currentReveals[revIndex].stakeDensity;
randomNumber = keccak256(abi.encodePacked(winnerSelectionAnchor, redundancyCount));
randomNumberTrunc = uint256(randomNumber & MAX_H);
if (
randomNumberTrunc * currentWinnerSelectionSum <
currentReveals[revIndex].stakeDensity * (uint256(MAX_H) + 1)
) {
winnerIs = currentReveals[revIndex].overlay;
}
redundancyCount++;
}
unchecked {
++i;
}
}
return (winnerIs == _overlay);
}
function socFunction(ChunkInclusionProof calldata entryProof) internal pure {
if (entryProof.socProof.length == 0) return;
if (
!Signatures.socVerify(
entryProof.socProof[0].signer,
entryProof.socProof[0].signature,
entryProof.socProof[0].identifier,
entryProof.socProof[0].chunkAddr
)
) {
revert SocVerificationFailed(entryProof.socProof[0].chunkAddr);
}
if (
calculateSocAddress(entryProof.socProof[0].identifier, entryProof.socProof[0].signer) !=
entryProof.proveSegment
) {
revert SocCalcNotMatching(entryProof.socProof[0].chunkAddr);
}
}
function stampFunction(ChunkInclusionProof calldata entryProof) internal view {
(address batchOwner, uint8 batchDepth, uint8 bucketDepth, , , ) = PostageContract.batches(
entryProof.postageProof.postageId
);
if (batchOwner == address(0)) {
revert BatchDoesNotExist(entryProof.postageProof.postageId);
}
uint32 postageIndex = getPostageIndex(entryProof.postageProof.index);
uint256 maxPostageIndex = postageStampIndexCount(batchDepth, bucketDepth);
if (postageIndex >= maxPostageIndex) {
revert IndexOutsideSet(entryProof.postageProof.postageId);
}
uint64 postageBucket = getPostageBucket(entryProof.postageProof.index);
uint64 addressBucket = addressToBucket(entryProof.proveSegment, bucketDepth);
if (postageBucket != addressBucket) {
revert BucketDiffers(entryProof.postageProof.postageId);
}
if (
!Signatures.postageVerify(
batchOwner,
entryProof.postageProof.signature,
entryProof.proveSegment,
entryProof.postageProof.postageId,
entryProof.postageProof.index,
entryProof.postageProof.timeStamp
)
) {
revert SigRecoveryFailed(entryProof.postageProof.postageId);
}
}
function addressToBucket(bytes32 swarmAddress, uint8 bucketDepth) internal pure returns (uint32) {
uint32 prefix = uint32(uint256(swarmAddress) >> (256 - 32));
return prefix >> (32 - bucketDepth);
}
function postageStampIndexCount(uint8 postageDepth, uint8 bucketDepth) internal pure returns (uint256) {
return 1 << (postageDepth - bucketDepth);
}
function getPostageIndex(uint64 signedIndex) internal pure returns (uint32) {
return uint32(signedIndex);
}
function getPostageBucket(uint64 signedIndex) internal pure returns (uint64) {
return uint32(signedIndex >> 32);
}
function calculateSocAddress(bytes32 identifier, address signer) internal pure returns (bytes32) {
return keccak256(abi.encodePacked(identifier, signer));
}
function checkOrder(uint256 a, uint256 b, bytes32 trA1, bytes32 trA2, bytes32 trALast) internal pure {
if (a < b) {
if (uint256(trA1) >= uint256(trA2)) {
revert RandomElementCheckFailed();
}
if (uint256(trA2) >= uint256(trALast)) {
revert LastElementCheckFailed();
}
} else {
if (uint256(trA2) >= uint256(trA1)) {
revert RandomElementCheckFailed();
}
if (uint256(trA1) >= uint256(trALast)) {
revert LastElementCheckFailed();
}
}
}
function estimateSize(bytes32 trALast) internal view {
if (uint256(trALast) >= sampleMaxValue) {
revert ReserveCheckFailed(trALast);
}
}
}
文件 11 的 13:Signatures.sol
pragma solidity ^0.8.19;
library Signatures {
error InvalidSignatureLength();
function getPostageMessageHash(
bytes32 _chunkAddr,
bytes32 _batchId,
uint64 _index,
uint64 _timeStamp
) internal pure returns (bytes32) {
return keccak256(abi.encodePacked(_chunkAddr, _batchId, _index, _timeStamp));
}
function postageVerify(
address _signer,
bytes memory _signature,
bytes32 _chunkAddr,
bytes32 _postageId,
uint64 _index,
uint64 _timeStamp
) internal pure returns (bool) {
bytes32 messageHash = getPostageMessageHash(_chunkAddr, _postageId, _index, _timeStamp);
bytes32 ethMessageHash = getEthSignedMessageHash(messageHash);
return recoverSigner(ethMessageHash, _signature) == _signer;
}
function getEthSignedMessageHash(bytes32 _messageHash) internal pure returns (bytes32) {
return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", _messageHash));
}
function recoverSigner(
bytes32 _ethSignedMessageHash,
bytes memory _signature
) internal pure returns (address) {
(bytes32 r, bytes32 s, uint8 v) = splitSignature(_signature);
return ecrecover(_ethSignedMessageHash, v, r, s);
}
function splitSignature(bytes memory sig) internal pure returns (bytes32 r_, bytes32 s_, uint8 v_) {
if (sig.length != 65) {
revert InvalidSignatureLength();
}
assembly {
r_ := mload(add(sig, 32))
s_ := mload(add(sig, 64))
v_ := byte(0, mload(add(sig, 96)))
}
}
function getSocMessageHash(bytes32 _identifier, bytes32 _chunkAddr) internal pure returns (bytes32) {
return keccak256(abi.encodePacked(_identifier, _chunkAddr));
}
function socVerify(
address _signer,
bytes memory _signature,
bytes32 _identifier,
bytes32 _chunkAddr
) internal pure returns (bool) {
bytes32 messageHash = getSocMessageHash(_identifier, _chunkAddr);
bytes32 ethMessageHash = getEthSignedMessageHash(messageHash);
return recoverSigner(ethMessageHash, _signature) == _signer;
}
}
文件 12 的 13:Strings.sol
pragma solidity ^0.8.0;
import "./math/Math.sol";
library Strings {
bytes16 private constant _SYMBOLS = "0123456789abcdef";
uint8 private constant _ADDRESS_LENGTH = 20;
function toString(uint256 value) internal pure returns (string memory) {
unchecked {
uint256 length = Math.log10(value) + 1;
string memory buffer = new string(length);
uint256 ptr;
assembly {
ptr := add(buffer, add(32, length))
}
while (true) {
ptr--;
assembly {
mstore8(ptr, byte(mod(value, 10), _SYMBOLS))
}
value /= 10;
if (value == 0) break;
}
return buffer;
}
}
function toHexString(uint256 value) internal pure returns (string memory) {
unchecked {
return toHexString(value, Math.log256(value) + 1);
}
}
function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
bytes memory buffer = new bytes(2 * length + 2);
buffer[0] = "0";
buffer[1] = "x";
for (uint256 i = 2 * length + 1; i > 1; --i) {
buffer[i] = _SYMBOLS[value & 0xf];
value >>= 4;
}
require(value == 0, "Strings: hex length insufficient");
return string(buffer);
}
function toHexString(address addr) internal pure returns (string memory) {
return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);
}
}
文件 13 的 13:TransformedChunkProof.sol
pragma solidity ^0.8.19;
library TransformedBMTChunk {
uint256 public constant MAX_CHUNK_PAYLOAD_SIZE = 4096;
uint256 public constant SEGMENT_SIZE = 32;
function transformedRootHashFromInclusionProof(
bytes32[] memory _proofSegments,
bytes32 _proveSegment,
uint256 _proveSegmentIndex,
bytes32 key
) internal pure returns (bytes32 _calculatedHash) {
_calculatedHash = _proveSegment;
for (uint256 i = 0; i < _proofSegments.length; i++) {
bool mergeFromRight = _proveSegmentIndex % 2 == 0 ? true : false;
_calculatedHash = transformedMergeSegment(_calculatedHash, _proofSegments[i], mergeFromRight, key);
_proveSegmentIndex >>= 1;
}
return _calculatedHash;
}
function reverseUint64(uint64 _b) public pure returns (uint64) {
uint256 v = _b;
v =
((v >> 8) & 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |
((v & 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) << 8);
v =
((v >> 16) & 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |
((v & 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) << 16);
v =
((v >> 32) & 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |
((v & 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) << 32);
return uint64(v);
}
function transformedChunkAddressFromInclusionProof(
bytes32[] memory _proofSegments,
bytes32 _proveSegment,
uint256 _proveSegmentIndex,
uint64 _chunkSpan,
bytes32 key
) internal pure returns (bytes32) {
bytes32 rootHash = transformedRootHashFromInclusionProof(
_proofSegments,
_proveSegment,
_proveSegmentIndex,
key
);
return keccak256(abi.encodePacked(key, reverseUint64(_chunkSpan), rootHash));
}
function transformedMergeSegment(
bytes32 _calculatedHash,
bytes32 _proofSegment,
bool mergeFromRight,
bytes32 key
) internal pure returns (bytes32 res) {
if (mergeFromRight) {
res = keccak256(abi.encode(key, _calculatedHash, _proofSegment));
} else {
res = keccak256(abi.encode(key, _proofSegment, _calculatedHash));
}
return res;
}
}
{
"compilationTarget": {
"src/Redistribution.sol": "Redistribution"
},
"evmVersion": "paris",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs",
"useLiteralContent": true
},
"optimizer": {
"enabled": true,
"runs": 1000
},
"remappings": []
}
[{"inputs":[{"internalType":"address","name":"staking","type":"address"},{"internalType":"address","name":"postageContract","type":"address"},{"internalType":"address","name":"oracleContract","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AlreadyClaimed","type":"error"},{"inputs":[],"name":"AlreadyCommitted","type":"error"},{"inputs":[],"name":"AlreadyRevealed","type":"error"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"BatchDoesNotExist","type":"error"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"BucketDiffers","type":"error"},{"inputs":[],"name":"CommitRoundNotStarted","type":"error"},{"inputs":[],"name":"CommitRoundOver","type":"error"},{"inputs":[],"name":"FirstRevealDone","type":"error"},{"inputs":[{"internalType":"uint8","name":"","type":"uint8"},{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"InclusionProofFailed","type":"error"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"IndexOutsideSet","type":"error"},{"inputs":[],"name":"InvalidSignatureLength","type":"error"},{"inputs":[],"name":"LastElementCheckFailed","type":"error"},{"inputs":[],"name":"MustStake2Rounds","type":"error"},{"inputs":[],"name":"NoCommitsReceived","type":"error"},{"inputs":[],"name":"NoMatchingCommit","type":"error"},{"inputs":[],"name":"NoReveals","type":"error"},{"inputs":[],"name":"NotAdmin","type":"error"},{"inputs":[],"name":"NotClaimPhase","type":"error"},{"inputs":[],"name":"NotCommitPhase","type":"error"},{"inputs":[],"name":"NotMatchingOwner","type":"error"},{"inputs":[],"name":"NotRevealPhase","type":"error"},{"inputs":[],"name":"NotStaked","type":"error"},{"inputs":[],"name":"OnlyPauser","type":"error"},{"inputs":[],"name":"OutOfDepth","type":"error"},{"inputs":[{"internalType":"uint8","name":"","type":"uint8"}],"name":"OutOfDepthClaim","type":"error"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"OutOfDepthReveal","type":"error"},{"inputs":[],"name":"PhaseLastBlock","type":"error"},{"inputs":[],"name":"RandomElementCheckFailed","type":"error"},{"inputs":[{"internalType":"bytes32","name":"trALast","type":"bytes32"}],"name":"ReserveCheckFailed","type":"error"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"SigRecoveryFailed","type":"error"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"SocCalcNotMatching","type":"error"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"SocVerificationFailed","type":"error"},{"inputs":[],"name":"WrongPhase","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"validChunkCount","type":"uint256"}],"name":"ChunkCount","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"roundNumber","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"overlay","type":"bytes32"},{"indexed":false,"internalType":"uint8","name":"height","type":"uint8"}],"name":"Committed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_count","type":"uint256"}],"name":"CountCommits","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_count","type":"uint256"}],"name":"CountReveals","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"roundNumber","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"anchor","type":"bytes32"}],"name":"CurrentRevealAnchor","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"redundancyCount","type":"uint16"}],"name":"PriceAdjustmentSkipped","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"roundNumber","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"overlay","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"stake","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"stakeDensity","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"reserveCommitment","type":"bytes32"},{"indexed":false,"internalType":"uint8","name":"depth","type":"uint8"}],"name":"Revealed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"hash","type":"bytes32"},{"indexed":false,"internalType":"uint8","name":"depth","type":"uint8"}],"name":"TruthSelected","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"components":[{"internalType":"bytes32","name":"overlay","type":"bytes32"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint8","name":"depth","type":"uint8"},{"internalType":"uint256","name":"stake","type":"uint256"},{"internalType":"uint256","name":"stakeDensity","type":"uint256"},{"internalType":"bytes32","name":"hash","type":"bytes32"}],"indexed":false,"internalType":"struct Redistribution.Reveal","name":"winner","type":"tuple"}],"name":"WinnerSelected","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"owner","type":"address"}],"name":"WithdrawFailed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"indexInRC","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"chunkAddress","type":"bytes32"}],"name":"transformedChunkAddressFromInclusionProof","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"OracleContract","outputs":[{"internalType":"contract IPriceOracle","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PostageContract","outputs":[{"internalType":"contract IPostageStamp","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"Stakes","outputs":[{"internalType":"contract IStakeRegistry","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"bytes32[]","name":"proofSegments","type":"bytes32[]"},{"internalType":"bytes32","name":"proveSegment","type":"bytes32"},{"internalType":"bytes32[]","name":"proofSegments2","type":"bytes32[]"},{"internalType":"bytes32","name":"proveSegment2","type":"bytes32"},{"internalType":"uint64","name":"chunkSpan","type":"uint64"},{"internalType":"bytes32[]","name":"proofSegments3","type":"bytes32[]"},{"components":[{"internalType":"bytes","name":"signature","type":"bytes"},{"internalType":"bytes32","name":"postageId","type":"bytes32"},{"internalType":"uint64","name":"index","type":"uint64"},{"internalType":"uint64","name":"timeStamp","type":"uint64"}],"internalType":"struct Redistribution.PostageProof","name":"postageProof","type":"tuple"},{"components":[{"internalType":"address","name":"signer","type":"address"},{"internalType":"bytes","name":"signature","type":"bytes"},{"internalType":"bytes32","name":"identifier","type":"bytes32"},{"internalType":"bytes32","name":"chunkAddr","type":"bytes32"}],"internalType":"struct Redistribution.SOCProof[]","name":"socProof","type":"tuple[]"}],"internalType":"struct Redistribution.ChunkInclusionProof","name":"entryProof1","type":"tuple"},{"components":[{"internalType":"bytes32[]","name":"proofSegments","type":"bytes32[]"},{"internalType":"bytes32","name":"proveSegment","type":"bytes32"},{"internalType":"bytes32[]","name":"proofSegments2","type":"bytes32[]"},{"internalType":"bytes32","name":"proveSegment2","type":"bytes32"},{"internalType":"uint64","name":"chunkSpan","type":"uint64"},{"internalType":"bytes32[]","name":"proofSegments3","type":"bytes32[]"},{"components":[{"internalType":"bytes","name":"signature","type":"bytes"},{"internalType":"bytes32","name":"postageId","type":"bytes32"},{"internalType":"uint64","name":"index","type":"uint64"},{"internalType":"uint64","name":"timeStamp","type":"uint64"}],"internalType":"struct Redistribution.PostageProof","name":"postageProof","type":"tuple"},{"components":[{"internalType":"address","name":"signer","type":"address"},{"internalType":"bytes","name":"signature","type":"bytes"},{"internalType":"bytes32","name":"identifier","type":"bytes32"},{"internalType":"bytes32","name":"chunkAddr","type":"bytes32"}],"internalType":"struct Redistribution.SOCProof[]","name":"socProof","type":"tuple[]"}],"internalType":"struct Redistribution.ChunkInclusionProof","name":"entryProof2","type":"tuple"},{"components":[{"internalType":"bytes32[]","name":"proofSegments","type":"bytes32[]"},{"internalType":"bytes32","name":"proveSegment","type":"bytes32"},{"internalType":"bytes32[]","name":"proofSegments2","type":"bytes32[]"},{"internalType":"bytes32","name":"proveSegment2","type":"bytes32"},{"internalType":"uint64","name":"chunkSpan","type":"uint64"},{"internalType":"bytes32[]","name":"proofSegments3","type":"bytes32[]"},{"components":[{"internalType":"bytes","name":"signature","type":"bytes"},{"internalType":"bytes32","name":"postageId","type":"bytes32"},{"internalType":"uint64","name":"index","type":"uint64"},{"internalType":"uint64","name":"timeStamp","type":"uint64"}],"internalType":"struct Redistribution.PostageProof","name":"postageProof","type":"tuple"},{"components":[{"internalType":"address","name":"signer","type":"address"},{"internalType":"bytes","name":"signature","type":"bytes"},{"internalType":"bytes32","name":"identifier","type":"bytes32"},{"internalType":"bytes32","name":"chunkAddr","type":"bytes32"}],"internalType":"struct Redistribution.SOCProof[]","name":"socProof","type":"tuple[]"}],"internalType":"struct Redistribution.ChunkInclusionProof","name":"entryProofLast","type":"tuple"}],"name":"claim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_obfuscatedHash","type":"bytes32"},{"internalType":"uint64","name":"_roundNumber","type":"uint64"}],"name":"commit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"currentClaimRound","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"currentCommitRound","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"currentCommits","outputs":[{"internalType":"bytes32","name":"overlay","type":"bytes32"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"bool","name":"revealed","type":"bool"},{"internalType":"uint8","name":"height","type":"uint8"},{"internalType":"uint256","name":"stake","type":"uint256"},{"internalType":"bytes32","name":"obfuscatedHash","type":"bytes32"},{"internalType":"uint256","name":"revealIndex","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"currentMinimumDepth","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"currentPhaseClaim","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"currentPhaseCommit","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"currentPhaseReveal","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"currentRevealRound","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"currentReveals","outputs":[{"internalType":"bytes32","name":"overlay","type":"bytes32"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint8","name":"depth","type":"uint8"},{"internalType":"uint256","name":"stake","type":"uint256"},{"internalType":"uint256","name":"stakeDensity","type":"uint256"},{"internalType":"bytes32","name":"hash","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"currentRound","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"currentRoundAnchor","outputs":[{"internalType":"bytes32","name":"returnVal","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"currentRoundReveals","outputs":[{"components":[{"internalType":"bytes32","name":"overlay","type":"bytes32"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint8","name":"depth","type":"uint8"},{"internalType":"uint256","name":"stake","type":"uint256"},{"internalType":"uint256","name":"stakeDensity","type":"uint256"},{"internalType":"bytes32","name":"hash","type":"bytes32"}],"internalType":"struct Redistribution.Reveal[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"currentSeed","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"A","type":"bytes32"},{"internalType":"bytes32","name":"B","type":"bytes32"},{"internalType":"uint8","name":"minimum","type":"uint8"}],"name":"inProximity","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"uint8","name":"_depth","type":"uint8"}],"name":"isParticipatingInUpcomingRound","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_overlay","type":"bytes32"}],"name":"isWinner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nextSeed","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"_depth","type":"uint8"},{"internalType":"bytes32","name":"_hash","type":"bytes32"},{"internalType":"bytes32","name":"_revealNonce","type":"bytes32"}],"name":"reveal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"_penaltyMultiplierDisagreement","type":"uint8"},{"internalType":"uint8","name":"_penaltyMultiplierNonRevealed","type":"uint8"},{"internalType":"uint8","name":"_penaltyRandomFactor","type":"uint8"}],"name":"setFreezingParams","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_sampleMaxValue","type":"uint256"}],"name":"setSampleMaxValue","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"unPause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"winner","outputs":[{"internalType":"bytes32","name":"overlay","type":"bytes32"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint8","name":"depth","type":"uint8"},{"internalType":"uint256","name":"stake","type":"uint256"},{"internalType":"uint256","name":"stakeDensity","type":"uint256"},{"internalType":"bytes32","name":"hash","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_overlay","type":"bytes32"},{"internalType":"uint8","name":"_depth","type":"uint8"},{"internalType":"bytes32","name":"_hash","type":"bytes32"},{"internalType":"bytes32","name":"revealNonce","type":"bytes32"}],"name":"wrapCommit","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"}]