Source Code
Overview
S Balance
S Value
Less Than $0.01 (@ $0.07/S)Latest 25 from a total of 10,323 transactions
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Free Dig | 41727951 | 175 days ago | IN | 0.05336974 S | 0.01074642 | ||||
| Free Dig | 41727751 | 175 days ago | IN | 0.05336974 S | 0.01074642 | ||||
| Free Dig | 41727710 | 175 days ago | IN | 0.05336974 S | 0.01074642 | ||||
| Free Dig | 41727677 | 175 days ago | IN | 0.05336974 S | 0.01074642 | ||||
| Free Dig | 41727630 | 175 days ago | IN | 0.05336974 S | 0.01074642 | ||||
| Free Dig | 41726561 | 175 days ago | IN | 0.05336974 S | 0.01074642 | ||||
| Free Dig | 41726451 | 175 days ago | IN | 0.05336974 S | 0.01074642 | ||||
| Free Dig | 41726376 | 175 days ago | IN | 0.05336974 S | 0.01074642 | ||||
| Free Dig | 41726333 | 175 days ago | IN | 0.05336974 S | 0.01074642 | ||||
| Free Dig | 41726286 | 175 days ago | IN | 0.05336974 S | 0.01074642 | ||||
| Free Dig | 41726249 | 175 days ago | IN | 0.05336974 S | 0.01074642 | ||||
| Free Dig | 41725659 | 175 days ago | IN | 0.05336974 S | 0.01074642 | ||||
| Free Dig | 41725608 | 175 days ago | IN | 0.05336974 S | 0.0107595 | ||||
| Free Dig | 41725546 | 175 days ago | IN | 0.05336974 S | 0.01074642 | ||||
| Free Dig | 41725458 | 175 days ago | IN | 0.05336974 S | 0.01074642 | ||||
| Free Dig | 41725405 | 175 days ago | IN | 0.05336974 S | 0.01074642 | ||||
| Free Dig | 41720392 | 175 days ago | IN | 0.05336974 S | 0.01074642 | ||||
| Free Dig | 41720335 | 175 days ago | IN | 0.05336974 S | 0.01074642 | ||||
| Free Dig | 41720273 | 175 days ago | IN | 0.05336974 S | 0.01074642 | ||||
| Free Dig | 41720222 | 175 days ago | IN | 0.05336974 S | 0.01074642 | ||||
| Free Dig | 41720154 | 175 days ago | IN | 0.05336974 S | 0.01074642 | ||||
| Free Dig | 41720097 | 175 days ago | IN | 0.05336974 S | 0.01074642 | ||||
| Free Dig | 41719974 | 175 days ago | IN | 0.05336974 S | 0.01074642 | ||||
| Free Dig | 41719933 | 175 days ago | IN | 0.05336974 S | 0.01074642 | ||||
| Free Dig | 41651622 | 176 days ago | IN | 0.05336974 S | 0.0112957 |
Latest 25 internal transactions (View All)
Advanced mode:
| Parent Transaction Hash | Block | From | To | |||
|---|---|---|---|---|---|---|
| 42663528 | 168 days ago | 9.91958598 S | ||||
| 41727951 | 175 days ago | 0.042 S | ||||
| 41727751 | 175 days ago | 0.042 S | ||||
| 41727710 | 175 days ago | 0.042 S | ||||
| 41727677 | 175 days ago | 0.042 S | ||||
| 41727630 | 175 days ago | 0.042 S | ||||
| 41726561 | 175 days ago | 0.042 S | ||||
| 41726451 | 175 days ago | 0.042 S | ||||
| 41726376 | 175 days ago | 0.042 S | ||||
| 41726333 | 175 days ago | 0.042 S | ||||
| 41726286 | 175 days ago | 0.042 S | ||||
| 41726249 | 175 days ago | 0.042 S | ||||
| 41725659 | 175 days ago | 0.042 S | ||||
| 41725608 | 175 days ago | 0.042 S | ||||
| 41725546 | 175 days ago | 0.042 S | ||||
| 41725458 | 175 days ago | 0.042 S | ||||
| 41725405 | 175 days ago | 0.042 S | ||||
| 41720392 | 175 days ago | 0.042 S | ||||
| 41720335 | 175 days ago | 0.042 S | ||||
| 41720273 | 175 days ago | 0.042 S | ||||
| 41720222 | 175 days ago | 0.042 S | ||||
| 41720154 | 175 days ago | 0.042 S | ||||
| 41720097 | 175 days ago | 0.042 S | ||||
| 41719974 | 175 days ago | 0.042 S | ||||
| 41719933 | 175 days ago | 0.042 S |
Cross-Chain Transactions
Loading...
Loading
Contract Name:
DiggaGame
Compiler Version
v0.8.28+commit.7893614a
Optimization Enabled:
Yes with 100000 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
// ##################
// ##################
// ####++++++++++++++++####
// ######++--------------+#######
// #####++----------------++++####
// #####++--------------------++####
// ####++----------------------++####
// #####+++-----------------------++####
// ######+--------------------------++####
// ####+++----------++++++++---------++####
// ####++++--------+++++++++------+++++####
// #######+++++++++++++++++------++++#####
// #######+++++++++++++++---+++++#######
// ######++++++++++---+++++++#####
// ############+++++++---+++++#######
// ###############++++++++++++######
// ##################++++++++#######
// ######################+++++#######
// #####++++++####### #####+######
// #######+++++######### ###########
// #######+++++######## #####
// #####++++++######### #####
// #######++++++########
// #####++++++#########
// #######+++++#########
// #####++++++########
// #######+++++#########
// #######++++++#######
// ######++++++#########
// #############+++########
// #####################
// ##############+++++++++###########
// ######################+-------++#######
// ###########+++++++++++++-------++#######
// #########+++----+++++++++++++++++####
// ####++----------+#########++++++#####
// ####++----++++++##########++++++#####
// ####+++++++####### ####++++++#####
// #######++++++##### ####++++#######
// #####++++++############++++####
// ######+++++++######+++++++####
// #####++++-++#####++++++#####
// #####+-++++###++++++#####
// #####+++-++#+++++#######
// ####+++++++++#####
// ######+++++++#####
// ####++++#######
// ############
// #########
// Crafted with care by Drikkx , twitter: drikkxeth
pragma solidity ^0.8.22;
import {ReentrancyGuard} from "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
import {AccessControl} from "@openzeppelin/contracts/access/AccessControl.sol";
import {IDiggaToken} from "./interfaces/IDiggaToken.sol";
import {IDiggaResources} from "./interfaces/IDiggaResources.sol";
import {IEntropyConsumer} from "@pythnetwork/entropy-sdk-solidity/IEntropyConsumer.sol";
import {IEntropy} from "@pythnetwork/entropy-sdk-solidity/IEntropy.sol";
import {DiggaLibrary} from "./libraries/DiggaLibrary.sol";
/**
* @title DiggingGame
* @author Drikkx
* @notice A game contract that allows users to dig for artefacts using DIGGA tokens
* @dev Implements a game where users can stake DIGGA tokens to dig for artefacts with random outcomes
*/
contract DiggaGame is ReentrancyGuard, AccessControl, IEntropyConsumer {
using DiggaLibrary for DiggaLibrary.Resources;
bytes32 public constant REFEREE_ROLE = keccak256("REFEREE_ROLE");
bytes32 public constant AIRDROP_CLAIMER = keccak256("AIRDROP_CLAIMER");
bytes32 public constant FARM_ROLE = keccak256("FARM_ROLE");
// Constants
uint64 private constant MINES = 3;
uint128 private constant FREE_DIGGING_WIN = 3;
uint128 private constant AIRDROP_PERCENTAGE = 10; // 0,1% of each bet goes to airdrop
uint128 private constant REFERRAL_DIVISOR = 20; // 100 / REFERRAL_PERCENTAGE for gas optimization
uint128 private constant EXPERIENCE_DECIMALS = 100;
/// @notice Ranges for artefact distribution
uint8 private constant RANGE_0 = 45;
uint8 private constant RANGE_1 = 60;
uint8 private constant RANGE_2 = 75;
uint8 private constant RANGE_3 = 85;
uint8 private constant RANGE_4 = 93;
uint8 private constant RANGE_5 = 95;
uint8 private constant RANGE_6 = 97;
uint256 private constant RANGE_6_256 = 97;
/// @notice Quest system constants
uint40 private constant CLAIM_PERIOD = 7 days;
uint16 private constant MIN_DIGS_FOR_REWARD = 50;
uint128 private constant BASE_REWARD = 2500000;
uint16 private constant BONUS_THRESHOLD_1 = 80;
uint16 private constant BONUS_THRESHOLD_2 = 160;
uint128 private constant BONUS_MULTIPLIER = 2;
uint128 private constant MONTHLY_BONUS = 20000000;
uint16 private constant MONTHLY_QUESTS_REQUIRED = 4;
uint128 private minimalStake;
IEntropy private entropy;
IDiggaToken private digga;
IDiggaResources private diggaResources;
uint128 private airdropPool;
uint128 private rngFees;
/// @notice Multipliers for each artefact
uint128[7] private multipliers = [5, 10, 20, 50, 250, 1000, 0];
/// @notice User digging state
struct DigState {
uint128 freeDigging;
uint128 freeDiggingStake;
uint128 experience;
uint8[3] lastDigging;
uint16 totalDigs;
}
/// @notice User quest state
struct QuestState {
uint40 lastClaimTimestamp;
uint16 completedQuests;
bool hasClaimed;
}
/// @notice Random number generation request
struct Request {
address user;
uint64 sequenceNumber;
uint128 stake;
bytes32 userRandomNumber;
}
/// @notice Digging result
struct Result {
address winner;
uint128 winStake;
uint8[3] artefacts;
bool isWin;
}
/// @notice Combined request state
struct RequestState {
Request request;
bool completed;
Result result;
}
/// @notice Mapping of user addresses to their digging state
mapping(address => DigState) private digStates;
/// @notice Mapping of user addresses to their quest state
mapping(address => QuestState) private questStates;
/// @notice Mapping of sequence numbers to request states
mapping(uint64 => RequestState) public requestStates;
/// @notice Mapping of user addresses to their referrers
mapping(address => address) private referrers;
/// @notice Emitted when the base stake is updated
event NewBaseStake(uint256 indexed minimalStake);
/// @notice Emitted when a random number is requested
event RandomNumberRequested(
uint64 indexed sequenceNumber,
address indexed user,
uint128 stake
);
/// @notice Emitted when digging results are processed
event DiggingResult(
uint8[3] artefacts,
address indexed winner,
uint128 winStake,
bool indexed isWin
);
/// @notice Emitted when RNG values are generated
event RNG(uint80[3] rngs);
/// @notice Emitted when free digging is awarded
event FreeDiggingAwarded(address indexed user, uint128 amount);
/// @notice Emitted when referral experience is minted
event ReferralExperienceMinted(address indexed referrer, uint128 amount);
error InvalidRequest();
error RequestAlreadyCompleted();
error InvalidStakeAmount();
error InvalidAddress();
error UserAlreadyHasReferrer();
error SelfReferralNotAllowed();
error InvalidRequestState();
error InvalidProvider();
error RequestNotCompleted();
error InvalidAmounts();
error InsufficientDIGGABalance();
error UseFreeDiggingFirst();
error NoFreeDiggingAvailable();
error UserAlreadyHasFreeDigging();
error TransferFailed();
error NeedMoreExperienceToClaim();
/**
* @notice Constructor for the DiggingGame contract
* @param entropyAddress Address of the entropy provider
* @param diggaAddress Address of the DIGGA token
* @param diggaResourcesAddress Address of the DIGGA resources contract
*/
constructor(
address entropyAddress,
address diggaAddress,
address diggaResourcesAddress
) {
minimalStake = 1e18;
entropy = IEntropy(entropyAddress);
digga = IDiggaToken(diggaAddress);
diggaResources = IDiggaResources(diggaResourcesAddress);
_setRngFeesAjusted();
_grantRole(DEFAULT_ADMIN_ROLE, msg.sender);
}
/// @dev Register my contract on Sonic FeeM
function registerMe() external {
(bool _success, ) = address(0xDC2B0D2Dd2b7759D97D50db4eabDC36973110830)
.call(abi.encodeWithSignature("selfRegister(uint256)", 145));
require(_success, "FeeM registration failed");
}
/**
* @notice Allows a user to dig for artefacts
* @param stake Amount of DIGGA tokens to stake
*/
function dig(uint128 stake) external payable nonReentrant {
if (msg.value < rngFees) revert InvalidAmounts();
if (stake < minimalStake) revert InvalidStakeAmount();
DigState storage digState = digStates[msg.sender];
if (digState.freeDigging != 0) revert UseFreeDiggingFirst();
digga.burnFrom(msg.sender, stake);
airdropPool += (stake * AIRDROP_PERCENTAGE) / 10000;
uint128 baseExperience = (stake * EXPERIENCE_DECIMALS) / 1e18;
digState.experience += baseExperience;
digState.totalDigs += 1;
_requestRandomNumbers(stake);
}
/**
* @notice Allows a user to claim period rewards
*/
function claimPeriodRewards() external {
QuestState storage questState = questStates[msg.sender];
DigState storage digState = digStates[msg.sender];
if (
uint40(block.timestamp) >
questState.lastClaimTimestamp + CLAIM_PERIOD
) {
questState.hasClaimed = false;
}
if (questState.hasClaimed) {
revert RequestAlreadyCompleted();
}
if (digState.totalDigs < MIN_DIGS_FOR_REWARD) {
revert InvalidRequest();
}
uint128 reward = BASE_REWARD;
if (digState.totalDigs >= BONUS_THRESHOLD_1) {
reward = reward * BONUS_MULTIPLIER;
}
if (digState.totalDigs >= BONUS_THRESHOLD_2) {
reward = reward * BONUS_MULTIPLIER;
}
if (questState.completedQuests + 1 == MONTHLY_QUESTS_REQUIRED) {
reward = reward + MONTHLY_BONUS;
questState.completedQuests = 0;
} else {
questState.completedQuests = questState.completedQuests + 1;
}
digState.experience = digState.experience + reward;
questState.lastClaimTimestamp = uint40(block.timestamp);
questState.hasClaimed = true;
digState.totalDigs = 0;
}
/**
* @notice Allows a user to perform a free dig
*/
function freeDig() external payable nonReentrant {
DigState storage digState = digStates[_msgSender()];
if (digState.freeDigging == 0) revert NoFreeDiggingAvailable();
if (msg.value < rngFees) revert InvalidAmounts();
if (digState.freeDiggingStake == 0) revert InvalidAmounts();
_requestRandomNumbers(digState.freeDiggingStake);
digState.freeDigging -= 1;
}
/**
* @notice Awards free digs to a user
* @param user Address of the user to award
* @param digs Number of free digs to award
* @param stake Stake amount for the free digs
*/
function awardFreeDigs(
address user,
uint128 digs,
uint128 stake
) external onlyRole(FARM_ROLE) {
DigState storage digState = digStates[user];
if (digState.freeDigging > 0 && digState.freeDiggingStake != stake)
revert UserAlreadyHasFreeDigging();
digState.freeDigging += digs;
digState.freeDiggingStake = stake;
}
/**
* @notice Requests random numbers for digging
* @param stake Amount of DIGGA tokens staked
*/
function _requestRandomNumbers(uint128 stake) private {
bytes32 userRandomNumber = keccak256(
abi.encodePacked(
uint40(block.timestamp),
block.prevrandao,
msg.sender
)
);
address entropyProvider = entropy.getDefaultProvider();
uint256 fee = entropy.getFee(entropyProvider);
uint64 sequenceNumber = entropy.requestWithCallback{value: fee}(
entropyProvider,
userRandomNumber
);
requestStates[sequenceNumber] = RequestState({
request: Request(
_msgSender(),
sequenceNumber,
stake,
userRandomNumber
),
completed: false,
result: Result(address(0), 0, [uint8(0), uint8(0), uint8(0)], false)
});
emit RandomNumberRequested(sequenceNumber, _msgSender(), stake);
}
/**
* @notice Callback function for entropy provider
* @param sequenceNumber Sequence number of the request
* @param randomNumber Random number provided by the entropy provider
*/
function entropyCallback(
uint64 sequenceNumber,
address /*provider*/,
bytes32 randomNumber
) internal override {
RequestState storage state = requestStates[sequenceNumber];
uint256[3] memory randomWords;
if (state.request.user == address(0)) revert InvalidRequest();
if (state.completed) revert RequestAlreadyCompleted();
for (uint i = 0; i < MINES; i++) {
randomWords[i] = uint256(
keccak256(abi.encodePacked(randomNumber, i))
);
}
_processDigging(sequenceNumber, state.request.stake, randomWords);
state.completed = true;
}
/**
* @notice Returns the entropy provider address
* @return address Address of the entropy provider
*/
function getEntropy() internal view override returns (address) {
return address(entropy);
}
/**
* @notice Processes digging results
* @param sequenceNumber Sequence number of the request
* @param stake Amount of DIGGA tokens staked
* @param randomWords Array of random numbers
*/
function _processDigging(
uint64 sequenceNumber,
uint128 stake,
uint256[3] memory randomWords
) private {
uint8[3] memory artefacts;
address digger = requestStates[sequenceNumber].request.user;
DigState storage digState = digStates[digger];
for (uint i = 0; i < MINES; i++) {
uint256 rng = randomWords[i] % RANGE_6_256;
artefacts[i] = _getArtefact(uint8(rng));
if (artefacts[i] == 6) {
digState.freeDigging += FREE_DIGGING_WIN;
emit FreeDiggingAwarded(digger, FREE_DIGGING_WIN);
}
}
uint128 winStake = stake * multipliers[artefacts[0]];
bool isWin = (artefacts[0] == artefacts[1] &&
artefacts[0] == artefacts[2]);
if (isWin && winStake > 0) {
digga.mint(digger, uint256(winStake));
}
if (digState.freeDigging > 0) {
digState.freeDiggingStake = stake;
}
requestStates[sequenceNumber].result = Result(
digger,
isWin ? winStake : 0,
artefacts,
isWin
);
digState.lastDigging = artefacts;
emit DiggingResult(artefacts, digger, isWin ? winStake : 0, isWin);
}
/**
* @notice Sets the RNG fees with adjustment
*/
function _setRngFeesAjusted() private {
address entropyProvider = entropy.getDefaultProvider();
uint256 fee = entropy.getFee(entropyProvider);
rngFees = uint128((fee * 125) / 100);
}
/**
* @notice Determines the artefact based on random number
* @param random Random number
* @return uint8 Artefact number
*/
function _getArtefact(uint8 random) private pure returns (uint8) {
if (random < RANGE_0) return 0;
if (random < RANGE_1) return 1;
if (random < RANGE_2) return 2;
if (random < RANGE_3) return 3;
if (random < RANGE_4) return 4;
if (random < RANGE_5) return 5;
return 6;
}
/**
* @notice Returns the user's state
* @param user Address of the user
* @return digState User's digging state
* @return questState User's quest state
*/
function getUserState(
address user
)
external
view
returns (DigState memory digState, QuestState memory questState)
{
return (digStates[user], questStates[user]);
}
/**
* @notice Returns the minimal stake amount
* @return uint128 Minimal stake amount
*/
function getMinimalStake() external view returns (uint128) {
return minimalStake;
}
/**
* @notice Returns the multipliers for artefacts
* @return uint128[7] Array of multipliers
*/
function getMultipliers() external view returns (uint128[7] memory) {
return multipliers;
}
/**
* @notice Checks if a request is completed
* @param sequenceNumber Sequence number of the request
* @return bool True if request is completed
*/
function isRequestCompleted(
uint64 sequenceNumber
) external view returns (bool) {
return requestStates[sequenceNumber].completed;
}
/**
* @notice Returns the request details
* @param sequenceNumber Sequence number of the request
* @return Request Request details
*/
function getRequest(
uint64 sequenceNumber
) external view returns (Request memory) {
return requestStates[sequenceNumber].request;
}
/**
* @notice Returns the result of a request
* @param sequenceNumber Sequence number of the request
* @return Result Result details
*/
function getResult(
uint64 sequenceNumber
) external view returns (Result memory) {
return requestStates[sequenceNumber].result;
}
/**
* @notice Returns the airdrop pool balance
* @return uint128 Airdrop pool balance
*/
function getAirdropPool() external view returns (uint128) {
return airdropPool;
}
/**
* @notice Returns the RNG fees
* @return uint128 RNG fees
*/
function getRngFees() external view returns (uint128) {
return rngFees;
}
/**
* @notice Allows a user to claim their experience
*/
function claimExperience() external nonReentrant {
DigState storage digState = digStates[msg.sender];
if (digState.experience < EXPERIENCE_DECIMALS * 100)
revert NeedMoreExperienceToClaim();
diggaResources.mint(
msg.sender,
uint256(DiggaLibrary.Resources.Experience),
digState.experience / EXPERIENCE_DECIMALS,
""
);
address referrer = referrers[msg.sender];
if (referrer != address(0)) {
uint128 referrerExperienceToClaim = digState.experience /
REFERRAL_DIVISOR /
EXPERIENCE_DECIMALS;
diggaResources.mint(
referrer,
uint256(DiggaLibrary.Resources.Experience),
uint256(referrerExperienceToClaim),
""
);
emit ReferralExperienceMinted(referrer, referrerExperienceToClaim);
}
digState.experience = 0;
}
/**
* @notice Returns quest system constants
* @return bonusMultiplier Bonus multiplier
* @return monthlyBonus Monthly bonus amount
* @return baseReward Base reward amount
* @return claimPeriod Claim period in seconds
* @return minDigsForReward Minimum digs required for reward
* @return bonusThreshold1 First bonus threshold
* @return bonusThreshold2 Second bonus threshold
* @return monthlyQuestsRequired Number of quests required for monthly bonus
*/
function getQuestConstants()
external
pure
returns (
uint128 bonusMultiplier,
uint128 monthlyBonus,
uint128 baseReward,
uint40 claimPeriod,
uint16 minDigsForReward,
uint16 bonusThreshold1,
uint16 bonusThreshold2,
uint16 monthlyQuestsRequired
)
{
return (
BONUS_MULTIPLIER,
MONTHLY_BONUS,
BASE_REWARD,
CLAIM_PERIOD,
MIN_DIGS_FOR_REWARD,
BONUS_THRESHOLD_1,
BONUS_THRESHOLD_2,
MONTHLY_QUESTS_REQUIRED
);
}
/**
* @notice Returns the pending experience from period rewards
* @param user Address of the user to check
* @return uint128 Amount of pending experience
*/
function getPendingPeriodRewards(
address user
) external view returns (uint128) {
QuestState memory questState = questStates[user];
DigState memory digState = digStates[user];
if (
uint40(block.timestamp) <=
questState.lastClaimTimestamp + CLAIM_PERIOD
) {
if (questState.hasClaimed) {
return 0;
}
}
if (digState.totalDigs < MIN_DIGS_FOR_REWARD) {
return 0;
}
uint128 reward = BASE_REWARD;
if (digState.totalDigs >= BONUS_THRESHOLD_1) {
reward = reward * BONUS_MULTIPLIER;
}
if (digState.totalDigs >= BONUS_THRESHOLD_2) {
reward = reward * BONUS_MULTIPLIER;
}
if (questState.completedQuests + 1 == MONTHLY_QUESTS_REQUIRED) {
reward = reward + MONTHLY_BONUS;
}
return reward;
}
/**
* @notice Sets the minimal stake amount
* @param amount New minimal stake amount
*/
function setMinimalStake(
uint128 amount
) external onlyRole(DEFAULT_ADMIN_ROLE) {
if (amount == 0) revert InvalidStakeAmount();
minimalStake = amount;
emit NewBaseStake(amount);
}
/**
* @notice Sets a referrer for a user
* @param referrer Address of the referrer
* @param user Address of the user
*/
function setReferrer(
address referrer,
address user
) external onlyRole(REFEREE_ROLE) {
if (referrer == address(0)) revert InvalidAddress();
if (user == address(0)) revert InvalidAddress();
if (referrers[user] != address(0)) revert UserAlreadyHasReferrer();
if (user == referrer) revert SelfReferralNotAllowed();
referrers[user] = referrer;
}
/**
* @notice Transfers ownership to a new address
* @param newAddress Address of the new owner
*/
function newOwner(
address newAddress
) external onlyRole(DEFAULT_ADMIN_ROLE) {
if (newAddress == address(0)) revert InvalidAddress();
_grantRole(DEFAULT_ADMIN_ROLE, newAddress);
_revokeRole(DEFAULT_ADMIN_ROLE, msg.sender);
}
/**
* @notice Sets the RNG fees
* @param newRngFees New RNG fees amount
*/
function setRngFees(
uint128 newRngFees
) external onlyRole(DEFAULT_ADMIN_ROLE) {
rngFees = newRngFees;
}
/**
* @notice Sets the RNG fees with adjustment
*/
function setRngFeesAjusted() external onlyRole(DEFAULT_ADMIN_ROLE) {
_setRngFeesAjusted();
}
/**
* @notice Allows contract to receive ETH
*/
function deposit() external payable {}
/**
* @notice Fallback function to receive ETH
*/
receive() external payable {}
/**
* @notice Withdraws ETH from the contract
*/
function withdraw() external onlyRole(DEFAULT_ADMIN_ROLE) {
uint256 balance = address(this).balance;
uint256 amount = balance - rngFees;
(bool success, ) = payable(msg.sender).call{value: amount}("");
if (!success) revert TransferFailed();
}
/**
* @notice Claims airdrop reserves
*/
function claimAirdropReserves() external onlyRole(AIRDROP_CLAIMER) {
digga.mint(msg.sender, uint256(airdropPool));
airdropPool = 0;
}
/**
* @notice Sets the entropy provider address
* @param newEntropyAddress New entropy provider address
*/
function setEntropyAddress(
address newEntropyAddress
) external onlyRole(DEFAULT_ADMIN_ROLE) {
entropy = IEntropy(newEntropyAddress);
}
/**
* @notice Sets the DIGGA token address
* @param newDiggaAddress New DIGGA token address
*/
function setDiggaAddress(
address newDiggaAddress
) external onlyRole(DEFAULT_ADMIN_ROLE) {
digga = IDiggaToken(newDiggaAddress);
}
/**
* @notice Sets the DIGGA resources address
* @param newDiggaResourcesAddress New DIGGA resources address
*/
function setDiggaResourcesAddress(
address newDiggaResourcesAddress
) external onlyRole(DEFAULT_ADMIN_ROLE) {
diggaResources = IDiggaResources(newDiggaResourcesAddress);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.3.0) (access/AccessControl.sol)
pragma solidity ^0.8.20;
import {IAccessControl} from "./IAccessControl.sol";
import {Context} from "../utils/Context.sol";
import {ERC165} from "../utils/introspection/ERC165.sol";
/**
* @dev Contract module that allows children to implement role-based access
* control mechanisms. This is a lightweight version that doesn't allow enumerating role
* members except through off-chain means by accessing the contract event logs. Some
* applications may benefit from on-chain enumerability, for those cases see
* {AccessControlEnumerable}.
*
* Roles are referred to by their `bytes32` identifier. These should be exposed
* in the external API and be unique. The best way to achieve this is by
* using `public constant` hash digests:
*
* ```solidity
* bytes32 public constant MY_ROLE = keccak256("MY_ROLE");
* ```
*
* Roles can be used to represent a set of permissions. To restrict access to a
* function call, use {hasRole}:
*
* ```solidity
* function foo() public {
* require(hasRole(MY_ROLE, msg.sender));
* ...
* }
* ```
*
* Roles can be granted and revoked dynamically via the {grantRole} and
* {revokeRole} functions. Each role has an associated admin role, and only
* accounts that have a role's admin role can call {grantRole} and {revokeRole}.
*
* By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means
* that only accounts with this role will be able to grant or revoke other
* roles. More complex role relationships can be created by using
* {_setRoleAdmin}.
*
* WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to
* grant and revoke this role. Extra precautions should be taken to secure
* accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules}
* to enforce additional security measures for this role.
*/
abstract contract AccessControl is Context, IAccessControl, ERC165 {
struct RoleData {
mapping(address account => bool) hasRole;
bytes32 adminRole;
}
mapping(bytes32 role => RoleData) private _roles;
bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;
/**
* @dev Modifier that checks that an account has a specific role. Reverts
* with an {AccessControlUnauthorizedAccount} error including the required role.
*/
modifier onlyRole(bytes32 role) {
_checkRole(role);
_;
}
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);
}
/**
* @dev Returns `true` if `account` has been granted `role`.
*/
function hasRole(bytes32 role, address account) public view virtual returns (bool) {
return _roles[role].hasRole[account];
}
/**
* @dev Reverts with an {AccessControlUnauthorizedAccount} error if `_msgSender()`
* is missing `role`. Overriding this function changes the behavior of the {onlyRole} modifier.
*/
function _checkRole(bytes32 role) internal view virtual {
_checkRole(role, _msgSender());
}
/**
* @dev Reverts with an {AccessControlUnauthorizedAccount} error if `account`
* is missing `role`.
*/
function _checkRole(bytes32 role, address account) internal view virtual {
if (!hasRole(role, account)) {
revert AccessControlUnauthorizedAccount(account, role);
}
}
/**
* @dev Returns the admin role that controls `role`. See {grantRole} and
* {revokeRole}.
*
* To change a role's admin, use {_setRoleAdmin}.
*/
function getRoleAdmin(bytes32 role) public view virtual returns (bytes32) {
return _roles[role].adminRole;
}
/**
* @dev Grants `role` to `account`.
*
* If `account` had not been already granted `role`, emits a {RoleGranted}
* event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*
* May emit a {RoleGranted} event.
*/
function grantRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) {
_grantRole(role, account);
}
/**
* @dev Revokes `role` from `account`.
*
* If `account` had been granted `role`, emits a {RoleRevoked} event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*
* May emit a {RoleRevoked} event.
*/
function revokeRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) {
_revokeRole(role, account);
}
/**
* @dev Revokes `role` from the calling account.
*
* Roles are often managed via {grantRole} and {revokeRole}: this function's
* purpose is to provide a mechanism for accounts to lose their privileges
* if they are compromised (such as when a trusted device is misplaced).
*
* If the calling account had been revoked `role`, emits a {RoleRevoked}
* event.
*
* Requirements:
*
* - the caller must be `callerConfirmation`.
*
* May emit a {RoleRevoked} event.
*/
function renounceRole(bytes32 role, address callerConfirmation) public virtual {
if (callerConfirmation != _msgSender()) {
revert AccessControlBadConfirmation();
}
_revokeRole(role, callerConfirmation);
}
/**
* @dev Sets `adminRole` as ``role``'s admin role.
*
* Emits a {RoleAdminChanged} event.
*/
function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
bytes32 previousAdminRole = getRoleAdmin(role);
_roles[role].adminRole = adminRole;
emit RoleAdminChanged(role, previousAdminRole, adminRole);
}
/**
* @dev Attempts to grant `role` to `account` and returns a boolean indicating if `role` was granted.
*
* Internal function without access restriction.
*
* May emit a {RoleGranted} event.
*/
function _grantRole(bytes32 role, address account) internal virtual returns (bool) {
if (!hasRole(role, account)) {
_roles[role].hasRole[account] = true;
emit RoleGranted(role, account, _msgSender());
return true;
} else {
return false;
}
}
/**
* @dev Attempts to revoke `role` from `account` and returns a boolean indicating if `role` was revoked.
*
* Internal function without access restriction.
*
* May emit a {RoleRevoked} event.
*/
function _revokeRole(bytes32 role, address account) internal virtual returns (bool) {
if (hasRole(role, account)) {
_roles[role].hasRole[account] = false;
emit RoleRevoked(role, account, _msgSender());
return true;
} else {
return false;
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.3.0) (access/IAccessControl.sol)
pragma solidity ^0.8.20;
/**
* @dev External interface of AccessControl declared to support ERC-165 detection.
*/
interface IAccessControl {
/**
* @dev The `account` is missing a role.
*/
error AccessControlUnauthorizedAccount(address account, bytes32 neededRole);
/**
* @dev The caller of a function is not the expected one.
*
* NOTE: Don't confuse with {AccessControlUnauthorizedAccount}.
*/
error AccessControlBadConfirmation();
/**
* @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`
*
* `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite
* {RoleAdminChanged} not being emitted to signal this.
*/
event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);
/**
* @dev Emitted when `account` is granted `role`.
*
* `sender` is the account that originated the contract call. This account bears the admin role (for the granted role).
* Expected in cases where the role was granted using the internal {AccessControl-_grantRole}.
*/
event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);
/**
* @dev Emitted when `account` is revoked `role`.
*
* `sender` is the account that originated the contract call:
* - if using `revokeRole`, it is the admin role bearer
* - if using `renounceRole`, it is the role bearer (i.e. `account`)
*/
event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);
/**
* @dev Returns `true` if `account` has been granted `role`.
*/
function hasRole(bytes32 role, address account) external view returns (bool);
/**
* @dev Returns the admin role that controls `role`. See {grantRole} and
* {revokeRole}.
*
* To change a role's admin, use {AccessControl-_setRoleAdmin}.
*/
function getRoleAdmin(bytes32 role) external view returns (bytes32);
/**
* @dev Grants `role` to `account`.
*
* If `account` had not been already granted `role`, emits a {RoleGranted}
* event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*/
function grantRole(bytes32 role, address account) external;
/**
* @dev Revokes `role` from `account`.
*
* If `account` had been granted `role`, emits a {RoleRevoked} event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*/
function revokeRole(bytes32 role, address account) external;
/**
* @dev Revokes `role` from the calling account.
*
* Roles are often managed via {grantRole} and {revokeRole}: this function's
* purpose is to provide a mechanism for accounts to lose their privileges
* if they are compromised (such as when a trusted device is misplaced).
*
* If the calling account had been granted `role`, emits a {RoleRevoked}
* event.
*
* Requirements:
*
* - the caller must be `callerConfirmation`.
*/
function renounceRole(bytes32 role, address callerConfirmation) external;
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.3.0) (token/ERC1155/IERC1155.sol)
pragma solidity ^0.8.20;
import {IERC165} from "../../utils/introspection/IERC165.sol";
/**
* @dev Required interface of an ERC-1155 compliant contract, as defined in the
* https://eips.ethereum.org/EIPS/eip-1155[ERC].
*/
interface IERC1155 is IERC165 {
/**
* @dev Emitted when `value` amount of tokens of type `id` are transferred from `from` to `to` by `operator`.
*/
event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);
/**
* @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all
* transfers.
*/
event TransferBatch(
address indexed operator,
address indexed from,
address indexed to,
uint256[] ids,
uint256[] values
);
/**
* @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to
* `approved`.
*/
event ApprovalForAll(address indexed account, address indexed operator, bool approved);
/**
* @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.
*
* If an {URI} event was emitted for `id`, the standard
* https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value
* returned by {IERC1155MetadataURI-uri}.
*/
event URI(string value, uint256 indexed id);
/**
* @dev Returns the value of tokens of token type `id` owned by `account`.
*/
function balanceOf(address account, uint256 id) external view returns (uint256);
/**
* @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.
*
* Requirements:
*
* - `accounts` and `ids` must have the same length.
*/
function balanceOfBatch(
address[] calldata accounts,
uint256[] calldata ids
) external view returns (uint256[] memory);
/**
* @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,
*
* Emits an {ApprovalForAll} event.
*
* Requirements:
*
* - `operator` cannot be the zero address.
*/
function setApprovalForAll(address operator, bool approved) external;
/**
* @dev Returns true if `operator` is approved to transfer ``account``'s tokens.
*
* See {setApprovalForAll}.
*/
function isApprovedForAll(address account, address operator) external view returns (bool);
/**
* @dev Transfers a `value` amount of tokens of type `id` from `from` to `to`.
*
* WARNING: This function can potentially allow a reentrancy attack when transferring tokens
* to an untrusted contract, when invoking {IERC1155Receiver-onERC1155Received} on the receiver.
* Ensure to follow the checks-effects-interactions pattern and consider employing
* reentrancy guards when interacting with untrusted contracts.
*
* Emits a {TransferSingle} event.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}.
* - `from` must have a balance of tokens of type `id` of at least `value` amount.
* - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
* acceptance magic value.
*/
function safeTransferFrom(address from, address to, uint256 id, uint256 value, bytes calldata data) external;
/**
* @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.
*
* WARNING: This function can potentially allow a reentrancy attack when transferring tokens
* to an untrusted contract, when invoking {IERC1155Receiver-onERC1155BatchReceived} on the receiver.
* Ensure to follow the checks-effects-interactions pattern and consider employing
* reentrancy guards when interacting with untrusted contracts.
*
* Emits either a {TransferSingle} or a {TransferBatch} event, depending on the length of the array arguments.
*
* Requirements:
*
* - `ids` and `values` must have the same length.
* - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
* acceptance magic value.
*/
function safeBatchTransferFrom(
address from,
address to,
uint256[] calldata ids,
uint256[] calldata values,
bytes calldata data
) external;
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.20;
/**
* @dev Interface of the ERC-20 standard as defined in the ERC.
*/
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 value of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the value of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves a `value` amount of 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 value) 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 a `value` amount of tokens 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 value) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from `from` to `to` using the
* allowance mechanism. `value` 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 value) external returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)
pragma solidity ^0.8.20;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/introspection/ERC165.sol)
pragma solidity ^0.8.20;
import {IERC165} from "./IERC165.sol";
/**
* @dev Implementation of the {IERC165} interface.
*
* Contracts that want to implement ERC-165 should inherit from this contract and override {supportsInterface} to check
* for the additional interface id that will be supported. For example:
*
* ```solidity
* function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
* return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
* }
* ```
*/
abstract contract ERC165 is IERC165 {
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/introspection/IERC165.sol)
pragma solidity ^0.8.20;
/**
* @dev Interface of the ERC-165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[ERC].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165 {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[ERC section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/ReentrancyGuard.sol)
pragma solidity ^0.8.20;
/**
* @dev Contract module that helps prevent reentrant calls to a function.
*
* Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
* available, which can be applied to functions to make sure there are no nested
* (reentrant) calls to them.
*
* Note that because there is a single `nonReentrant` guard, functions marked as
* `nonReentrant` may not call one another. This can be worked around by making
* those functions `private`, and then adding `external` `nonReentrant` entry
* points to them.
*
* TIP: If EIP-1153 (transient storage) is available on the chain you're deploying at,
* consider using {ReentrancyGuardTransient} instead.
*
* TIP: If you would like to learn more about reentrancy and alternative ways
* to protect against it, check out our blog post
* https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
*/
abstract contract ReentrancyGuard {
// Booleans are more expensive than uint256 or any type that takes up a full
// word because each write operation emits an extra SLOAD to first read the
// slot's contents, replace the bits taken up by the boolean, and then write
// back. This is the compiler's defense against contract upgrades and
// pointer aliasing, and it cannot be disabled.
// The values being non-zero value makes deployment a bit more expensive,
// but in exchange the refund on every call to nonReentrant will be lower in
// amount. Since refunds are capped to a percentage of the total
// transaction's gas, it is best to keep them low in cases like this one, to
// increase the likelihood of the full refund coming into effect.
uint256 private constant NOT_ENTERED = 1;
uint256 private constant ENTERED = 2;
uint256 private _status;
/**
* @dev Unauthorized reentrant call.
*/
error ReentrancyGuardReentrantCall();
constructor() {
_status = NOT_ENTERED;
}
/**
* @dev Prevents a contract from calling itself, directly or indirectly.
* Calling a `nonReentrant` function from another `nonReentrant`
* function is not supported. It is possible to prevent this from happening
* by making the `nonReentrant` function external, and making it call a
* `private` function that does the actual work.
*/
modifier nonReentrant() {
_nonReentrantBefore();
_;
_nonReentrantAfter();
}
function _nonReentrantBefore() private {
// On the first call to nonReentrant, _status will be NOT_ENTERED
if (_status == ENTERED) {
revert ReentrancyGuardReentrantCall();
}
// Any calls to nonReentrant after this point will fail
_status = ENTERED;
}
function _nonReentrantAfter() private {
// By storing the original value once again, a refund is triggered (see
// https://eips.ethereum.org/EIPS/eip-2200)
_status = NOT_ENTERED;
}
/**
* @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a
* `nonReentrant` function in the call stack.
*/
function _reentrancyGuardEntered() internal view returns (bool) {
return _status == ENTERED;
}
}// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.0;
import "./EntropyStructs.sol";
interface EntropyEvents {
event Registered(EntropyStructs.ProviderInfo provider);
event Requested(EntropyStructs.Request request);
event RequestedWithCallback(
address indexed provider,
address indexed requestor,
uint64 indexed sequenceNumber,
bytes32 userRandomNumber,
EntropyStructs.Request request
);
event Revealed(
EntropyStructs.Request request,
bytes32 userRevelation,
bytes32 providerRevelation,
bytes32 blockHash,
bytes32 randomNumber
);
event RevealedWithCallback(
EntropyStructs.Request request,
bytes32 userRandomNumber,
bytes32 providerRevelation,
bytes32 randomNumber
);
event ProviderFeeUpdated(address provider, uint128 oldFee, uint128 newFee);
event ProviderUriUpdated(address provider, bytes oldUri, bytes newUri);
event ProviderFeeManagerUpdated(
address provider,
address oldFeeManager,
address newFeeManager
);
event Withdrawal(
address provider,
address recipient,
uint128 withdrawnAmount
);
}// SPDX-License-Identifier: Apache 2
pragma solidity ^0.8.0;
contract EntropyStructs {
struct ProviderInfo {
uint128 feeInWei;
uint128 accruedFeesInWei;
// The commitment that the provider posted to the blockchain, and the sequence number
// where they committed to this. This value is not advanced after the provider commits,
// and instead is stored to help providers track where they are in the hash chain.
bytes32 originalCommitment;
uint64 originalCommitmentSequenceNumber;
// Metadata for the current commitment. Providers may optionally use this field to help
// manage rotations (i.e., to pick the sequence number from the correct hash chain).
bytes commitmentMetadata;
// Optional URI where clients can retrieve revelations for the provider.
// Client SDKs can use this field to automatically determine how to retrieve random values for each provider.
// TODO: specify the API that must be implemented at this URI
bytes uri;
// The first sequence number that is *not* included in the current commitment (i.e., an exclusive end index).
// The contract maintains the invariant that sequenceNumber <= endSequenceNumber.
// If sequenceNumber == endSequenceNumber, the provider must rotate their commitment to add additional random values.
uint64 endSequenceNumber;
// The sequence number that will be assigned to the next inbound user request.
uint64 sequenceNumber;
// The current commitment represents an index/value in the provider's hash chain.
// These values are used to verify requests for future sequence numbers. Note that
// currentCommitmentSequenceNumber < sequenceNumber.
//
// The currentCommitment advances forward through the provider's hash chain as values
// are revealed on-chain.
bytes32 currentCommitment;
uint64 currentCommitmentSequenceNumber;
// An address that is authorized to set / withdraw fees on behalf of this provider.
address feeManager;
}
struct Request {
// Storage slot 1 //
address provider;
uint64 sequenceNumber;
// The number of hashes required to verify the provider revelation.
uint32 numHashes;
// Storage slot 2 //
// The commitment is keccak256(userCommitment, providerCommitment). Storing the hash instead of both saves 20k gas by
// eliminating 1 store.
bytes32 commitment;
// Storage slot 3 //
// The number of the block where this request was created.
// Note that we're using a uint64 such that we have an additional space for an address and other fields in
// this storage slot. Although block.number returns a uint256, 64 bits should be plenty to index all of the
// blocks ever generated.
uint64 blockNumber;
// The address that requested this random number.
address requester;
// If true, incorporate the blockhash of blockNumber into the generated random value.
bool useBlockhash;
// If true, the requester will be called back with the generated random value.
bool isRequestWithCallback;
// There are 2 remaining bytes of free space in this slot.
}
}// SPDX-License-Identifier: Apache 2
pragma solidity ^0.8.0;
import "./EntropyEvents.sol";
interface IEntropy is EntropyEvents {
// Register msg.sender as a randomness provider. The arguments are the provider's configuration parameters
// and initial commitment. Re-registering the same provider rotates the provider's commitment (and updates
// the feeInWei).
//
// chainLength is the number of values in the hash chain *including* the commitment, that is, chainLength >= 1.
function register(
uint128 feeInWei,
bytes32 commitment,
bytes calldata commitmentMetadata,
uint64 chainLength,
bytes calldata uri
) external;
// Withdraw a portion of the accumulated fees for the provider msg.sender.
// Calling this function will transfer `amount` wei to the caller (provided that they have accrued a sufficient
// balance of fees in the contract).
function withdraw(uint128 amount) external;
// Withdraw a portion of the accumulated fees for provider. The msg.sender must be the fee manager for this provider.
// Calling this function will transfer `amount` wei to the caller (provided that they have accrued a sufficient
// balance of fees in the contract).
function withdrawAsFeeManager(address provider, uint128 amount) external;
// As a user, request a random number from `provider`. Prior to calling this method, the user should
// generate a random number x and keep it secret. The user should then compute hash(x) and pass that
// as the userCommitment argument. (You may call the constructUserCommitment method to compute the hash.)
//
// This method returns a sequence number. The user should pass this sequence number to
// their chosen provider (the exact method for doing so will depend on the provider) to retrieve the provider's
// number. The user should then call fulfillRequest to construct the final random number.
//
// This method will revert unless the caller provides a sufficient fee (at least getFee(provider)) as msg.value.
// Note that excess value is *not* refunded to the caller.
function request(
address provider,
bytes32 userCommitment,
bool useBlockHash
) external payable returns (uint64 assignedSequenceNumber);
// Request a random number. The method expects the provider address and a secret random number
// in the arguments. It returns a sequence number.
//
// The address calling this function should be a contract that inherits from the IEntropyConsumer interface.
// The `entropyCallback` method on that interface will receive a callback with the generated random number.
//
// This method will revert unless the caller provides a sufficient fee (at least getFee(provider)) as msg.value.
// Note that excess value is *not* refunded to the caller.
function requestWithCallback(
address provider,
bytes32 userRandomNumber
) external payable returns (uint64 assignedSequenceNumber);
// Fulfill a request for a random number. This method validates the provided userRandomness and provider's proof
// against the corresponding commitments in the in-flight request. If both values are validated, this function returns
// the corresponding random number.
//
// Note that this function can only be called once per in-flight request. Calling this function deletes the stored
// request information (so that the contract doesn't use a linear amount of storage in the number of requests).
// If you need to use the returned random number more than once, you are responsible for storing it.
function reveal(
address provider,
uint64 sequenceNumber,
bytes32 userRevelation,
bytes32 providerRevelation
) external returns (bytes32 randomNumber);
// Fulfill a request for a random number. This method validates the provided userRandomness
// and provider's revelation against the corresponding commitment in the in-flight request. If both values are validated
// and the requestor address is a contract address, this function calls the requester's entropyCallback method with the
// sequence number, provider address and the random number as arguments. Else if the requestor is an EOA, it won't call it.
//
// Note that this function can only be called once per in-flight request. Calling this function deletes the stored
// request information (so that the contract doesn't use a linear amount of storage in the number of requests).
// If you need to use the returned random number more than once, you are responsible for storing it.
//
// Anyone can call this method to fulfill a request, but the callback will only be made to the original requester.
function revealWithCallback(
address provider,
uint64 sequenceNumber,
bytes32 userRandomNumber,
bytes32 providerRevelation
) external;
function getProviderInfo(
address provider
) external view returns (EntropyStructs.ProviderInfo memory info);
function getDefaultProvider() external view returns (address provider);
function getRequest(
address provider,
uint64 sequenceNumber
) external view returns (EntropyStructs.Request memory req);
function getFee(address provider) external view returns (uint128 feeAmount);
function getAccruedPythFees()
external
view
returns (uint128 accruedPythFeesInWei);
function setProviderFee(uint128 newFeeInWei) external;
function setProviderFeeAsFeeManager(
address provider,
uint128 newFeeInWei
) external;
function setProviderUri(bytes calldata newUri) external;
// Set manager as the fee manager for the provider msg.sender.
// After calling this function, manager will be able to set the provider's fees and withdraw them.
// Only one address can be the fee manager for a provider at a time -- calling this function again with a new value
// will override the previous value. Call this function with the all-zero address to disable the fee manager role.
function setFeeManager(address manager) external;
function constructUserCommitment(
bytes32 userRandomness
) external pure returns (bytes32 userCommitment);
function combineRandomValues(
bytes32 userRandomness,
bytes32 providerRandomness,
bytes32 blockHash
) external pure returns (bytes32 combinedRandomness);
}// SPDX-License-Identifier: Apache 2
pragma solidity ^0.8.0;
abstract contract IEntropyConsumer {
// This method is called by Entropy to provide the random number to the consumer.
// It asserts that the msg.sender is the Entropy contract. It is not meant to be
// override by the consumer.
function _entropyCallback(
uint64 sequence,
address provider,
bytes32 randomNumber
) external {
address entropy = getEntropy();
require(entropy != address(0), "Entropy address not set");
require(msg.sender == entropy, "Only Entropy can call this function");
entropyCallback(sequence, provider, randomNumber);
}
// getEntropy returns Entropy contract address. The method is being used to check that the
// callback is indeed from Entropy contract. The consumer is expected to implement this method.
// Entropy address can be found here - https://docs.pyth.network/entropy/contract-addresses
function getEntropy() internal view virtual returns (address);
// This method is expected to be implemented by the consumer to handle the random number.
// It will be called by _entropyCallback after _entropyCallback ensures that the call is
// indeed from Entropy contract.
function entropyCallback(
uint64 sequence,
address provider,
bytes32 randomNumber
) internal virtual;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.22;
import {IERC1155} from "@openzeppelin/contracts/token/ERC1155/IERC1155.sol";
interface IDiggaResources is IERC1155 {
function burn(address account, uint256 id, uint256 amount) external;
function mint(address account, uint256 id, uint256 amount, bytes memory data) external;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.22;
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
interface IDiggaToken is IERC20 {
function burnFrom(address account, uint256 amount) external;
function mint(address to, uint256 amount) external;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.22;
library DiggaLibrary {
enum Resources {
Experience,
Shovel_Wood, // Pelles de bois
Shovel_Stone, // Pelles de pierre
Shovel_Iron, // Pelles de fer
Shovel_Gold, // Pelles d'or
Shovel_Diamond, // Pelles de diamant
Hole_Basic,
Hole_Advanced,
Hole_Epic,
Hole_Legendary
}
}{
"optimizer": {
"enabled": true,
"runs": 100000
},
"viaIR": true,
"evmVersion": "paris",
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"entropyAddress","type":"address"},{"internalType":"address","name":"diggaAddress","type":"address"},{"internalType":"address","name":"diggaResourcesAddress","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AccessControlBadConfirmation","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bytes32","name":"neededRole","type":"bytes32"}],"name":"AccessControlUnauthorizedAccount","type":"error"},{"inputs":[],"name":"InsufficientDIGGABalance","type":"error"},{"inputs":[],"name":"InvalidAddress","type":"error"},{"inputs":[],"name":"InvalidAmounts","type":"error"},{"inputs":[],"name":"InvalidProvider","type":"error"},{"inputs":[],"name":"InvalidRequest","type":"error"},{"inputs":[],"name":"InvalidRequestState","type":"error"},{"inputs":[],"name":"InvalidStakeAmount","type":"error"},{"inputs":[],"name":"NeedMoreExperienceToClaim","type":"error"},{"inputs":[],"name":"NoFreeDiggingAvailable","type":"error"},{"inputs":[],"name":"ReentrancyGuardReentrantCall","type":"error"},{"inputs":[],"name":"RequestAlreadyCompleted","type":"error"},{"inputs":[],"name":"RequestNotCompleted","type":"error"},{"inputs":[],"name":"SelfReferralNotAllowed","type":"error"},{"inputs":[],"name":"TransferFailed","type":"error"},{"inputs":[],"name":"UseFreeDiggingFirst","type":"error"},{"inputs":[],"name":"UserAlreadyHasFreeDigging","type":"error"},{"inputs":[],"name":"UserAlreadyHasReferrer","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8[3]","name":"artefacts","type":"uint8[3]"},{"indexed":true,"internalType":"address","name":"winner","type":"address"},{"indexed":false,"internalType":"uint128","name":"winStake","type":"uint128"},{"indexed":true,"internalType":"bool","name":"isWin","type":"bool"}],"name":"DiggingResult","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint128","name":"amount","type":"uint128"}],"name":"FreeDiggingAwarded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"minimalStake","type":"uint256"}],"name":"NewBaseStake","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint80[3]","name":"rngs","type":"uint80[3]"}],"name":"RNG","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint64","name":"sequenceNumber","type":"uint64"},{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint128","name":"stake","type":"uint128"}],"name":"RandomNumberRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"referrer","type":"address"},{"indexed":false,"internalType":"uint128","name":"amount","type":"uint128"}],"name":"ReferralExperienceMinted","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"},{"inputs":[],"name":"AIRDROP_CLAIMER","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FARM_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"REFEREE_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"sequence","type":"uint64"},{"internalType":"address","name":"provider","type":"address"},{"internalType":"bytes32","name":"randomNumber","type":"bytes32"}],"name":"_entropyCallback","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint128","name":"digs","type":"uint128"},{"internalType":"uint128","name":"stake","type":"uint128"}],"name":"awardFreeDigs","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claimAirdropReserves","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claimExperience","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claimPeriodRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"deposit","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint128","name":"stake","type":"uint128"}],"name":"dig","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"freeDig","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"getAirdropPool","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMinimalStake","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMultipliers","outputs":[{"internalType":"uint128[7]","name":"","type":"uint128[7]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"getPendingPeriodRewards","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getQuestConstants","outputs":[{"internalType":"uint128","name":"bonusMultiplier","type":"uint128"},{"internalType":"uint128","name":"monthlyBonus","type":"uint128"},{"internalType":"uint128","name":"baseReward","type":"uint128"},{"internalType":"uint40","name":"claimPeriod","type":"uint40"},{"internalType":"uint16","name":"minDigsForReward","type":"uint16"},{"internalType":"uint16","name":"bonusThreshold1","type":"uint16"},{"internalType":"uint16","name":"bonusThreshold2","type":"uint16"},{"internalType":"uint16","name":"monthlyQuestsRequired","type":"uint16"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint64","name":"sequenceNumber","type":"uint64"}],"name":"getRequest","outputs":[{"components":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint64","name":"sequenceNumber","type":"uint64"},{"internalType":"uint128","name":"stake","type":"uint128"},{"internalType":"bytes32","name":"userRandomNumber","type":"bytes32"}],"internalType":"struct DiggaGame.Request","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"sequenceNumber","type":"uint64"}],"name":"getResult","outputs":[{"components":[{"internalType":"address","name":"winner","type":"address"},{"internalType":"uint128","name":"winStake","type":"uint128"},{"internalType":"uint8[3]","name":"artefacts","type":"uint8[3]"},{"internalType":"bool","name":"isWin","type":"bool"}],"internalType":"struct DiggaGame.Result","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getRngFees","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"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":"address","name":"user","type":"address"}],"name":"getUserState","outputs":[{"components":[{"internalType":"uint128","name":"freeDigging","type":"uint128"},{"internalType":"uint128","name":"freeDiggingStake","type":"uint128"},{"internalType":"uint128","name":"experience","type":"uint128"},{"internalType":"uint8[3]","name":"lastDigging","type":"uint8[3]"},{"internalType":"uint16","name":"totalDigs","type":"uint16"}],"internalType":"struct DiggaGame.DigState","name":"digState","type":"tuple"},{"components":[{"internalType":"uint40","name":"lastClaimTimestamp","type":"uint40"},{"internalType":"uint16","name":"completedQuests","type":"uint16"},{"internalType":"bool","name":"hasClaimed","type":"bool"}],"internalType":"struct DiggaGame.QuestState","name":"questState","type":"tuple"}],"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":"uint64","name":"sequenceNumber","type":"uint64"}],"name":"isRequestCompleted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newAddress","type":"address"}],"name":"newOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"registerMe","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"callerConfirmation","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"","type":"uint64"}],"name":"requestStates","outputs":[{"components":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint64","name":"sequenceNumber","type":"uint64"},{"internalType":"uint128","name":"stake","type":"uint128"},{"internalType":"bytes32","name":"userRandomNumber","type":"bytes32"}],"internalType":"struct DiggaGame.Request","name":"request","type":"tuple"},{"internalType":"bool","name":"completed","type":"bool"},{"components":[{"internalType":"address","name":"winner","type":"address"},{"internalType":"uint128","name":"winStake","type":"uint128"},{"internalType":"uint8[3]","name":"artefacts","type":"uint8[3]"},{"internalType":"bool","name":"isWin","type":"bool"}],"internalType":"struct DiggaGame.Result","name":"result","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newDiggaAddress","type":"address"}],"name":"setDiggaAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newDiggaResourcesAddress","type":"address"}],"name":"setDiggaResourcesAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newEntropyAddress","type":"address"}],"name":"setEntropyAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint128","name":"amount","type":"uint128"}],"name":"setMinimalStake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"referrer","type":"address"},{"internalType":"address","name":"user","type":"address"}],"name":"setReferrer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint128","name":"newRngFees","type":"uint128"}],"name":"setRngFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"setRngFeesAjusted","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":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]Contract Creation Code
6080806040523461027057606081613f9a803803809161001f828561030e565b8339810103126102705761003281610331565b61004a604061004360208501610331565b9301610331565b600160005560405190919060e081016001600160401b038111828210176102f85760405260058152600a6020820152601460408201526032606082015260fa60808201526103e860a0820152600060c082015260005b600381106102ae575060009060005b6001811061027d575050600a55600280546001600160801b031916670de0b6b3a7640000179055600380546001600160a01b03199081166001600160a01b0393841690811790925560048054821695841695909517855560058054909116939092169290921790556040516320bba64360e21b81529091602090829081855afa80156102325760009061023e575b604051631711922960e31b81526001600160a01b0390911660048201529160209150829060249082905afa908115610232576000916101e9575b506001600160801b0316607d81810291808304909114901517156101d357600680546001600160801b0316606490920460801b6001600160801b0319169190911790556101c333610345565b50604051613ba690816103d48239f35b634e487b7160e01b600052601160045260246000fd5b6020813d60201161022a575b816102026020938361030e565b810103126102265751906001600160801b0382168203610223575038610177565b80fd5b5080fd5b3d91506101f5565b6040513d6000823e3d90fd5b506020813d602011610275575b816102586020938361030e565b810103126102705761026b602091610331565b61013d565b600080fd5b3d915061024b565b81519192909160019160209161ffff16600785901b90811b6001600160801b0390911b1990911617930191016100af565b6000805b600281106102c8575060078201556001016100a0565b835160209094019361ffff16600782901b90811b6001600160801b0390911b1990921691909117906001016102b2565b634e487b7160e01b600052604160045260246000fd5b601f909101601f19168101906001600160401b038211908210176102f857604052565b51906001600160a01b038216820361027057565b6001600160a01b0381166000908152600080516020613f7a833981519152602052604090205460ff166103cd576001600160a01b03166000818152600080516020613f7a83398151915260205260408120805460ff191660011790553391907f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d8180a4600190565b5060009056fe608080604052600436101561001d575b50361561001b57600080fd5b005b600090813560e01c90816301ffc9a714612a315750806315f4b23f146129af578063248a9ca31461295b57806326e8500f1461288a5780632c2ed6cf146128175780632f2ff15d146127b857806331ff060c1461276a57806335d06f2a146124da57806336568abe146124515780633ccfd60b146123c9578063416ae768146122685780635140f3281461207f57806352a5f1f81461187e5780636318754d1461181f57806371104c36146117c657806379873f8a146116e05780637c293a021461154257806385952454146114ab57806391d148541461143357806393ad9550146113b1578063945ffa2f146112315780639a198d61146111365780639d566523146110e8578063a217fddf146110ae578063af74bc1414611055578063b62b78a614610d3f578063bac14f5314610ab0578063bbddaca3146108b3578063cbbf67ec146107e1578063d05aad771461075f578063d0e30db014610732578063d30c077c146106f3578063d455530f1461069a578063d547741f14610632578063dd8b38be146105d6578063e20c1848146103ce578063edff42d61461033a578063f4d22691146102b75763fcdb9d360361000f57346102b45760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102b45760406101609167ffffffffffffffff610219612b84565b168152600d602052206102b261022e82612cb5565b91610243600460ff6003840154169201612d46565b906102a160405180956060809173ffffffffffffffffffffffffffffffffffffffff815116845267ffffffffffffffff60208201511660208501526fffffffffffffffffffffffffffffffff60408201511660408501520151910152565b1515608084015260a0830190612b9b565bf35b80fd5b50346102b45760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102b4576102ef612b3a565b6102f76130a3565b6fffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffff000000000000000000000000000000006006549260801b1691161760065580f35b50346102b45760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102b4576103c16004604060c09367ffffffffffffffff610385612b84565b826060855161039381612c58565b82815282602082015286516103a88382612c74565b82368237878201520152168152600d6020522001612d46565b6102b26040518092612b9b565b50346102b45760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102b457610406612aef565b90602435916fffffffffffffffffffffffffffffffff831683036105d257604435906fffffffffffffffffffffffffffffffff8216908183036105ce577f08e2fe187e4fb484bb675d870bd92d638b9fe0a6ca9c0c64fe8209d4beb48519845260016020526040842073ffffffffffffffffffffffffffffffffffffffff331660005260205260ff604060002054161561057e5773ffffffffffffffffffffffffffffffffffffffff168352600b602052604083209081546fffffffffffffffffffffffffffffffff8116918215159182610570575b50506105485761050161054594956fffffffffffffffffffffffffffffffff92612e71565b6fffffffffffffffffffffffffffffffff91161660809290921b7fffffffffffffffffffffffffffffffff0000000000000000000000000000000016919091179055565b80f35b6004847fa2bfdd59000000000000000000000000000000000000000000000000000000008152fd5b60801c1415905038806104dc565b6044847fe2517d3f000000000000000000000000000000000000000000000000000000008152336004527f08e2fe187e4fb484bb675d870bd92d638b9fe0a6ca9c0c64fe8209d4beb48519602452fd5b8380fd5b5080fd5b50346102b45760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102b4576020610618610613612aef565b612fa0565b6fffffffffffffffffffffffffffffffff60405191168152f35b50346102b45760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102b457610696600435610670612b17565b9061069161068c82600052600160205260016040600020015490565b61310f565b613420565b5080f35b50346102b457807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102b45760206040517f08e2fe187e4fb484bb675d870bd92d638b9fe0a6ca9c0c64fe8209d4beb485198152f35b50346102b457807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102b457602060065460801c604051908152f35b50807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102b45780f35b50346102b45760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102b45773ffffffffffffffffffffffffffffffffffffffff6107ac612aef565b6107b46130a3565b167fffffffffffffffffffffffff0000000000000000000000000000000000000000600454161760045580f35b50346102b45760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102b457610856604060809267ffffffffffffffff61082a612b84565b826060855161083881612c58565b82815282602082015282878201520152168152600d60205220612cb5565b6102b260405180926060809173ffffffffffffffffffffffffffffffffffffffff815116845267ffffffffffffffff60208201511660208501526fffffffffffffffffffffffffffffffff60408201511660408501520151910152565b50346102b45760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102b4576108eb612aef565b6108f3612b17565b907faef88082b8671e875d97d0d6c81d06fb9e76f97b3ad7523a55a378e5298aeeee835260016020526040832073ffffffffffffffffffffffffffffffffffffffff331660005260205260ff6040600020541615610a605773ffffffffffffffffffffffffffffffffffffffff16908115610a385773ffffffffffffffffffffffffffffffffffffffff168015610a3857808352600e60205273ffffffffffffffffffffffffffffffffffffffff604084205416610a10578181146109e8578252600e60205260408220907fffffffffffffffffffffffff000000000000000000000000000000000000000082541617905580f35b6004837f83463f4a000000000000000000000000000000000000000000000000000000008152fd5b6004837fb027d58e000000000000000000000000000000000000000000000000000000008152fd5b6004837fe6c4247b000000000000000000000000000000000000000000000000000000008152fd5b6044837fe2517d3f000000000000000000000000000000000000000000000000000000008152336004527faef88082b8671e875d97d0d6c81d06fb9e76f97b3ad7523a55a378e5298aeeee602452fd5b50346102b457807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102b457610ae7613588565b338152600b602052600160408220016fffffffffffffffffffffffffffffffff8154166127108110610d17578290606473ffffffffffffffffffffffffffffffffffffffff600554169104813b15610d13576fffffffffffffffffffffffffffffffff60a484928360405195869485937f731133e9000000000000000000000000000000000000000000000000000000008552336004860152836024860152166044840152608060648401528160848401525af18015610cf357610cfe575b5050338252600e60205273ffffffffffffffffffffffffffffffffffffffff60408320541680610bff575b507fffffffffffffffffffffffffffffffff0000000000000000000000000000000081541690556001815580f35b60646fffffffffffffffffffffffffffffffff601481855416041604836fffffffffffffffffffffffffffffffff73ffffffffffffffffffffffffffffffffffffffff60055416921691803b156105d25781809160a4604051809481937f731133e9000000000000000000000000000000000000000000000000000000008352896004840152816024840152886044840152608060648401528160848401525af18015610cf357610cde575b505060207fede1ca8e7bdbd055149ea55be3038250bb1eb503b2783bf356cb78895d20df8e91604051908152a238610bd1565b81610ce891612c74565b6105ce578338610cab565b6040513d84823e3d90fd5b81610d0891612c74565b6105d2578138610ba6565b8280fd5b6004837f7c42ccf4000000000000000000000000000000000000000000000000000000008152fd5b5060207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102b457610d72612b3a565b610d7a613588565b60065460801c341061102d576fffffffffffffffffffffffffffffffff600254166fffffffffffffffffffffffffffffffff821690811061100557338352600b60205260408320906fffffffffffffffffffffffffffffffff825416610fdd578373ffffffffffffffffffffffffffffffffffffffff60045416803b156105d2578180916044604051809481937f79cc67900000000000000000000000000000000000000000000000000000000083523360048401528860248401525af18015610cf357610fc8575b5050600a81026fffffffffffffffffffffffffffffffff8116908103610f9b5790612710606492047fffffffffffffffffffffffffffffffff000000000000000000000000000000006fffffffffffffffffffffffffffffffff610eac60065493828516612e71565b16911617600655026fffffffffffffffffffffffffffffffff8116908103610f6e57610f679291670de0b6b3a7640000600392046fffffffffffffffffffffffffffffffff610f02600184019282845416612e71565b167fffffffffffffffffffffffffffffffff000000000000000000000000000000008254161790550161ffff610f3a81835416612e2a565b167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00008254161790556135c3565b6001815580f35b6024847f4e487b710000000000000000000000000000000000000000000000000000000081526011600452fd5b6024857f4e487b710000000000000000000000000000000000000000000000000000000081526011600452fd5b81610fd291612c74565b6105ce578338610e43565b6004847fb392d881000000000000000000000000000000000000000000000000000000008152fd5b6004837f040ef8ec000000000000000000000000000000000000000000000000000000008152fd5b6004827fd856fc5a000000000000000000000000000000000000000000000000000000008152fd5b50346102b457807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102b45760206040517faef88082b8671e875d97d0d6c81d06fb9e76f97b3ad7523a55a378e5298aeeee8152f35b50346102b457807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102b457602090604051908152f35b50346102b457807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102b45760206fffffffffffffffffffffffffffffffff60065416604051908152f35b50346102b457807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102b457808060405160208101907f1e60fd1400000000000000000000000000000000000000000000000000000000825260916024820152602481526111a8604482612c74565b51908273dc2b0d2dd2b7759d97d50db4eabdc369731108305af16111ca612ea3565b50156111d35780f35b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f4665654d20726567697374726174696f6e206661696c656400000000000000006044820152fd5b50807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102b457611263613588565b338152600b6020526040812080546fffffffffffffffffffffffffffffffff8116156113895760065460801c34106113615760801c8015611361576112a7906135c3565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6fffffffffffffffffffffffffffffffff825416016fffffffffffffffffffffffffffffffff8111611334576fffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffff000000000000000000000000000000008254161790556001815580f35b6024837f4e487b710000000000000000000000000000000000000000000000000000000081526011600452fd5b6004837fd856fc5a000000000000000000000000000000000000000000000000000000008152fd5b6004837fbc2e7b13000000000000000000000000000000000000000000000000000000008152fd5b50346102b45760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102b45773ffffffffffffffffffffffffffffffffffffffff6113fe612aef565b6114066130a3565b167fffffffffffffffffffffffff0000000000000000000000000000000000000000600354161760035580f35b50346102b45760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102b45773ffffffffffffffffffffffffffffffffffffffff6040611482612b17565b9260043581526001602052209116600052602052602060ff604060002054166040519015158152f35b50346102b45760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102b4576114e3612aef565b6114eb6130a3565b73ffffffffffffffffffffffffffffffffffffffff81161561151a576115109061317c565b506106963361333e565b6004827fe6c4247b000000000000000000000000000000000000000000000000000000008152fd5b50346102b457807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102b4577f617b7366a53d5e938aa39800cda5d5b3cb5a765907174ff1971dcbc731804e06815260016020526040812073ffffffffffffffffffffffffffffffffffffffff331660005260205260ff6040600020541615611690578073ffffffffffffffffffffffffffffffffffffffff600454166fffffffffffffffffffffffffffffffff6006541690803b1561168c576040517f40c10f19000000000000000000000000000000000000000000000000000000008152336004820152602481019290925282908290604490829084905af18015610cf357611677575b507fffffffffffffffffffffffffffffffff000000000000000000000000000000006006541660065580f35b8161168191612c74565b6102b457803861164b565b5050fd5b807fe2517d3f0000000000000000000000000000000000000000000000000000000060449252336004527f617b7366a53d5e938aa39800cda5d5b3cb5a765907174ff1971dcbc731804e06602452fd5b50346102b457807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102b45760e090816040516117208282612c74565b36903760405190816007825b600760018201106117935750546fffffffffffffffffffffffffffffffff1690526117578383612c74565b6040519190825b6007821061176b57505050f35b6020806001926fffffffffffffffffffffffffffffffff86511681520193019101909161175e565b81546fffffffffffffffffffffffffffffffff8116845260801c602084015260409092019160019091019060020161172c565b50346102b457807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102b45760206040517f617b7366a53d5e938aa39800cda5d5b3cb5a765907174ff1971dcbc731804e068152f35b50346102b45760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102b45760ff6003604060209367ffffffffffffffff611869612b84565b168152600d8552200154166040519015158152f35b50346102b45760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102b4576118b6612b84565b6118be612b17565b506044359073ffffffffffffffffffffffffffffffffffffffff600354168015612021573303611f9d5767ffffffffffffffff16808352600d602052604083206060906040519061190f8383612c74565b8236833773ffffffffffffffffffffffffffffffffffffffff81541615611f7557600381019460ff865416611f4d57865b60038110611f1757505060016fffffffffffffffffffffffffffffffff9101541691604051916119708284612c74565b81368437848752600d60205273ffffffffffffffffffffffffffffffffffffffff60408820541693848852600b6020526040882091885b60038110611e055750508351600760ff82161015611dd857806080617f80607f6fffffffffffffffffffffffffffffffff9460011c16600701549260071b16161c168102916fffffffffffffffffffffffffffffffff8316928303611dab5760ff85511660ff602087015116149182611d95575b8280611d8c575b611ce6575b6fffffffffffffffffffffffffffffffff825416611ca1575b508115611c9b57825b8960405191611a5783612c58565b8883526fffffffffffffffffffffffffffffffff60208401911681526fffffffffffffffffffffffffffffffff604084019189835273ffffffffffffffffffffffffffffffffffffffff60408a8701958915159e8f88528152600d6020522095511673ffffffffffffffffffffffffffffffffffffffff6004870191167fffffffffffffffffffffffff000000000000000000000000000000000000000082541617905551166fffffffffffffffffffffffffffffffff6005850191167fffffffffffffffffffffffffffffffff00000000000000000000000000000000825416179055518b908c5b60038110611c6d57505082916007916006611b8c95015551151591019060ff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0083541691151516179055565b889085825b60038110611c3f5750506002015515611c38575b6040519287845b60038210611c1f575050506fffffffffffffffffffffffffffffffff16908201527f924ed04bd50ab8e80b69ebf285df0bd772014e87fba679821fa39b1a2753d22b90608090a360017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082541617905580f35b60208060019260ff865116815201930191019091611bac565b5085611ba5565b90926020611c646001928460ff885116919060ff809160031b9316831b921b19161790565b94019101611b91565b90916020611c926001928460ff875116919060ff809160031b9316831b921b19161790565b93019101611b40565b88611a49565b81546fffffffffffffffffffffffffffffffff1660809190911b7fffffffffffffffffffffffffffffffff000000000000000000000000000000001617815538611a40565b73ffffffffffffffffffffffffffffffffffffffff600454168a813b156102b4576040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8a16600482015260248101879052918290604490829084905af18015611d8157611d6d575b50611a27565b8a611d7a919b929b612c74565b9838611d67565b6040513d8d823e3d90fd5b50831515611a22565b915060ff85511660ff6040870151161491611a1b565b6024897f4e487b710000000000000000000000000000000000000000000000000000000081526011600452fd5b6024897f4e487b710000000000000000000000000000000000000000000000000000000081526032600452fd5b611e1e60ff6061611e168486613548565b510616613b1c565b60ff611e2a8389613548565b91169052600660ff611e3c8389613548565b511614611e4c575b6001016119a7565b60036fffffffffffffffffffffffffffffffff855416016fffffffffffffffffffffffffffffffff8111611eea57906fffffffffffffffffffffffffffffffff600192167fffffffffffffffffffffffffffffffff00000000000000000000000000000000865416178555877f18b8046382a3c246493e09c351024b814d62fe474031bed134120b055239613a602060405160038152a29050611e44565b60248b7f4e487b710000000000000000000000000000000000000000000000000000000081526011600452fd5b600190604051602081019084825282604082015260408152611f398882612c74565b519020611f468287613548565b5201611940565b6004877ffb776379000000000000000000000000000000000000000000000000000000008152fd5b6004867f41abc801000000000000000000000000000000000000000000000000000000008152fd5b60846040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f4f6e6c7920456e74726f70792063616e2063616c6c20746869732066756e637460448201527f696f6e00000000000000000000000000000000000000000000000000000000006064820152fd5b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f456e74726f70792061646472657373206e6f74207365740000000000000000006044820152fd5b50346102b457807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102b4576120b66130a3565b73ffffffffffffffffffffffffffffffffffffffff600354166040517f82ee990c000000000000000000000000000000000000000000000000000000008152602081600481855afa801561225d57602473ffffffffffffffffffffffffffffffffffffffff916020938691612230575b5060405194859384927fb88c91480000000000000000000000000000000000000000000000000000000084521660048301525afa8015610cf3576fffffffffffffffffffffffffffffffff918391612201575b5016607d810290808204607d14901517156121d4576fffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffff000000000000000000000000000000006064600654930460801b1691161760065580f35b6024827f4e487b710000000000000000000000000000000000000000000000000000000081526011600452fd5b612223915060203d602011612229575b61221b8183612c74565b810190613520565b38612179565b503d612211565b6122509150843d8611612256575b6122488183612c74565b8101906134f4565b38612126565b503d61223e565b6040513d85823e3d90fd5b50346102b45760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102b4576101409060406122a6612aef565b9161ffff60806123386123328573ffffffffffffffffffffffffffffffffffffffff8151986122d48a612bf1565b878a528760208b015287838b0152878660609b8c6122f487519182612c74565b8d3682378d82015201528783805161230b81612c3c565b82815282602082015201521695868152600b602052818120968152600c6020522094612f01565b93612f6a565b926123988551966fffffffffffffffffffffffffffffffff83511688526fffffffffffffffffffffffffffffffff60208401511660208901526fffffffffffffffffffffffffffffffff8784015116878901528083015190880190612b59565b01511660c084015264ffffffffff81511660e084015261ffff60208201511661010084015201511515610120820152f35b50346102b457807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102b4576124006130a3565b4760065460801c81039081116121d4578180808093335af1612420612ea3565b50156124295780f35b807f90b8ec180000000000000000000000000000000000000000000000000000000060049252fd5b50346102b45760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102b457612489612b17565b3373ffffffffffffffffffffffffffffffffffffffff8216036124b25761069690600435613420565b6004827f6697b232000000000000000000000000000000000000000000000000000000008152fd5b50346102b457807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102b457338152600c60205260408120338252600b602052604082209064ffffffffff4216815464ffffffffff61253d818316612dac565b168211612740575b5081549260ff8460381c1661271857600381019361ffff85541690603282106126f05790670100000000000000939291622625a09160508110156126e5575b60a011156126d0575b61ffff9060281c16600461ffff6125a383612e2a565b160361267557506125fc60016125c96fffffffffffffffffffffffffffffffff93612e3e565b937fffffffffffffffffffffffffffffffffffffffffffffffffff0000ffffffffff88541688555b019282845416612e71565b167fffffffffffffffffffffffffffffffff000000000000000000000000000000008254161790557fffffffffffffffffffffffffffffffffffffffffffffffff00ffff0000000000835416171790557fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000815416905580f35b60016fffffffffffffffffffffffffffffffff92936126966125fc93612e2a565b7fffffffffffffffffffffffffffffffffffffffffffffffffff0000ffffffffff66ffff00000000008a549260281b1691161788556125f1565b906126dd61ffff91612df7565b91905061258d565b624c4b409250612584565b6004877f41abc801000000000000000000000000000000000000000000000000000000008152fd5b6004857ffb776379000000000000000000000000000000000000000000000000000000008152fd5b7fffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffff16825538612545565b50346102b457807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102b45760206fffffffffffffffffffffffffffffffff60025416604051908152f35b50346102b45760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102b4576106966004356127f6612b17565b9061281261068c82600052600160205260016040600020015490565b613266565b50346102b457807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102b457610100604051600281526301312d006020820152622625a0604082015262093a80606082015260326080820152605060a082015260a060c0820152600460e0820152f35b50346102b45760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102b4576fffffffffffffffffffffffffffffffff6128d3612b3a565b6128db6130a3565b16801561293357807fffffffffffffffffffffffffffffffff0000000000000000000000000000000060025416176002557fbd249363dcf68d3781deb8de6ddf794b2eb3f769e65757014396e6644f1aef478280a280f35b6004827f040ef8ec000000000000000000000000000000000000000000000000000000008152fd5b50346102b45760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102b45760206129a7600435600052600160205260016040600020015490565b604051908152f35b50346102b45760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102b45773ffffffffffffffffffffffffffffffffffffffff6129fc612aef565b612a046130a3565b167fffffffffffffffffffffffff0000000000000000000000000000000000000000600554161760055580f35b9050346105d25760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126105d2576004357fffffffff000000000000000000000000000000000000000000000000000000008116809103610d1357602092507f7965db0b000000000000000000000000000000000000000000000000000000008114908115612ac5575b5015158152f35b7f01ffc9a70000000000000000000000000000000000000000000000000000000091501438612abe565b6004359073ffffffffffffffffffffffffffffffffffffffff82168203612b1257565b600080fd5b6024359073ffffffffffffffffffffffffffffffffffffffff82168203612b1257565b600435906fffffffffffffffffffffffffffffffff82168203612b1257565b906000905b60038210612b6b57505050565b60208060019260ff865116815201930191019091612b5e565b6004359067ffffffffffffffff82168203612b1257565b606060a09173ffffffffffffffffffffffffffffffffffffffff81511684526fffffffffffffffffffffffffffffffff6020820151166020850152612be860408201516040860190612b59565b01511515910152565b60a0810190811067ffffffffffffffff821117612c0d57604052565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6060810190811067ffffffffffffffff821117612c0d57604052565b6080810190811067ffffffffffffffff821117612c0d57604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff821117612c0d57604052565b90604051612cc281612c58565b60606002829467ffffffffffffffff815473ffffffffffffffffffffffffffffffffffffffff8116865260a01c1660208501526fffffffffffffffffffffffffffffffff60018201541660408501520154910152565b9060ff60405192548181168452818160081c16602085015260101c166040830152612d44606083612c74565b565b90604051612d5381612c58565b606060ff6003839573ffffffffffffffffffffffffffffffffffffffff81541685526fffffffffffffffffffffffffffffffff6001820154166020860152612d9d60028201612d18565b60408601520154161515910152565b64ffffffffff62093a809116019064ffffffffff8211612dc857565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60011b907001fffffffffffffffffffffffffffffffe6ffffffffffffffffffffffffffffffffe831692168203612dc857565b61ffff60019116019061ffff8211612dc857565b6fffffffffffffffffffffffffffffffff6301312d00911601906fffffffffffffffffffffffffffffffff8211612dc857565b906fffffffffffffffffffffffffffffffff809116911601906fffffffffffffffffffffffffffffffff8211612dc857565b3d15612efc573d9067ffffffffffffffff8211612c0d5760405191612ef060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8401160184612c74565b82523d6000602084013e565b606090565b90604051612f0e81612bf1565b608061ffff6003839580546fffffffffffffffffffffffffffffffff81168652841c60208601526fffffffffffffffffffffffffffffffff6001820154166040860152612f5d60028201612d18565b6060860152015416910152565b90604051612f7781612c3c565b604060ff82945464ffffffffff8116845261ffff8160281c16602085015260381c161515910152565b73ffffffffffffffffffffffffffffffffffffffff1680600052600c602052612fcc6040600020612f6a565b90600052600b602052612fe26040600020612f01565b64ffffffffff612ff481845116612dac565b1664ffffffffff42161115613091575b6080019061ffff8251169160328310613089576050622625a093101561307e575b61ffff60a0915116101561305d575b61ffff613048816020600494015116612e2a565b16146130515790565b61305a90612e3e565b90565b9061ffff613048816020613072600495612df7565b95945050505050613034565b624c4b409250613025565b505050600090565b604082015115613004575b5050600090565b3360009081527fa6eef7e35abe7026729641147f7915573c7e97b47efa546f5f6e3230263bcb49602052604090205460ff16156130dc57565b7fe2517d3f0000000000000000000000000000000000000000000000000000000060005233600452600060245260446000fd5b806000526001602052604060002073ffffffffffffffffffffffffffffffffffffffff331660005260205260ff604060002054161561314b5750565b7fe2517d3f000000000000000000000000000000000000000000000000000000006000523360045260245260446000fd5b73ffffffffffffffffffffffffffffffffffffffff811660009081527fa6eef7e35abe7026729641147f7915573c7e97b47efa546f5f6e3230263bcb49602052604090205460ff166132605773ffffffffffffffffffffffffffffffffffffffff1660008181527fa6eef7e35abe7026729641147f7915573c7e97b47efa546f5f6e3230263bcb496020526040812080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790553391907f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d8180a4600190565b50600090565b806000526001602052604060002073ffffffffffffffffffffffffffffffffffffffff831660005260205260ff604060002054161560001461309c57806000526001602052604060002073ffffffffffffffffffffffffffffffffffffffff8316600052602052604060002060017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082541617905573ffffffffffffffffffffffffffffffffffffffff339216907f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d600080a4600190565b73ffffffffffffffffffffffffffffffffffffffff811660009081527fa6eef7e35abe7026729641147f7915573c7e97b47efa546f5f6e3230263bcb49602052604090205460ff16156132605773ffffffffffffffffffffffffffffffffffffffff1660008181527fa6eef7e35abe7026729641147f7915573c7e97b47efa546f5f6e3230263bcb496020526040812080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690553391907ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b8180a4600190565b806000526001602052604060002073ffffffffffffffffffffffffffffffffffffffff831660005260205260ff6040600020541660001461309c57806000526001602052604060002073ffffffffffffffffffffffffffffffffffffffff831660005260205260406000207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00815416905573ffffffffffffffffffffffffffffffffffffffff339216907ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b600080a4600190565b90816020910312612b12575173ffffffffffffffffffffffffffffffffffffffff81168103612b125790565b90816020910312612b1257516fffffffffffffffffffffffffffffffff81168103612b125790565b9060038110156135595760051b0190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600260005414613599576002600055565b7f3ee5aeb50000000000000000000000000000000000000000000000000000000060005260046000fd5b60405160208101907fffffffffff0000000000000000000000000000000000000000000000000000004260d81b1682524460258201523360601b604582015260398152613611605982612c74565b5190209073ffffffffffffffffffffffffffffffffffffffff60035416604051907f82ee990c000000000000000000000000000000000000000000000000000000008252602082600481845afa918215613ad057600092613afb575b506040517fb88c914800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83166004820152602081602481855afa8015613ad05761373a936020938793600093613adc575b506fffffffffffffffffffffffffffffffff6040518097819682957f19cb825f000000000000000000000000000000000000000000000000000000008452600484016020909392919373ffffffffffffffffffffffffffffffffffffffff60408201951681520152565b039316905af1908115613ad057600091613a8d575b506fffffffffffffffffffffffffffffffff67ffffffffffffffff6040519261377784612c58565b33845216928360208401521692836040830152606082015260405161379b81612c3c565b600081526000602082015260006040820152604051906137ba82612c58565b6000825260006020830152604082015260006060820152604051916137de83612c3c565b825261392760208301600081526040840192835284600052600d60205260606040600020945173ffffffffffffffffffffffffffffffffffffffff80825116167fffffffffffffffffffffffff000000000000000000000000000000000000000087541617865560208101517fffffffff0000000000000000ffffffffffffffffffffffffffffffffffffffff7bffffffffffffffff000000000000000000000000000000000000000088549260a01b1691161786556fffffffffffffffffffffffffffffffff6040820151166fffffffffffffffffffffffffffffffff6001880191167fffffffffffffffffffffffffffffffff0000000000000000000000000000000082541617905501516002850155511515600384019060ff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0083541691151516179055565b5173ffffffffffffffffffffffffffffffffffffffff81511673ffffffffffffffffffffffffffffffffffffffff6004840191167fffffffffffffffffffffffff00000000000000000000000000000000000000008254161790556fffffffffffffffffffffffffffffffff6020820151166fffffffffffffffffffffffffffffffff6005840191167fffffffffffffffffffffffffffffffff00000000000000000000000000000000825416179055604081015160009060005b60038110613a5f575050606083926007926006613a319601550151151591019060ff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0083541691151516179055565b6040519182527f4e6a2d8bf1b50be5dfc1ff3a046a6b613d0a86e34105e29dfa84058410a384cc60203393a3565b90916020613a846001928460ff875116919060ff809160031b9316831b921b19161790565b930191016139e2565b6020813d602011613ac8575b81613aa660209383612c74565b810103126105d257519067ffffffffffffffff821682036102b457503861374f565b3d9150613a99565b6040513d6000823e3d90fd5b613af4919350853d87116122295761221b8183612c74565b91386136d0565b613b1591925060203d602011612256576122488183612c74565b903861366d565b60ff16602d811061326057603c8110613b6a57604b8110613b645760558110613b5e57605d8110613b5857605f11613b5357600690565b600590565b50600490565b50600390565b50600290565b5060019056fea26469706673582212208095c23d1e76effe874ed661a295122b54cb0cee45daf8708bd3aa913f71c35c64736f6c634300081c0033a6eef7e35abe7026729641147f7915573c7e97b47efa546f5f6e3230263bcb4900000000000000000000000036825bf3fbdf5a29e2d5148bfe7dcf7b5639e32000000000000000000000000013d4b3b27c949c4390607aba2b691b1e2f3aadb000000000000000000000000041b3faac8a28ed9a76bc23fba2c7b1cd08115c7f
Deployed Bytecode
0x608080604052600436101561001d575b50361561001b57600080fd5b005b600090813560e01c90816301ffc9a714612a315750806315f4b23f146129af578063248a9ca31461295b57806326e8500f1461288a5780632c2ed6cf146128175780632f2ff15d146127b857806331ff060c1461276a57806335d06f2a146124da57806336568abe146124515780633ccfd60b146123c9578063416ae768146122685780635140f3281461207f57806352a5f1f81461187e5780636318754d1461181f57806371104c36146117c657806379873f8a146116e05780637c293a021461154257806385952454146114ab57806391d148541461143357806393ad9550146113b1578063945ffa2f146112315780639a198d61146111365780639d566523146110e8578063a217fddf146110ae578063af74bc1414611055578063b62b78a614610d3f578063bac14f5314610ab0578063bbddaca3146108b3578063cbbf67ec146107e1578063d05aad771461075f578063d0e30db014610732578063d30c077c146106f3578063d455530f1461069a578063d547741f14610632578063dd8b38be146105d6578063e20c1848146103ce578063edff42d61461033a578063f4d22691146102b75763fcdb9d360361000f57346102b45760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102b45760406101609167ffffffffffffffff610219612b84565b168152600d602052206102b261022e82612cb5565b91610243600460ff6003840154169201612d46565b906102a160405180956060809173ffffffffffffffffffffffffffffffffffffffff815116845267ffffffffffffffff60208201511660208501526fffffffffffffffffffffffffffffffff60408201511660408501520151910152565b1515608084015260a0830190612b9b565bf35b80fd5b50346102b45760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102b4576102ef612b3a565b6102f76130a3565b6fffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffff000000000000000000000000000000006006549260801b1691161760065580f35b50346102b45760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102b4576103c16004604060c09367ffffffffffffffff610385612b84565b826060855161039381612c58565b82815282602082015286516103a88382612c74565b82368237878201520152168152600d6020522001612d46565b6102b26040518092612b9b565b50346102b45760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102b457610406612aef565b90602435916fffffffffffffffffffffffffffffffff831683036105d257604435906fffffffffffffffffffffffffffffffff8216908183036105ce577f08e2fe187e4fb484bb675d870bd92d638b9fe0a6ca9c0c64fe8209d4beb48519845260016020526040842073ffffffffffffffffffffffffffffffffffffffff331660005260205260ff604060002054161561057e5773ffffffffffffffffffffffffffffffffffffffff168352600b602052604083209081546fffffffffffffffffffffffffffffffff8116918215159182610570575b50506105485761050161054594956fffffffffffffffffffffffffffffffff92612e71565b6fffffffffffffffffffffffffffffffff91161660809290921b7fffffffffffffffffffffffffffffffff0000000000000000000000000000000016919091179055565b80f35b6004847fa2bfdd59000000000000000000000000000000000000000000000000000000008152fd5b60801c1415905038806104dc565b6044847fe2517d3f000000000000000000000000000000000000000000000000000000008152336004527f08e2fe187e4fb484bb675d870bd92d638b9fe0a6ca9c0c64fe8209d4beb48519602452fd5b8380fd5b5080fd5b50346102b45760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102b4576020610618610613612aef565b612fa0565b6fffffffffffffffffffffffffffffffff60405191168152f35b50346102b45760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102b457610696600435610670612b17565b9061069161068c82600052600160205260016040600020015490565b61310f565b613420565b5080f35b50346102b457807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102b45760206040517f08e2fe187e4fb484bb675d870bd92d638b9fe0a6ca9c0c64fe8209d4beb485198152f35b50346102b457807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102b457602060065460801c604051908152f35b50807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102b45780f35b50346102b45760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102b45773ffffffffffffffffffffffffffffffffffffffff6107ac612aef565b6107b46130a3565b167fffffffffffffffffffffffff0000000000000000000000000000000000000000600454161760045580f35b50346102b45760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102b457610856604060809267ffffffffffffffff61082a612b84565b826060855161083881612c58565b82815282602082015282878201520152168152600d60205220612cb5565b6102b260405180926060809173ffffffffffffffffffffffffffffffffffffffff815116845267ffffffffffffffff60208201511660208501526fffffffffffffffffffffffffffffffff60408201511660408501520151910152565b50346102b45760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102b4576108eb612aef565b6108f3612b17565b907faef88082b8671e875d97d0d6c81d06fb9e76f97b3ad7523a55a378e5298aeeee835260016020526040832073ffffffffffffffffffffffffffffffffffffffff331660005260205260ff6040600020541615610a605773ffffffffffffffffffffffffffffffffffffffff16908115610a385773ffffffffffffffffffffffffffffffffffffffff168015610a3857808352600e60205273ffffffffffffffffffffffffffffffffffffffff604084205416610a10578181146109e8578252600e60205260408220907fffffffffffffffffffffffff000000000000000000000000000000000000000082541617905580f35b6004837f83463f4a000000000000000000000000000000000000000000000000000000008152fd5b6004837fb027d58e000000000000000000000000000000000000000000000000000000008152fd5b6004837fe6c4247b000000000000000000000000000000000000000000000000000000008152fd5b6044837fe2517d3f000000000000000000000000000000000000000000000000000000008152336004527faef88082b8671e875d97d0d6c81d06fb9e76f97b3ad7523a55a378e5298aeeee602452fd5b50346102b457807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102b457610ae7613588565b338152600b602052600160408220016fffffffffffffffffffffffffffffffff8154166127108110610d17578290606473ffffffffffffffffffffffffffffffffffffffff600554169104813b15610d13576fffffffffffffffffffffffffffffffff60a484928360405195869485937f731133e9000000000000000000000000000000000000000000000000000000008552336004860152836024860152166044840152608060648401528160848401525af18015610cf357610cfe575b5050338252600e60205273ffffffffffffffffffffffffffffffffffffffff60408320541680610bff575b507fffffffffffffffffffffffffffffffff0000000000000000000000000000000081541690556001815580f35b60646fffffffffffffffffffffffffffffffff601481855416041604836fffffffffffffffffffffffffffffffff73ffffffffffffffffffffffffffffffffffffffff60055416921691803b156105d25781809160a4604051809481937f731133e9000000000000000000000000000000000000000000000000000000008352896004840152816024840152886044840152608060648401528160848401525af18015610cf357610cde575b505060207fede1ca8e7bdbd055149ea55be3038250bb1eb503b2783bf356cb78895d20df8e91604051908152a238610bd1565b81610ce891612c74565b6105ce578338610cab565b6040513d84823e3d90fd5b81610d0891612c74565b6105d2578138610ba6565b8280fd5b6004837f7c42ccf4000000000000000000000000000000000000000000000000000000008152fd5b5060207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102b457610d72612b3a565b610d7a613588565b60065460801c341061102d576fffffffffffffffffffffffffffffffff600254166fffffffffffffffffffffffffffffffff821690811061100557338352600b60205260408320906fffffffffffffffffffffffffffffffff825416610fdd578373ffffffffffffffffffffffffffffffffffffffff60045416803b156105d2578180916044604051809481937f79cc67900000000000000000000000000000000000000000000000000000000083523360048401528860248401525af18015610cf357610fc8575b5050600a81026fffffffffffffffffffffffffffffffff8116908103610f9b5790612710606492047fffffffffffffffffffffffffffffffff000000000000000000000000000000006fffffffffffffffffffffffffffffffff610eac60065493828516612e71565b16911617600655026fffffffffffffffffffffffffffffffff8116908103610f6e57610f679291670de0b6b3a7640000600392046fffffffffffffffffffffffffffffffff610f02600184019282845416612e71565b167fffffffffffffffffffffffffffffffff000000000000000000000000000000008254161790550161ffff610f3a81835416612e2a565b167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00008254161790556135c3565b6001815580f35b6024847f4e487b710000000000000000000000000000000000000000000000000000000081526011600452fd5b6024857f4e487b710000000000000000000000000000000000000000000000000000000081526011600452fd5b81610fd291612c74565b6105ce578338610e43565b6004847fb392d881000000000000000000000000000000000000000000000000000000008152fd5b6004837f040ef8ec000000000000000000000000000000000000000000000000000000008152fd5b6004827fd856fc5a000000000000000000000000000000000000000000000000000000008152fd5b50346102b457807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102b45760206040517faef88082b8671e875d97d0d6c81d06fb9e76f97b3ad7523a55a378e5298aeeee8152f35b50346102b457807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102b457602090604051908152f35b50346102b457807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102b45760206fffffffffffffffffffffffffffffffff60065416604051908152f35b50346102b457807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102b457808060405160208101907f1e60fd1400000000000000000000000000000000000000000000000000000000825260916024820152602481526111a8604482612c74565b51908273dc2b0d2dd2b7759d97d50db4eabdc369731108305af16111ca612ea3565b50156111d35780f35b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f4665654d20726567697374726174696f6e206661696c656400000000000000006044820152fd5b50807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102b457611263613588565b338152600b6020526040812080546fffffffffffffffffffffffffffffffff8116156113895760065460801c34106113615760801c8015611361576112a7906135c3565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6fffffffffffffffffffffffffffffffff825416016fffffffffffffffffffffffffffffffff8111611334576fffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffff000000000000000000000000000000008254161790556001815580f35b6024837f4e487b710000000000000000000000000000000000000000000000000000000081526011600452fd5b6004837fd856fc5a000000000000000000000000000000000000000000000000000000008152fd5b6004837fbc2e7b13000000000000000000000000000000000000000000000000000000008152fd5b50346102b45760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102b45773ffffffffffffffffffffffffffffffffffffffff6113fe612aef565b6114066130a3565b167fffffffffffffffffffffffff0000000000000000000000000000000000000000600354161760035580f35b50346102b45760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102b45773ffffffffffffffffffffffffffffffffffffffff6040611482612b17565b9260043581526001602052209116600052602052602060ff604060002054166040519015158152f35b50346102b45760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102b4576114e3612aef565b6114eb6130a3565b73ffffffffffffffffffffffffffffffffffffffff81161561151a576115109061317c565b506106963361333e565b6004827fe6c4247b000000000000000000000000000000000000000000000000000000008152fd5b50346102b457807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102b4577f617b7366a53d5e938aa39800cda5d5b3cb5a765907174ff1971dcbc731804e06815260016020526040812073ffffffffffffffffffffffffffffffffffffffff331660005260205260ff6040600020541615611690578073ffffffffffffffffffffffffffffffffffffffff600454166fffffffffffffffffffffffffffffffff6006541690803b1561168c576040517f40c10f19000000000000000000000000000000000000000000000000000000008152336004820152602481019290925282908290604490829084905af18015610cf357611677575b507fffffffffffffffffffffffffffffffff000000000000000000000000000000006006541660065580f35b8161168191612c74565b6102b457803861164b565b5050fd5b807fe2517d3f0000000000000000000000000000000000000000000000000000000060449252336004527f617b7366a53d5e938aa39800cda5d5b3cb5a765907174ff1971dcbc731804e06602452fd5b50346102b457807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102b45760e090816040516117208282612c74565b36903760405190816007825b600760018201106117935750546fffffffffffffffffffffffffffffffff1690526117578383612c74565b6040519190825b6007821061176b57505050f35b6020806001926fffffffffffffffffffffffffffffffff86511681520193019101909161175e565b81546fffffffffffffffffffffffffffffffff8116845260801c602084015260409092019160019091019060020161172c565b50346102b457807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102b45760206040517f617b7366a53d5e938aa39800cda5d5b3cb5a765907174ff1971dcbc731804e068152f35b50346102b45760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102b45760ff6003604060209367ffffffffffffffff611869612b84565b168152600d8552200154166040519015158152f35b50346102b45760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102b4576118b6612b84565b6118be612b17565b506044359073ffffffffffffffffffffffffffffffffffffffff600354168015612021573303611f9d5767ffffffffffffffff16808352600d602052604083206060906040519061190f8383612c74565b8236833773ffffffffffffffffffffffffffffffffffffffff81541615611f7557600381019460ff865416611f4d57865b60038110611f1757505060016fffffffffffffffffffffffffffffffff9101541691604051916119708284612c74565b81368437848752600d60205273ffffffffffffffffffffffffffffffffffffffff60408820541693848852600b6020526040882091885b60038110611e055750508351600760ff82161015611dd857806080617f80607f6fffffffffffffffffffffffffffffffff9460011c16600701549260071b16161c168102916fffffffffffffffffffffffffffffffff8316928303611dab5760ff85511660ff602087015116149182611d95575b8280611d8c575b611ce6575b6fffffffffffffffffffffffffffffffff825416611ca1575b508115611c9b57825b8960405191611a5783612c58565b8883526fffffffffffffffffffffffffffffffff60208401911681526fffffffffffffffffffffffffffffffff604084019189835273ffffffffffffffffffffffffffffffffffffffff60408a8701958915159e8f88528152600d6020522095511673ffffffffffffffffffffffffffffffffffffffff6004870191167fffffffffffffffffffffffff000000000000000000000000000000000000000082541617905551166fffffffffffffffffffffffffffffffff6005850191167fffffffffffffffffffffffffffffffff00000000000000000000000000000000825416179055518b908c5b60038110611c6d57505082916007916006611b8c95015551151591019060ff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0083541691151516179055565b889085825b60038110611c3f5750506002015515611c38575b6040519287845b60038210611c1f575050506fffffffffffffffffffffffffffffffff16908201527f924ed04bd50ab8e80b69ebf285df0bd772014e87fba679821fa39b1a2753d22b90608090a360017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082541617905580f35b60208060019260ff865116815201930191019091611bac565b5085611ba5565b90926020611c646001928460ff885116919060ff809160031b9316831b921b19161790565b94019101611b91565b90916020611c926001928460ff875116919060ff809160031b9316831b921b19161790565b93019101611b40565b88611a49565b81546fffffffffffffffffffffffffffffffff1660809190911b7fffffffffffffffffffffffffffffffff000000000000000000000000000000001617815538611a40565b73ffffffffffffffffffffffffffffffffffffffff600454168a813b156102b4576040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8a16600482015260248101879052918290604490829084905af18015611d8157611d6d575b50611a27565b8a611d7a919b929b612c74565b9838611d67565b6040513d8d823e3d90fd5b50831515611a22565b915060ff85511660ff6040870151161491611a1b565b6024897f4e487b710000000000000000000000000000000000000000000000000000000081526011600452fd5b6024897f4e487b710000000000000000000000000000000000000000000000000000000081526032600452fd5b611e1e60ff6061611e168486613548565b510616613b1c565b60ff611e2a8389613548565b91169052600660ff611e3c8389613548565b511614611e4c575b6001016119a7565b60036fffffffffffffffffffffffffffffffff855416016fffffffffffffffffffffffffffffffff8111611eea57906fffffffffffffffffffffffffffffffff600192167fffffffffffffffffffffffffffffffff00000000000000000000000000000000865416178555877f18b8046382a3c246493e09c351024b814d62fe474031bed134120b055239613a602060405160038152a29050611e44565b60248b7f4e487b710000000000000000000000000000000000000000000000000000000081526011600452fd5b600190604051602081019084825282604082015260408152611f398882612c74565b519020611f468287613548565b5201611940565b6004877ffb776379000000000000000000000000000000000000000000000000000000008152fd5b6004867f41abc801000000000000000000000000000000000000000000000000000000008152fd5b60846040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f4f6e6c7920456e74726f70792063616e2063616c6c20746869732066756e637460448201527f696f6e00000000000000000000000000000000000000000000000000000000006064820152fd5b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f456e74726f70792061646472657373206e6f74207365740000000000000000006044820152fd5b50346102b457807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102b4576120b66130a3565b73ffffffffffffffffffffffffffffffffffffffff600354166040517f82ee990c000000000000000000000000000000000000000000000000000000008152602081600481855afa801561225d57602473ffffffffffffffffffffffffffffffffffffffff916020938691612230575b5060405194859384927fb88c91480000000000000000000000000000000000000000000000000000000084521660048301525afa8015610cf3576fffffffffffffffffffffffffffffffff918391612201575b5016607d810290808204607d14901517156121d4576fffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffff000000000000000000000000000000006064600654930460801b1691161760065580f35b6024827f4e487b710000000000000000000000000000000000000000000000000000000081526011600452fd5b612223915060203d602011612229575b61221b8183612c74565b810190613520565b38612179565b503d612211565b6122509150843d8611612256575b6122488183612c74565b8101906134f4565b38612126565b503d61223e565b6040513d85823e3d90fd5b50346102b45760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102b4576101409060406122a6612aef565b9161ffff60806123386123328573ffffffffffffffffffffffffffffffffffffffff8151986122d48a612bf1565b878a528760208b015287838b0152878660609b8c6122f487519182612c74565b8d3682378d82015201528783805161230b81612c3c565b82815282602082015201521695868152600b602052818120968152600c6020522094612f01565b93612f6a565b926123988551966fffffffffffffffffffffffffffffffff83511688526fffffffffffffffffffffffffffffffff60208401511660208901526fffffffffffffffffffffffffffffffff8784015116878901528083015190880190612b59565b01511660c084015264ffffffffff81511660e084015261ffff60208201511661010084015201511515610120820152f35b50346102b457807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102b4576124006130a3565b4760065460801c81039081116121d4578180808093335af1612420612ea3565b50156124295780f35b807f90b8ec180000000000000000000000000000000000000000000000000000000060049252fd5b50346102b45760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102b457612489612b17565b3373ffffffffffffffffffffffffffffffffffffffff8216036124b25761069690600435613420565b6004827f6697b232000000000000000000000000000000000000000000000000000000008152fd5b50346102b457807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102b457338152600c60205260408120338252600b602052604082209064ffffffffff4216815464ffffffffff61253d818316612dac565b168211612740575b5081549260ff8460381c1661271857600381019361ffff85541690603282106126f05790670100000000000000939291622625a09160508110156126e5575b60a011156126d0575b61ffff9060281c16600461ffff6125a383612e2a565b160361267557506125fc60016125c96fffffffffffffffffffffffffffffffff93612e3e565b937fffffffffffffffffffffffffffffffffffffffffffffffffff0000ffffffffff88541688555b019282845416612e71565b167fffffffffffffffffffffffffffffffff000000000000000000000000000000008254161790557fffffffffffffffffffffffffffffffffffffffffffffffff00ffff0000000000835416171790557fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000815416905580f35b60016fffffffffffffffffffffffffffffffff92936126966125fc93612e2a565b7fffffffffffffffffffffffffffffffffffffffffffffffffff0000ffffffffff66ffff00000000008a549260281b1691161788556125f1565b906126dd61ffff91612df7565b91905061258d565b624c4b409250612584565b6004877f41abc801000000000000000000000000000000000000000000000000000000008152fd5b6004857ffb776379000000000000000000000000000000000000000000000000000000008152fd5b7fffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffff16825538612545565b50346102b457807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102b45760206fffffffffffffffffffffffffffffffff60025416604051908152f35b50346102b45760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102b4576106966004356127f6612b17565b9061281261068c82600052600160205260016040600020015490565b613266565b50346102b457807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102b457610100604051600281526301312d006020820152622625a0604082015262093a80606082015260326080820152605060a082015260a060c0820152600460e0820152f35b50346102b45760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102b4576fffffffffffffffffffffffffffffffff6128d3612b3a565b6128db6130a3565b16801561293357807fffffffffffffffffffffffffffffffff0000000000000000000000000000000060025416176002557fbd249363dcf68d3781deb8de6ddf794b2eb3f769e65757014396e6644f1aef478280a280f35b6004827f040ef8ec000000000000000000000000000000000000000000000000000000008152fd5b50346102b45760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102b45760206129a7600435600052600160205260016040600020015490565b604051908152f35b50346102b45760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102b45773ffffffffffffffffffffffffffffffffffffffff6129fc612aef565b612a046130a3565b167fffffffffffffffffffffffff0000000000000000000000000000000000000000600554161760055580f35b9050346105d25760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126105d2576004357fffffffff000000000000000000000000000000000000000000000000000000008116809103610d1357602092507f7965db0b000000000000000000000000000000000000000000000000000000008114908115612ac5575b5015158152f35b7f01ffc9a70000000000000000000000000000000000000000000000000000000091501438612abe565b6004359073ffffffffffffffffffffffffffffffffffffffff82168203612b1257565b600080fd5b6024359073ffffffffffffffffffffffffffffffffffffffff82168203612b1257565b600435906fffffffffffffffffffffffffffffffff82168203612b1257565b906000905b60038210612b6b57505050565b60208060019260ff865116815201930191019091612b5e565b6004359067ffffffffffffffff82168203612b1257565b606060a09173ffffffffffffffffffffffffffffffffffffffff81511684526fffffffffffffffffffffffffffffffff6020820151166020850152612be860408201516040860190612b59565b01511515910152565b60a0810190811067ffffffffffffffff821117612c0d57604052565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6060810190811067ffffffffffffffff821117612c0d57604052565b6080810190811067ffffffffffffffff821117612c0d57604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff821117612c0d57604052565b90604051612cc281612c58565b60606002829467ffffffffffffffff815473ffffffffffffffffffffffffffffffffffffffff8116865260a01c1660208501526fffffffffffffffffffffffffffffffff60018201541660408501520154910152565b9060ff60405192548181168452818160081c16602085015260101c166040830152612d44606083612c74565b565b90604051612d5381612c58565b606060ff6003839573ffffffffffffffffffffffffffffffffffffffff81541685526fffffffffffffffffffffffffffffffff6001820154166020860152612d9d60028201612d18565b60408601520154161515910152565b64ffffffffff62093a809116019064ffffffffff8211612dc857565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60011b907001fffffffffffffffffffffffffffffffe6ffffffffffffffffffffffffffffffffe831692168203612dc857565b61ffff60019116019061ffff8211612dc857565b6fffffffffffffffffffffffffffffffff6301312d00911601906fffffffffffffffffffffffffffffffff8211612dc857565b906fffffffffffffffffffffffffffffffff809116911601906fffffffffffffffffffffffffffffffff8211612dc857565b3d15612efc573d9067ffffffffffffffff8211612c0d5760405191612ef060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8401160184612c74565b82523d6000602084013e565b606090565b90604051612f0e81612bf1565b608061ffff6003839580546fffffffffffffffffffffffffffffffff81168652841c60208601526fffffffffffffffffffffffffffffffff6001820154166040860152612f5d60028201612d18565b6060860152015416910152565b90604051612f7781612c3c565b604060ff82945464ffffffffff8116845261ffff8160281c16602085015260381c161515910152565b73ffffffffffffffffffffffffffffffffffffffff1680600052600c602052612fcc6040600020612f6a565b90600052600b602052612fe26040600020612f01565b64ffffffffff612ff481845116612dac565b1664ffffffffff42161115613091575b6080019061ffff8251169160328310613089576050622625a093101561307e575b61ffff60a0915116101561305d575b61ffff613048816020600494015116612e2a565b16146130515790565b61305a90612e3e565b90565b9061ffff613048816020613072600495612df7565b95945050505050613034565b624c4b409250613025565b505050600090565b604082015115613004575b5050600090565b3360009081527fa6eef7e35abe7026729641147f7915573c7e97b47efa546f5f6e3230263bcb49602052604090205460ff16156130dc57565b7fe2517d3f0000000000000000000000000000000000000000000000000000000060005233600452600060245260446000fd5b806000526001602052604060002073ffffffffffffffffffffffffffffffffffffffff331660005260205260ff604060002054161561314b5750565b7fe2517d3f000000000000000000000000000000000000000000000000000000006000523360045260245260446000fd5b73ffffffffffffffffffffffffffffffffffffffff811660009081527fa6eef7e35abe7026729641147f7915573c7e97b47efa546f5f6e3230263bcb49602052604090205460ff166132605773ffffffffffffffffffffffffffffffffffffffff1660008181527fa6eef7e35abe7026729641147f7915573c7e97b47efa546f5f6e3230263bcb496020526040812080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790553391907f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d8180a4600190565b50600090565b806000526001602052604060002073ffffffffffffffffffffffffffffffffffffffff831660005260205260ff604060002054161560001461309c57806000526001602052604060002073ffffffffffffffffffffffffffffffffffffffff8316600052602052604060002060017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082541617905573ffffffffffffffffffffffffffffffffffffffff339216907f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d600080a4600190565b73ffffffffffffffffffffffffffffffffffffffff811660009081527fa6eef7e35abe7026729641147f7915573c7e97b47efa546f5f6e3230263bcb49602052604090205460ff16156132605773ffffffffffffffffffffffffffffffffffffffff1660008181527fa6eef7e35abe7026729641147f7915573c7e97b47efa546f5f6e3230263bcb496020526040812080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690553391907ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b8180a4600190565b806000526001602052604060002073ffffffffffffffffffffffffffffffffffffffff831660005260205260ff6040600020541660001461309c57806000526001602052604060002073ffffffffffffffffffffffffffffffffffffffff831660005260205260406000207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00815416905573ffffffffffffffffffffffffffffffffffffffff339216907ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b600080a4600190565b90816020910312612b12575173ffffffffffffffffffffffffffffffffffffffff81168103612b125790565b90816020910312612b1257516fffffffffffffffffffffffffffffffff81168103612b125790565b9060038110156135595760051b0190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600260005414613599576002600055565b7f3ee5aeb50000000000000000000000000000000000000000000000000000000060005260046000fd5b60405160208101907fffffffffff0000000000000000000000000000000000000000000000000000004260d81b1682524460258201523360601b604582015260398152613611605982612c74565b5190209073ffffffffffffffffffffffffffffffffffffffff60035416604051907f82ee990c000000000000000000000000000000000000000000000000000000008252602082600481845afa918215613ad057600092613afb575b506040517fb88c914800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83166004820152602081602481855afa8015613ad05761373a936020938793600093613adc575b506fffffffffffffffffffffffffffffffff6040518097819682957f19cb825f000000000000000000000000000000000000000000000000000000008452600484016020909392919373ffffffffffffffffffffffffffffffffffffffff60408201951681520152565b039316905af1908115613ad057600091613a8d575b506fffffffffffffffffffffffffffffffff67ffffffffffffffff6040519261377784612c58565b33845216928360208401521692836040830152606082015260405161379b81612c3c565b600081526000602082015260006040820152604051906137ba82612c58565b6000825260006020830152604082015260006060820152604051916137de83612c3c565b825261392760208301600081526040840192835284600052600d60205260606040600020945173ffffffffffffffffffffffffffffffffffffffff80825116167fffffffffffffffffffffffff000000000000000000000000000000000000000087541617865560208101517fffffffff0000000000000000ffffffffffffffffffffffffffffffffffffffff7bffffffffffffffff000000000000000000000000000000000000000088549260a01b1691161786556fffffffffffffffffffffffffffffffff6040820151166fffffffffffffffffffffffffffffffff6001880191167fffffffffffffffffffffffffffffffff0000000000000000000000000000000082541617905501516002850155511515600384019060ff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0083541691151516179055565b5173ffffffffffffffffffffffffffffffffffffffff81511673ffffffffffffffffffffffffffffffffffffffff6004840191167fffffffffffffffffffffffff00000000000000000000000000000000000000008254161790556fffffffffffffffffffffffffffffffff6020820151166fffffffffffffffffffffffffffffffff6005840191167fffffffffffffffffffffffffffffffff00000000000000000000000000000000825416179055604081015160009060005b60038110613a5f575050606083926007926006613a319601550151151591019060ff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0083541691151516179055565b6040519182527f4e6a2d8bf1b50be5dfc1ff3a046a6b613d0a86e34105e29dfa84058410a384cc60203393a3565b90916020613a846001928460ff875116919060ff809160031b9316831b921b19161790565b930191016139e2565b6020813d602011613ac8575b81613aa660209383612c74565b810103126105d257519067ffffffffffffffff821682036102b457503861374f565b3d9150613a99565b6040513d6000823e3d90fd5b613af4919350853d87116122295761221b8183612c74565b91386136d0565b613b1591925060203d602011612256576122488183612c74565b903861366d565b60ff16602d811061326057603c8110613b6a57604b8110613b645760558110613b5e57605d8110613b5857605f11613b5357600690565b600590565b50600490565b50600390565b50600290565b5060019056fea26469706673582212208095c23d1e76effe874ed661a295122b54cb0cee45daf8708bd3aa913f71c35c64736f6c634300081c0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000036825bf3fbdf5a29e2d5148bfe7dcf7b5639e32000000000000000000000000013d4b3b27c949c4390607aba2b691b1e2f3aadb000000000000000000000000041b3faac8a28ed9a76bc23fba2c7b1cd08115c7f
-----Decoded View---------------
Arg [0] : entropyAddress (address): 0x36825bf3Fbdf5a29E2d5148bfe7Dcf7B5639e320
Arg [1] : diggaAddress (address): 0x13d4B3B27C949c4390607abA2b691b1E2F3aaDb0
Arg [2] : diggaResourcesAddress (address): 0x41B3fAaC8A28eD9A76bC23FBA2c7b1CD08115c7f
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 00000000000000000000000036825bf3fbdf5a29e2d5148bfe7dcf7b5639e320
Arg [1] : 00000000000000000000000013d4b3b27c949c4390607aba2b691b1e2f3aadb0
Arg [2] : 00000000000000000000000041b3faac8a28ed9a76bc23fba2c7b1cd08115c7f
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in S
Token Allocations
S
100.00%
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|---|---|---|---|---|
| SONIC | 100.00% | $0.066872 | 0.0638 | $0.004263 |
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.