Source Code
Overview
APE Balance
APE Value
$0.00Multichain Info
N/A
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Cross-Chain Transactions
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
MintotaurColiseum
Compiler Version
v0.8.26+commit.8a97fa7a
Optimization Enabled:
Yes with 200 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
import "@openzeppelin/contracts/token/ERC721/IERC721.sol";
import {IEntropyConsumer} from "@pythnetwork/entropy-sdk-solidity/IEntropyConsumer.sol";
import {IEntropy} from "@pythnetwork/entropy-sdk-solidity/IEntropy.sol";
/**
* @title IMintotaurColiseumRewards
* @notice Interface for the rewards contract that handles battle rewards
*/
interface IMintotaurColiseumRewards {
function mintForDefeatingContract(address winner, address defeatedContractAddress) external;
}
/**
* @title MintotaurColiseum
* @notice A battle arena where NFTs can compete against each other
* @dev Uses UUPS upgradeability pattern and integrates with Pyth Network for randomness
*
* Key features:
* - NFT battle system with attribute-based combat
* - Temporary attribute boosters
* - Battle cooldowns
* - Rewards distribution
* - On-chain battle history
*/
contract MintotaurColiseum is
Initializable,
OwnableUpgradeable,
ReentrancyGuardUpgradeable,
PausableUpgradeable,
UUPSUpgradeable,
IEntropyConsumer
{
/// @custom:oz-upgrades-unsafe-allow constructor
constructor() {
_disableInitializers();
}
// Achievement type constants
uint256 constant ACHIEVEMENT_WIN_COUNT = 1;
uint256 constant ACHIEVEMENT_WIN_STREAK = 2;
/// @notice Tracks which NFT contracts are allowed to participate in battles
mapping(address => bool) public allowedContracts;
/// @notice Interface to the Pyth Network entropy source
IEntropy public entropy;
/// @notice Address of the entropy provider for randomness
address entropyProvider;
/// @notice Address of the contract that handles battle rewards
address public rewardsContractAddress;
/// @notice Address of the addresses that can make calls
mapping(address => bool) public authorizedAddresses;
modifier onlyAuthorized() {
require(authorizedAddresses[msg.sender] == true, "Not authorized");
_;
}
/**
* @notice Core attributes that determine a fighter's capabilities
* @param attack Physical attack power
* @param defense Physical defense capability
* @param magicAttack Magical attack power
* @param magicDef Magical defense capability
* @param dexterity Affects accuracy and evasion
* @param luck Influences critical hits and special events
* @param intelligence Affects magical ability and strategy
* @param speed Determines turn order and action frequency
*/
struct FighterAttributes {
int256 attack;
int256 defense;
int256 magicAttack;
int256 magicDef;
int256 dexterity;
int256 luck;
int256 intelligence;
int256 speed;
int256 vitality;
}
struct FightingChoice {
uint256[] choices; // Array of choice IDs (1-6)
}
/**
* @notice Types of achievements that can be earned
*/
enum AchievementType {
WIN_MILESTONE, // Achievements for total wins (1,5,10,25)
WIN_STREAK // Achievements for consecutive wins
}
/**
* @notice Tracks achievement progress and claimed status
*/
struct AchievementProgress {
mapping(AchievementType => uint256) claimedBitmap;
}
/**
* @notice Comprehensive data about a fighter
* @param wins Total number of victories
* @param losses Total number of defeats
* @param draws Total number of draws
* @param lastBattleTimestamp Time of last battle for cooldown
* @param wonLastBattle Result of the last battle
* @param currentStreak Current win streak counter
* @param achievements Tracking for achievement progress
* @param baseAttributes Permanent base attributes
* @param boosters Temporary attribute enhancements
*/
struct Fighter {
uint256 wins;
uint256 losses;
uint256 draws;
uint256 lastBattleTimestamp;
bool wonLastBattle;
uint256 currentStreak;
AchievementProgress achievements;
FighterAttributes baseAttributes;
FighterAttributes boosters;
}
/**
* @notice Records the outcome and details of a battle
* @param challengerContract Address of challenger's NFT contract
* @param challengerTokenId Token ID of challenger
* @param opponentContract Address of opponent's NFT contract
* @param opponentTokenId Token ID of opponent
* @param challengerWon Whether the challenger won
* @param isDraw Whether the battle ended in a draw
* @param timestamp When the battle occurred
* @param challengerScore Challenger's battle performance score
* @param opponentScore Opponent's battle performance score
*/
struct BattleResult {
address challengerContract;
uint256 challengerTokenId;
address opponentContract;
uint256 opponentTokenId;
bool challengerWon;
bool isDraw;
uint256 timestamp;
uint256 challengerScore;
uint256 opponentScore;
}
/**
* @notice Information about a battle awaiting entropy for resolution
* @param challengerContract Address of challenger's NFT contract
* @param challengerTokenId Token ID of challenger
* @param opponentContract Address of opponent's NFT contract
* @param opponentTokenId Token ID of opponent
* @param challengerAttributes Challenger's attributes at time of battle
* @param opponentAttributes Opponent's attributes at time of battle
* @param sequenceNumber Unique identifier for the pending battle
* @param isProcessed Whether the battle has been resolved
*/
struct PendingBattle {
address challengerContract;
uint256 challengerTokenId;
address opponentContract;
uint256 opponentTokenId;
FighterAttributes challengerAttributes;
FighterAttributes opponentAttributes;
FightingChoice challengerChoices;
FightingChoice opponentChoices;
uint64 sequenceNumber;
bool isProcessed;
}
/// @notice Maps NFT contract and token ID to fighter data
mapping(address => mapping(uint256 => Fighter)) internal fighters;
/// @notice Maps NFT contract address to its base attributes
mapping(address => FighterAttributes) public contractBaseAttributes;
/// @notice Maps battle ID to battle result
mapping(uint256 => BattleResult) public battleResults;
/// @notice Time required between battles for each fighter
uint256 public battleCooldown;
uint256 public loserCooldown;
/// @notice Total number of battles that have occurred
uint256 public battleCount;
/// @notice Maps sequence numbers to pending battles
mapping(uint64 => PendingBattle) public pendingBattles;
/**
* @notice Emitted when a battle is completed
* @param sequenceNumber Unique identifier for the battle
* @param challengerContract Challenger's NFT contract address
* @param challengerTokenId Challenger's token ID
* @param opponentContract Opponent's NFT contract address
* @param opponentTokenId Opponent's token ID
* @param challengerWon Whether the challenger won
* @param isDraw Whether the battle ended in a draw
* @param challengerScore Challenger's battle performance score
* @param opponentScore Opponent's battle performance score
*/
event BattleComplete(
uint64 indexed sequenceNumber,
address indexed challengerContract,
uint256 indexed challengerTokenId,
address opponentContract,
uint256 opponentTokenId,
bool challengerWon,
bool isDraw,
uint256 challengerScore,
uint256 opponentScore
);
/**
* @notice Emitted when a new battle is initiated
* @param sequenceNumber Unique identifier for the battle
* @param challengerContract Challenger's NFT contract address
* @param challengerTokenId Challenger's token ID
* @param opponentContract Opponent's NFT contract address
* @param opponentTokenId Opponent's token ID
*/
event BattleInitiated(
uint64 indexed sequenceNumber,
address indexed challengerContract,
uint256 indexed challengerTokenId,
address opponentContract,
uint256 opponentTokenId
);
/**
* @notice Initialize the coliseum contract
* @param _initialAllowedContracts Initial list of allowed NFT contracts
* @param _battleCooldown Cooldown period between battles in seconds
* @param _entropy Address of the Pyth Network entropy contract
* @param _provider Address of the entropy provider
* @dev This function can only be called once during contract deployment
*/
function initialize(
address[] memory _initialAllowedContracts,
uint256 _battleCooldown,
uint256 _loserCooldown,
address _entropy,
address _provider
) public initializer {
__Ownable_init();
__ReentrancyGuard_init();
__Pausable_init();
__UUPSUpgradeable_init();
battleCooldown = _battleCooldown;
loserCooldown = _loserCooldown;
for (uint256 i = 0; i < _initialAllowedContracts.length; i++) {
allowedContracts[_initialAllowedContracts[i]] = true;
}
entropy = IEntropy(_entropy);
entropyProvider = _provider;
authorizedAddresses[msg.sender] = true;
}
function setAuthorizedAddresses(
address[] calldata addresses,
bool[] calldata allowed
) external onlyOwner {
for (uint256 i = 0; i < addresses.length; i++) {
authorizedAddresses[addresses[i]] = allowed[i];
}
}
/**
* @notice Batch add or remove NFT contracts from the allowed list
* @param contractAddresses The addresses of the NFT contracts
* @param allowed Whether the contracts should be allowed
* @dev Only callable by the contract owner
*/
function batchSetContractsAllowed(
address[] calldata contractAddresses,
bool allowed
) external onlyOwner {
for (uint256 i = 0; i < contractAddresses.length; i++) {
allowedContracts[contractAddresses[i]] = allowed;
}
}
/**
* @notice Set base attributes for a contract
* @param contractAddress The NFT contract address
* @param attributes The base attributes for all fighters from this contract
* @dev Only callable by the contract owner
*/
function setContractBaseAttributes(
address contractAddress,
FighterAttributes memory attributes
) external onlyOwner {
require(allowedContracts[contractAddress], "Contract not allowed");
contractBaseAttributes[contractAddress] = attributes;
}
/**
* @notice Initialize multiple fighters with base attributes
* @param contractAddress The contract address of the NFT collection
* @param startTokenId The starting token ID in the range
* @param endTokenId The ending token ID in the range (inclusive)
* @dev Only callable by the contract owner
* @dev The NFT contract must be in the allowed list
*/
function batchInitializeFighters(
address contractAddress,
uint256 startTokenId,
uint256 endTokenId
) external onlyOwner {
require(allowedContracts[contractAddress], "Contract not allowed");
require(startTokenId <= endTokenId, "Invalid token ID range");
require(endTokenId - startTokenId <= 5000, "Range too large"); // Safety limit
require(contractBaseAttributes[contractAddress].attack != 0, "Contract base attributes not set");
FighterAttributes memory baseAttributes = contractBaseAttributes[contractAddress];
for (uint256 tokenId = startTokenId; tokenId <= endTokenId; tokenId++) {
Fighter storage fighter = fighters[contractAddress][tokenId];
fighter.baseAttributes = baseAttributes;
}
}
/**
* @notice Apply boosters or degraders to a fighter before battle
* @param contractAddress The contract address of the NFT
* @param tokenId The token ID of the NFT
* @param boosters The attribute boosters to apply (use 0 for no change, negative for degraders)
*/
function applyBoosters(
address contractAddress,
uint256 tokenId,
FighterAttributes memory boosters
) external onlyAuthorized {
require(allowedContracts[contractAddress], "Contract not allowed");
require(
fighters[contractAddress][tokenId].baseAttributes.attack > 0,
"Fighter not initialized"
);
// Apply boosters
fighters[contractAddress][tokenId].boosters = boosters;
}
/**
* @notice Apply boosters to multiple fighters in a single transaction
* @param contractAddress The contract address of the NFTs
* @param tokenIds Array of token IDs
* @param boosters Array of attribute boosters to apply
*/
function applyBoostersBatch(
address contractAddress,
uint256[] calldata tokenIds,
FighterAttributes[] calldata boosters
) external onlyAuthorized {
require(allowedContracts[contractAddress], "Contract not allowed");
require(tokenIds.length == boosters.length, "Array lengths must match");
require(tokenIds.length > 0, "Empty arrays not allowed");
require(tokenIds.length <= 50, "Batch size too large"); // Cap at 50 to prevent gas issues
for(uint256 i = 0; i < tokenIds.length; i++) {
require(
fighters[contractAddress][tokenIds[i]].baseAttributes.attack > 0,
"Fighter not initialized"
);
fighters[contractAddress][tokenIds[i]].boosters = boosters[i];
}
}
/**
* @notice Start a battle between two fighters
* @param challengerContract The contract address of the challenger's NFT
* @param challengerTokenId The token ID of the challenger's NFT
* @param opponentContract The contract address of the opponent's NFT
* @param opponentTokenId The token ID of the opponent's NFT
*/
function battle(
address challengerContract,
uint256 challengerTokenId,
address opponentContract,
uint256 opponentTokenId,
bytes32 userRandomNumber,
uint256[] calldata challengerChoices,
uint256[] calldata opponentChoices
) external payable nonReentrant onlyAuthorized returns (uint64) {
// Validate choices
require(challengerChoices.length <= 2, "Too many challenger choices");
require(opponentChoices.length <= 2, "Too many opponent choices");
for (uint256 i = 0; i < challengerChoices.length; i++) {
require(challengerChoices[i] >= 1 && challengerChoices[i] <= 6, "Invalid challenger choice");
}
for (uint256 i = 0; i < opponentChoices.length; i++) {
require(opponentChoices[i] >= 1 && opponentChoices[i] <= 6, "Invalid opponent choice");
}
uint128 requestFee = entropy.getFee(entropyProvider);
if (msg.value < requestFee) revert("not enough fees");
uint64 sequenceNumber = entropy.requestWithCallback{value: requestFee}(
entropyProvider,
userRandomNumber
);
_validateBattle(
challengerContract,
challengerTokenId,
opponentContract,
opponentTokenId
);
FighterAttributes memory challengerAttributes = getEffectiveAttributes(
challengerContract,
challengerTokenId
);
FighterAttributes memory opponentAttributes = getEffectiveAttributes(
opponentContract,
opponentTokenId
);
// Apply fighting choices effects
challengerAttributes = _applyFightingChoices(challengerAttributes, challengerChoices);
opponentAttributes = _applyFightingChoices(opponentAttributes, opponentChoices);
pendingBattles[sequenceNumber] = PendingBattle({
challengerContract: challengerContract,
challengerTokenId: challengerTokenId,
opponentContract: opponentContract,
opponentTokenId: opponentTokenId,
challengerAttributes: challengerAttributes,
opponentAttributes: opponentAttributes,
challengerChoices: FightingChoice({choices: challengerChoices}),
opponentChoices: FightingChoice({choices: opponentChoices}),
sequenceNumber: sequenceNumber,
isProcessed: false
});
emit BattleInitiated(
sequenceNumber,
challengerContract,
challengerTokenId,
opponentContract,
opponentTokenId
);
return sequenceNumber;
}
function _applyFightingChoices(
FighterAttributes memory attributes,
uint256[] memory choices
) internal pure returns (FighterAttributes memory) {
for (uint256 i = 0; i < choices.length; i++) {
if (choices[i] == 1) { // Aggressive Stance
attributes.attack += 15;
attributes.defense -= 8;
} else if (choices[i] == 2) { // Defensive Position
attributes.defense += 15;
attributes.attack -= 8;
} else if (choices[i] == 3) { // Magic Focus
attributes.magicAttack += 15;
attributes.attack -= 8;
} else if (choices[i] == 4) { // Counter Stance
attributes.luck += 20;
attributes.defense -= 10;
} else if (choices[i] == 5) { // Balanced Form
attributes.attack += 5;
attributes.defense += 5;
attributes.magicAttack += 5;
attributes.magicDef += 5;
} else if (choices[i] == 6) { // Tactical Approach
attributes.intelligence += 15;
attributes.luck += 10;
attributes.speed -= 5;
}
}
return attributes;
}
/**
* @notice Validate battle participants
*/
function _validateBattle(
address _challengerContract,
uint256 _challengerTokenId,
address _opponentContract,
uint256 _opponentTokenId
) private {
// Validate inputs
require(
allowedContracts[_challengerContract],
"Challenger contract not allowed"
);
require(
allowedContracts[_opponentContract],
"Opponent contract not allowed"
);
require(
_challengerContract != _opponentContract ||
_challengerTokenId != _opponentTokenId,
"Cannot battle yourself"
);
Fighter storage challenger = fighters[_challengerContract][
_challengerTokenId
];
Fighter storage opponent = fighters[_opponentContract][
_opponentTokenId
];
// Check if fighters are initialized
require(
challenger.baseAttributes.attack > 0,
"Challenger not initialized"
);
require(opponent.baseAttributes.attack > 0, "Opponent not initialized");
// 1. Check regular battle cooldown for both fighters
require(
block.timestamp >= challenger.lastBattleTimestamp + battleCooldown,
"Challenger on cooldown"
);
require(
block.timestamp >= opponent.lastBattleTimestamp + battleCooldown,
"Opponent on cooldown"
);
// 2. Check additional 2-week cooldown for fighters who lost their last battle
// For the challenger
if (!challenger.wonLastBattle && challenger.lastBattleTimestamp > 0) {
require(
block.timestamp >= challenger.lastBattleTimestamp + loserCooldown,
"Challenger in recovery after last loss"
);
}
// For the opponent
if (!opponent.wonLastBattle && opponent.lastBattleTimestamp > 0) {
require(
block.timestamp >= opponent.lastBattleTimestamp + loserCooldown,
"Opponent in recovery after last loss"
);
}
// Update last battle timestamp
challenger.lastBattleTimestamp = block.timestamp;
opponent.lastBattleTimestamp = block.timestamp;
}
/**
* @notice Calculate the battle score for a fighter
* @param attributes The fighter's attributes
* @param randomness The random seed for main roll
* @param critRandomness Random value for critical hit/miss check
* @return The battle score
*/
function _calculateBattleScore(
FighterAttributes memory attributes,
uint256 randomness,
uint256 critRandomness
) private pure returns (uint256) {
// Use randomness directly for efficiency
uint256 seed = randomness;
// Calculate base score using all attributes (normalized to prevent overflow)
// Each attribute is capped at 150 and has a minimum of -150
uint256 baseScore;
int256 dexterity;
int256 intelligence;
int256 luckValue;
unchecked { // Safe because attributes are capped at ±150
// Cap each attribute between -150 and 150 to prevent overflow
// and ensure balanced gameplay
int256 attack = attributes.attack > int256(150) ? int256(150) : (attributes.attack < int256(-150) ? int256(-150) : attributes.attack);
int256 defense = attributes.defense > int256(150) ? int256(150) : (attributes.defense < int256(-150) ? int256(-150) : attributes.defense);
int256 magicAttack = attributes.magicAttack > int256(150) ? int256(150) : (attributes.magicAttack < int256(-150) ? int256(-150) : attributes.magicAttack);
int256 magicDef = attributes.magicDef > int256(150) ? int256(150) : (attributes.magicDef < int256(-150) ? int256(-150) : attributes.magicDef);
dexterity = attributes.dexterity > int256(150) ? int256(150) : (attributes.dexterity < int256(-150) ? int256(-150) : attributes.dexterity);
intelligence = attributes.intelligence > int256(150) ? int256(150) : (attributes.intelligence < int256(-150) ? int256(-150) : attributes.intelligence);
int256 speed = attributes.speed > int256(150) ? int256(150) : (attributes.speed < int256(-150) ? int256(-150) : attributes.speed);
luckValue = attributes.luck > int256(150) ? int256(150) : (attributes.luck < int256(-150) ? int256(-150) : attributes.luck);
// Physical combat score calculation (max 600)
// Attack and defense are weighted equally (2x multiplier each)
int256 physicalScore = attack * 2 + defense * 2;
// Magical combat score calculation (max 600)
// Magic attack and defense also weighted equally
int256 magicalScore = magicAttack * 2 + magicDef * 2;
// Utility score combines speed, intelligence and dexterity (max 450)
// These attributes affect critical hits and other special mechanics
int256 utilityScore = dexterity + intelligence + speed;
// Combine all scores, ensuring minimum of 0
int256 totalScore = physicalScore + magicalScore + utilityScore;
baseScore = totalScore > 0 ? uint256(totalScore) : 0;
}
// Apply random factor influenced by luck (±10% variation)
// randomFactor ranges from 0 to 30
uint256 randomFactor = (seed % 31);
unchecked {
if (randomFactor > 10) {
// Positive adjustment: up to +20% bonus
baseScore += (baseScore * (randomFactor - 10)) / 100;
} else {
// Negative adjustment: reduced by positive luck
// Each 30 points of luck reduces penalty by 1%
uint256 luckReduction = luckValue > 0 ? uint256(luckValue / 30) : 0;
if (luckValue < 0) {
// Negative luck increases the penalty
randomFactor += uint256(-luckValue / 30);
} else if (randomFactor < luckReduction) {
randomFactor = 0;
} else {
randomFactor -= luckReduction;
}
// Apply penalty (up to -10%, more with negative luck)
baseScore = randomFactor >= baseScore ? 1 : baseScore - (baseScore * randomFactor) / 100;
}
}
// Critical hit system adds excitement and variability
unchecked {
// Calculate crit chance based on dexterity, intelligence and luck
// Luck has 2x weight in crit calculations
int256 critChanceRaw = (dexterity + intelligence + (luckValue * 2)) / 6;
uint256 critChance = critChanceRaw > 0 ? uint256(critChanceRaw) : 0;
// Roll 1-100 for crit check
uint256 critRoll = (critRandomness % 100) + 1;
if (critRoll <= critChance) {
// Critical hit: +50% damage bonus
baseScore += (baseScore * 50) / 100;
} else if (critRoll >= (95 - (critChanceRaw > 0 ? uint256(critChanceRaw / 7) : 0))) {
// Critical miss: -25% penalty (or more with negative attributes)
// High positive attributes reduce chance of critical miss
uint256 penalty = 25;
if (critChanceRaw < 0) {
// Negative attributes increase critical miss penalty
penalty += uint256(-critChanceRaw / 4);
}
baseScore = baseScore <= penalty ? 1 : baseScore - (baseScore * penalty) / 100;
}
}
// Ensure minimum score of 1 to prevent zero scores
return baseScore > 0 ? baseScore : 1;
}
/**
* @notice Get the effective attributes of a fighter (base + boosters)
* @param contractAddress The contract address of the NFT
* @param tokenId The token ID of the NFT
* @return The effective attributes
*/
function getEffectiveAttributes(
address contractAddress,
uint256 tokenId
) public view returns (FighterAttributes memory) {
Fighter storage fighter = fighters[contractAddress][tokenId];
// Calculate effective attributes (can now be negative)
int256 attack = fighter.baseAttributes.attack + fighter.boosters.attack;
int256 defense = fighter.baseAttributes.defense + fighter.boosters.defense;
int256 magicAttack = fighter.baseAttributes.magicAttack + fighter.boosters.magicAttack;
int256 magicDef = fighter.baseAttributes.magicDef + fighter.boosters.magicDef;
int256 dexterity = fighter.baseAttributes.dexterity + fighter.boosters.dexterity;
int256 luck = fighter.baseAttributes.luck + fighter.boosters.luck;
int256 intelligence = fighter.baseAttributes.intelligence + fighter.boosters.intelligence;
int256 speed = fighter.baseAttributes.speed + fighter.boosters.speed;
int256 vitality = fighter.baseAttributes.vitality + fighter.boosters.vitality;
return FighterAttributes(
attack,
defense,
magicAttack,
magicDef,
dexterity,
luck,
intelligence,
speed,
vitality
);
}
/**
* @notice Get battle result by ID
* @param battleId The battle ID to query
*/
function getBattleResult(
uint256 battleId
) external view returns (BattleResult memory) {
return battleResults[battleId];
}
/**
* @notice Get fighter data excluding achievement mappings
*/
function getFighterData(
address contractAddress,
uint256 tokenId
) external view returns (
uint256 wins,
uint256 losses,
uint256 draws,
uint256 lastBattleTimestamp,
bool wonLastBattle,
uint256 currentStreak,
FighterAttributes memory baseAttributes,
FighterAttributes memory boosters
) {
Fighter storage fighter = fighters[contractAddress][tokenId];
return (
fighter.wins,
fighter.losses,
fighter.draws,
fighter.lastBattleTimestamp,
fighter.wonLastBattle,
fighter.currentStreak,
fighter.baseAttributes,
fighter.boosters
);
}
/**
* @notice Check if a contract is allowed
* @param contractAddress The address of the NFT contract
* @return Whether the contract is allowed
*/
function isContractAllowed(
address contractAddress
) public view returns (bool) {
return allowedContracts[contractAddress];
}
/**
* @notice Set the battle cooldown period
* @param _battleCooldown The new cooldown period in seconds
*/
function setBattleCooldown(uint256 _battleCooldown) external onlyOwner {
battleCooldown = _battleCooldown;
}
/**
* @notice Set the loser cooldown period
* @param _loserCooldown The new cooldown period in seconds
*/
function setLoserCooldown(uint256 _loserCooldown) external onlyOwner {
loserCooldown = _loserCooldown;
}
// Add a function to set the rewards contract address
function setRewardsContractAddress(
address _rewardsContract
) external onlyOwner {
rewardsContractAddress = _rewardsContract;
}
/**
* @notice Pause the coliseum
*/
function pause() external onlyOwner {
_pause();
}
/**
* @notice Unpause the coliseum
*/
function unpause() external onlyOwner {
_unpause();
}
/**
* @notice Check if an address is the owner of an NFT
* @param user The address to check
* @param contractAddress The address of the NFT contract
* @param tokenId The ID of the NFT
* @return Whether the address is the owner
*/
function _isOwnerOf(
address user,
address contractAddress,
uint256 tokenId
) internal view returns (bool) {
try IERC721(contractAddress).ownerOf(tokenId) returns (address owner) {
return owner == user;
} catch {
return false;
}
}
/**
* @notice Process the battle result after receiving entropy
*/
function _processBattleResult(
PendingBattle storage pendingBattle,
uint256 challengerScore,
uint256 opponentScore
) private {
Fighter storage challenger = fighters[pendingBattle.challengerContract][
pendingBattle.challengerTokenId
];
Fighter storage opponent = fighters[pendingBattle.opponentContract][
pendingBattle.opponentTokenId
];
bool challengerWon = challengerScore > opponentScore;
bool isDraw = challengerScore == opponentScore;
// Update fighter stats and streaks
if (isDraw) {
challenger.draws++;
opponent.draws++;
challenger.wonLastBattle = false;
opponent.wonLastBattle = false;
// Reset streaks on draw
challenger.currentStreak = 0;
opponent.currentStreak = 0;
} else if (challengerWon) {
challenger.wins++;
opponent.losses++;
challenger.wonLastBattle = true;
opponent.wonLastBattle = false;
// Update streaks
challenger.currentStreak++;
opponent.currentStreak = 0;
} else {
challenger.losses++;
opponent.wins++;
challenger.wonLastBattle = false;
opponent.wonLastBattle = true;
// Update streaks
challenger.currentStreak = 0;
opponent.currentStreak++;
}
// Record battle result
battleResults[battleCount] = BattleResult({
challengerContract: pendingBattle.challengerContract,
challengerTokenId: pendingBattle.challengerTokenId,
opponentContract: pendingBattle.opponentContract,
opponentTokenId: pendingBattle.opponentTokenId,
challengerWon: challengerWon,
isDraw: isDraw,
timestamp: block.timestamp,
challengerScore: challengerScore,
opponentScore: opponentScore
});
// Emit battle completion event
emit BattleComplete(
pendingBattle.sequenceNumber,
pendingBattle.challengerContract,
pendingBattle.challengerTokenId,
pendingBattle.opponentContract,
pendingBattle.opponentTokenId,
challengerWon,
isDraw,
challengerScore,
opponentScore
);
// Handle rewards
if (rewardsContractAddress != address(0)) {
IMintotaurColiseumRewards rewards = IMintotaurColiseumRewards(rewardsContractAddress);
address challengerOwner = IERC721(pendingBattle.challengerContract)
.ownerOf(pendingBattle.challengerTokenId);
address opponentOwner = IERC721(pendingBattle.opponentContract)
.ownerOf(pendingBattle.opponentTokenId);
// Handle win-based trophies
if (!isDraw) {
address winnerOwner = challengerWon ? challengerOwner : opponentOwner;
address loserContract = challengerWon
? pendingBattle.opponentContract
: pendingBattle.challengerContract;
rewards.mintForDefeatingContract(winnerOwner, loserContract);
}
}
}
/**
* @notice Required by the UUPS pattern
* @param newImplementation Address of the new implementation
*/
function _authorizeUpgrade(
address newImplementation
) internal override onlyOwner {}
// @param sequenceNumber The sequence number of the request.
// @param provider The address of the provider that generated the random number. If your app uses multiple providers, you can use this argument to distinguish which one is calling the app back.
// @param randomNumber The generated random number.
// This method is called by the entropy contract when a random number is generated.
// This method **must** be implemented on the same contract that requested the random number.
// This method should **never** return an error -- if it returns an error, then the keeper will not be able to invoke the callback.
// If you are having problems receiving the callback, the most likely cause is that the callback is erroring.
// See the callback debugging guide here to identify the error https://docs.pyth.network/entropy/debug-callback-failures
function entropyCallback(
uint64 sequenceNumber,
address provider,
bytes32 randomNumber
) internal override {
// Keep storage reference for _processBattleResult
PendingBattle storage pendingBattleStorage = pendingBattles[sequenceNumber];
require(!pendingBattleStorage.isProcessed, "Battle already processed");
// Convert the bytes32 random number into a uint256 for bit manipulation
uint256 combinedSeed = uint256(randomNumber);
// Split the 256-bit random number into 4 independent 64-bit seeds
// We use bit shifting (>>) and masking (&) to extract different portions:
// Challenger's main seed: bits 192-255 (highest 64 bits)
// Shift right by 192 to move these bits to the lowest position
// Then mask with (2^64 - 1) to keep only the lowest 64 bits
uint256 challengerSeed = (combinedSeed >> 192) & ((1 << 64) - 1);
// Opponent's main seed: bits 128-191
// Similar process but shift by 128
uint256 opponentSeed = (combinedSeed >> 128) & ((1 << 64) - 1);
// Challenger's critical hit seed: bits 64-127
// Shift by 64 to get these bits
uint256 challengerCritSeed = (combinedSeed >> 64) & ((1 << 64) - 1);
// Opponent's critical hit seed: bits 0-63 (lowest 64 bits)
// No shift needed, just mask to get lowest 64 bits
uint256 opponentCritSeed = combinedSeed & ((1 << 64) - 1);
// Each seed is now a unique 64-bit number (0 to 2^64-1)
// This provides plenty of entropy for battle calculations
// while being much more gas efficient than using keccak256
// Calculate scores using the independent seeds
uint256 challengerScore = _calculateBattleScore(
pendingBattleStorage.challengerAttributes,
challengerSeed,
challengerCritSeed
);
uint256 opponentScore = _calculateBattleScore(
pendingBattleStorage.opponentAttributes,
opponentSeed,
opponentCritSeed
);
// Process battle result and update storage once
_processBattleResult(pendingBattleStorage, challengerScore, opponentScore);
// Update storage state in a single operation
pendingBattleStorage.isProcessed = true;
unchecked {
++battleCount; // Use unchecked for gas savings since overflow is impossible in practice
}
}
// This method is required by the IEntropyConsumer interface.
// It returns the address of the entropy contract which will call the callback.
function getEntropy() internal view override returns (address) {
return address(entropy);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)
pragma solidity ^0.8.0;
import "../utils/ContextUpgradeable.sol";
import "../proxy/utils/Initializable.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
function __Ownable_init() internal onlyInitializing {
__Ownable_init_unchained();
}
function __Ownable_init_unchained() internal onlyInitializing {
_transferOwnership(_msgSender());
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions anymore. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby removing any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
/**
* @dev This empty reserved space is put in place to allow future versions to add new
* variables without shifting down storage in the inheritance chain.
* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
*/
uint256[49] private __gap;
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)
pragma solidity ^0.8.0;
/**
* @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified
* proxy whose upgrades are fully controlled by the current implementation.
*/
interface IERC1822ProxiableUpgradeable {
/**
* @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation
* address.
*
* IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks
* bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this
* function revert if invoked through a proxy.
*/
function proxiableUUID() external view returns (bytes32);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.3) (interfaces/IERC1967.sol)
pragma solidity ^0.8.0;
/**
* @dev ERC-1967: Proxy Storage Slots. This interface contains the events defined in the ERC.
*
* _Available since v4.9._
*/
interface IERC1967Upgradeable {
/**
* @dev Emitted when the implementation is upgraded.
*/
event Upgraded(address indexed implementation);
/**
* @dev Emitted when the admin account has changed.
*/
event AdminChanged(address previousAdmin, address newAdmin);
/**
* @dev Emitted when the beacon is changed.
*/
event BeaconUpgraded(address indexed beacon);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)
pragma solidity ^0.8.0;
/**
* @dev This is the interface that {BeaconProxy} expects of its beacon.
*/
interface IBeaconUpgradeable {
/**
* @dev Must return an address that can be used as a delegate call target.
*
* {BeaconProxy} will check that this address is a contract.
*/
function implementation() external view returns (address);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.3) (proxy/ERC1967/ERC1967Upgrade.sol)
pragma solidity ^0.8.2;
import "../beacon/IBeaconUpgradeable.sol";
import "../../interfaces/IERC1967Upgradeable.sol";
import "../../interfaces/draft-IERC1822Upgradeable.sol";
import "../../utils/AddressUpgradeable.sol";
import "../../utils/StorageSlotUpgradeable.sol";
import "../utils/Initializable.sol";
/**
* @dev This abstract contract provides getters and event emitting update functions for
* https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.
*
* _Available since v4.1._
*
* @custom:oz-upgrades-unsafe-allow delegatecall
*/
abstract contract ERC1967UpgradeUpgradeable is Initializable, IERC1967Upgradeable {
function __ERC1967Upgrade_init() internal onlyInitializing {
}
function __ERC1967Upgrade_init_unchained() internal onlyInitializing {
}
// This is the keccak-256 hash of "eip1967.proxy.rollback" subtracted by 1
bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;
/**
* @dev Storage slot with the address of the current implementation.
* This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1, and is
* validated in the constructor.
*/
bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
/**
* @dev Returns the current implementation address.
*/
function _getImplementation() internal view returns (address) {
return StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value;
}
/**
* @dev Stores a new address in the EIP1967 implementation slot.
*/
function _setImplementation(address newImplementation) private {
require(AddressUpgradeable.isContract(newImplementation), "ERC1967: new implementation is not a contract");
StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;
}
/**
* @dev Perform implementation upgrade
*
* Emits an {Upgraded} event.
*/
function _upgradeTo(address newImplementation) internal {
_setImplementation(newImplementation);
emit Upgraded(newImplementation);
}
/**
* @dev Perform implementation upgrade with additional setup call.
*
* Emits an {Upgraded} event.
*/
function _upgradeToAndCall(
address newImplementation,
bytes memory data,
bool forceCall
) internal {
_upgradeTo(newImplementation);
if (data.length > 0 || forceCall) {
_functionDelegateCall(newImplementation, data);
}
}
/**
* @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.
*
* Emits an {Upgraded} event.
*/
function _upgradeToAndCallUUPS(
address newImplementation,
bytes memory data,
bool forceCall
) internal {
// Upgrades from old implementations will perform a rollback test. This test requires the new
// implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing
// this special case will break upgrade paths from old UUPS implementation to new ones.
if (StorageSlotUpgradeable.getBooleanSlot(_ROLLBACK_SLOT).value) {
_setImplementation(newImplementation);
} else {
try IERC1822ProxiableUpgradeable(newImplementation).proxiableUUID() returns (bytes32 slot) {
require(slot == _IMPLEMENTATION_SLOT, "ERC1967Upgrade: unsupported proxiableUUID");
} catch {
revert("ERC1967Upgrade: new implementation is not UUPS");
}
_upgradeToAndCall(newImplementation, data, forceCall);
}
}
/**
* @dev Storage slot with the admin of the contract.
* This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1, and is
* validated in the constructor.
*/
bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;
/**
* @dev Returns the current admin.
*/
function _getAdmin() internal view returns (address) {
return StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value;
}
/**
* @dev Stores a new address in the EIP1967 admin slot.
*/
function _setAdmin(address newAdmin) private {
require(newAdmin != address(0), "ERC1967: new admin is the zero address");
StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value = newAdmin;
}
/**
* @dev Changes the admin of the proxy.
*
* Emits an {AdminChanged} event.
*/
function _changeAdmin(address newAdmin) internal {
emit AdminChanged(_getAdmin(), newAdmin);
_setAdmin(newAdmin);
}
/**
* @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.
* This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.
*/
bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;
/**
* @dev Returns the current beacon.
*/
function _getBeacon() internal view returns (address) {
return StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value;
}
/**
* @dev Stores a new beacon in the EIP1967 beacon slot.
*/
function _setBeacon(address newBeacon) private {
require(AddressUpgradeable.isContract(newBeacon), "ERC1967: new beacon is not a contract");
require(
AddressUpgradeable.isContract(IBeaconUpgradeable(newBeacon).implementation()),
"ERC1967: beacon implementation is not a contract"
);
StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value = newBeacon;
}
/**
* @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does
* not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).
*
* Emits a {BeaconUpgraded} event.
*/
function _upgradeBeaconToAndCall(
address newBeacon,
bytes memory data,
bool forceCall
) internal {
_setBeacon(newBeacon);
emit BeaconUpgraded(newBeacon);
if (data.length > 0 || forceCall) {
_functionDelegateCall(IBeaconUpgradeable(newBeacon).implementation(), data);
}
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function _functionDelegateCall(address target, bytes memory data) private returns (bytes memory) {
require(AddressUpgradeable.isContract(target), "Address: delegate call to non-contract");
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytes memory returndata) = target.delegatecall(data);
return AddressUpgradeable.verifyCallResult(success, returndata, "Address: low-level delegate call failed");
}
/**
* @dev This empty reserved space is put in place to allow future versions to add new
* variables without shifting down storage in the inheritance chain.
* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
*/
uint256[50] private __gap;
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.1) (proxy/utils/Initializable.sol)
pragma solidity ^0.8.2;
import "../../utils/AddressUpgradeable.sol";
/**
* @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed
* behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an
* external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer
* function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.
*
* The initialization functions use a version number. Once a version number is used, it is consumed and cannot be
* reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in
* case an upgrade adds a module that needs to be initialized.
*
* For example:
*
* [.hljs-theme-light.nopadding]
* ```
* contract MyToken is ERC20Upgradeable {
* function initialize() initializer public {
* __ERC20_init("MyToken", "MTK");
* }
* }
* contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {
* function initializeV2() reinitializer(2) public {
* __ERC20Permit_init("MyToken");
* }
* }
* ```
*
* TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as
* possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.
*
* CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure
* that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.
*
* [CAUTION]
* ====
* Avoid leaving a contract uninitialized.
*
* An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation
* contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke
* the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:
*
* [.hljs-theme-light.nopadding]
* ```
* /// @custom:oz-upgrades-unsafe-allow constructor
* constructor() {
* _disableInitializers();
* }
* ```
* ====
*/
abstract contract Initializable {
/**
* @dev Indicates that the contract has been initialized.
* @custom:oz-retyped-from bool
*/
uint8 private _initialized;
/**
* @dev Indicates that the contract is in the process of being initialized.
*/
bool private _initializing;
/**
* @dev Triggered when the contract has been initialized or reinitialized.
*/
event Initialized(uint8 version);
/**
* @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,
* `onlyInitializing` functions can be used to initialize parent contracts.
*
* Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a
* constructor.
*
* Emits an {Initialized} event.
*/
modifier initializer() {
bool isTopLevelCall = !_initializing;
require(
(isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),
"Initializable: contract is already initialized"
);
_initialized = 1;
if (isTopLevelCall) {
_initializing = true;
}
_;
if (isTopLevelCall) {
_initializing = false;
emit Initialized(1);
}
}
/**
* @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the
* contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be
* used to initialize parent contracts.
*
* A reinitializer may be used after the original initialization step. This is essential to configure modules that
* are added through upgrades and that require initialization.
*
* When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`
* cannot be nested. If one is invoked in the context of another, execution will revert.
*
* Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in
* a contract, executing them in the right order is up to the developer or operator.
*
* WARNING: setting the version to 255 will prevent any future reinitialization.
*
* Emits an {Initialized} event.
*/
modifier reinitializer(uint8 version) {
require(!_initializing && _initialized < version, "Initializable: contract is already initialized");
_initialized = version;
_initializing = true;
_;
_initializing = false;
emit Initialized(version);
}
/**
* @dev Modifier to protect an initialization function so that it can only be invoked by functions with the
* {initializer} and {reinitializer} modifiers, directly or indirectly.
*/
modifier onlyInitializing() {
require(_initializing, "Initializable: contract is not initializing");
_;
}
/**
* @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.
* Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized
* to any version. It is recommended to use this to lock implementation contracts that are designed to be called
* through proxies.
*
* Emits an {Initialized} event the first time it is successfully executed.
*/
function _disableInitializers() internal virtual {
require(!_initializing, "Initializable: contract is initializing");
if (_initialized < type(uint8).max) {
_initialized = type(uint8).max;
emit Initialized(type(uint8).max);
}
}
/**
* @dev Returns the highest version that has been initialized. See {reinitializer}.
*/
function _getInitializedVersion() internal view returns (uint8) {
return _initialized;
}
/**
* @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.
*/
function _isInitializing() internal view returns (bool) {
return _initializing;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (proxy/utils/UUPSUpgradeable.sol)
pragma solidity ^0.8.0;
import "../../interfaces/draft-IERC1822Upgradeable.sol";
import "../ERC1967/ERC1967UpgradeUpgradeable.sol";
import "./Initializable.sol";
/**
* @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an
* {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy.
*
* A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is
* reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing
* `UUPSUpgradeable` with a custom implementation of upgrades.
*
* The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism.
*
* _Available since v4.1._
*/
abstract contract UUPSUpgradeable is Initializable, IERC1822ProxiableUpgradeable, ERC1967UpgradeUpgradeable {
function __UUPSUpgradeable_init() internal onlyInitializing {
}
function __UUPSUpgradeable_init_unchained() internal onlyInitializing {
}
/// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment
address private immutable __self = address(this);
/**
* @dev Check that the execution is being performed through a delegatecall call and that the execution context is
* a proxy contract with an implementation (as defined in ERC1967) pointing to self. This should only be the case
* for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a
* function through ERC1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to
* fail.
*/
modifier onlyProxy() {
require(address(this) != __self, "Function must be called through delegatecall");
require(_getImplementation() == __self, "Function must be called through active proxy");
_;
}
/**
* @dev Check that the execution is not being performed through a delegate call. This allows a function to be
* callable on the implementing contract but not through proxies.
*/
modifier notDelegated() {
require(address(this) == __self, "UUPSUpgradeable: must not be called through delegatecall");
_;
}
/**
* @dev Implementation of the ERC1822 {proxiableUUID} function. This returns the storage slot used by the
* implementation. It is used to validate the implementation's compatibility when performing an upgrade.
*
* IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks
* bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this
* function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier.
*/
function proxiableUUID() external view virtual override notDelegated returns (bytes32) {
return _IMPLEMENTATION_SLOT;
}
/**
* @dev Upgrade the implementation of the proxy to `newImplementation`.
*
* Calls {_authorizeUpgrade}.
*
* Emits an {Upgraded} event.
*/
function upgradeTo(address newImplementation) external virtual onlyProxy {
_authorizeUpgrade(newImplementation);
_upgradeToAndCallUUPS(newImplementation, new bytes(0), false);
}
/**
* @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call
* encoded in `data`.
*
* Calls {_authorizeUpgrade}.
*
* Emits an {Upgraded} event.
*/
function upgradeToAndCall(address newImplementation, bytes memory data) external payable virtual onlyProxy {
_authorizeUpgrade(newImplementation);
_upgradeToAndCallUUPS(newImplementation, data, true);
}
/**
* @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by
* {upgradeTo} and {upgradeToAndCall}.
*
* Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}.
*
* ```solidity
* function _authorizeUpgrade(address) internal override onlyOwner {}
* ```
*/
function _authorizeUpgrade(address newImplementation) internal virtual;
/**
* @dev This empty reserved space is put in place to allow future versions to add new
* variables without shifting down storage in the inheritance chain.
* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
*/
uint256[50] private __gap;
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol)
pragma solidity ^0.8.0;
import "../utils/ContextUpgradeable.sol";
import "../proxy/utils/Initializable.sol";
/**
* @dev Contract module which allows children to implement an emergency stop
* mechanism that can be triggered by an authorized account.
*
* This module is used through inheritance. It will make available the
* modifiers `whenNotPaused` and `whenPaused`, which can be applied to
* the functions of your contract. Note that they will not be pausable by
* simply including this module, only once the modifiers are put in place.
*/
abstract contract PausableUpgradeable is Initializable, ContextUpgradeable {
/**
* @dev Emitted when the pause is triggered by `account`.
*/
event Paused(address account);
/**
* @dev Emitted when the pause is lifted by `account`.
*/
event Unpaused(address account);
bool private _paused;
/**
* @dev Initializes the contract in unpaused state.
*/
function __Pausable_init() internal onlyInitializing {
__Pausable_init_unchained();
}
function __Pausable_init_unchained() internal onlyInitializing {
_paused = false;
}
/**
* @dev Modifier to make a function callable only when the contract is not paused.
*
* Requirements:
*
* - The contract must not be paused.
*/
modifier whenNotPaused() {
_requireNotPaused();
_;
}
/**
* @dev Modifier to make a function callable only when the contract is paused.
*
* Requirements:
*
* - The contract must be paused.
*/
modifier whenPaused() {
_requirePaused();
_;
}
/**
* @dev Returns true if the contract is paused, and false otherwise.
*/
function paused() public view virtual returns (bool) {
return _paused;
}
/**
* @dev Throws if the contract is paused.
*/
function _requireNotPaused() internal view virtual {
require(!paused(), "Pausable: paused");
}
/**
* @dev Throws if the contract is not paused.
*/
function _requirePaused() internal view virtual {
require(paused(), "Pausable: not paused");
}
/**
* @dev Triggers stopped state.
*
* Requirements:
*
* - The contract must not be paused.
*/
function _pause() internal virtual whenNotPaused {
_paused = true;
emit Paused(_msgSender());
}
/**
* @dev Returns to normal state.
*
* Requirements:
*
* - The contract must be paused.
*/
function _unpause() internal virtual whenPaused {
_paused = false;
emit Unpaused(_msgSender());
}
/**
* @dev This empty reserved space is put in place to allow future versions to add new
* variables without shifting down storage in the inheritance chain.
* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
*/
uint256[49] private __gap;
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (security/ReentrancyGuard.sol)
pragma solidity ^0.8.0;
import "../proxy/utils/Initializable.sol";
/**
* @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 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 ReentrancyGuardUpgradeable is Initializable {
// 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;
function __ReentrancyGuard_init() internal onlyInitializing {
__ReentrancyGuard_init_unchained();
}
function __ReentrancyGuard_init_unchained() internal onlyInitializing {
_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
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
// 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 This empty reserved space is put in place to allow future versions to add new
* variables without shifting down storage in the inheritance chain.
* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
*/
uint256[49] private __gap;
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol)
pragma solidity ^0.8.1;
/**
* @dev Collection of functions related to the address type
*/
library AddressUpgradeable {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
* ====
*
* [IMPORTANT]
* ====
* You shouldn't rely on `isContract` to protect against flash loan attacks!
*
* Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
* like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
* constructor.
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize/address.code.length, which returns 0
// for contracts in construction, since the code is only stored at the end
// of the constructor execution.
return account.code.length > 0;
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain `call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason, it is bubbled up by this
* function (like regular Solidity function calls).
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, "Address: low-level call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
* `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value
) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
* the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
*
* _Available since v4.8._
*/
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata,
string memory errorMessage
) internal view returns (bytes memory) {
if (success) {
if (returndata.length == 0) {
// only check isContract if the call was successful and the return data is empty
// otherwise we already know that it was a contract
require(isContract(target), "Address: call to non-contract");
}
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
/**
* @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
* revert reason or using the provided one.
*
* _Available since v4.3._
*/
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
function _revert(bytes memory returndata, string memory errorMessage) private pure {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
/// @solidity memory-safe-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)
pragma solidity ^0.8.0;
import "../proxy/utils/Initializable.sol";
/**
* @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 ContextUpgradeable is Initializable {
function __Context_init() internal onlyInitializing {
}
function __Context_init_unchained() internal onlyInitializing {
}
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
/**
* @dev This empty reserved space is put in place to allow future versions to add new
* variables without shifting down storage in the inheritance chain.
* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
*/
uint256[50] private __gap;
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol)
pragma solidity ^0.8.0;
/**
* @dev Library for reading and writing primitive types to specific storage slots.
*
* Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.
* This library helps with reading and writing to such slots without the need for inline assembly.
*
* The functions in this library return Slot structs that contain a `value` member that can be used to read or write.
*
* Example usage to set ERC1967 implementation slot:
* ```
* contract ERC1967 {
* bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
*
* function _getImplementation() internal view returns (address) {
* return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;
* }
*
* function _setImplementation(address newImplementation) internal {
* require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract");
* StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;
* }
* }
* ```
*
* _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._
*/
library StorageSlotUpgradeable {
struct AddressSlot {
address value;
}
struct BooleanSlot {
bool value;
}
struct Bytes32Slot {
bytes32 value;
}
struct Uint256Slot {
uint256 value;
}
/**
* @dev Returns an `AddressSlot` with member `value` located at `slot`.
*/
function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := slot
}
}
/**
* @dev Returns an `BooleanSlot` with member `value` located at `slot`.
*/
function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := slot
}
}
/**
* @dev Returns an `Bytes32Slot` with member `value` located at `slot`.
*/
function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := slot
}
}
/**
* @dev Returns an `Uint256Slot` with member `value` located at `slot`.
*/
function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := slot
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol)
pragma solidity ^0.8.0;
import "../../utils/introspection/IERC165.sol";
/**
* @dev Required interface of an ERC721 compliant contract.
*/
interface IERC721 is IERC165 {
/**
* @dev Emitted when `tokenId` token is transferred from `from` to `to`.
*/
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
/**
* @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.
*/
event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
/**
* @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.
*/
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
/**
* @dev Returns the number of tokens in ``owner``'s account.
*/
function balanceOf(address owner) external view returns (uint256 balance);
/**
* @dev Returns the owner of the `tokenId` token.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function ownerOf(uint256 tokenId) external view returns (address owner);
/**
* @dev Safely transfers `tokenId` token from `from` to `to`.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must exist and be owned by `from`.
* - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
* - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
*
* Emits a {Transfer} event.
*/
function safeTransferFrom(
address from,
address to,
uint256 tokenId,
bytes calldata data
) external;
/**
* @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
* are aware of the ERC721 protocol to prevent tokens from being forever locked.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must exist and be owned by `from`.
* - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.
* - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
*
* Emits a {Transfer} event.
*/
function safeTransferFrom(
address from,
address to,
uint256 tokenId
) external;
/**
* @dev Transfers `tokenId` token from `from` to `to`.
*
* WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721
* or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must
* understand this adds an external call which potentially creates a reentrancy vulnerability.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must be owned by `from`.
* - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
*
* Emits a {Transfer} event.
*/
function transferFrom(
address from,
address to,
uint256 tokenId
) external;
/**
* @dev Gives permission to `to` to transfer `tokenId` token to another account.
* The approval is cleared when the token is transferred.
*
* Only a single account can be approved at a time, so approving the zero address clears previous approvals.
*
* Requirements:
*
* - The caller must own the token or be an approved operator.
* - `tokenId` must exist.
*
* Emits an {Approval} event.
*/
function approve(address to, uint256 tokenId) external;
/**
* @dev Approve or remove `operator` as an operator for the caller.
* Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.
*
* Requirements:
*
* - The `operator` cannot be the caller.
*
* Emits an {ApprovalForAll} event.
*/
function setApprovalForAll(address operator, bool _approved) external;
/**
* @dev Returns the account approved for `tokenId` token.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function getApproved(uint256 tokenId) external view returns (address operator);
/**
* @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.
*
* See {setApprovalForAll}
*/
function isApprovedForAll(address owner, address operator) external view returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[EIP].
*
* 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[EIP 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: 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;
}{
"optimizer": {
"enabled": true,
"runs": 200
},
"viaIR": false,
"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":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"previousAdmin","type":"address"},{"indexed":false,"internalType":"address","name":"newAdmin","type":"address"}],"name":"AdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint64","name":"sequenceNumber","type":"uint64"},{"indexed":true,"internalType":"address","name":"challengerContract","type":"address"},{"indexed":true,"internalType":"uint256","name":"challengerTokenId","type":"uint256"},{"indexed":false,"internalType":"address","name":"opponentContract","type":"address"},{"indexed":false,"internalType":"uint256","name":"opponentTokenId","type":"uint256"},{"indexed":false,"internalType":"bool","name":"challengerWon","type":"bool"},{"indexed":false,"internalType":"bool","name":"isDraw","type":"bool"},{"indexed":false,"internalType":"uint256","name":"challengerScore","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"opponentScore","type":"uint256"}],"name":"BattleComplete","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint64","name":"sequenceNumber","type":"uint64"},{"indexed":true,"internalType":"address","name":"challengerContract","type":"address"},{"indexed":true,"internalType":"uint256","name":"challengerTokenId","type":"uint256"},{"indexed":false,"internalType":"address","name":"opponentContract","type":"address"},{"indexed":false,"internalType":"uint256","name":"opponentTokenId","type":"uint256"}],"name":"BattleInitiated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"beacon","type":"address"}],"name":"BeaconUpgraded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"implementation","type":"address"}],"name":"Upgraded","type":"event"},{"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":"","type":"address"}],"name":"allowedContracts","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"components":[{"internalType":"int256","name":"attack","type":"int256"},{"internalType":"int256","name":"defense","type":"int256"},{"internalType":"int256","name":"magicAttack","type":"int256"},{"internalType":"int256","name":"magicDef","type":"int256"},{"internalType":"int256","name":"dexterity","type":"int256"},{"internalType":"int256","name":"luck","type":"int256"},{"internalType":"int256","name":"intelligence","type":"int256"},{"internalType":"int256","name":"speed","type":"int256"},{"internalType":"int256","name":"vitality","type":"int256"}],"internalType":"struct MintotaurColiseum.FighterAttributes","name":"boosters","type":"tuple"}],"name":"applyBoosters","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"},{"components":[{"internalType":"int256","name":"attack","type":"int256"},{"internalType":"int256","name":"defense","type":"int256"},{"internalType":"int256","name":"magicAttack","type":"int256"},{"internalType":"int256","name":"magicDef","type":"int256"},{"internalType":"int256","name":"dexterity","type":"int256"},{"internalType":"int256","name":"luck","type":"int256"},{"internalType":"int256","name":"intelligence","type":"int256"},{"internalType":"int256","name":"speed","type":"int256"},{"internalType":"int256","name":"vitality","type":"int256"}],"internalType":"struct MintotaurColiseum.FighterAttributes[]","name":"boosters","type":"tuple[]"}],"name":"applyBoostersBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"authorizedAddresses","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"uint256","name":"startTokenId","type":"uint256"},{"internalType":"uint256","name":"endTokenId","type":"uint256"}],"name":"batchInitializeFighters","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"contractAddresses","type":"address[]"},{"internalType":"bool","name":"allowed","type":"bool"}],"name":"batchSetContractsAllowed","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"challengerContract","type":"address"},{"internalType":"uint256","name":"challengerTokenId","type":"uint256"},{"internalType":"address","name":"opponentContract","type":"address"},{"internalType":"uint256","name":"opponentTokenId","type":"uint256"},{"internalType":"bytes32","name":"userRandomNumber","type":"bytes32"},{"internalType":"uint256[]","name":"challengerChoices","type":"uint256[]"},{"internalType":"uint256[]","name":"opponentChoices","type":"uint256[]"}],"name":"battle","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"battleCooldown","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"battleCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"battleResults","outputs":[{"internalType":"address","name":"challengerContract","type":"address"},{"internalType":"uint256","name":"challengerTokenId","type":"uint256"},{"internalType":"address","name":"opponentContract","type":"address"},{"internalType":"uint256","name":"opponentTokenId","type":"uint256"},{"internalType":"bool","name":"challengerWon","type":"bool"},{"internalType":"bool","name":"isDraw","type":"bool"},{"internalType":"uint256","name":"timestamp","type":"uint256"},{"internalType":"uint256","name":"challengerScore","type":"uint256"},{"internalType":"uint256","name":"opponentScore","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"contractBaseAttributes","outputs":[{"internalType":"int256","name":"attack","type":"int256"},{"internalType":"int256","name":"defense","type":"int256"},{"internalType":"int256","name":"magicAttack","type":"int256"},{"internalType":"int256","name":"magicDef","type":"int256"},{"internalType":"int256","name":"dexterity","type":"int256"},{"internalType":"int256","name":"luck","type":"int256"},{"internalType":"int256","name":"intelligence","type":"int256"},{"internalType":"int256","name":"speed","type":"int256"},{"internalType":"int256","name":"vitality","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"entropy","outputs":[{"internalType":"contract IEntropy","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"battleId","type":"uint256"}],"name":"getBattleResult","outputs":[{"components":[{"internalType":"address","name":"challengerContract","type":"address"},{"internalType":"uint256","name":"challengerTokenId","type":"uint256"},{"internalType":"address","name":"opponentContract","type":"address"},{"internalType":"uint256","name":"opponentTokenId","type":"uint256"},{"internalType":"bool","name":"challengerWon","type":"bool"},{"internalType":"bool","name":"isDraw","type":"bool"},{"internalType":"uint256","name":"timestamp","type":"uint256"},{"internalType":"uint256","name":"challengerScore","type":"uint256"},{"internalType":"uint256","name":"opponentScore","type":"uint256"}],"internalType":"struct MintotaurColiseum.BattleResult","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getEffectiveAttributes","outputs":[{"components":[{"internalType":"int256","name":"attack","type":"int256"},{"internalType":"int256","name":"defense","type":"int256"},{"internalType":"int256","name":"magicAttack","type":"int256"},{"internalType":"int256","name":"magicDef","type":"int256"},{"internalType":"int256","name":"dexterity","type":"int256"},{"internalType":"int256","name":"luck","type":"int256"},{"internalType":"int256","name":"intelligence","type":"int256"},{"internalType":"int256","name":"speed","type":"int256"},{"internalType":"int256","name":"vitality","type":"int256"}],"internalType":"struct MintotaurColiseum.FighterAttributes","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getFighterData","outputs":[{"internalType":"uint256","name":"wins","type":"uint256"},{"internalType":"uint256","name":"losses","type":"uint256"},{"internalType":"uint256","name":"draws","type":"uint256"},{"internalType":"uint256","name":"lastBattleTimestamp","type":"uint256"},{"internalType":"bool","name":"wonLastBattle","type":"bool"},{"internalType":"uint256","name":"currentStreak","type":"uint256"},{"components":[{"internalType":"int256","name":"attack","type":"int256"},{"internalType":"int256","name":"defense","type":"int256"},{"internalType":"int256","name":"magicAttack","type":"int256"},{"internalType":"int256","name":"magicDef","type":"int256"},{"internalType":"int256","name":"dexterity","type":"int256"},{"internalType":"int256","name":"luck","type":"int256"},{"internalType":"int256","name":"intelligence","type":"int256"},{"internalType":"int256","name":"speed","type":"int256"},{"internalType":"int256","name":"vitality","type":"int256"}],"internalType":"struct MintotaurColiseum.FighterAttributes","name":"baseAttributes","type":"tuple"},{"components":[{"internalType":"int256","name":"attack","type":"int256"},{"internalType":"int256","name":"defense","type":"int256"},{"internalType":"int256","name":"magicAttack","type":"int256"},{"internalType":"int256","name":"magicDef","type":"int256"},{"internalType":"int256","name":"dexterity","type":"int256"},{"internalType":"int256","name":"luck","type":"int256"},{"internalType":"int256","name":"intelligence","type":"int256"},{"internalType":"int256","name":"speed","type":"int256"},{"internalType":"int256","name":"vitality","type":"int256"}],"internalType":"struct MintotaurColiseum.FighterAttributes","name":"boosters","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_initialAllowedContracts","type":"address[]"},{"internalType":"uint256","name":"_battleCooldown","type":"uint256"},{"internalType":"uint256","name":"_loserCooldown","type":"uint256"},{"internalType":"address","name":"_entropy","type":"address"},{"internalType":"address","name":"_provider","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"contractAddress","type":"address"}],"name":"isContractAllowed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"loserCooldown","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"","type":"uint64"}],"name":"pendingBattles","outputs":[{"internalType":"address","name":"challengerContract","type":"address"},{"internalType":"uint256","name":"challengerTokenId","type":"uint256"},{"internalType":"address","name":"opponentContract","type":"address"},{"internalType":"uint256","name":"opponentTokenId","type":"uint256"},{"components":[{"internalType":"int256","name":"attack","type":"int256"},{"internalType":"int256","name":"defense","type":"int256"},{"internalType":"int256","name":"magicAttack","type":"int256"},{"internalType":"int256","name":"magicDef","type":"int256"},{"internalType":"int256","name":"dexterity","type":"int256"},{"internalType":"int256","name":"luck","type":"int256"},{"internalType":"int256","name":"intelligence","type":"int256"},{"internalType":"int256","name":"speed","type":"int256"},{"internalType":"int256","name":"vitality","type":"int256"}],"internalType":"struct MintotaurColiseum.FighterAttributes","name":"challengerAttributes","type":"tuple"},{"components":[{"internalType":"int256","name":"attack","type":"int256"},{"internalType":"int256","name":"defense","type":"int256"},{"internalType":"int256","name":"magicAttack","type":"int256"},{"internalType":"int256","name":"magicDef","type":"int256"},{"internalType":"int256","name":"dexterity","type":"int256"},{"internalType":"int256","name":"luck","type":"int256"},{"internalType":"int256","name":"intelligence","type":"int256"},{"internalType":"int256","name":"speed","type":"int256"},{"internalType":"int256","name":"vitality","type":"int256"}],"internalType":"struct MintotaurColiseum.FighterAttributes","name":"opponentAttributes","type":"tuple"},{"components":[{"internalType":"uint256[]","name":"choices","type":"uint256[]"}],"internalType":"struct MintotaurColiseum.FightingChoice","name":"challengerChoices","type":"tuple"},{"components":[{"internalType":"uint256[]","name":"choices","type":"uint256[]"}],"internalType":"struct MintotaurColiseum.FightingChoice","name":"opponentChoices","type":"tuple"},{"internalType":"uint64","name":"sequenceNumber","type":"uint64"},{"internalType":"bool","name":"isProcessed","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"proxiableUUID","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rewardsContractAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"addresses","type":"address[]"},{"internalType":"bool[]","name":"allowed","type":"bool[]"}],"name":"setAuthorizedAddresses","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_battleCooldown","type":"uint256"}],"name":"setBattleCooldown","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"contractAddress","type":"address"},{"components":[{"internalType":"int256","name":"attack","type":"int256"},{"internalType":"int256","name":"defense","type":"int256"},{"internalType":"int256","name":"magicAttack","type":"int256"},{"internalType":"int256","name":"magicDef","type":"int256"},{"internalType":"int256","name":"dexterity","type":"int256"},{"internalType":"int256","name":"luck","type":"int256"},{"internalType":"int256","name":"intelligence","type":"int256"},{"internalType":"int256","name":"speed","type":"int256"},{"internalType":"int256","name":"vitality","type":"int256"}],"internalType":"struct MintotaurColiseum.FighterAttributes","name":"attributes","type":"tuple"}],"name":"setContractBaseAttributes","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_loserCooldown","type":"uint256"}],"name":"setLoserCooldown","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_rewardsContract","type":"address"}],"name":"setRewardsContractAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newImplementation","type":"address"}],"name":"upgradeTo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newImplementation","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"upgradeToAndCall","outputs":[],"stateMutability":"payable","type":"function"}]Contract Creation Code
60a06040523060805234801561001457600080fd5b5061001d610022565b6100e2565b600054610100900460ff161561008e5760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff90811610156100e0576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b608051614814610119600039600081816109180152818161096101528181610f6701528181610fa7015261128d01526148146000f3fe6080604052600436106102045760003560e01c806376050eda11610118578063d41c71ae116100a0578063e00b63631161006f578063e00b636314610631578063f19e207e14610648578063f2fde38b14610679578063f458c65114610699578063fa778f4d1461074757600080fd5b8063d41c71ae146105b9578063d44985ca146105d9578063db91aba4146105fa578063dea6b7151461061157600080fd5b80638da5cb5b116100e75780638da5cb5b1461050e578063a844d6f51461052c578063c2c3872a1461054c578063c9b43db214610582578063d1006a6f146105a257600080fd5b806376050eda1461048e5780637b25be4e146104b95780637e92c872146104d95780638456cb59146104f957600080fd5b80634f1ef2861161019b57806352d1902d1161016a57806352d1902d146103e45780635c975abb1461040757806364a291aa1461041f5780636f2ddb5f1461043f578063715018a61461047957600080fd5b80634f1ef2861461033c578063500067cd1461034f57806351e0e26b1461038357806352a5f1f8146103c457600080fd5b80633f4ba83a116101d75780633f4ba83a146102ae5780634211d52e146102c357806347ce07cc146102e35780634996d5891461031c57600080fd5b80632904c529146102095780633659cfe61461023f57806336cbbe2f146102615780633e8d435b14610281575b600080fd5b34801561021557600080fd5b50610229610224366004613ba9565b610814565b6040516102369190613bc2565b60405180910390f35b34801561024b57600080fd5b5061025f61025a366004613c6b565b61090e565b005b34801561026d57600080fd5b5061025f61027c366004613d70565b6109f6565b34801561028d57600080fd5b506102a161029c366004613da7565b610aac565b6040516102369190613e2d565b3480156102ba57600080fd5b5061025f610c0c565b3480156102cf57600080fd5b5061025f6102de366004613e97565b610c1e565b3480156102ef57600080fd5b5061012e54610304906001600160a01b031681565b6040516001600160a01b039091168152602001610236565b34801561032857600080fd5b5061025f610337366004613eea565b610c94565b61025f61034a366004613fa1565b610f5d565b34801561035b57600080fd5b5061036f61036a366004613da7565b61102d565b60405161023698979695949392919061404c565b34801561038f57600080fd5b506103b461039e366004613c6b565b61012d6020526000908152604090205460ff1681565b6040519015158152602001610236565b3480156103d057600080fd5b5061025f6103df3660046140a8565b6111a4565b3480156103f057600080fd5b506103f9611280565b604051908152602001610236565b34801561041357600080fd5b5060975460ff166103b4565b34801561042b57600080fd5b5061025f61043a366004613ba9565b611333565b34801561044b57600080fd5b506103b461045a366004613c6b565b6001600160a01b0316600090815261012d602052604090205460ff1690565b34801561048557600080fd5b5061025f611341565b6104a161049c3660046140e9565b611353565b6040516001600160401b039091168152602001610236565b3480156104c557600080fd5b5061025f6104d43660046141a0565b611a5d565b3480156104e557600080fd5b5061025f6104f4366004613c6b565b611bbb565b34801561050557600080fd5b5061025f611be6565b34801561051a57600080fd5b506033546001600160a01b0316610304565b34801561053857600080fd5b5061025f6105473660046141d7565b611bf6565b34801561055857600080fd5b5061056c6105673660046142c3565b611ddc565b6040516102369a9998979695949392919061432b565b34801561058e57600080fd5b5061025f61059d3660046143be565b611feb565b3480156105ae57600080fd5b506103f96101355481565b3480156105c557600080fd5b5061025f6105d436600461442d565b612088565b3480156105e557600080fd5b5061013054610304906001600160a01b031681565b34801561060657600080fd5b506103f96101365481565b34801561061d57600080fd5b5061025f61062c366004613ba9565b6122de565b34801561063d57600080fd5b506103f96101375481565b34801561065457600080fd5b506103b4610663366004613c6b565b6101316020526000908152604090205460ff1681565b34801561068557600080fd5b5061025f610694366004613c6b565b6122ec565b3480156106a557600080fd5b506107036106b4366004613c6b565b6101336020528060005260406000206000915090508060000154908060010154908060020154908060030154908060040154908060050154908060060154908060070154908060080154905089565b60408051998a5260208a0198909852968801959095526060870193909352608086019190915260a085015260c084015260e083015261010082015261012001610236565b34801561075357600080fd5b506107bd610762366004613ba9565b61013460205260009081526040902080546001820154600283015460038401546004850154600586015460068701546007909701546001600160a01b0396871697959690941694929360ff8084169461010090940416929089565b604080516001600160a01b039a8b1681526020810199909952969098169587019590955260608601939093529015156080850152151560a084015260c083015260e082015261010081019190915261012001610236565b61087960405180610120016040528060006001600160a01b031681526020016000815260200160006001600160a01b03168152602001600081526020016000151581526020016000151581526020016000815260200160008152602001600081525090565b506000908152610134602090815260409182902082516101208101845281546001600160a01b03908116825260018301549382019390935260028201549092169282019290925260038201546060820152600482015460ff808216151560808401526101009182900416151560a0830152600583015460c0830152600683015460e08301526007909201549181019190915290565b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016300361095f5760405162461bcd60e51b815260040161095690614462565b60405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166109a8600080516020614798833981519152546001600160a01b031690565b6001600160a01b0316146109ce5760405162461bcd60e51b8152600401610956906144ae565b6109d781612362565b604080516000808252602082019092526109f39183919061236a565b50565b6109fe6124da565b6001600160a01b038216600090815261012d602052604090205460ff16610a375760405162461bcd60e51b8152600401610956906144fa565b6001600160a01b039091166000908152610133602090815260409182902083518155908301516001820155908201516002820155606082015160038201556080820151600482015560a0820151600582015560c0820151600682015560e0820151600782015561010090910151600890910155565b610ab4613afd565b6001600160a01b038316600090815261013260209081526040808320858452909152812060108101546007820154919291610aef919061453e565b60118301546008840154919250600091610b09919061453e565b60128401546009850154919250600091610b23919061453e565b6013850154600a860154919250600091610b3d919061453e565b6014860154600b870154919250600091610b57919061453e565b6015870154600c880154919250600091610b71919061453e565b6016880154600d890154919250600091610b8b919061453e565b6017890154600e8a0154919250600091610ba5919061453e565b60188a0154600f8b0154919250600091610bbf919061453e565b60408051610120810182529a8b5260208b0199909952978901969096526060880194909452608087019290925260a086015260c085015260e0840152506101008201529150505b92915050565b610c146124da565b610c1c612534565b565b610c266124da565b60005b82811015610c8e578161012d6000868685818110610c4957610c49614566565b9050602002016020810190610c5e9190613c6b565b6001600160a01b031681526020810191909152604001600020805460ff1916911515919091179055600101610c29565b50505050565b336000908152610131602052604090205460ff161515600114610cc95760405162461bcd60e51b81526004016109569061457c565b6001600160a01b038516600090815261012d602052604090205460ff16610d025760405162461bcd60e51b8152600401610956906144fa565b828114610d515760405162461bcd60e51b815260206004820152601860248201527f4172726179206c656e67746873206d757374206d6174636800000000000000006044820152606401610956565b82610d9e5760405162461bcd60e51b815260206004820152601860248201527f456d70747920617272617973206e6f7420616c6c6f77656400000000000000006044820152606401610956565b6032831115610de65760405162461bcd60e51b815260206004820152601460248201527342617463682073697a6520746f6f206c6172676560601b6044820152606401610956565b60005b83811015610f55576001600160a01b03861660009081526101326020526040812081878785818110610e1d57610e1d614566565b9050602002013581526020019081526020016000206007016000015413610e805760405162461bcd60e51b8152602060048201526017602482015276119a59da1d195c881b9bdd081a5b9a5d1a585b1a5e9959604a1b6044820152606401610956565b828282818110610e9257610e92614566565b905061012002016101326000886001600160a01b03166001600160a01b031681526020019081526020016000206000878785818110610ed357610ed3614566565b9050602002013581526020019081526020016000206010018181610f4b9190813581556020820135600182015560408201356002820155606082013560038201556080820135600482015560a0820135600582015560c0820135600682015560e0820135600782015561010090910135600890910155565b5050600101610de9565b505050505050565b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163003610fa55760405162461bcd60e51b815260040161095690614462565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316610fee600080516020614798833981519152546001600160a01b031690565b6001600160a01b0316146110145760405162461bcd60e51b8152600401610956906144ae565b61101d82612362565b6110298282600161236a565b5050565b60008060008060008061103e613afd565b611046613afd565b600061013260008c6001600160a01b03166001600160a01b0316815260200190815260200160002060008b8152602001908152602001600020905080600001548160010154826002015483600301548460040160009054906101000a900460ff168560050154866007018760100181604051806101200160405290816000820154815260200160018201548152602001600282015481526020016003820154815260200160048201548152602001600582015481526020016006820154815260200160078201548152602001600882015481525050915080604051806101200160405290816000820154815260200160018201548152602001600282015481526020016003820154815260200160048201548152602001600582015481526020016006820154815260200160078201548152602001600882015481525050905098509850985098509850985098509850509295985092959890939650565b60006111b961012e546001600160a01b031690565b90506001600160a01b0381166112115760405162461bcd60e51b815260206004820152601760248201527f456e74726f70792061646472657373206e6f74207365740000000000000000006044820152606401610956565b336001600160a01b038216146112755760405162461bcd60e51b815260206004820152602360248201527f4f6e6c7920456e74726f70792063616e2063616c6c20746869732066756e637460448201526234b7b760e91b6064820152608401610956565b610c8e848484612586565b6000306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146113205760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c00000000000000006064820152608401610956565b5060008051602061479883398151915290565b61133b6124da565b61013555565b6113496124da565b610c1c6000612749565b600061135d61279b565b336000908152610131602052604090205460ff1615156001146113925760405162461bcd60e51b81526004016109569061457c565b60028411156113e35760405162461bcd60e51b815260206004820152601b60248201527f546f6f206d616e79206368616c6c656e6765722063686f6963657300000000006044820152606401610956565b60028211156114345760405162461bcd60e51b815260206004820152601960248201527f546f6f206d616e79206f70706f6e656e742063686f69636573000000000000006044820152606401610956565b60005b848110156114d557600186868381811061145357611453614566565b90506020020135101580156114815750600686868381811061147757611477614566565b9050602002013511155b6114cd5760405162461bcd60e51b815260206004820152601960248201527f496e76616c6964206368616c6c656e6765722063686f696365000000000000006044820152606401610956565b600101611437565b5060005b828110156115775760018484838181106114f5576114f5614566565b90506020020135101580156115235750600684848381811061151957611519614566565b9050602002013511155b61156f5760405162461bcd60e51b815260206004820152601760248201527f496e76616c6964206f70706f6e656e742063686f6963650000000000000000006044820152606401610956565b6001016114d9565b5061012e5461012f54604051631711922960e31b81526001600160a01b039182166004820152600092919091169063b88c914890602401602060405180830381865afa1580156115cb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115ef91906145a4565b9050806001600160801b031634101561163c5760405162461bcd60e51b815260206004820152600f60248201526e6e6f7420656e6f756768206665657360881b6044820152606401610956565b61012e5461012f546040516319cb825f60e01b81526001600160a01b039182166004820152602481018a905260009291909116906319cb825f906001600160801b0385169060440160206040518083038185885af11580156116a2573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906116c791906145cd565b90506116d58c8c8c8c6127f4565b60006116e18d8d610aac565b905060006116ef8c8c610aac565b905061172e828a8a80806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250612bec92505050565b915061176d81888880806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250612bec92505050565b90506040518061014001604052808f6001600160a01b031681526020018e81526020018d6001600160a01b031681526020018c815260200183815260200182815260200160405180602001604052808c8c80806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250505091525081526040805160208a8102808301840184528282018c81529190940193919283928d918d9182918601908490808284376000920182905250939094525050918352506001600160401b03861660208084018290526040938401839052908252610138815290829020835181546001600160a01b039182166001600160a01b03199182161783558584015160018401558585015160028401805491909316911617905560608085015160038301556080808601518051600485015580850151600585015580860151600685015580830151600785015580820151600885015560a080820151600986015560c080830151600a87015560e080840151600b88015561010093840151600c880155828a01518051600d89015580890151600e89015598890151600f880155948801516010870155928701516011860155860151601285015585820151601385015591850151601484015593015160158201559183015180518051919260168501926119699284920190613b49565b50505060e082015180518051601784019161198991839160200190613b49565b5050506101008201518160180160006101000a8154816001600160401b0302191690836001600160401b031602179055506101208201518160180160086101000a81548160ff0219169083151502179055509050508c8e6001600160a01b0316846001600160401b03167f558108c089cd207f059ff0b5865c1c2444a0f45e9a344cf514d680d09d70f5f98f8f604051611a389291906001600160a01b03929092168252602082015260400190565b60405180910390a4509092505050611a506001606555565b9998505050505050505050565b336000908152610131602052604090205460ff161515600114611a925760405162461bcd60e51b81526004016109569061457c565b6001600160a01b038316600090815261012d602052604090205460ff16611acb5760405162461bcd60e51b8152600401610956906144fa565b6001600160a01b03831660009081526101326020908152604080832085845290915281206007015413611b3a5760405162461bcd60e51b8152602060048201526017602482015276119a59da1d195c881b9bdd081a5b9a5d1a585b1a5e9959604a1b6044820152606401610956565b6001600160a01b039092166000908152610132602090815260408083209383529281529082902083516010820155908301516011820155908201516012820155606082015160138201556080820151601482015560a0820151601582015560c0820151601682015560e0820151601782015561010090910151601890910155565b611bc36124da565b61013080546001600160a01b0319166001600160a01b0392909216919091179055565b611bee6124da565b610c1c612e18565b600054610100900460ff1615808015611c165750600054600160ff909116105b80611c305750303b158015611c30575060005460ff166001145b611c935760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610956565b6000805460ff191660011790558015611cb6576000805461ff0019166101001790555b611cbe612e55565b611cc6612e84565b611cce612eb3565b611cd6612ee2565b61013585905561013684905560005b8651811015611d4157600161012d6000898481518110611d0757611d07614566565b6020908102919091018101516001600160a01b03168252810191909152604001600020805460ff1916911515919091179055600101611ce5565b5061012e80546001600160a01b038086166001600160a01b03199283161790925561012f80549285169290911691909117905533600090815261013160205260409020805460ff191660011790558015610f55576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a1505050505050565b6101386020528060005260406000206000915090508060000160009054906101000a90046001600160a01b0316908060010154908060020160009054906101000a90046001600160a01b031690806003015490806004016040518061012001604052908160008201548152602001600182015481526020016002820154815260200160038201548152602001600482015481526020016005820154815260200160068201548152602001600782015481526020016008820154815250509080600d01604051806101200160405290816000820154815260200160018201548152602001600282015481526020016003820154815260200160048201548152602001600582015481526020016006820154815260200160078201548152602001600882015481525050908060160160405180602001604052908160008201805480602002602001604051908101604052809291908181526020018280548015611f6357602002820191906000526020600020905b815481526020019060010190808311611f4f575b505050919092525050604080516017850180546020818102840185018552830181815295969592945090928492918491840182828015611fc257602002820191906000526020600020905b815481526020019060010190808311611fae575b505050919092525050506018909101546001600160401b0381169060ff600160401b909104168a565b611ff36124da565b60005b838110156120815782828281811061201057612010614566565b905060200201602081019061202591906145ea565b610131600087878581811061203c5761203c614566565b90506020020160208101906120519190613c6b565b6001600160a01b031681526020810191909152604001600020805460ff1916911515919091179055600101611ff6565b5050505050565b6120906124da565b6001600160a01b038316600090815261012d602052604090205460ff166120c95760405162461bcd60e51b8152600401610956906144fa565b808211156121125760405162461bcd60e51b8152602060048201526016602482015275496e76616c696420746f6b656e2049442072616e676560501b6044820152606401610956565b61138861211f8383614605565b111561215f5760405162461bcd60e51b815260206004820152600f60248201526e52616e676520746f6f206c6172676560881b6044820152606401610956565b6001600160a01b0383166000908152610133602052604081205490036121c75760405162461bcd60e51b815260206004820181905260248201527f436f6e747261637420626173652061747472696275746573206e6f74207365746044820152606401610956565b6001600160a01b03831660009081526101336020908152604091829020825161012081018452815481526001820154928101929092526002810154928201929092526003820154606082015260048201546080820152600582015460a0820152600682015460c0820152600782015460e0820152600890910154610100820152825b828111612081576001600160a01b038516600090815261013260209081526040808320848452825291829020845160078201559084015160088201559083015160098201556060830151600a8201556080830151600b82015560a0830151600c82015560c0830151600d82015560e0830151600e820155610100830151600f90910155806122d681614618565b915050612249565b6122e66124da565b61013655565b6122f46124da565b6001600160a01b0381166123595760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610956565b6109f381612749565b6109f36124da565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff16156123a25761239d83612f09565b505050565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa9250505080156123fc575060408051601f3d908101601f191682019092526123f991810190614631565b60015b61245f5760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b6064820152608401610956565b60008051602061479883398151915281146124ce5760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b6064820152608401610956565b5061239d838383612fa5565b6033546001600160a01b03163314610c1c5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610956565b61253c612fca565b6097805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b6001600160401b0383166000908152610138602052604090206018810154600160401b900460ff16156125fb5760405162461bcd60e51b815260206004820152601860248201527f426174746c6520616c72656164792070726f63657373656400000000000000006044820152606401610956565b60408051610120810182526004830154815260058301546020820152600683015481830152600783015460608201526008830154608080830191909152600984015460a0830152600a84015460c080840191909152600b85015460e0840152600c85015461010084015285939084901c926001600160401b039285901c8316929185901c821691851690600090612693908685613013565b9050600061270b88600d016040518061012001604052908160008201548152602001600182015481526020016002820154815260200160038201548152602001600482015481526020016005820154815260200160068201548152602001600782015481526020016008820154815250508685613013565b9050612718888383613332565b5050506018909401805468ff00000000000000001916600160401b1790555050610137805460010190555050505050565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6002606554036127ed5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610956565b6002606555565b6001600160a01b038416600090815261012d602052604090205460ff1661285d5760405162461bcd60e51b815260206004820152601f60248201527f4368616c6c656e67657220636f6e7472616374206e6f7420616c6c6f776564006044820152606401610956565b6001600160a01b038216600090815261012d602052604090205460ff166128c65760405162461bcd60e51b815260206004820152601d60248201527f4f70706f6e656e7420636f6e7472616374206e6f7420616c6c6f7765640000006044820152606401610956565b816001600160a01b0316846001600160a01b03161415806128e75750808314155b61292c5760405162461bcd60e51b815260206004820152601660248201527521b0b73737ba103130ba3a3632903cb7bab939b2b63360511b6044820152606401610956565b6001600160a01b03808516600090815261013260208181526040808420888552825280842094871684529181528183208584529052812060078301549091126129b75760405162461bcd60e51b815260206004820152601a60248201527f4368616c6c656e676572206e6f7420696e697469616c697a65640000000000006044820152606401610956565b6007810154600012612a0b5760405162461bcd60e51b815260206004820152601860248201527f4f70706f6e656e74206e6f7420696e697469616c697a656400000000000000006044820152606401610956565b610135548260030154612a1e919061464a565b421015612a665760405162461bcd60e51b815260206004820152601660248201527521b430b63632b733b2b91037b71031b7b7b63237bbb760511b6044820152606401610956565b610135548160030154612a79919061464a565b421015612abf5760405162461bcd60e51b815260206004820152601460248201527327b83837b732b73a1037b71031b7b7b63237bbb760611b6044820152606401610956565b600482015460ff16158015612ad8575060008260030154115b15612b4e57610136548260030154612af0919061464a565b421015612b4e5760405162461bcd60e51b815260206004820152602660248201527f4368616c6c656e67657220696e207265636f76657279206166746572206c617360448201526574206c6f737360d01b6064820152608401610956565b600481015460ff16158015612b67575060008160030154115b15612bda57610136548160030154612b7f919061464a565b421015612bda5760405162461bcd60e51b8152602060048201526024808201527f4f70706f6e656e7420696e207265636f76657279206166746572206c617374206044820152636c6f737360e01b6064820152608401610956565b42600392830181905591015550505050565b612bf4613afd565b60005b8251811015612e0957828181518110612c1257612c12614566565b6020026020010151600103612c5457600f84600001818151612c34919061453e565b90525060208401805160089190612c4c90839061465d565b905250612e01565b828181518110612c6657612c66614566565b6020026020010151600203612c9d57600f84602001818151612c88919061453e565b90525083516008908590612c4c90839061465d565b828181518110612caf57612caf614566565b6020026020010151600303612cd157600f84604001818151612c88919061453e565b828181518110612ce357612ce3614566565b6020026020010151600403612d1d5760148460a001818151612d05919061453e565b905250602084018051600a9190612c4c90839061465d565b828181518110612d2f57612d2f614566565b6020026020010151600503612d9957600584600001818151612d51919061453e565b90525060208401805160059190612d6990839061453e565b90525060408401805160059190612d8190839061453e565b90525060608401805160059190612c4c90839061453e565b828181518110612dab57612dab614566565b6020026020010151600603612e0157600f8460c001818151612dcd919061453e565b90525060a084018051600a9190612de590839061453e565b90525060e08401805160059190612dfd90839061465d565b9052505b600101612bf7565b509192915050565b6001606555565b612e206138bb565b6097805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586125693390565b600054610100900460ff16612e7c5760405162461bcd60e51b815260040161095690614684565b610c1c613901565b600054610100900460ff16612eab5760405162461bcd60e51b815260040161095690614684565b610c1c613931565b600054610100900460ff16612eda5760405162461bcd60e51b815260040161095690614684565b610c1c613958565b600054610100900460ff16610c1c5760405162461bcd60e51b815260040161095690614684565b6001600160a01b0381163b612f765760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608401610956565b60008051602061479883398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b612fae8361398b565b600082511180612fbb5750805b1561239d57610c8e83836139cb565b60975460ff16610c1c5760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401610956565b600080839050600080600080600060968a60000151136130465789516095191361303e578951613049565b609519613049565b60965b9050600060968b6020015113613078576095198b6020015112613070578a6020015161307b565b60951961307b565b60965b9050600060968c60400151136130aa576095198c60400151126130a2578b604001516130ad565b6095196130ad565b60965b9050600060968d60600151136130dc576095198d60600151126130d4578c606001516130df565b6095196130df565b60965b905060968d608001511361310c576095198d6080015112613104578c6080015161310f565b60951961310f565b60965b965060968d60c001511361313c576095198d60c0015112613134578c60c0015161313f565b60951961313f565b60965b9550600060968e60e001511361316e576095198e60e0015112613166578d60e00151613171565b609519613171565b60965b905060968e60a001511361319e576095198e60a0015112613196578d60a001516131a1565b6095196131a1565b60965b9550600285810281860201908481029084020189890183018183018101600081136131cd5760006131cf565b805b9c505050505050505050506000601f866131e991906146e5565b9050600a811115613207576064600919820186020485019450613277565b600080831361321757600061321c565b601e83055b9050600083121561324457601e836000038161323a5761323a6146cf565b058201915061325b565b80821015613255576000915061325b565b80820391505b85821015613270576064868302048603613273565b60015b9550505b60066002830284860101056000808213613292576000613294565b815b9050600160648b06018181116132b457606460328902048801975061330e565b600083136132c35760006132c8565b600783055b605f03811061330e57601960008412156132f257600484600003816132ef576132ef6146cf565b05015b8089111561330757606489820204890361330a565b60015b9850505b50505060008511613320576001613322565b845b96505050505050505b9392505050565b82546001600160a01b0390811660009081526101326020818152604080842060018901548552825280842060028901549095168452918152818320600388015484529052902082841184841480156133de5760028401805490600061339683614618565b90915550506002830180549060006133ad83614618565b90915550506004808501805460ff1990811690915590840180549091169055600060058086018290558401556134b3565b811561344e5783548460006133f283614618565b909155505060018301805490600061340983614618565b90915550506004808501805460ff199081166001179091559084018054909116905560058401805490600061343d83614618565b9091555050600060058401556134b3565b60018401805490600061346083614618565b9091555050825483600061347383614618565b90915550506004808501805460ff19908116909155908401805490911660011790556000600580860182905584018054916134ad83614618565b91905055505b6040518061012001604052808860000160009054906101000a90046001600160a01b03166001600160a01b03168152602001886001015481526020018860020160009054906101000a90046001600160a01b03166001600160a01b03168152602001886003015481526020018315158152602001821515815260200142815260200187815260200186815250610134600061013754815260200190815260200160002060008201518160000160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506020820151816001015560408201518160020160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506060820151816003015560808201518160040160006101000a81548160ff02191690831515021790555060a08201518160040160016101000a81548160ff02191690831515021790555060c0820151816005015560e08201518160060155610100820151816007015590505086600101548760000160009054906101000a90046001600160a01b03166001600160a01b03168860180160009054906101000a90046001600160401b03166001600160401b03167f04e6f5d061be18b80a26d4ddc6f304b48c8363346e553436e9f13863b23137438a60020160009054906101000a90046001600160a01b03168b6003015487878d8d6040516136f1969594939291906001600160a01b039690961686526020860194909452911515604085015215156060840152608083015260a082015260c00190565b60405180910390a4610130546001600160a01b0316156138b25761013054875460018901546040516331a9108f60e11b815260048101919091526001600160a01b03928316926000921690636352211e90602401602060405180830381865afa158015613762573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137869190614707565b60028a015460038b01546040516331a9108f60e11b81529293506000926001600160a01b0390921691636352211e916137c59160040190815260200190565b602060405180830381865afa1580156137e2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138069190614707565b9050836138ae5760008561381a578161381c565b825b9050600086613835578b546001600160a01b0316613844565b60028c01546001600160a01b03165b604051634ba5750960e11b81526001600160a01b03848116600483015280831660248301529192509086169063974aea1290604401600060405180830381600087803b15801561389357600080fd5b505af11580156138a7573d6000803e3d6000fd5b5050505050505b5050505b50505050505050565b60975460ff1615610c1c5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610956565b600054610100900460ff166139285760405162461bcd60e51b815260040161095690614684565b610c1c33612749565b600054610100900460ff16612e115760405162461bcd60e51b815260040161095690614684565b600054610100900460ff1661397f5760405162461bcd60e51b815260040161095690614684565b6097805460ff19169055565b61399481612f09565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606001600160a01b0383163b613a335760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b6064820152608401610956565b600080846001600160a01b031684604051613a4e9190614748565b600060405180830381855af49150503d8060008114613a89576040519150601f19603f3d011682016040523d82523d6000602084013e613a8e565b606091505b5091509150613ab682826040518060600160405280602781526020016147b860279139613abf565b95945050505050565b60608315613ace57508161332b565b61332b8383815115613ae35781518083602001fd5b8060405162461bcd60e51b81526004016109569190614764565b6040518061012001604052806000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b828054828255906000526020600020908101928215613b84579160200282015b82811115613b84578251825591602001919060010190613b69565b50613b90929150613b94565b5090565b5b80821115613b905760008155600101613b95565b600060208284031215613bbb57600080fd5b5035919050565b81516001600160a01b039081168252602080840151908301526040808401519091169082015260608083015190820152608080830151610120830191613c0b9084018215159052565b5060a0830151613c1f60a084018215159052565b5060c083015160c083015260e083015160e083015261010083015161010083015292915050565b6001600160a01b03811681146109f357600080fd5b8035613c6681613c46565b919050565b600060208284031215613c7d57600080fd5b813561332b81613c46565b634e487b7160e01b600052604160045260246000fd5b60405161012081016001600160401b0381118282101715613cc157613cc1613c88565b60405290565b604051601f8201601f191681016001600160401b0381118282101715613cef57613cef613c88565b604052919050565b60006101208284031215613d0a57600080fd5b613d12613c9e565b823581526020808401359082015260408084013590820152606080840135908201526080808401359082015260a0808401359082015260c0808401359082015260e08084013590820152610100928301359281019290925250919050565b6000806101408385031215613d8457600080fd5b8235613d8f81613c46565b9150613d9e8460208501613cf7565b90509250929050565b60008060408385031215613dba57600080fd5b8235613dc581613c46565b946020939093013593505050565b805182526020810151602083015260408101516040830152606081015160608301526080810151608083015260a081015160a083015260c081015160c083015260e081015160e08301526101008101516101008301525050565b6101208101610c068284613dd3565b60008083601f840112613e4e57600080fd5b5081356001600160401b03811115613e6557600080fd5b6020830191508360208260051b8501011115613e8057600080fd5b9250929050565b80358015158114613c6657600080fd5b600080600060408486031215613eac57600080fd5b83356001600160401b03811115613ec257600080fd5b613ece86828701613e3c565b9094509250613ee1905060208501613e87565b90509250925092565b600080600080600060608688031215613f0257600080fd5b8535613f0d81613c46565b945060208601356001600160401b03811115613f2857600080fd5b613f3488828901613e3c565b90955093505060408601356001600160401b03811115613f5357600080fd5b8601601f81018813613f6457600080fd5b80356001600160401b03811115613f7a57600080fd5b88602061012083028401011115613f9057600080fd5b959894975092955050506020019190565b60008060408385031215613fb457600080fd5b8235613fbf81613c46565b915060208301356001600160401b03811115613fda57600080fd5b8301601f81018513613feb57600080fd5b80356001600160401b0381111561400457614004613c88565b614017601f8201601f1916602001613cc7565b81815286602083850101111561402c57600080fd5b816020840160208301376000602083830101528093505050509250929050565b60006103008201905089825288602083015287604083015286606083015285151560808301528460a083015261408560c0830185613dd3565b611a506101e0830184613dd3565b6001600160401b03811681146109f357600080fd5b6000806000606084860312156140bd57600080fd5b83356140c881614093565b925060208401356140d881613c46565b929592945050506040919091013590565b600080600080600080600080600060e08a8c03121561410757600080fd5b893561411281613c46565b985060208a0135975060408a013561412981613c46565b965060608a0135955060808a0135945060a08a01356001600160401b0381111561415257600080fd5b61415e8c828d01613e3c565b90955093505060c08a01356001600160401b0381111561417d57600080fd5b6141898c828d01613e3c565b915080935050809150509295985092959850929598565b600080600061016084860312156141b657600080fd5b83356141c181613c46565b925060208401359150613ee18560408601613cf7565b600080600080600060a086880312156141ef57600080fd5b85356001600160401b0381111561420557600080fd5b8601601f8101881361421657600080fd5b80356001600160401b0381111561422f5761422f613c88565b8060051b61423f60208201613cc7565b9182526020818401810192908101908b84111561425b57600080fd5b6020850194505b83851015614289578435925061427783613c46565b82825260209485019490910190614262565b98505050506020870135945050604086013592506142a960608701613c5b565b91506142b760808701613c5b565b90509295509295909350565b6000602082840312156142d557600080fd5b813561332b81614093565b80516020808452815184820181905260009290910190829060408601905b8083101561432157835182526020820191506020840193506001830192506142fe565b5095945050505050565b6001600160a01b038b81168252602082018b9052891660408201526060810188905261435a6080820188613dd3565b6143686101a0820187613dd3565b6103406102c082015260006143816103408301876142e0565b8281036102e084015261439481876142e0565b6001600160401b039590951661030084015250509015156103209091015298975050505050505050565b600080600080604085870312156143d457600080fd5b84356001600160401b038111156143ea57600080fd5b6143f687828801613e3c565b90955093505060208501356001600160401b0381111561441557600080fd5b61442187828801613e3c565b95989497509550505050565b60008060006060848603121561444257600080fd5b833561444d81613c46565b95602085013595506040909401359392505050565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b60208082526014908201527310dbdb9d1c9858dd081b9bdd08185b1b1bddd95960621b604082015260600190565b634e487b7160e01b600052601160045260246000fd5b808201828112600083128015821682158216171561455e5761455e614528565b505092915050565b634e487b7160e01b600052603260045260246000fd5b6020808252600e908201526d139bdd08185d5d1a1bdc9a5e995960921b604082015260600190565b6000602082840312156145b657600080fd5b81516001600160801b038116811461332b57600080fd5b6000602082840312156145df57600080fd5b815161332b81614093565b6000602082840312156145fc57600080fd5b61332b82613e87565b81810381811115610c0657610c06614528565b60006001820161462a5761462a614528565b5060010190565b60006020828403121561464357600080fd5b5051919050565b80820180821115610c0657610c06614528565b818103600083128015838313168383128216171561467d5761467d614528565b5092915050565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b634e487b7160e01b600052601260045260246000fd5b60008261470257634e487b7160e01b600052601260045260246000fd5b500690565b60006020828403121561471957600080fd5b815161332b81613c46565b60005b8381101561473f578181015183820152602001614727565b50506000910152565b6000825161475a818460208701614724565b9190910192915050565b6020815260008251806020840152614783816040850160208701614724565b601f01601f1916919091016040019291505056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a264697066735822122022c85bbd49530e3eae6aa6ea2339f85d5249395f1a6b9d38719ffa3ae9bb739f64736f6c634300081a0033
Deployed Bytecode
0x6080604052600436106102045760003560e01c806376050eda11610118578063d41c71ae116100a0578063e00b63631161006f578063e00b636314610631578063f19e207e14610648578063f2fde38b14610679578063f458c65114610699578063fa778f4d1461074757600080fd5b8063d41c71ae146105b9578063d44985ca146105d9578063db91aba4146105fa578063dea6b7151461061157600080fd5b80638da5cb5b116100e75780638da5cb5b1461050e578063a844d6f51461052c578063c2c3872a1461054c578063c9b43db214610582578063d1006a6f146105a257600080fd5b806376050eda1461048e5780637b25be4e146104b95780637e92c872146104d95780638456cb59146104f957600080fd5b80634f1ef2861161019b57806352d1902d1161016a57806352d1902d146103e45780635c975abb1461040757806364a291aa1461041f5780636f2ddb5f1461043f578063715018a61461047957600080fd5b80634f1ef2861461033c578063500067cd1461034f57806351e0e26b1461038357806352a5f1f8146103c457600080fd5b80633f4ba83a116101d75780633f4ba83a146102ae5780634211d52e146102c357806347ce07cc146102e35780634996d5891461031c57600080fd5b80632904c529146102095780633659cfe61461023f57806336cbbe2f146102615780633e8d435b14610281575b600080fd5b34801561021557600080fd5b50610229610224366004613ba9565b610814565b6040516102369190613bc2565b60405180910390f35b34801561024b57600080fd5b5061025f61025a366004613c6b565b61090e565b005b34801561026d57600080fd5b5061025f61027c366004613d70565b6109f6565b34801561028d57600080fd5b506102a161029c366004613da7565b610aac565b6040516102369190613e2d565b3480156102ba57600080fd5b5061025f610c0c565b3480156102cf57600080fd5b5061025f6102de366004613e97565b610c1e565b3480156102ef57600080fd5b5061012e54610304906001600160a01b031681565b6040516001600160a01b039091168152602001610236565b34801561032857600080fd5b5061025f610337366004613eea565b610c94565b61025f61034a366004613fa1565b610f5d565b34801561035b57600080fd5b5061036f61036a366004613da7565b61102d565b60405161023698979695949392919061404c565b34801561038f57600080fd5b506103b461039e366004613c6b565b61012d6020526000908152604090205460ff1681565b6040519015158152602001610236565b3480156103d057600080fd5b5061025f6103df3660046140a8565b6111a4565b3480156103f057600080fd5b506103f9611280565b604051908152602001610236565b34801561041357600080fd5b5060975460ff166103b4565b34801561042b57600080fd5b5061025f61043a366004613ba9565b611333565b34801561044b57600080fd5b506103b461045a366004613c6b565b6001600160a01b0316600090815261012d602052604090205460ff1690565b34801561048557600080fd5b5061025f611341565b6104a161049c3660046140e9565b611353565b6040516001600160401b039091168152602001610236565b3480156104c557600080fd5b5061025f6104d43660046141a0565b611a5d565b3480156104e557600080fd5b5061025f6104f4366004613c6b565b611bbb565b34801561050557600080fd5b5061025f611be6565b34801561051a57600080fd5b506033546001600160a01b0316610304565b34801561053857600080fd5b5061025f6105473660046141d7565b611bf6565b34801561055857600080fd5b5061056c6105673660046142c3565b611ddc565b6040516102369a9998979695949392919061432b565b34801561058e57600080fd5b5061025f61059d3660046143be565b611feb565b3480156105ae57600080fd5b506103f96101355481565b3480156105c557600080fd5b5061025f6105d436600461442d565b612088565b3480156105e557600080fd5b5061013054610304906001600160a01b031681565b34801561060657600080fd5b506103f96101365481565b34801561061d57600080fd5b5061025f61062c366004613ba9565b6122de565b34801561063d57600080fd5b506103f96101375481565b34801561065457600080fd5b506103b4610663366004613c6b565b6101316020526000908152604090205460ff1681565b34801561068557600080fd5b5061025f610694366004613c6b565b6122ec565b3480156106a557600080fd5b506107036106b4366004613c6b565b6101336020528060005260406000206000915090508060000154908060010154908060020154908060030154908060040154908060050154908060060154908060070154908060080154905089565b60408051998a5260208a0198909852968801959095526060870193909352608086019190915260a085015260c084015260e083015261010082015261012001610236565b34801561075357600080fd5b506107bd610762366004613ba9565b61013460205260009081526040902080546001820154600283015460038401546004850154600586015460068701546007909701546001600160a01b0396871697959690941694929360ff8084169461010090940416929089565b604080516001600160a01b039a8b1681526020810199909952969098169587019590955260608601939093529015156080850152151560a084015260c083015260e082015261010081019190915261012001610236565b61087960405180610120016040528060006001600160a01b031681526020016000815260200160006001600160a01b03168152602001600081526020016000151581526020016000151581526020016000815260200160008152602001600081525090565b506000908152610134602090815260409182902082516101208101845281546001600160a01b03908116825260018301549382019390935260028201549092169282019290925260038201546060820152600482015460ff808216151560808401526101009182900416151560a0830152600583015460c0830152600683015460e08301526007909201549181019190915290565b6001600160a01b037f000000000000000000000000b390434c72cd7e0ce9eace8023a2a1fcf442b58816300361095f5760405162461bcd60e51b815260040161095690614462565b60405180910390fd5b7f000000000000000000000000b390434c72cd7e0ce9eace8023a2a1fcf442b5886001600160a01b03166109a8600080516020614798833981519152546001600160a01b031690565b6001600160a01b0316146109ce5760405162461bcd60e51b8152600401610956906144ae565b6109d781612362565b604080516000808252602082019092526109f39183919061236a565b50565b6109fe6124da565b6001600160a01b038216600090815261012d602052604090205460ff16610a375760405162461bcd60e51b8152600401610956906144fa565b6001600160a01b039091166000908152610133602090815260409182902083518155908301516001820155908201516002820155606082015160038201556080820151600482015560a0820151600582015560c0820151600682015560e0820151600782015561010090910151600890910155565b610ab4613afd565b6001600160a01b038316600090815261013260209081526040808320858452909152812060108101546007820154919291610aef919061453e565b60118301546008840154919250600091610b09919061453e565b60128401546009850154919250600091610b23919061453e565b6013850154600a860154919250600091610b3d919061453e565b6014860154600b870154919250600091610b57919061453e565b6015870154600c880154919250600091610b71919061453e565b6016880154600d890154919250600091610b8b919061453e565b6017890154600e8a0154919250600091610ba5919061453e565b60188a0154600f8b0154919250600091610bbf919061453e565b60408051610120810182529a8b5260208b0199909952978901969096526060880194909452608087019290925260a086015260c085015260e0840152506101008201529150505b92915050565b610c146124da565b610c1c612534565b565b610c266124da565b60005b82811015610c8e578161012d6000868685818110610c4957610c49614566565b9050602002016020810190610c5e9190613c6b565b6001600160a01b031681526020810191909152604001600020805460ff1916911515919091179055600101610c29565b50505050565b336000908152610131602052604090205460ff161515600114610cc95760405162461bcd60e51b81526004016109569061457c565b6001600160a01b038516600090815261012d602052604090205460ff16610d025760405162461bcd60e51b8152600401610956906144fa565b828114610d515760405162461bcd60e51b815260206004820152601860248201527f4172726179206c656e67746873206d757374206d6174636800000000000000006044820152606401610956565b82610d9e5760405162461bcd60e51b815260206004820152601860248201527f456d70747920617272617973206e6f7420616c6c6f77656400000000000000006044820152606401610956565b6032831115610de65760405162461bcd60e51b815260206004820152601460248201527342617463682073697a6520746f6f206c6172676560601b6044820152606401610956565b60005b83811015610f55576001600160a01b03861660009081526101326020526040812081878785818110610e1d57610e1d614566565b9050602002013581526020019081526020016000206007016000015413610e805760405162461bcd60e51b8152602060048201526017602482015276119a59da1d195c881b9bdd081a5b9a5d1a585b1a5e9959604a1b6044820152606401610956565b828282818110610e9257610e92614566565b905061012002016101326000886001600160a01b03166001600160a01b031681526020019081526020016000206000878785818110610ed357610ed3614566565b9050602002013581526020019081526020016000206010018181610f4b9190813581556020820135600182015560408201356002820155606082013560038201556080820135600482015560a0820135600582015560c0820135600682015560e0820135600782015561010090910135600890910155565b5050600101610de9565b505050505050565b6001600160a01b037f000000000000000000000000b390434c72cd7e0ce9eace8023a2a1fcf442b588163003610fa55760405162461bcd60e51b815260040161095690614462565b7f000000000000000000000000b390434c72cd7e0ce9eace8023a2a1fcf442b5886001600160a01b0316610fee600080516020614798833981519152546001600160a01b031690565b6001600160a01b0316146110145760405162461bcd60e51b8152600401610956906144ae565b61101d82612362565b6110298282600161236a565b5050565b60008060008060008061103e613afd565b611046613afd565b600061013260008c6001600160a01b03166001600160a01b0316815260200190815260200160002060008b8152602001908152602001600020905080600001548160010154826002015483600301548460040160009054906101000a900460ff168560050154866007018760100181604051806101200160405290816000820154815260200160018201548152602001600282015481526020016003820154815260200160048201548152602001600582015481526020016006820154815260200160078201548152602001600882015481525050915080604051806101200160405290816000820154815260200160018201548152602001600282015481526020016003820154815260200160048201548152602001600582015481526020016006820154815260200160078201548152602001600882015481525050905098509850985098509850985098509850509295985092959890939650565b60006111b961012e546001600160a01b031690565b90506001600160a01b0381166112115760405162461bcd60e51b815260206004820152601760248201527f456e74726f70792061646472657373206e6f74207365740000000000000000006044820152606401610956565b336001600160a01b038216146112755760405162461bcd60e51b815260206004820152602360248201527f4f6e6c7920456e74726f70792063616e2063616c6c20746869732066756e637460448201526234b7b760e91b6064820152608401610956565b610c8e848484612586565b6000306001600160a01b037f000000000000000000000000b390434c72cd7e0ce9eace8023a2a1fcf442b58816146113205760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c00000000000000006064820152608401610956565b5060008051602061479883398151915290565b61133b6124da565b61013555565b6113496124da565b610c1c6000612749565b600061135d61279b565b336000908152610131602052604090205460ff1615156001146113925760405162461bcd60e51b81526004016109569061457c565b60028411156113e35760405162461bcd60e51b815260206004820152601b60248201527f546f6f206d616e79206368616c6c656e6765722063686f6963657300000000006044820152606401610956565b60028211156114345760405162461bcd60e51b815260206004820152601960248201527f546f6f206d616e79206f70706f6e656e742063686f69636573000000000000006044820152606401610956565b60005b848110156114d557600186868381811061145357611453614566565b90506020020135101580156114815750600686868381811061147757611477614566565b9050602002013511155b6114cd5760405162461bcd60e51b815260206004820152601960248201527f496e76616c6964206368616c6c656e6765722063686f696365000000000000006044820152606401610956565b600101611437565b5060005b828110156115775760018484838181106114f5576114f5614566565b90506020020135101580156115235750600684848381811061151957611519614566565b9050602002013511155b61156f5760405162461bcd60e51b815260206004820152601760248201527f496e76616c6964206f70706f6e656e742063686f6963650000000000000000006044820152606401610956565b6001016114d9565b5061012e5461012f54604051631711922960e31b81526001600160a01b039182166004820152600092919091169063b88c914890602401602060405180830381865afa1580156115cb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115ef91906145a4565b9050806001600160801b031634101561163c5760405162461bcd60e51b815260206004820152600f60248201526e6e6f7420656e6f756768206665657360881b6044820152606401610956565b61012e5461012f546040516319cb825f60e01b81526001600160a01b039182166004820152602481018a905260009291909116906319cb825f906001600160801b0385169060440160206040518083038185885af11580156116a2573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906116c791906145cd565b90506116d58c8c8c8c6127f4565b60006116e18d8d610aac565b905060006116ef8c8c610aac565b905061172e828a8a80806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250612bec92505050565b915061176d81888880806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250612bec92505050565b90506040518061014001604052808f6001600160a01b031681526020018e81526020018d6001600160a01b031681526020018c815260200183815260200182815260200160405180602001604052808c8c80806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250505091525081526040805160208a8102808301840184528282018c81529190940193919283928d918d9182918601908490808284376000920182905250939094525050918352506001600160401b03861660208084018290526040938401839052908252610138815290829020835181546001600160a01b039182166001600160a01b03199182161783558584015160018401558585015160028401805491909316911617905560608085015160038301556080808601518051600485015580850151600585015580860151600685015580830151600785015580820151600885015560a080820151600986015560c080830151600a87015560e080840151600b88015561010093840151600c880155828a01518051600d89015580890151600e89015598890151600f880155948801516010870155928701516011860155860151601285015585820151601385015591850151601484015593015160158201559183015180518051919260168501926119699284920190613b49565b50505060e082015180518051601784019161198991839160200190613b49565b5050506101008201518160180160006101000a8154816001600160401b0302191690836001600160401b031602179055506101208201518160180160086101000a81548160ff0219169083151502179055509050508c8e6001600160a01b0316846001600160401b03167f558108c089cd207f059ff0b5865c1c2444a0f45e9a344cf514d680d09d70f5f98f8f604051611a389291906001600160a01b03929092168252602082015260400190565b60405180910390a4509092505050611a506001606555565b9998505050505050505050565b336000908152610131602052604090205460ff161515600114611a925760405162461bcd60e51b81526004016109569061457c565b6001600160a01b038316600090815261012d602052604090205460ff16611acb5760405162461bcd60e51b8152600401610956906144fa565b6001600160a01b03831660009081526101326020908152604080832085845290915281206007015413611b3a5760405162461bcd60e51b8152602060048201526017602482015276119a59da1d195c881b9bdd081a5b9a5d1a585b1a5e9959604a1b6044820152606401610956565b6001600160a01b039092166000908152610132602090815260408083209383529281529082902083516010820155908301516011820155908201516012820155606082015160138201556080820151601482015560a0820151601582015560c0820151601682015560e0820151601782015561010090910151601890910155565b611bc36124da565b61013080546001600160a01b0319166001600160a01b0392909216919091179055565b611bee6124da565b610c1c612e18565b600054610100900460ff1615808015611c165750600054600160ff909116105b80611c305750303b158015611c30575060005460ff166001145b611c935760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610956565b6000805460ff191660011790558015611cb6576000805461ff0019166101001790555b611cbe612e55565b611cc6612e84565b611cce612eb3565b611cd6612ee2565b61013585905561013684905560005b8651811015611d4157600161012d6000898481518110611d0757611d07614566565b6020908102919091018101516001600160a01b03168252810191909152604001600020805460ff1916911515919091179055600101611ce5565b5061012e80546001600160a01b038086166001600160a01b03199283161790925561012f80549285169290911691909117905533600090815261013160205260409020805460ff191660011790558015610f55576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a1505050505050565b6101386020528060005260406000206000915090508060000160009054906101000a90046001600160a01b0316908060010154908060020160009054906101000a90046001600160a01b031690806003015490806004016040518061012001604052908160008201548152602001600182015481526020016002820154815260200160038201548152602001600482015481526020016005820154815260200160068201548152602001600782015481526020016008820154815250509080600d01604051806101200160405290816000820154815260200160018201548152602001600282015481526020016003820154815260200160048201548152602001600582015481526020016006820154815260200160078201548152602001600882015481525050908060160160405180602001604052908160008201805480602002602001604051908101604052809291908181526020018280548015611f6357602002820191906000526020600020905b815481526020019060010190808311611f4f575b505050919092525050604080516017850180546020818102840185018552830181815295969592945090928492918491840182828015611fc257602002820191906000526020600020905b815481526020019060010190808311611fae575b505050919092525050506018909101546001600160401b0381169060ff600160401b909104168a565b611ff36124da565b60005b838110156120815782828281811061201057612010614566565b905060200201602081019061202591906145ea565b610131600087878581811061203c5761203c614566565b90506020020160208101906120519190613c6b565b6001600160a01b031681526020810191909152604001600020805460ff1916911515919091179055600101611ff6565b5050505050565b6120906124da565b6001600160a01b038316600090815261012d602052604090205460ff166120c95760405162461bcd60e51b8152600401610956906144fa565b808211156121125760405162461bcd60e51b8152602060048201526016602482015275496e76616c696420746f6b656e2049442072616e676560501b6044820152606401610956565b61138861211f8383614605565b111561215f5760405162461bcd60e51b815260206004820152600f60248201526e52616e676520746f6f206c6172676560881b6044820152606401610956565b6001600160a01b0383166000908152610133602052604081205490036121c75760405162461bcd60e51b815260206004820181905260248201527f436f6e747261637420626173652061747472696275746573206e6f74207365746044820152606401610956565b6001600160a01b03831660009081526101336020908152604091829020825161012081018452815481526001820154928101929092526002810154928201929092526003820154606082015260048201546080820152600582015460a0820152600682015460c0820152600782015460e0820152600890910154610100820152825b828111612081576001600160a01b038516600090815261013260209081526040808320848452825291829020845160078201559084015160088201559083015160098201556060830151600a8201556080830151600b82015560a0830151600c82015560c0830151600d82015560e0830151600e820155610100830151600f90910155806122d681614618565b915050612249565b6122e66124da565b61013655565b6122f46124da565b6001600160a01b0381166123595760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610956565b6109f381612749565b6109f36124da565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff16156123a25761239d83612f09565b505050565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa9250505080156123fc575060408051601f3d908101601f191682019092526123f991810190614631565b60015b61245f5760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b6064820152608401610956565b60008051602061479883398151915281146124ce5760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b6064820152608401610956565b5061239d838383612fa5565b6033546001600160a01b03163314610c1c5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610956565b61253c612fca565b6097805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b6001600160401b0383166000908152610138602052604090206018810154600160401b900460ff16156125fb5760405162461bcd60e51b815260206004820152601860248201527f426174746c6520616c72656164792070726f63657373656400000000000000006044820152606401610956565b60408051610120810182526004830154815260058301546020820152600683015481830152600783015460608201526008830154608080830191909152600984015460a0830152600a84015460c080840191909152600b85015460e0840152600c85015461010084015285939084901c926001600160401b039285901c8316929185901c821691851690600090612693908685613013565b9050600061270b88600d016040518061012001604052908160008201548152602001600182015481526020016002820154815260200160038201548152602001600482015481526020016005820154815260200160068201548152602001600782015481526020016008820154815250508685613013565b9050612718888383613332565b5050506018909401805468ff00000000000000001916600160401b1790555050610137805460010190555050505050565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6002606554036127ed5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610956565b6002606555565b6001600160a01b038416600090815261012d602052604090205460ff1661285d5760405162461bcd60e51b815260206004820152601f60248201527f4368616c6c656e67657220636f6e7472616374206e6f7420616c6c6f776564006044820152606401610956565b6001600160a01b038216600090815261012d602052604090205460ff166128c65760405162461bcd60e51b815260206004820152601d60248201527f4f70706f6e656e7420636f6e7472616374206e6f7420616c6c6f7765640000006044820152606401610956565b816001600160a01b0316846001600160a01b03161415806128e75750808314155b61292c5760405162461bcd60e51b815260206004820152601660248201527521b0b73737ba103130ba3a3632903cb7bab939b2b63360511b6044820152606401610956565b6001600160a01b03808516600090815261013260208181526040808420888552825280842094871684529181528183208584529052812060078301549091126129b75760405162461bcd60e51b815260206004820152601a60248201527f4368616c6c656e676572206e6f7420696e697469616c697a65640000000000006044820152606401610956565b6007810154600012612a0b5760405162461bcd60e51b815260206004820152601860248201527f4f70706f6e656e74206e6f7420696e697469616c697a656400000000000000006044820152606401610956565b610135548260030154612a1e919061464a565b421015612a665760405162461bcd60e51b815260206004820152601660248201527521b430b63632b733b2b91037b71031b7b7b63237bbb760511b6044820152606401610956565b610135548160030154612a79919061464a565b421015612abf5760405162461bcd60e51b815260206004820152601460248201527327b83837b732b73a1037b71031b7b7b63237bbb760611b6044820152606401610956565b600482015460ff16158015612ad8575060008260030154115b15612b4e57610136548260030154612af0919061464a565b421015612b4e5760405162461bcd60e51b815260206004820152602660248201527f4368616c6c656e67657220696e207265636f76657279206166746572206c617360448201526574206c6f737360d01b6064820152608401610956565b600481015460ff16158015612b67575060008160030154115b15612bda57610136548160030154612b7f919061464a565b421015612bda5760405162461bcd60e51b8152602060048201526024808201527f4f70706f6e656e7420696e207265636f76657279206166746572206c617374206044820152636c6f737360e01b6064820152608401610956565b42600392830181905591015550505050565b612bf4613afd565b60005b8251811015612e0957828181518110612c1257612c12614566565b6020026020010151600103612c5457600f84600001818151612c34919061453e565b90525060208401805160089190612c4c90839061465d565b905250612e01565b828181518110612c6657612c66614566565b6020026020010151600203612c9d57600f84602001818151612c88919061453e565b90525083516008908590612c4c90839061465d565b828181518110612caf57612caf614566565b6020026020010151600303612cd157600f84604001818151612c88919061453e565b828181518110612ce357612ce3614566565b6020026020010151600403612d1d5760148460a001818151612d05919061453e565b905250602084018051600a9190612c4c90839061465d565b828181518110612d2f57612d2f614566565b6020026020010151600503612d9957600584600001818151612d51919061453e565b90525060208401805160059190612d6990839061453e565b90525060408401805160059190612d8190839061453e565b90525060608401805160059190612c4c90839061453e565b828181518110612dab57612dab614566565b6020026020010151600603612e0157600f8460c001818151612dcd919061453e565b90525060a084018051600a9190612de590839061453e565b90525060e08401805160059190612dfd90839061465d565b9052505b600101612bf7565b509192915050565b6001606555565b612e206138bb565b6097805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586125693390565b600054610100900460ff16612e7c5760405162461bcd60e51b815260040161095690614684565b610c1c613901565b600054610100900460ff16612eab5760405162461bcd60e51b815260040161095690614684565b610c1c613931565b600054610100900460ff16612eda5760405162461bcd60e51b815260040161095690614684565b610c1c613958565b600054610100900460ff16610c1c5760405162461bcd60e51b815260040161095690614684565b6001600160a01b0381163b612f765760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608401610956565b60008051602061479883398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b612fae8361398b565b600082511180612fbb5750805b1561239d57610c8e83836139cb565b60975460ff16610c1c5760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401610956565b600080839050600080600080600060968a60000151136130465789516095191361303e578951613049565b609519613049565b60965b9050600060968b6020015113613078576095198b6020015112613070578a6020015161307b565b60951961307b565b60965b9050600060968c60400151136130aa576095198c60400151126130a2578b604001516130ad565b6095196130ad565b60965b9050600060968d60600151136130dc576095198d60600151126130d4578c606001516130df565b6095196130df565b60965b905060968d608001511361310c576095198d6080015112613104578c6080015161310f565b60951961310f565b60965b965060968d60c001511361313c576095198d60c0015112613134578c60c0015161313f565b60951961313f565b60965b9550600060968e60e001511361316e576095198e60e0015112613166578d60e00151613171565b609519613171565b60965b905060968e60a001511361319e576095198e60a0015112613196578d60a001516131a1565b6095196131a1565b60965b9550600285810281860201908481029084020189890183018183018101600081136131cd5760006131cf565b805b9c505050505050505050506000601f866131e991906146e5565b9050600a811115613207576064600919820186020485019450613277565b600080831361321757600061321c565b601e83055b9050600083121561324457601e836000038161323a5761323a6146cf565b058201915061325b565b80821015613255576000915061325b565b80820391505b85821015613270576064868302048603613273565b60015b9550505b60066002830284860101056000808213613292576000613294565b815b9050600160648b06018181116132b457606460328902048801975061330e565b600083136132c35760006132c8565b600783055b605f03811061330e57601960008412156132f257600484600003816132ef576132ef6146cf565b05015b8089111561330757606489820204890361330a565b60015b9850505b50505060008511613320576001613322565b845b96505050505050505b9392505050565b82546001600160a01b0390811660009081526101326020818152604080842060018901548552825280842060028901549095168452918152818320600388015484529052902082841184841480156133de5760028401805490600061339683614618565b90915550506002830180549060006133ad83614618565b90915550506004808501805460ff1990811690915590840180549091169055600060058086018290558401556134b3565b811561344e5783548460006133f283614618565b909155505060018301805490600061340983614618565b90915550506004808501805460ff199081166001179091559084018054909116905560058401805490600061343d83614618565b9091555050600060058401556134b3565b60018401805490600061346083614618565b9091555050825483600061347383614618565b90915550506004808501805460ff19908116909155908401805490911660011790556000600580860182905584018054916134ad83614618565b91905055505b6040518061012001604052808860000160009054906101000a90046001600160a01b03166001600160a01b03168152602001886001015481526020018860020160009054906101000a90046001600160a01b03166001600160a01b03168152602001886003015481526020018315158152602001821515815260200142815260200187815260200186815250610134600061013754815260200190815260200160002060008201518160000160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506020820151816001015560408201518160020160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506060820151816003015560808201518160040160006101000a81548160ff02191690831515021790555060a08201518160040160016101000a81548160ff02191690831515021790555060c0820151816005015560e08201518160060155610100820151816007015590505086600101548760000160009054906101000a90046001600160a01b03166001600160a01b03168860180160009054906101000a90046001600160401b03166001600160401b03167f04e6f5d061be18b80a26d4ddc6f304b48c8363346e553436e9f13863b23137438a60020160009054906101000a90046001600160a01b03168b6003015487878d8d6040516136f1969594939291906001600160a01b039690961686526020860194909452911515604085015215156060840152608083015260a082015260c00190565b60405180910390a4610130546001600160a01b0316156138b25761013054875460018901546040516331a9108f60e11b815260048101919091526001600160a01b03928316926000921690636352211e90602401602060405180830381865afa158015613762573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137869190614707565b60028a015460038b01546040516331a9108f60e11b81529293506000926001600160a01b0390921691636352211e916137c59160040190815260200190565b602060405180830381865afa1580156137e2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138069190614707565b9050836138ae5760008561381a578161381c565b825b9050600086613835578b546001600160a01b0316613844565b60028c01546001600160a01b03165b604051634ba5750960e11b81526001600160a01b03848116600483015280831660248301529192509086169063974aea1290604401600060405180830381600087803b15801561389357600080fd5b505af11580156138a7573d6000803e3d6000fd5b5050505050505b5050505b50505050505050565b60975460ff1615610c1c5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610956565b600054610100900460ff166139285760405162461bcd60e51b815260040161095690614684565b610c1c33612749565b600054610100900460ff16612e115760405162461bcd60e51b815260040161095690614684565b600054610100900460ff1661397f5760405162461bcd60e51b815260040161095690614684565b6097805460ff19169055565b61399481612f09565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606001600160a01b0383163b613a335760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b6064820152608401610956565b600080846001600160a01b031684604051613a4e9190614748565b600060405180830381855af49150503d8060008114613a89576040519150601f19603f3d011682016040523d82523d6000602084013e613a8e565b606091505b5091509150613ab682826040518060600160405280602781526020016147b860279139613abf565b95945050505050565b60608315613ace57508161332b565b61332b8383815115613ae35781518083602001fd5b8060405162461bcd60e51b81526004016109569190614764565b6040518061012001604052806000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b828054828255906000526020600020908101928215613b84579160200282015b82811115613b84578251825591602001919060010190613b69565b50613b90929150613b94565b5090565b5b80821115613b905760008155600101613b95565b600060208284031215613bbb57600080fd5b5035919050565b81516001600160a01b039081168252602080840151908301526040808401519091169082015260608083015190820152608080830151610120830191613c0b9084018215159052565b5060a0830151613c1f60a084018215159052565b5060c083015160c083015260e083015160e083015261010083015161010083015292915050565b6001600160a01b03811681146109f357600080fd5b8035613c6681613c46565b919050565b600060208284031215613c7d57600080fd5b813561332b81613c46565b634e487b7160e01b600052604160045260246000fd5b60405161012081016001600160401b0381118282101715613cc157613cc1613c88565b60405290565b604051601f8201601f191681016001600160401b0381118282101715613cef57613cef613c88565b604052919050565b60006101208284031215613d0a57600080fd5b613d12613c9e565b823581526020808401359082015260408084013590820152606080840135908201526080808401359082015260a0808401359082015260c0808401359082015260e08084013590820152610100928301359281019290925250919050565b6000806101408385031215613d8457600080fd5b8235613d8f81613c46565b9150613d9e8460208501613cf7565b90509250929050565b60008060408385031215613dba57600080fd5b8235613dc581613c46565b946020939093013593505050565b805182526020810151602083015260408101516040830152606081015160608301526080810151608083015260a081015160a083015260c081015160c083015260e081015160e08301526101008101516101008301525050565b6101208101610c068284613dd3565b60008083601f840112613e4e57600080fd5b5081356001600160401b03811115613e6557600080fd5b6020830191508360208260051b8501011115613e8057600080fd5b9250929050565b80358015158114613c6657600080fd5b600080600060408486031215613eac57600080fd5b83356001600160401b03811115613ec257600080fd5b613ece86828701613e3c565b9094509250613ee1905060208501613e87565b90509250925092565b600080600080600060608688031215613f0257600080fd5b8535613f0d81613c46565b945060208601356001600160401b03811115613f2857600080fd5b613f3488828901613e3c565b90955093505060408601356001600160401b03811115613f5357600080fd5b8601601f81018813613f6457600080fd5b80356001600160401b03811115613f7a57600080fd5b88602061012083028401011115613f9057600080fd5b959894975092955050506020019190565b60008060408385031215613fb457600080fd5b8235613fbf81613c46565b915060208301356001600160401b03811115613fda57600080fd5b8301601f81018513613feb57600080fd5b80356001600160401b0381111561400457614004613c88565b614017601f8201601f1916602001613cc7565b81815286602083850101111561402c57600080fd5b816020840160208301376000602083830101528093505050509250929050565b60006103008201905089825288602083015287604083015286606083015285151560808301528460a083015261408560c0830185613dd3565b611a506101e0830184613dd3565b6001600160401b03811681146109f357600080fd5b6000806000606084860312156140bd57600080fd5b83356140c881614093565b925060208401356140d881613c46565b929592945050506040919091013590565b600080600080600080600080600060e08a8c03121561410757600080fd5b893561411281613c46565b985060208a0135975060408a013561412981613c46565b965060608a0135955060808a0135945060a08a01356001600160401b0381111561415257600080fd5b61415e8c828d01613e3c565b90955093505060c08a01356001600160401b0381111561417d57600080fd5b6141898c828d01613e3c565b915080935050809150509295985092959850929598565b600080600061016084860312156141b657600080fd5b83356141c181613c46565b925060208401359150613ee18560408601613cf7565b600080600080600060a086880312156141ef57600080fd5b85356001600160401b0381111561420557600080fd5b8601601f8101881361421657600080fd5b80356001600160401b0381111561422f5761422f613c88565b8060051b61423f60208201613cc7565b9182526020818401810192908101908b84111561425b57600080fd5b6020850194505b83851015614289578435925061427783613c46565b82825260209485019490910190614262565b98505050506020870135945050604086013592506142a960608701613c5b565b91506142b760808701613c5b565b90509295509295909350565b6000602082840312156142d557600080fd5b813561332b81614093565b80516020808452815184820181905260009290910190829060408601905b8083101561432157835182526020820191506020840193506001830192506142fe565b5095945050505050565b6001600160a01b038b81168252602082018b9052891660408201526060810188905261435a6080820188613dd3565b6143686101a0820187613dd3565b6103406102c082015260006143816103408301876142e0565b8281036102e084015261439481876142e0565b6001600160401b039590951661030084015250509015156103209091015298975050505050505050565b600080600080604085870312156143d457600080fd5b84356001600160401b038111156143ea57600080fd5b6143f687828801613e3c565b90955093505060208501356001600160401b0381111561441557600080fd5b61442187828801613e3c565b95989497509550505050565b60008060006060848603121561444257600080fd5b833561444d81613c46565b95602085013595506040909401359392505050565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b60208082526014908201527310dbdb9d1c9858dd081b9bdd08185b1b1bddd95960621b604082015260600190565b634e487b7160e01b600052601160045260246000fd5b808201828112600083128015821682158216171561455e5761455e614528565b505092915050565b634e487b7160e01b600052603260045260246000fd5b6020808252600e908201526d139bdd08185d5d1a1bdc9a5e995960921b604082015260600190565b6000602082840312156145b657600080fd5b81516001600160801b038116811461332b57600080fd5b6000602082840312156145df57600080fd5b815161332b81614093565b6000602082840312156145fc57600080fd5b61332b82613e87565b81810381811115610c0657610c06614528565b60006001820161462a5761462a614528565b5060010190565b60006020828403121561464357600080fd5b5051919050565b80820180821115610c0657610c06614528565b818103600083128015838313168383128216171561467d5761467d614528565b5092915050565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b634e487b7160e01b600052601260045260246000fd5b60008261470257634e487b7160e01b600052601260045260246000fd5b500690565b60006020828403121561471957600080fd5b815161332b81613c46565b60005b8381101561473f578181015183820152602001614727565b50506000910152565b6000825161475a818460208701614724565b9190910192915050565b6020815260008251806020840152614783816040850160208701614724565b601f01601f1916919091016040019291505056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a264697066735822122022c85bbd49530e3eae6aa6ea2339f85d5249395f1a6b9d38719ffa3ae9bb739f64736f6c634300081a0033
Loading...
Loading
Loading...
Loading
Loading...
Loading
Loading...
Loading
Loading...
Loading
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.