Source Code
Overview
GLMR Balance
GLMR Value
$0.00Latest 25 from a total of 64 transactions
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Set Custom Name | 5786366 | 678 days ago | IN | 0 GLMR | 0.0526559 | ||||
| Set Custom Name | 5697362 | 690 days ago | IN | 0 GLMR | 0.03593679 | ||||
| Set Custom Name | 5681582 | 692 days ago | IN | 0 GLMR | 0.04284267 | ||||
| Set Custom Name | 5681579 | 692 days ago | IN | 0 GLMR | 0.04290187 | ||||
| Set Custom Name | 5681578 | 692 days ago | IN | 0 GLMR | 0.04291683 | ||||
| Set Custom Name | 5681576 | 692 days ago | IN | 0 GLMR | 0.043224 | ||||
| Set Custom Name | 5681575 | 692 days ago | IN | 0 GLMR | 0.04293064 | ||||
| Set Custom Name | 5673887 | 693 days ago | IN | 0 GLMR | 0.04480546 | ||||
| Set Custom Name | 5673871 | 693 days ago | IN | 0 GLMR | 0.04451541 | ||||
| Set Custom Name | 5673851 | 693 days ago | IN | 0 GLMR | 0.04415582 | ||||
| Set Custom Name | 5673803 | 694 days ago | IN | 0 GLMR | 0.04500007 | ||||
| Set Custom Name | 5666227 | 695 days ago | IN | 0 GLMR | 0.05691321 | ||||
| Set Custom Name | 5666226 | 695 days ago | IN | 0 GLMR | 0.05695084 | ||||
| Set Custom Name | 5666225 | 695 days ago | IN | 0 GLMR | 0.05701432 | ||||
| Set Custom Name | 5666225 | 695 days ago | IN | 0 GLMR | 0.05701432 | ||||
| Set Custom Name | 5610644 | 702 days ago | IN | 0 GLMR | 0.03613288 | ||||
| Set Custom Name | 5610027 | 703 days ago | IN | 0 GLMR | 0.04611105 | ||||
| Set Custom Name | 5610008 | 703 days ago | IN | 0 GLMR | 0.03913871 | ||||
| Set Custom Name | 5408640 | 731 days ago | IN | 0 GLMR | 0.03061921 | ||||
| Set Custom Name | 5384564 | 734 days ago | IN | 0 GLMR | 0.03087912 | ||||
| Set Custom Name | 5384559 | 734 days ago | IN | 0 GLMR | 0.03090325 | ||||
| Set Custom Name | 5384555 | 734 days ago | IN | 0 GLMR | 0.03092653 | ||||
| Set Custom Name | 5384551 | 734 days ago | IN | 0 GLMR | 0.03097368 | ||||
| Set Custom Name | 5384550 | 734 days ago | IN | 0 GLMR | 0.03097084 | ||||
| Set Custom Name | 5384546 | 734 days ago | IN | 0 GLMR | 0.03096419 |
View more zero value Internal Transactions in Advanced View mode
Cross-Chain Transactions
Loading...
Loading
Contract Name:
AttributesManager
Compiler Version
v0.8.21+commit.d9974bed
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.21;
import "@rmrk-team/evm-contracts/contracts/RMRK/extension/tokenAttributes/IERC7508.sol";
import "@rmrk-team/evm-contracts/contracts/RMRK/access/Ownable.sol";
import "@rmrk-team/evm-contracts/contracts/RMRK/nestable/IERC7401.sol";
import "@rmrk-team/evm-contracts/contracts/RMRK/equippable/IERC6220.sol";
import "./INameChangeTicket.sol";
error BattleNotFinished();
error CannotChallengeYourself();
error CannotChangeName();
error CannotHaveMultipleActiveChallenges();
error InvalidChallenge();
error NameChangeTicketNeeded();
error NotEnoughFreePoints();
error NotEnoughStamina();
error NotOwnedSnake();
error ResultAlreadyStored();
contract AttributesManager is Ownable {
modifier onlySoldierOwner(uint256 soldierId) {
_checkSoldierOwner(soldierId);
_;
}
enum Element {
Fire,
Earth,
Water,
Air,
None // Needed for enemy element in of case calculating boosts without enemy
}
enum Faction {
Desert,
Mountain,
Islands,
Valley,
Forest,
None
}
enum Skill {
Combat,
Tank,
Heal,
Sniper,
None
}
enum Landscape {
None,
IslandsDay,
IslandsNight,
IslandsEclipse,
DesertDay,
DesertNight,
DesertEclipse,
ValleyDay,
ValleyNight,
ValleyEclipse,
MountainDay,
MountainNight,
MountainEclipse,
ForestDay,
ForestNight,
ForestEclipse
}
struct BattleStats {
uint256 id; // Not stored, just used to identify the soldier
uint24 attack; // Over 16M
uint24 defense; // Over 16M
uint24 health; // Over 16M
uint24 stamina; // Over 16M
uint24 maxHealth; // Over 16M
uint24 maxStamina; // Over 16M
uint16 level; // Over 65k levels
uint16 freePoints; // Over 65k
uint32 experience; // Over 65k levels (XP accumulates)
uint32 lastStatsUpdate; // Up to year 2106
}
struct BattleBoostsPercentage {
int16 elementElement;
uint8 elementSkill;
uint8 elementTerritory;
uint8 factionTerritory;
uint8 forest;
uint8 landscape;
}
struct EquippedItems {
Element element;
Faction faction;
Skill skill;
Landscape landscape;
}
string private constant _STATS_KEY = "STATS";
string private constant _NAME_KEY = "NAME";
uint256 private constant _COMMANDERS_OFFSET = 20;
uint256 private constant _SOLDIERS_OFFSET = 200;
uint256 private _staminaRecoveredPerHour = 2;
uint8 private _landscapeTerritoryBoost = 5;
uint8 private _landscapeDaynightBoost = 5;
uint8 private _elementSkillBoost = 10;
uint8 private _elementTerritoryBoost = 10;
uint8 private _factionTerritoryBoost = 10;
uint8 private _forestBoost = 10;
address private _snakeSoldiers;
address private _elementGems;
address private _skillGems;
address private _factionGems;
address private _landscapes;
INameChangeTicket private _nameChangeTicket;
IERC7508 private _attributesRepository;
constructor(
address snakeSoldiers,
address elementGems,
address skillGems,
address factionGems,
address landscapes,
address attributesRepository
) {
_snakeSoldiers = snakeSoldiers;
_elementGems = elementGems;
_skillGems = skillGems;
_factionGems = factionGems;
_landscapes = landscapes;
_attributesRepository = IERC7508(attributesRepository);
}
// CONFIG GETTERS
function getBoostsConfig()
public
view
returns (
uint8 landscapeTerritoryBoost,
uint8 landscapeDaynightBoost,
uint8 elementSkillBoost,
uint8 elementTerritoryBoost,
uint8 factionTerritoryBoost,
uint8 forestBoost
)
{
landscapeTerritoryBoost = _landscapeTerritoryBoost;
landscapeDaynightBoost = _landscapeDaynightBoost;
elementSkillBoost = _elementSkillBoost;
elementTerritoryBoost = _elementTerritoryBoost;
factionTerritoryBoost = _factionTerritoryBoost;
forestBoost = _forestBoost;
}
// CONFIG SETTERS
function setBoostsConfig(
uint8 landscapeTerritoryBoost,
uint8 landscapeDaynightBoost,
uint8 elementSkillBoost,
uint8 elementTerritoryBoost,
uint8 factionTerritoryBoost,
uint8 forestBoost
) public onlyOwner {
_landscapeTerritoryBoost = landscapeTerritoryBoost;
_landscapeDaynightBoost = landscapeDaynightBoost;
_elementSkillBoost = elementSkillBoost;
_elementTerritoryBoost = elementTerritoryBoost;
_factionTerritoryBoost = factionTerritoryBoost;
_forestBoost = forestBoost;
}
function setNameChangeTicketAddress(
address nameChangeTicket
) public onlyOwner {
_nameChangeTicket = INameChangeTicket(nameChangeTicket);
}
// STATS
function getStats(
uint256 soldierId
) public view returns (BattleStats memory stats) {
uint256 mergedStats = _attributesRepository.getUintAttribute(
_snakeSoldiers,
soldierId,
_STATS_KEY
);
stats.id = soldierId;
stats.attack = uint24(mergedStats);
stats.defense = uint24(mergedStats >> 24);
stats.health = uint24(mergedStats >> 48);
stats.stamina = uint24(mergedStats >> 72);
stats.maxHealth = uint24(mergedStats >> 96);
stats.maxStamina = uint24(mergedStats >> 120);
stats.level = uint16(mergedStats >> 144);
stats.freePoints = uint16(mergedStats >> 160);
stats.experience = uint32(mergedStats >> 176);
stats.lastStatsUpdate = uint32(mergedStats >> 208);
stats.stamina = getCurrentStamina(stats);
}
function getCurrentStamina(
BattleStats memory stats
) public view returns (uint24) {
if (stats.lastStatsUpdate == 0) {
return stats.maxStamina;
}
uint24 staminaRecovered = uint24(
((block.timestamp - stats.lastStatsUpdate) / 3600) *
_staminaRecoveredPerHour
);
if (staminaRecovered + stats.stamina > stats.maxStamina) {
return stats.maxStamina;
} else {
return staminaRecovered + stats.stamina;
}
}
function getBoostedStatsForSnake(
uint256 soldierId,
Element enemyElement
) external view returns (BattleStats memory boostedStats) {
BattleStats memory snakeStats = getStats(soldierId);
EquippedItems memory snakeItems = getEquippedItems(soldierId);
(
Faction currentTerritory,
bool currentDayNight
) = getCurrentLandAndDayNight();
BattleBoostsPercentage
memory snakeBoosts = getBoostsFromGemsTerritoryAndCelestialPhase(
snakeItems,
currentTerritory,
currentDayNight,
enemyElement
);
boostedStats = applyBoosts(snakeStats, snakeBoosts);
}
function getAdjustedStatsForBothSnakes(
BattleStats memory challengerStats,
BattleStats memory challengedStats,
Faction challengeTerritory,
bool challengeDayNight
)
public
view
returns (
BattleStats memory challengerAdjustedStats,
BattleStats memory challengedAdjustedStats
)
{
EquippedItems memory challengerItems = getEquippedItems(
challengerStats.id
);
EquippedItems memory challengedItems = getEquippedItems(
challengedStats.id
);
BattleBoostsPercentage
memory challengerBoosts = getBoostsFromGemsTerritoryAndCelestialPhase(
challengerItems,
challengeTerritory,
challengeDayNight,
challengedItems.element
);
BattleBoostsPercentage
memory challengedBoosts = getBoostsFromGemsTerritoryAndCelestialPhase(
challengedItems,
challengeTerritory,
challengeDayNight,
challengerItems.element
);
challengerAdjustedStats = applyBoosts(
challengerStats,
challengerBoosts
);
challengedAdjustedStats = applyBoosts(
challengedStats,
challengedBoosts
);
}
function getCurrentLandAndDayNight()
public
view
returns (Faction currentLand, bool currentDayNight)
{
// Every 12 hours, the land changes
// Every 6 hours, the day/night changes
currentDayNight = (block.timestamp / 21600) % 2 == 0;
currentLand = Faction((block.timestamp / 43200) % 5);
}
// NAME
function getCustomName(
uint256 soldierId
) public view returns (string memory) {
return
IERC7508(_attributesRepository).getStringAttribute(
_snakeSoldiers,
soldierId,
_NAME_KEY
);
}
function setCustomName(
uint256 soldierId,
string memory name
) external onlySoldierOwner(soldierId) {
string memory curentName = getCustomName(soldierId);
if (bytes(curentName).length > 0) {
if (address(_nameChangeTicket) == address(0))
revert CannotChangeName();
if (_nameChangeTicket.balanceOf(msg.sender) == 0)
revert NameChangeTicketNeeded();
_nameChangeTicket.useTicket(msg.sender);
}
IERC7508(_attributesRepository).setStringAttribute(
_snakeSoldiers,
soldierId,
_NAME_KEY,
name
);
}
// BOOSTS
function getBoostsForSnake(
uint256 soldierId,
Element enemyElement
) external view returns (BattleBoostsPercentage memory boosts) {
EquippedItems memory items = getEquippedItems(soldierId);
(
Faction challengeTerritory,
bool challengeDayNight
) = getCurrentLandAndDayNight();
boosts = getBoostsFromGemsTerritoryAndCelestialPhase(
items,
challengeTerritory,
challengeDayNight,
enemyElement
);
}
function getBoostsFromGemsTerritoryAndCelestialPhase(
EquippedItems memory items,
Faction challengeTerritory,
bool challengeDayNight,
Element enemyElement
) public pure returns (BattleBoostsPercentage memory boosts) {
boosts.elementSkill = getElementSkillBoost(items.element, items.skill);
boosts.factionTerritory = getFactionTerritoryBoost(
items.faction,
challengeTerritory
);
boosts.elementTerritory = getElementTerritoryBoost(
items.element,
challengeTerritory
);
boosts.forest = getForestBoost(items.faction);
boosts.elementElement = getFightingElementsBoost(
items.element,
enemyElement
);
boosts.landscape = getLandscapeBoost(
items.landscape,
challengeTerritory,
challengeDayNight
);
}
function applyBoosts(
BattleStats memory stats,
BattleBoostsPercentage memory boosts
) public pure returns (BattleStats memory adjustedStats) {
adjustedStats = stats;
uint256 baseAttackBoost = uint256(uint16(100 + boosts.elementElement));
uint256 attackBoosts = baseAttackBoost +
boosts.elementSkill +
boosts.elementTerritory +
boosts.landscape +
boosts.forest;
uint256 defenseBoosts = 100 +
boosts.factionTerritory +
boosts.landscape +
boosts.forest;
adjustedStats.attack = uint24((stats.attack * attackBoosts) / 100);
adjustedStats.defense = uint24((stats.defense * defenseBoosts) / 100);
}
function getElementTerritoryBoost(
Element element,
Faction territory
) public pure returns (uint8) {
if (uint256(element) == uint256(territory) && element != Element.None)
return 10;
else return 0;
}
function getForestBoost(Faction faction) public pure returns (uint8) {
if (faction == Faction.Forest) {
return 10;
} else {
return 0;
}
}
function getElementSkillBoost(
Element element,
Skill skill
) public pure returns (uint8) {
if (uint8(element) == uint8(skill) && element != Element.None) {
return 10;
} else {
return 0;
}
}
function getFightingElementsBoost(
Element elementA,
Element elementB
) public pure returns (int16) {
if (elementB == Element.None) {
// Not calculating with enemy
return 0;
} else if (elementA == Element.Fire && elementB == Element.Air) {
// Fire->Air: +30%
return 30;
} else if (elementA == Element.Fire && elementB == Element.Earth) {
// Fire->Earth: -5%
return -5;
} else if (elementA == Element.Fire && elementB == Element.Water) {
// Fire->Water: 0%
return 0;
} else if (elementA == Element.Air && elementB == Element.Fire) {
// Air->Fire: -10%
return -10;
} else if (elementA == Element.Air && elementB == Element.Earth) {
// Air->Earth: +25%
return 25;
} else if (elementA == Element.Air && elementB == Element.Water) {
// Air->Water: 0%
return 0;
} else if (elementA == Element.Earth && elementB == Element.Fire) {
// Earth->Fire: +10%
return 10;
} else if (elementA == Element.Earth && elementB == Element.Air) {
// Earth->Air: -20%
return -20;
} else if (elementA == Element.Earth && elementB == Element.Water) {
// Earth->Water: +20%
return 20;
} else if (elementA == Element.Water && elementB == Element.Fire) {
// Water->Fire: +25%
return 25;
} else if (elementA == Element.Water && elementB == Element.Air) {
// Water->Air: +5%
return 5;
} else if (elementA == Element.Water && elementB == Element.Earth) {
// Water->Earth: -10%
return -10;
} else {
// Same element: -20%, -20%
return -20;
}
}
function getLandscapeBoost(
Landscape landscape,
Faction challengeTerritory,
bool challengeDayNight
) public pure returns (uint8 boost) {
if (
challengeTerritory == Faction.Desert &&
(landscape == Landscape.DesertDay ||
landscape == Landscape.DesertNight ||
landscape == Landscape.DesertEclipse)
) boost += 5;
else if (
challengeTerritory == Faction.Forest &&
(landscape == Landscape.ForestDay ||
landscape == Landscape.ForestNight ||
landscape == Landscape.ForestEclipse)
) boost += 5;
else if (
challengeTerritory == Faction.Islands &&
(landscape == Landscape.IslandsDay ||
landscape == Landscape.IslandsNight ||
landscape == Landscape.IslandsEclipse)
) boost += 5;
else if (
challengeTerritory == Faction.Mountain &&
(landscape == Landscape.MountainDay ||
landscape == Landscape.MountainNight ||
landscape == Landscape.MountainEclipse)
) boost += 5;
else if (
challengeTerritory == Faction.Valley &&
(landscape == Landscape.ValleyDay ||
landscape == Landscape.ValleyNight ||
landscape == Landscape.ValleyEclipse)
) boost += 5;
if (
landscape == Landscape.DesertEclipse ||
landscape == Landscape.ForestEclipse ||
landscape == Landscape.IslandsEclipse ||
landscape == Landscape.MountainEclipse ||
landscape == Landscape.ValleyEclipse
) boost += 5;
else if (
challengeDayNight &&
(landscape == Landscape.DesertDay ||
landscape == Landscape.ForestDay ||
landscape == Landscape.IslandsDay ||
landscape == Landscape.MountainDay ||
landscape == Landscape.ValleyDay)
) boost += 5;
else if (
!challengeDayNight &&
(landscape == Landscape.DesertNight ||
landscape == Landscape.ForestNight ||
landscape == Landscape.IslandsNight ||
landscape == Landscape.MountainNight ||
landscape == Landscape.ValleyNight)
) boost += 5;
}
function getFactionTerritoryBoost(
Faction faction,
Faction territory
) public pure returns (uint8) {
if (faction == territory && faction != Faction.None) return 10;
else return 0;
}
// INIT STATS
function batchSetStats(BattleStats[] memory allStats) public onlyOwner {
for (uint256 i; i < allStats.length; ) {
_storeStats(allStats[i], false);
unchecked {
++i;
}
}
}
// OTHER
function getEquippedItems(
uint256 soldierId
) public view returns (EquippedItems memory items) {
IERC7401.Child[] memory children = IERC7401(_snakeSoldiers).childrenOf(
soldierId
);
uint256 length = children.length;
for (uint256 i; i < length; ) {
IERC7401.Child memory child = children[i];
if (
IERC6220(_snakeSoldiers).isChildEquipped(
soldierId,
child.contractAddress,
child.tokenId
)
) {
// Only consider equipped
if (child.contractAddress == _elementGems) {
items.element = Element(child.tokenId % 4);
} else if (child.contractAddress == _skillGems) {
if (child.tokenId > _SOLDIERS_OFFSET) {
items.skill = Skill((child.tokenId % 8) / 2);
} else {
// For generals and commanders, we ensure the skills match the elements:
items.skill = Skill(child.tokenId % 4);
}
} else if (child.contractAddress == _factionGems) {
if (child.tokenId > _COMMANDERS_OFFSET) {
items.faction = Faction(child.tokenId % 5);
} else {
// For generals, we ensure the faction match the elements
items.faction = Faction(child.tokenId % 4);
}
} else if (child.contractAddress == _landscapes) {
uint64[] memory assetIds = IERC5773(_landscapes)
.getActiveAssets(child.tokenId);
items.landscape = Landscape(assetIds[0]);
}
}
unchecked {
++i;
}
}
}
function useFreePoints(
uint256 soldierId,
uint24 attack,
uint24 defense,
uint24 maxHealth,
uint24 maxStamina
) external onlySoldierOwner(soldierId) returns (BattleStats memory stats) {
stats = getStats(soldierId);
uint24 usedPoints = attack + defense + maxHealth + maxStamina;
if (usedPoints > stats.freePoints) revert NotEnoughFreePoints();
stats.attack += attack;
stats.defense += defense;
stats.maxHealth += maxHealth;
stats.maxStamina += maxStamina;
_storeStats(stats, false);
}
// INTERNAL HELPERS
function _storeStats(
BattleStats memory stats,
bool updateLevelAndFreePoints
) private {
if (updateLevelAndFreePoints) {
if (uint32((stats.level + 1) * stats.level) > stats.experience) {
stats.level += 1;
stats.freePoints += _freePointsForLevel(stats.level);
}
}
_attributesRepository.setUintAttribute(
_snakeSoldiers,
stats.id,
_STATS_KEY,
_mergeStats(stats)
);
}
function _freePointsForLevel(
uint16 level
) private pure returns (uint16 freePoints) {
while (level != 0) {
unchecked {
freePoints++;
}
level >>= level;
}
}
function _mergeStats(
BattleStats memory stats
) private pure returns (uint256 mergedStats) {
mergedStats = stats.attack;
mergedStats |= uint256(stats.defense) << 24; // 24 bits offset
mergedStats |= uint256(stats.health) << 48; // 24 bits offset
mergedStats |= uint256(stats.stamina) << 72; // 24 bits offset
mergedStats |= uint256(stats.maxHealth) << 96; // 24 bits offset
mergedStats |= uint256(stats.maxStamina) << 120; // 24 bits offset
mergedStats |= uint256(stats.level) << 144; // 24 bits offset
mergedStats |= uint256(stats.freePoints) << 160; // 16 bits offset
mergedStats |= uint256(stats.experience) << 176; // 16 bits offset
mergedStats |= uint256(stats.lastStatsUpdate) << 208; // 32 bits offset
}
function _checkSoldierOwner(uint256 soldierId) private view {
address owner = IERC7401(_snakeSoldiers).ownerOf(soldierId);
if (owner != msg.sender) {
revert NotOwnedSnake();
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)
pragma solidity ^0.8.0;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}// 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.21;
import "@openzeppelin/contracts/utils/Context.sol";
import "../library/RMRKErrors.sol";
/**
* @title Ownable
* @author RMRK team
* @notice A minimal ownable smart contractf or owner and contributors.
* @dev This smart contract is based on "openzeppelin's access/Ownable.sol".
*/
contract Ownable is Context {
address private _owner;
mapping(address => uint256) private _contributors;
/**
* @notice Used to anounce the transfer of ownership.
* @param previousOwner Address of the account that transferred their ownership role
* @param newOwner Address of the account receiving the ownership role
*/
event OwnershipTransferred(
address indexed previousOwner,
address indexed newOwner
);
/**
* @notice Event that signifies that an address was granted contributor role or that the permission has been
* revoked.
* @dev This can only be triggered by a current owner, so there is no need to include that information in the event.
* @param contributor Address of the account that had contributor role status updated
* @param isContributor A boolean value signifying whether the role has been granted (`true`) or revoked (`false`)
*/
event ContributorUpdate(address indexed contributor, bool isContributor);
/**
* @dev Reverts if called by any account other than the owner or an approved contributor.
*/
modifier onlyOwnerOrContributor() {
_onlyOwnerOrContributor();
_;
}
/**
* @dev Reverts if called by any account other than the owner.
*/
modifier onlyOwner() {
_onlyOwner();
_;
}
/**
* @dev Initializes the contract by setting the deployer as the initial owner.
*/
constructor() {
_transferOwnership(_msgSender());
}
/**
* @notice Returns the address of the current owner.
* @return Address of the current owner
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @notice Leaves the contract without owner. Functions using the `onlyOwner` modifier will be disabled.
* @dev Can only be called by the current owner.
* @dev 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));
}
/**
* @notice Transfers ownership of the contract to a new owner.
* @dev Can only be called by the current owner.
* @param newOwner Address of the new owner's account
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
if (newOwner == address(0)) revert RMRKNewOwnerIsZeroAddress();
_transferOwnership(newOwner);
}
/**
* @notice Transfers ownership of the contract to a new owner.
* @dev Internal function without access restriction.
* @dev Emits ***OwnershipTransferred*** event.
* @param newOwner Address of the new owner's account
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
/**
* @notice Adds or removes a contributor to the smart contract.
* @dev Can only be called by the owner.
* @dev Emits ***ContributorUpdate*** event.
* @param contributor Address of the contributor's account
* @param grantRole A boolean value signifying whether the contributor role is being granted (`true`) or revoked
* (`false`)
*/
function manageContributor(
address contributor,
bool grantRole
) external onlyOwner {
if (contributor == address(0)) revert RMRKNewContributorIsZeroAddress();
grantRole
? _contributors[contributor] = 1
: _contributors[contributor] = 0;
emit ContributorUpdate(contributor, grantRole);
}
/**
* @notice Used to check if the address is one of the contributors.
* @param contributor Address of the contributor whose status we are checking
* @return Boolean value indicating whether the address is a contributor or not
*/
function isContributor(address contributor) public view returns (bool) {
return _contributors[contributor] == 1;
}
/**
* @notice Used to verify that the caller is either the owner or a contributor.
* @dev If the caller is not the owner or a contributor, the execution will be reverted.
*/
function _onlyOwnerOrContributor() private view {
if (owner() != _msgSender() && !isContributor(_msgSender()))
revert RMRKNotOwnerOrContributor();
}
/**
* @notice Used to verify that the caller is the owner.
* @dev If the caller is not the owner, the execution will be reverted.
*/
function _onlyOwner() private view {
if (owner() != _msgSender()) revert RMRKNotOwner();
}
}// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.21;
import "../multiasset/IERC5773.sol";
/**
* @title IERC6220
* @author RMRK team
* @notice Interface smart contract of the RMRK equippable module.
*/
interface IERC6220 is IERC5773 {
/**
* @notice Used to store the core structure of the `Equippable` RMRK lego.
* @return assetId The ID of the asset equipping a child
* @return childAssetId The ID of the asset used as equipment
* @return childId The ID of token that is equipped
* @return childEquippableAddress Address of the collection to which the child asset belongs to
*/
struct Equipment {
uint64 assetId;
uint64 childAssetId;
uint256 childId;
address childEquippableAddress;
}
/**
* @notice Used to provide a struct for inputing equip data.
* @dev Only used for input and not storage of data.
* @return tokenId ID of the token we are managing
* @return childIndex Index of a child in the list of token's active children
* @return assetId ID of the asset that we are equipping into
* @return slotPartId ID of the slot part that we are using to equip
* @return childAssetId ID of the asset that we are equipping
*/
struct IntakeEquip {
uint256 tokenId;
uint256 childIndex;
uint64 assetId;
uint64 slotPartId;
uint64 childAssetId;
}
/**
* @notice Used to notify listeners that a child's asset has been equipped into one of its parent assets.
* @param tokenId ID of the token that had an asset equipped
* @param assetId ID of the asset associated with the token we are equipping into
* @param slotPartId ID of the slot we are using to equip
* @param childId ID of the child token we are equipping into the slot
* @param childAddress Address of the child token's collection
* @param childAssetId ID of the asset associated with the token we are equipping
*/
event ChildAssetEquipped(
uint256 indexed tokenId,
uint64 indexed assetId,
uint64 indexed slotPartId,
uint256 childId,
address childAddress,
uint64 childAssetId
);
/**
* @notice Used to notify listeners that a child's asset has been unequipped from one of its parent assets.
* @param tokenId ID of the token that had an asset unequipped
* @param assetId ID of the asset associated with the token we are unequipping out of
* @param slotPartId ID of the slot we are unequipping from
* @param childId ID of the token being unequipped
* @param childAddress Address of the collection that a token that is being unequipped belongs to
* @param childAssetId ID of the asset associated with the token we are unequipping
*/
event ChildAssetUnequipped(
uint256 indexed tokenId,
uint64 indexed assetId,
uint64 indexed slotPartId,
uint256 childId,
address childAddress,
uint64 childAssetId
);
/**
* @notice Used to notify listeners that the assets belonging to a `equippableGroupId` have been marked as
* equippable into a given slot and parent
* @param equippableGroupId ID of the equippable group being marked as equippable into the slot associated with
* `slotPartId` of the `parentAddress` collection
* @param slotPartId ID of the slot part of the catalog into which the parts belonging to the equippable group
* associated with `equippableGroupId` can be equipped
* @param parentAddress Address of the collection into which the parts belonging to `equippableGroupId` can be
* equipped
*/
event ValidParentEquippableGroupIdSet(
uint64 indexed equippableGroupId,
uint64 indexed slotPartId,
address parentAddress
);
/**
* @notice Used to equip a child into a token.
* @dev The `IntakeEquip` stuct contains the following data:
* [
* tokenId,
* childIndex,
* assetId,
* slotPartId,
* childAssetId
* ]
* @param data An `IntakeEquip` struct specifying the equip data
*/
function equip(IntakeEquip memory data) external;
/**
* @notice Used to unequip child from parent token.
* @dev This can only be called by the owner of the token or by an account that has been granted permission to
* manage the given token by the current owner.
* @param tokenId ID of the parent from which the child is being unequipped
* @param assetId ID of the parent's asset that contains the `Slot` into which the child is equipped
* @param slotPartId ID of the `Slot` from which to unequip the child
*/
function unequip(
uint256 tokenId,
uint64 assetId,
uint64 slotPartId
) external;
/**
* @notice Used to check whether the token has a given child equipped.
* @dev This is used to prevent from transferring a child that is equipped.
* @param tokenId ID of the parent token for which we are querying for
* @param childAddress Address of the child token's smart contract
* @param childId ID of the child token
* @return A boolean value indicating whether the child token is equipped into the given token or not
*/
function isChildEquipped(
uint256 tokenId,
address childAddress,
uint256 childId
) external view returns (bool);
/**
* @notice Used to verify whether a token can be equipped into a given parent's slot.
* @param parent Address of the parent token's smart contract
* @param tokenId ID of the token we want to equip
* @param assetId ID of the asset associated with the token we want to equip
* @param slotId ID of the slot that we want to equip the token into
* @return A boolean indicating whether the token with the given asset can be equipped into the desired slot
*/
function canTokenBeEquippedWithAssetIntoSlot(
address parent,
uint256 tokenId,
uint64 assetId,
uint64 slotId
) external view returns (bool);
/**
* @notice Used to get the Equipment object equipped into the specified slot of the desired token.
* @dev The `Equipment` struct consists of the following data:
* [
* assetId,
* childAssetId,
* childId,
* childEquippableAddress
* ]
* @param tokenId ID of the token for which we are retrieving the equipped object
* @param targetCatalogAddress Address of the `Catalog` associated with the `Slot` part of the token
* @param slotPartId ID of the `Slot` part that we are checking for equipped objects
* @return The `Equipment` struct containing data about the equipped object
*/
function getEquipment(
uint256 tokenId,
address targetCatalogAddress,
uint64 slotPartId
) external view returns (Equipment memory);
/**
* @notice Used to get the asset and equippable data associated with given `assetId`.
* @param tokenId ID of the token for which to retrieve the asset
* @param assetId ID of the asset of which we are retrieving
* @return metadataURI The metadata URI of the asset
* @return equippableGroupId ID of the equippable group this asset belongs to
* @return catalogAddress The address of the catalog the part belongs to
* @return partIds An array of IDs of parts included in the asset
*/
function getAssetAndEquippableData(
uint256 tokenId,
uint64 assetId
)
external
view
returns (
string memory metadataURI,
uint64 equippableGroupId,
address catalogAddress,
uint64[] memory partIds
);
}// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.21;
import "@openzeppelin/contracts/utils/introspection/IERC165.sol";
/**
* @title IERC7508
* @author RMRK team
* @notice Interface smart contract of the RMRK token properties extension.
*/
interface IERC7508 is IERC165 {
/**
* @notice A list of supported access types.
* @return The `Issuer` type, where only the issuer can manage the parameter.
* @return The `Collaborator` type, where only the collaborators can manage the parameter.
* @return The `IssuerOrCollaborator` type, where only the issuer or collaborators can manage the parameter.
* @return The `TokenOwner` type, where only the token owner can manage the parameters of their tokens.
* @return The `SpecificAddress` type, where only specific addresses can manage the parameter.
*/
enum AccessType {
Issuer,
Collaborator,
IssuerOrCollaborator,
TokenOwner,
SpecificAddress
}
/**
* @notice Structure used to represent a string attribute.
* @return key The key of the attribute
* @return value The value of the attribute
*/
struct StringAttribute {
string key;
string value;
}
/**
* @notice Structure used to represent an uint attribute.
* @return key The key of the attribute
* @return value The value of the attribute
*/
struct UintAttribute {
string key;
uint256 value;
}
/**
* @notice Structure used to represent a boolean attribute.
* @return key The key of the attribute
* @return value The value of the attribute
*/
struct BoolAttribute {
string key;
bool value;
}
/**
* @notice Structure used to represent an address attribute.
* @return key The key of the attribute
* @return value The value of the attribute
*/
struct AddressAttribute {
string key;
address value;
}
/**
* @notice Structure used to represent a bytes attribute.
* @return key The key of the attribute
* @return value The value of the attribute
*/
struct BytesAttribute {
string key;
bytes value;
}
/**
* @notice Used to notify listeners that a new collection has been registered to use the repository.
* @param collection Address of the collection
* @param issuer Address of the issuer of the collection; the addess authorized to manage the access control
* @param registeringAddress Address that registered the collection
* @param useOwnable A boolean value indicating whether the collection uses the Ownable extension to verify the
* issuer (`true`) or not (`false`)
*/
event AccessControlRegistration(
address indexed collection,
address indexed issuer,
address indexed registeringAddress,
bool useOwnable
);
/**
* @notice Used to notify listeners that the access control settings for a specific parameter have been updated.
* @param collection Address of the collection
* @param key The name of the parameter for which the access control settings have been updated
* @param accessType The AccessType of the parameter for which the access control settings have been updated
* @param specificAddress The specific addresses that has been updated
*/
event AccessControlUpdate(
address indexed collection,
string key,
AccessType accessType,
address specificAddress
);
/**
* @notice Used to notify listeners that a new collaborator has been added or removed.
* @param collection Address of the collection
* @param collaborator Address of the collaborator
* @param isCollaborator A boolean value indicating whether the collaborator has been added (`true`) or removed
* (`false`)
*/
event CollaboratorUpdate(
address indexed collection,
address indexed collaborator,
bool isCollaborator
);
/**
* @notice Used to notify listeners that a string attribute has been updated.
* @param collection The collection address
* @param tokenId The token ID
* @param key The key of the attribute
* @param value The new value of the attribute
*/
event StringAttributeUpdated(
address indexed collection,
uint256 indexed tokenId,
string key,
string value
);
/**
* @notice Used to notify listeners that an uint attribute has been updated.
* @param collection The collection address
* @param tokenId The token ID
* @param key The key of the attribute
* @param value The new value of the attribute
*/
event UintAttributeUpdated(
address indexed collection,
uint256 indexed tokenId,
string key,
uint256 value
);
/**
* @notice Used to notify listeners that a boolean attribute has been updated.
* @param collection The collection address
* @param tokenId The token ID
* @param key The key of the attribute
* @param value The new value of the attribute
*/
event BoolAttributeUpdated(
address indexed collection,
uint256 indexed tokenId,
string key,
bool value
);
/**
* @notice Used to notify listeners that an address attribute has been updated.
* @param collection The collection address
* @param tokenId The token ID
* @param key The key of the attribute
* @param value The new value of the attribute
*/
event AddressAttributeUpdated(
address indexed collection,
uint256 indexed tokenId,
string key,
address value
);
/**
* @notice Used to notify listeners that a bytes attribute has been updated.
* @param collection The collection address
* @param tokenId The token ID
* @param key The key of the attribute
* @param value The new value of the attribute
*/
event BytesAttributeUpdated(
address indexed collection,
uint256 indexed tokenId,
string key,
bytes value
);
/**
* @notice Used to register a collection to use the RMRK token attributes repository.
* @dev If the collection does not implement the Ownable interface, the `useOwnable` value must be set to `false`.
* @dev Emits an {AccessControlRegistration} event.
* @param collection The address of the collection that will use the RMRK token attributes repository.
* @param issuer The address of the issuer of the collection.
* @param useOwnable The boolean value to indicate if the collection implements the Ownable interface and whether it
* should be used to validate that the caller is the issuer (`true`) or to use the manually set issuer address
* (`false`).
*/
function registerAccessControl(
address collection,
address issuer,
bool useOwnable
) external;
/**
* @notice Used to manage the access control settings for a specific parameter.
* @dev Only the `issuer` of the collection can call this function.
* @dev The possible `accessType` values are:
* [
* Issuer,
* Collaborator,
* IssuerOrCollaborator,
* TokenOwner,
* SpecificAddress,
* ]
* @dev Emits an {AccessControlUpdated} event.
* @param collection The address of the collection being managed.
* @param key The key of the attribute
* @param accessType The type of access control to be applied to the parameter.
* @param specificAddress The address to be added as a specific addresses allowed to manage the given
* parameter.
*/
function manageAccessControl(
address collection,
string memory key,
AccessType accessType,
address specificAddress
) external;
/**
* @notice Used to manage the collaborators of a collection.
* @dev The `collaboratorAddresses` and `collaboratorAddressAccess` arrays must be of the same length.
* @dev Emits a {CollaboratorUpdate} event.
* @param collection The address of the collection
* @param collaboratorAddresses The array of collaborator addresses being managed
* @param collaboratorAddressAccess The array of boolean values indicating if the collaborator address should
* receive the permission (`true`) or not (`false`).
*/
function manageCollaborators(
address collection,
address[] memory collaboratorAddresses,
bool[] memory collaboratorAddressAccess
) external;
/**
* @notice Used to set a number attribute.
* @dev Emits a {UintAttributeUpdated} event.
* @param collection Address of the collection receiving the attribute
* @param tokenId The token ID
* @param key The attribute key
* @param value The attribute value
*/
function setUintAttribute(
address collection,
uint256 tokenId,
string memory key,
uint256 value
) external;
/**
* @notice Used to set a string attribute.
* @dev Emits a {StringAttributeUpdated} event.
* @param collection Address of the collection receiving the attribute
* @param tokenId The token ID
* @param key The attribute key
* @param value The attribute value
*/
function setStringAttribute(
address collection,
uint256 tokenId,
string memory key,
string memory value
) external;
/**
* @notice Used to set a boolean attribute.
* @dev Emits a {BoolAttributeUpdated} event.
* @param collection Address of the collection receiving the attribute
* @param tokenId The token ID
* @param key The attribute key
* @param value The attribute value
*/
function setBoolAttribute(
address collection,
uint256 tokenId,
string memory key,
bool value
) external;
/**
* @notice Used to set an bytes attribute.
* @dev Emits a {BytesAttributeUpdated} event.
* @param collection Address of the collection receiving the attribute
* @param tokenId The token ID
* @param key The attribute key
* @param value The attribute value
*/
function setBytesAttribute(
address collection,
uint256 tokenId,
string memory key,
bytes memory value
) external;
/**
* @notice Used to set an address attribute.
* @dev Emits a {AddressAttributeUpdated} event.
* @param collection Address of the collection receiving the attribute
* @param tokenId The token ID
* @param key The attribute key
* @param value The attribute value
*/
function setAddressAttribute(
address collection,
uint256 tokenId,
string memory key,
address value
) external;
/**
* @notice Sets multiple string attributes for a token at once.
* @dev The `StringAttribute` struct contains the following fields:
* [
* string key,
* string value
* ]
* @param collection Address of the collection
* @param tokenId ID of the token
* @param attributes An array of `StringAttribute` structs to be assigned to the given token
*/
function setStringAttributes(
address collection,
uint256 tokenId,
StringAttribute[] memory attributes
) external;
/**
* @notice Sets multiple uint attributes for a token at once.
* @dev The `UintAttribute` struct contains the following fields:
* [
* string key,
* uint value
* ]
* @param collection Address of the collection
* @param tokenId ID of the token
* @param attributes An array of `UintAttribute` structs to be assigned to the given token
*/
function setUintAttributes(
address collection,
uint256 tokenId,
UintAttribute[] memory attributes
) external;
/**
* @notice Sets multiple bool attributes for a token at once.
* @dev The `BoolAttribute` struct contains the following fields:
* [
* string key,
* bool value
* ]
* @param collection Address of the collection
* @param tokenId ID of the token
* @param attributes An array of `BoolAttribute` structs to be assigned to the given token
*/
function setBoolAttributes(
address collection,
uint256 tokenId,
BoolAttribute[] memory attributes
) external;
/**
* @notice Sets multiple address attributes for a token at once.
* @dev The `AddressAttribute` struct contains the following fields:
* [
* string key,
* address value
* ]
* @param collection Address of the collection
* @param tokenId ID of the token
* @param attributes An array of `AddressAttribute` structs to be assigned to the given token
*/
function setAddressAttributes(
address collection,
uint256 tokenId,
AddressAttribute[] memory attributes
) external;
/**
* @notice Sets multiple bytes attributes for a token at once.
* @dev The `BytesAttribute` struct contains the following fields:
* [
* string key,
* bytes value
* ]
* @param collection Address of the collection
* @param tokenId ID of the token
* @param attributes An array of `BytesAttribute` structs to be assigned to the given token
*/
function setBytesAttributes(
address collection,
uint256 tokenId,
BytesAttribute[] memory attributes
) external;
/**
* @notice Sets multiple attributes of multiple types for a token at the same time.
* @dev Emits a separate event for each attribute set.
* @dev The `StringAttribute`, `UintAttribute`, `BoolAttribute`, `AddressAttribute` and `BytesAttribute` structs consists
* to the following fields (where `value` is of the appropriate type):
* [
* key,
* value,
* ]
* @param collection The address of the collection
* @param tokenId The token ID
* @param stringAttributes An array of `StringAttribute` structs containing string attributes to set
* @param uintAttributes An array of `UintAttribute` structs containing uint attributes to set
* @param boolAttributes An array of `BoolAttribute` structs containing bool attributes to set
* @param addressAttributes An array of `AddressAttribute` structs containing address attributes to set
* @param bytesAttributes An array of `BytesAttribute` structs containing bytes attributes to set
*/
function setAttributes(
address collection,
uint256 tokenId,
StringAttribute[] memory stringAttributes,
UintAttribute[] memory uintAttributes,
BoolAttribute[] memory boolAttributes,
AddressAttribute[] memory addressAttributes,
BytesAttribute[] memory bytesAttributes
) external;
/**
* @notice Used to set the uint attribute on behalf of an authorized account.
* @dev Emits a {UintAttributeUpdated} event.
* @param setter Address of the account that presigned the attribute change
* @param collection Address of the collection receiving the attribute
* @param tokenId The ID of the token receiving the attribute
* @param key The attribute key
* @param value The attribute value
* @param deadline The deadline timestamp for the presigned transaction
* @param v `v` value of an ECDSA signature of the presigned message
* @param r `r` value of an ECDSA signature of the presigned message
* @param s `s` value of an ECDSA signature of the presigned message
*/
function presignedSetUintAttribute(
address setter,
address collection,
uint256 tokenId,
string memory key,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
/**
* @notice Used to set the string attribute on behalf of an authorized account.
* @dev Emits a {StringAttributeUpdated} event.
* @param setter Address of the account that presigned the attribute change
* @param collection Address of the collection receiving the attribute
* @param tokenId The ID of the token receiving the attribute
* @param key The attribute key
* @param value The attribute value
* @param deadline The deadline timestamp for the presigned transaction
* @param v `v` value of an ECDSA signature of the presigned message
* @param r `r` value of an ECDSA signature of the presigned message
* @param s `s` value of an ECDSA signature of the presigned message
*/
function presignedSetStringAttribute(
address setter,
address collection,
uint256 tokenId,
string memory key,
string memory value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
/**
* @notice Used to set the bool attribute on behalf of an authorized account.
* @dev Emits a {BoolAttributeUpdated} event.
* @param setter Address of the account that presigned the attribute change
* @param collection Address of the collection receiving the attribute
* @param tokenId The ID of the token receiving the attribute
* @param key The attribute key
* @param value The attribute value
* @param deadline The deadline timestamp for the presigned transaction
* @param v `v` value of an ECDSA signature of the presigned message
* @param r `r` value of an ECDSA signature of the presigned message
* @param s `s` value of an ECDSA signature of the presigned message
*/
function presignedSetBoolAttribute(
address setter,
address collection,
uint256 tokenId,
string memory key,
bool value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
/**
* @notice Used to set the bytes attribute on behalf of an authorized account.
* @dev Emits a {BytesAttributeUpdated} event.
* @param setter Address of the account that presigned the attribute change
* @param collection Address of the collection receiving the attribute
* @param tokenId The ID of the token receiving the attribute
* @param key The attribute key
* @param value The attribute value
* @param deadline The deadline timestamp for the presigned transaction
* @param v `v` value of an ECDSA signature of the presigned message
* @param r `r` value of an ECDSA signature of the presigned message
* @param s `s` value of an ECDSA signature of the presigned message
*/
function presignedSetBytesAttribute(
address setter,
address collection,
uint256 tokenId,
string memory key,
bytes memory value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
/**
* @notice Used to set the address attribute on behalf of an authorized account.
* @dev Emits a {AddressAttributeUpdated} event.
* @param setter Address of the account that presigned the attribute change
* @param collection Address of the collection receiving the attribute
* @param tokenId The ID of the token receiving the attribute
* @param key The attribute key
* @param value The attribute value
* @param deadline The deadline timestamp for the presigned transaction
* @param v `v` value of an ECDSA signature of the presigned message
* @param r `r` value of an ECDSA signature of the presigned message
* @param s `s` value of an ECDSA signature of the presigned message
*/
function presignedSetAddressAttribute(
address setter,
address collection,
uint256 tokenId,
string memory key,
address value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
/**
* @notice Used to check if the specified address is listed as a collaborator of the given collection's parameter.
* @param collaborator Address to be checked.
* @param collection Address of the collection.
* @return Boolean value indicating if the address is a collaborator of the given collection's (`true`) or not
* (`false`).
*/
function isCollaborator(
address collaborator,
address collection
) external view returns (bool);
/**
* @notice Used to check if the specified address is listed as a specific address of the given collection's
* parameter.
* @param specificAddress Address to be checked.
* @param collection Address of the collection.
* @param key The key of the attribute
* @return Boolean value indicating if the address is a specific address of the given collection's parameter
* (`true`) or not (`false`).
*/
function isSpecificAddress(
address specificAddress,
address collection,
string memory key
) external view returns (bool);
/**
* @notice Used to retrieve the string type token attributes.
* @param collection The collection address
* @param tokenId The token ID
* @param key The key of the attribute
* @return The value of the string attribute
*/
function getStringAttribute(
address collection,
uint256 tokenId,
string memory key
) external view returns (string memory);
/**
* @notice Used to retrieve the uint type token attributes.
* @param collection The collection address
* @param tokenId The token ID
* @param key The key of the attribute
* @return The value of the uint attribute
*/
function getUintAttribute(
address collection,
uint256 tokenId,
string memory key
) external view returns (uint256);
/**
* @notice Used to retrieve the bool type token attributes.
* @param collection The collection address
* @param tokenId The token ID
* @param key The key of the attribute
* @return The value of the bool attribute
*/
function getBoolAttribute(
address collection,
uint256 tokenId,
string memory key
) external view returns (bool);
/**
* @notice Used to retrieve the address type token attributes.
* @param collection The collection address
* @param tokenId The token ID
* @param key The key of the attribute
* @return The value of the address attribute
*/
function getAddressAttribute(
address collection,
uint256 tokenId,
string memory key
) external view returns (address);
/**
* @notice Used to retrieve the bytes type token attributes.
* @param collection The collection address
* @param tokenId The token ID
* @param key The key of the attribute
* @return The value of the bytes attribute
*/
function getBytesAttribute(
address collection,
uint256 tokenId,
string memory key
) external view returns (bytes memory);
/**
* @notice Used to retrieve the message to be signed for submitting a presigned uint attribute change.
* @param collection The address of the collection smart contract of the token receiving the attribute
* @param tokenId The ID of the token receiving the attribute
* @param key The attribute key
* @param value The attribute value
* @param deadline The deadline timestamp for the presigned transaction after which the message is invalid
* @return Raw message to be signed by the authorized account
*/
function prepareMessageToPresignUintAttribute(
address collection,
uint256 tokenId,
string memory key,
uint256 value,
uint256 deadline
) external view returns (bytes32);
/**
* @notice Used to retrieve the message to be signed for submitting a presigned string attribute change.
* @param collection The address of the collection smart contract of the token receiving the attribute
* @param tokenId The ID of the token receiving the attribute
* @param key The attribute key
* @param value The attribute value
* @param deadline The deadline timestamp for the presigned transaction after which the message is invalid
* @return Raw message to be signed by the authorized account
*/
function prepareMessageToPresignStringAttribute(
address collection,
uint256 tokenId,
string memory key,
string memory value,
uint256 deadline
) external view returns (bytes32);
/**
* @notice Used to retrieve the message to be signed for submitting a presigned bool attribute change.
* @param collection The address of the collection smart contract of the token receiving the attribute
* @param tokenId The ID of the token receiving the attribute
* @param key The attribute key
* @param value The attribute value
* @param deadline The deadline timestamp for the presigned transaction after which the message is invalid
* @return Raw message to be signed by the authorized account
*/
function prepareMessageToPresignBoolAttribute(
address collection,
uint256 tokenId,
string memory key,
bool value,
uint256 deadline
) external view returns (bytes32);
/**
* @notice Used to retrieve the message to be signed for submitting a presigned bytes attribute change.
* @param collection The address of the collection smart contract of the token receiving the attribute
* @param tokenId The ID of the token receiving the attribute
* @param key The attribute key
* @param value The attribute value
* @param deadline The deadline timestamp for the presigned transaction after which the message is invalid
* @return Raw message to be signed by the authorized account
*/
function prepareMessageToPresignBytesAttribute(
address collection,
uint256 tokenId,
string memory key,
bytes memory value,
uint256 deadline
) external view returns (bytes32);
/**
* @notice Used to retrieve the message to be signed for submitting a presigned address attribute change.
* @param collection The address of the collection smart contract of the token receiving the attribute
* @param tokenId The ID of the token receiving the attribute
* @param key The attribute key
* @param value The attribute value
* @param deadline The deadline timestamp for the presigned transaction after which the message is invalid
* @return Raw message to be signed by the authorized account
*/
function prepareMessageToPresignAddressAttribute(
address collection,
uint256 tokenId,
string memory key,
address value,
uint256 deadline
) external view returns (bytes32);
/**
* @notice Used to retrieve multiple token attributes of any type at once.
* @dev The `StringAttribute`, `UintAttribute`, `BoolAttribute`, `AddressAttribute` and `BytesAttribute` structs consists
* to the following fields (where `value` is of the appropriate type):
* [
* key,
* value,
* ]
* @param collection The collection address
* @param tokenId The token ID
* @param stringKeys An array of string type attribute keys to retrieve
* @param uintKeys An array of uint type attribute keys to retrieve
* @param boolKeys An array of bool type attribute keys to retrieve
* @param addressKeys An array of address type attribute keys to retrieve
* @param bytesKeys An array of bytes type attribute keys to retrieve
* @return stringAttributes An array of `StringAttribute` structs containing the string type attributes
* @return uintAttributes An array of `UintAttribute` structs containing the uint type attributes
* @return boolAttributes An array of `BoolAttribute` structs containing the bool type attributes
* @return addressAttributes An array of `AddressAttribute` structs containing the address type attributes
* @return bytesAttributes An array of `BytesAttribute` structs containing the bytes type attributes
*/
function getAttributes(
address collection,
uint256 tokenId,
string[] memory stringKeys,
string[] memory uintKeys,
string[] memory boolKeys,
string[] memory addressKeys,
string[] memory bytesKeys
)
external
view
returns (
StringAttribute[] memory stringAttributes,
UintAttribute[] memory uintAttributes,
BoolAttribute[] memory boolAttributes,
AddressAttribute[] memory addressAttributes,
BytesAttribute[] memory bytesAttributes
);
/**
* @notice Used to get multiple sting parameter values for a token.
* @dev The `StringAttribute` struct contains the following fields:
* [
* string key,
* string value
* ]
* @param collection Address of the collection the token belongs to
* @param tokenId ID of the token for which the attributes are being retrieved
* @param stringKeys An array of string keys to retrieve
* @return An array of `StringAttribute` structs
*/
function getStringAttributes(
address collection,
uint256 tokenId,
string[] memory stringKeys
) external view returns (StringAttribute[] memory);
/**
* @notice Used to get multiple uint parameter values for a token.
* @dev The `UintAttribute` struct contains the following fields:
* [
* string key,
* uint value
* ]
* @param collection Address of the collection the token belongs to
* @param tokenId ID of the token for which the attributes are being retrieved
* @param uintKeys An array of uint keys to retrieve
* @return An array of `UintAttribute` structs
*/
function getUintAttributes(
address collection,
uint256 tokenId,
string[] memory uintKeys
) external view returns (UintAttribute[] memory);
/**
* @notice Used to get multiple bool parameter values for a token.
* @dev The `BoolAttribute` struct contains the following fields:
* [
* string key,
* bool value
* ]
* @param collection Address of the collection the token belongs to
* @param tokenId ID of the token for which the attributes are being retrieved
* @param boolKeys An array of bool keys to retrieve
* @return An array of `BoolAttribute` structs
*/
function getBoolAttributes(
address collection,
uint256 tokenId,
string[] memory boolKeys
) external view returns (BoolAttribute[] memory);
/**
* @notice Used to get multiple address parameter values for a token.
* @dev The `AddressAttribute` struct contains the following fields:
* [
* string key,
* address value
* ]
* @param collection Address of the collection the token belongs to
* @param tokenId ID of the token for which the attributes are being retrieved
* @param addressKeys An array of address keys to retrieve
* @return An array of `AddressAttribute` structs
*/
function getAddressAttributes(
address collection,
uint256 tokenId,
string[] memory addressKeys
) external view returns (AddressAttribute[] memory);
/**
* @notice Used to get multiple bytes parameter values for a token.
* @dev The `BytesAttribute` struct contains the following fields:
* [
* string key,
* bytes value
* ]
* @param collection Address of the collection the token belongs to
* @param tokenId ID of the token for which the attributes are being retrieved
* @param bytesKeys An array of bytes keys to retrieve
* @return An array of `BytesAttribute` structs
*/
function getBytesAttributes(
address collection,
uint256 tokenId,
string[] memory bytesKeys
) external view returns (BytesAttribute[] memory);
}// SPDX-License-Identifier: Apache-2.0 pragma solidity ^0.8.21; /// @title RMRKErrors /// @author RMRK team /// @notice A collection of errors used in the RMRK suite /// @dev Errors are kept in a centralised file in order to provide a central point of reference and to avoid error /// naming collisions due to inheritance /// Attempting to grant the token to 0x0 address error ERC721AddressZeroIsNotaValidOwner(); /// Attempting to grant approval to the current owner of the token error ERC721ApprovalToCurrentOwner(); /// Attempting to grant approval when not being owner or approved for all should not be permitted error ERC721ApproveCallerIsNotOwnerNorApprovedForAll(); /// Attempting to get approvals for a token owned by 0x0 (considered non-existent) error ERC721ApprovedQueryForNonexistentToken(); /// Attempting to grant approval to self error ERC721ApproveToCaller(); /// Attempting to use an invalid token ID error ERC721InvalidTokenId(); /// Attempting to mint to 0x0 address error ERC721MintToTheZeroAddress(); /// Attempting to manage a token without being its owner or approved by the owner error ERC721NotApprovedOrOwner(); /// Attempting to mint an already minted token error ERC721TokenAlreadyMinted(); /// Attempting to transfer the token from an address that is not the owner error ERC721TransferFromIncorrectOwner(); /// Attempting to safe transfer to an address that is unable to receive the token error ERC721TransferToNonReceiverImplementer(); /// Attempting to transfer the token to a 0x0 address error ERC721TransferToTheZeroAddress(); /// Attempting to grant approval of assets to their current owner error RMRKApprovalForAssetsToCurrentOwner(); /// Attempting to grant approval of assets without being the caller or approved for all error RMRKApproveForAssetsCallerIsNotOwnerNorApprovedForAll(); /// Attempting to incorrectly configue a Catalog item error RMRKBadConfig(); /// Attempting to set the priorities with an array of length that doesn't match the length of active assets array error RMRKBadPriorityListLength(); /// Attempting to add an asset entry with `Part`s, without setting the `Catalog` address error RMRKCatalogRequiredForParts(); /// Attempting to transfer a soulbound (non-transferrable) token error RMRKCannotTransferSoulbound(); /// Attempting to accept a child that has already been accepted error RMRKChildAlreadyExists(); /// Attempting to interact with a child, using index that is higher than the number of children error RMRKChildIndexOutOfRange(); /// Attempting to find the index of a child token on a parent which does not own it. error RMRKChildNotFoundInParent(); /// Attempting to pass collaborator address array and collaborator permission array of different lengths error RMRKCollaboratorArraysNotEqualLength(); /// Attempting to register a collection that is already registered error RMRKCollectionAlreadyRegistered(); /// Attempting to manage or interact with colleciton that is not registered error RMRKCollectionNotRegistered(); /// Attempting to equip a `Part` with a child not approved by the Catalog error RMRKEquippableEquipNotAllowedByCatalog(); /// Attempting to pass an epired ECDSA deadline error RMRKExpiredDeadline(); /// Attempting to use ID 0, which is not supported /// @dev The ID 0 in RMRK suite is reserved for empty values. Guarding against its use ensures the expected operation error RMRKIdZeroForbidden(); /// Attempting to interact with an asset, using index greater than number of assets error RMRKIndexOutOfRange(); /// Attempting to reclaim a child that can't be reclaimed error RMRKInvalidChildReclaim(); /// Attempting to use and invalid ECDSA signature error RMRKInvalidSignature(); /// Attempting to interact with an end-user account when the contract account is expected error RMRKIsNotContract(); /// Attempting to interact with a contract that had its operation locked error RMRKLocked(); /// Attempting to add a pending child after the number of pending children has reached the limit (default limit is 128) error RMRKMaxPendingChildrenReached(); /// Attempting to add a pending asset after the number of pending assets has reached the limit (default limit is /// 128) error RMRKMaxPendingAssetsReached(); /// Attempting to burn a total number of recursive children higher than maximum set /// @param childContract Address of the collection smart contract in which the maximum number of recursive burns was reached /// @param childId ID of the child token at which the maximum number of recursive burns was reached error RMRKMaxRecursiveBurnsReached(address childContract, uint256 childId); /// Attempting to mint a number of tokens that would cause the total supply to be greater than maximum supply error RMRKMintOverMax(); /// Attempting to mint a nested token to a smart contract that doesn't support nesting error RMRKMintToNonRMRKNestableImplementer(); /// Attempting to mint zero tokens error RMRKMintZero(); /// Attempting to pass complementary arrays of different lengths error RMRKMismachedArrayLength(); /// Attempting to transfer a child before it is unequipped error RMRKMustUnequipFirst(); /// Attempting to nest a child over the nestable limit (current limit is 100 levels of nesting) error RMRKNestableTooDeep(); /// Attempting to nest the token to own descendant, which would create a loop and leave the looped tokens in limbo error RMRKNestableTransferToDescendant(); /// Attempting to nest the token to a smart contract that doesn't support nesting error RMRKNestableTransferToNonRMRKNestableImplementer(); /// Attempting to nest the token into itself error RMRKNestableTransferToSelf(); /// Attempting to interact with an asset that can not be found error RMRKNoAssetMatchingId(); /// Attempting to manage an asset without owning it or having been granted permission by the owner to do so error RMRKNotApprovedForAssetsOrOwner(); /// Attempting to interact with a token without being its owner or having been granted permission by the /// owner to do so /// @dev When a token is nested, only the direct owner (NFT parent) can mange it. In that case, approved addresses are /// not allowed to manage it, in order to ensure the expected behaviour error RMRKNotApprovedOrDirectOwner(); /// Attempting to manage a collection without being the collection's collaborator error RMRKNotCollectionCollaborator(); /// Attemting to manage a collection without being the collection's issuer error RMRKNotCollectionIssuer(); /// Attempting to manage a collection without being the collection's issuer or collaborator error RMRKNotCollectionIssuerOrCollaborator(); /// Attempting to compose an asset wihtout having an associated Catalog error RMRKNotComposableAsset(); /// Attempting to unequip an item that isn't equipped error RMRKNotEquipped(); /// Attempting to interact with a management function without being the smart contract's owner error RMRKNotOwner(); /// Attempting to interact with a function without being the owner or contributor of the collection error RMRKNotOwnerOrContributor(); /// Attempting to manage a collection without being the specific address error RMRKNotSpecificAddress(); /// Attempting to manage a token without being its owner error RMRKNotTokenOwner(); /// Attempting to transfer the ownership to the 0x0 address error RMRKNewOwnerIsZeroAddress(); /// Attempting to assign a 0x0 address as a contributor error RMRKNewContributorIsZeroAddress(); /// Attemtping to use `Ownable` interface without implementing it error RMRKOwnableNotImplemented(); /// Attempting an operation requiring the token being nested, while it is not error RMRKParentIsNotNFT(); /// Attempting to add a `Part` with an ID that is already used error RMRKPartAlreadyExists(); /// Attempting to use a `Part` that doesn't exist error RMRKPartDoesNotExist(); /// Attempting to use a `Part` that is `Fixed` when `Slot` kind of `Part` should be used error RMRKPartIsNotSlot(); /// Attempting to interact with a pending child using an index greater than the size of pending array error RMRKPendingChildIndexOutOfRange(); /// Attempting to add an asset using an ID that has already been used error RMRKAssetAlreadyExists(); /// Attempting to equip an item into a slot that already has an item equipped error RMRKSlotAlreadyUsed(); /// Attempting to equip an item into a `Slot` that the target asset does not implement error RMRKTargetAssetCannotReceiveSlot(); /// Attempting to equip a child into a `Slot` and parent that the child's collection doesn't support error RMRKTokenCannotBeEquippedWithAssetIntoSlot(); /// Attempting to compose a NFT of a token without active assets error RMRKTokenDoesNotHaveAsset(); /// Attempting to determine the asset with the top priority on a token without assets error RMRKTokenHasNoAssets(); /// Attempting to accept or transfer a child which does not match the one at the specified index error RMRKUnexpectedChildId(); /// Attempting to reject all pending assets but more assets than expected are pending error RMRKUnexpectedNumberOfAssets(); /// Attempting to reject all pending children but children assets than expected are pending error RMRKUnexpectedNumberOfChildren(); /// Attempting to accept or reject an asset which does not match the one at the specified index error RMRKUnexpectedAssetId(); /// Attempting an operation expecting a parent to the token which is not the actual one error RMRKUnexpectedParent(); /// Attempting not to pass an empty array of equippable addresses when adding or setting the equippable addresses error RMRKZeroLengthIdsPassed(); /// Attempting to set the royalties to a value higher than 100% (10000 in basis points) error RMRKRoyaltiesTooHigh(); /// Attempting to do a bulk operation on a token that is not owned by the caller error RMRKCanOnlyDoBulkOperationsOnOwnedTokens(); /// Attempting to do a bulk operation with multiple tokens at a time error RMRKCanOnlyDoBulkOperationsWithOneTokenAtATime(); /// Attempting to pay with native token with a value different than expected error RMRKWrongValueSent();
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.21;
import "@openzeppelin/contracts/utils/introspection/IERC165.sol";
/**
* @title IERC5773
* @author RMRK team
* @notice Interface smart contract of the RMRK multi asset module.
*/
interface IERC5773 is IERC165 {
/**
* @notice Used to notify listeners that an asset object is initialized at `assetId`.
* @param assetId ID of the asset that was initialized
*/
event AssetSet(uint64 indexed assetId);
/**
* @notice Used to notify listeners that an asset object at `assetId` is added to token's pending asset
* array.
* @param tokenIds An array of token IDs that received a new pending asset
* @param assetId ID of the asset that has been added to the token's pending assets array
* @param replacesId ID of the asset that would be replaced
*/
event AssetAddedToTokens(
uint256[] tokenIds,
uint64 indexed assetId,
uint64 indexed replacesId
);
/**
* @notice Used to notify listeners that an asset object at `assetId` is accepted by the token and migrated
* from token's pending assets array to active assets array of the token.
* @param tokenId ID of the token that had a new asset accepted
* @param assetId ID of the asset that was accepted
* @param replacesId ID of the asset that was replaced
*/
event AssetAccepted(
uint256 indexed tokenId,
uint64 indexed assetId,
uint64 indexed replacesId
);
/**
* @notice Used to notify listeners that an asset object at `assetId` is rejected from token and is dropped
* from the pending assets array of the token.
* @param tokenId ID of the token that had an asset rejected
* @param assetId ID of the asset that was rejected
*/
event AssetRejected(uint256 indexed tokenId, uint64 indexed assetId);
/**
* @notice Used to notify listeners that token's prioritiy array is reordered.
* @param tokenId ID of the token that had the asset priority array updated
*/
event AssetPrioritySet(uint256 indexed tokenId);
/**
* @notice Used to notify listeners that owner has granted an approval to the user to manage the assets of a
* given token.
* @dev Approvals must be cleared on transfer
* @param owner Address of the account that has granted the approval for all token's assets
* @param approved Address of the account that has been granted approval to manage the token's assets
* @param tokenId ID of the token on which the approval was granted
*/
event ApprovalForAssets(
address indexed owner,
address indexed approved,
uint256 indexed tokenId
);
/**
* @notice Used to notify listeners that owner has granted approval to the user to manage assets of all of their
* tokens.
* @param owner Address of the account that has granted the approval for all assets on all of their tokens
* @param operator Address of the account that has been granted the approval to manage the token's assets on all of
* the tokens
* @param approved Boolean value signifying whether the permission has been granted (`true`) or revoked (`false`)
*/
event ApprovalForAllForAssets(
address indexed owner,
address indexed operator,
bool approved
);
/**
* @notice Accepts an asset at from the pending array of given token.
* @dev Migrates the asset from the token's pending asset array to the token's active asset array.
* @dev Active assets cannot be removed by anyone, but can be replaced by a new asset.
* @dev Requirements:
*
* - The caller must own the token or be approved to manage the token's assets
* - `tokenId` must exist.
* - `index` must be in range of the length of the pending asset array.
* @dev Emits an {AssetAccepted} event.
* @param tokenId ID of the token for which to accept the pending asset
* @param index Index of the asset in the pending array to accept
* @param assetId ID of the asset expected to be in the index
*/
function acceptAsset(
uint256 tokenId,
uint256 index,
uint64 assetId
) external;
/**
* @notice Rejects an asset from the pending array of given token.
* @dev Removes the asset from the token's pending asset array.
* @dev Requirements:
*
* - The caller must own the token or be approved to manage the token's assets
* - `tokenId` must exist.
* - `index` must be in range of the length of the pending asset array.
* @dev Emits a {AssetRejected} event.
* @param tokenId ID of the token that the asset is being rejected from
* @param index Index of the asset in the pending array to be rejected
* @param assetId ID of the asset expected to be in the index
*/
function rejectAsset(
uint256 tokenId,
uint256 index,
uint64 assetId
) external;
/**
* @notice Rejects all assets from the pending array of a given token.
* @dev Effecitvely deletes the pending array.
* @dev Requirements:
*
* - The caller must own the token or be approved to manage the token's assets
* - `tokenId` must exist.
* @dev Emits a {AssetRejected} event with assetId = 0.
* @param tokenId ID of the token of which to clear the pending array.
* @param maxRejections Maximum number of expected assets to reject, used to prevent from rejecting assets which
* arrive just before this operation.
*/
function rejectAllAssets(uint256 tokenId, uint256 maxRejections) external;
/**
* @notice Sets a new priority array for a given token.
* @dev The priority array is a non-sequential list of `uint64`s, where the lowest value is considered highest
* priority.
* @dev Value `0` of a priority is a special case equivalent to unitialized.
* @dev Requirements:
*
* - The caller must own the token or be approved to manage the token's assets
* - `tokenId` must exist.
* - The length of `priorities` must be equal the length of the active assets array.
* @dev Emits a {AssetPrioritySet} event.
* @param tokenId ID of the token to set the priorities for
* @param priorities An array of priorities of active assets. The succesion of items in the priorities array
* matches that of the succesion of items in the active array
*/
function setPriority(
uint256 tokenId,
uint64[] calldata priorities
) external;
/**
* @notice Used to retrieve IDs of the active assets of given token.
* @dev Asset data is stored by reference, in order to access the data corresponding to the ID, call
* `getAssetMetadata(tokenId, assetId)`.
* @dev You can safely get 10k
* @param tokenId ID of the token to retrieve the IDs of the active assets
* @return An array of active asset IDs of the given token
*/
function getActiveAssets(
uint256 tokenId
) external view returns (uint64[] memory);
/**
* @notice Used to retrieve IDs of the pending assets of given token.
* @dev Asset data is stored by reference, in order to access the data corresponding to the ID, call
* `getAssetMetadata(tokenId, assetId)`.
* @param tokenId ID of the token to retrieve the IDs of the pending assets
* @return An array of pending asset IDs of the given token
*/
function getPendingAssets(
uint256 tokenId
) external view returns (uint64[] memory);
/**
* @notice Used to retrieve the priorities of the active resoources of a given token.
* @dev Asset priorities are a non-sequential array of uint64 values with an array size equal to active asset
* priorites.
* @param tokenId ID of the token for which to retrieve the priorities of the active assets
* @return An array of priorities of the active assets of the given token
*/
function getActiveAssetPriorities(
uint256 tokenId
) external view returns (uint64[] memory);
/**
* @notice Used to retrieve the asset that will be replaced if a given asset from the token's pending array
* is accepted.
* @dev Asset data is stored by reference, in order to access the data corresponding to the ID, call
* `getAssetMetadata(tokenId, assetId)`.
* @param tokenId ID of the token to check
* @param newAssetId ID of the pending asset which will be accepted
* @return ID of the asset which will be replaced
*/
function getAssetReplacements(
uint256 tokenId,
uint64 newAssetId
) external view returns (uint64);
/**
* @notice Used to fetch the asset metadata of the specified token's active asset with the given index.
* @dev Assets are stored by reference mapping `_assets[assetId]`.
* @dev Can be overriden to implement enumerate, fallback or other custom logic.
* @param tokenId ID of the token from which to retrieve the asset metadata
* @param assetId Asset Id, must be in the active assets array
* @return The metadata of the asset belonging to the specified index in the token's active assets
* array
*/
function getAssetMetadata(
uint256 tokenId,
uint64 assetId
) external view returns (string memory);
// Approvals
/**
* @notice Used to grant permission to the user to manage token's assets.
* @dev This differs from transfer approvals, as approvals are not cleared when the approved party accepts or
* rejects an asset, or sets asset priorities. This approval is cleared on token transfer.
* @dev Only a single account can be approved at a time, so approving the `0x0` address clears previous approvals.
* @dev Requirements:
*
* - The caller must own the token or be an approved operator.
* - `tokenId` must exist.
* @dev Emits an {ApprovalForAssets} event.
* @param to Address of the account to grant the approval to
* @param tokenId ID of the token for which the approval to manage the assets is granted
*/
function approveForAssets(address to, uint256 tokenId) external;
/**
* @notice Used to retrieve the address of the account approved to manage assets of a given token.
* @dev Requirements:
*
* - `tokenId` must exist.
* @param tokenId ID of the token for which to retrieve the approved address
* @return Address of the account that is approved to manage the specified token's assets
*/
function getApprovedForAssets(
uint256 tokenId
) external view returns (address);
/**
* @notice Used to add or remove an operator of assets for the caller.
* @dev Operators can call {acceptAsset}, {rejectAsset}, {rejectAllAssets} or {setPriority} for any token
* owned by the caller.
* @dev Requirements:
*
* - The `operator` cannot be the caller.
* @dev Emits an {ApprovalForAllForAssets} event.
* @param operator Address of the account to which the operator role is granted or revoked from
* @param approved The boolean value indicating whether the operator role is being granted (`true`) or revoked
* (`false`)
*/
function setApprovalForAllForAssets(
address operator,
bool approved
) external;
/**
* @notice Used to check whether the address has been granted the operator role by a given address or not.
* @dev See {setApprovalForAllForAssets}.
* @param owner Address of the account that we are checking for whether it has granted the operator role
* @param operator Address of the account that we are checking whether it has the operator role or not
* @return A boolean value indicating wehter the account we are checking has been granted the operator role
*/
function isApprovedForAllForAssets(
address owner,
address operator
) external view returns (bool);
}// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.21;
import "@openzeppelin/contracts/utils/introspection/IERC165.sol";
/**
* @title IERC7401
* @author RMRK team
* @notice Interface smart contract of the RMRK nestable module.
*/
interface IERC7401 is IERC165 {
/**
* @notice The core struct of RMRK ownership.
* @dev The `DirectOwner` struct is used to store information of the next immediate owner, be it the parent token or
* the externally owned account.
* @dev If the token is owned by the externally owned account, the `tokenId` should equal `0`.
* @param tokenId ID of the parent token
* @param ownerAddress Address of the owner of the token. If the owner is another token, then the address should be
* the one of the parent token's collection smart contract. If the owner is externally owned account, the address
* should be the address of this account
* @param isNft A boolean value signifying whether the token is owned by another token (`true`) or by an externally
* owned account (`false`)
*/
struct DirectOwner {
uint256 tokenId;
address ownerAddress;
}
/**
* @notice Used to notify listeners that the token is being transferred.
* @dev Emitted when `tokenId` token is transferred from `from` to `to`.
* @param from Address of the previous immediate owner, which is a smart contract if the token was nested.
* @param to Address of the new immediate owner, which is a smart contract if the token is being nested.
* @param fromTokenId ID of the previous parent token. If the token was not nested before, the value should be `0`
* @param toTokenId ID of the new parent token. If the token is not being nested, the value should be `0`
* @param tokenId ID of the token being transferred
*/
event NestTransfer(
address indexed from,
address indexed to,
uint256 fromTokenId,
uint256 toTokenId,
uint256 indexed tokenId
);
/**
* @notice Used to notify listeners that a new token has been added to a given token's pending children array.
* @dev Emitted when a child NFT is added to a token's pending array.
* @param tokenId ID of the token that received a new pending child token
* @param childIndex Index of the proposed child token in the parent token's pending children array
* @param childAddress Address of the proposed child token's collection smart contract
* @param childId ID of the child token in the child token's collection smart contract
*/
event ChildProposed(
uint256 indexed tokenId,
uint256 childIndex,
address indexed childAddress,
uint256 indexed childId
);
/**
* @notice Used to notify listeners that a new child token was accepted by the parent token.
* @dev Emitted when a parent token accepts a token from its pending array, migrating it to the active array.
* @param tokenId ID of the token that accepted a new child token
* @param childIndex Index of the newly accepted child token in the parent token's active children array
* @param childAddress Address of the child token's collection smart contract
* @param childId ID of the child token in the child token's collection smart contract
*/
event ChildAccepted(
uint256 indexed tokenId,
uint256 childIndex,
address indexed childAddress,
uint256 indexed childId
);
/**
* @notice Used to notify listeners that all pending child tokens of a given token have been rejected.
* @dev Emitted when a token removes all a child tokens from its pending array.
* @param tokenId ID of the token that rejected all of the pending children
*/
event AllChildrenRejected(uint256 indexed tokenId);
/**
* @notice Used to notify listeners a child token has been transferred from parent token.
* @dev Emitted when a token transfers a child from itself, transferring ownership to the root owner.
* @param tokenId ID of the token that transferred a child token
* @param childIndex Index of a child in the array from which it is being transferred
* @param childAddress Address of the child token's collection smart contract
* @param childId ID of the child token in the child token's collection smart contract
* @param fromPending A boolean value signifying whether the token was in the pending child tokens array (`true`) or
* in the active child tokens array (`false`)
* @param toZero A boolean value signifying whether the token is being transferred to the `0x0` address (`true`) or
* not (`false`)
*/
event ChildTransferred(
uint256 indexed tokenId,
uint256 childIndex,
address indexed childAddress,
uint256 indexed childId,
bool fromPending,
bool toZero
);
/**
* @notice The core child token struct, holding the information about the child tokens.
* @return tokenId ID of the child token in the child token's collection smart contract
* @return contractAddress Address of the child token's smart contract
*/
struct Child {
uint256 tokenId;
address contractAddress;
}
/**
* @notice Used to retrieve the *root* owner of a given token.
* @dev The *root* owner of the token is an externally owned account (EOA). If the given token is child of another
* NFT, this will return an EOA address. Otherwise, if the token is owned by an EOA, this EOA wil be returned.
* @param tokenId ID of the token for which the *root* owner has been retrieved
* @return owner The *root* owner of the token
*/
function ownerOf(uint256 tokenId) external view returns (address owner);
/**
* @notice Used to retrieve the immediate owner of the given token.
* @dev If the immediate owner is another token, the address returned, should be the one of the parent token's
* collection smart contract.
* @param tokenId ID of the token for which the RMRK owner is being retrieved
* @return Address of the given token's owner
* @return The ID of the parent token. Should be `0` if the owner is an externally owned account
* @return The boolean value signifying whether the owner is an NFT or not
*/
function directOwnerOf(
uint256 tokenId
) external view returns (address, uint256, bool);
/**
* @notice Used to burn a given token.
* @dev When a token is burned, all of its child tokens are recursively burned as well.
* @dev When specifying the maximum recursive burns, the execution will be reverted if there are more children to be
* burned.
* @dev Setting the `maxRecursiveBurn` value to 0 will only attempt to burn the specified token and revert if there
* are any child tokens present.
* @dev The approvals are cleared when the token is burned.
* @dev Requirements:
*
* - `tokenId` must exist.
* @dev Emits a {Transfer} event.
* @param tokenId ID of the token to burn
* @param maxRecursiveBurns Maximum number of tokens to recursively burn
* @return Number of recursively burned children
*/
function burn(
uint256 tokenId,
uint256 maxRecursiveBurns
) external returns (uint256);
/**
* @notice Used to add a child token to a given parent token.
* @dev This adds the child token into the given parent token's pending child tokens array.
* @dev Requirements:
*
* - `directOwnerOf` on the child contract must resolve to the called contract.
* - the pending array of the parent contract must not be full.
* @param parentId ID of the parent token to receive the new child token
* @param childId ID of the new proposed child token
* @param data Additional data with no specified format
*/
function addChild(
uint256 parentId,
uint256 childId,
bytes memory data
) external;
/**
* @notice Used to accept a pending child token for a given parent token.
* @dev This moves the child token from parent token's pending child tokens array into the active child tokens
* array.
* @param parentId ID of the parent token for which the child token is being accepted
* @param childIndex Index of a child tokem in the given parent's pending children array
* @param childAddress Address of the collection smart contract of the child token expected to be located at the
* specified index of the given parent token's pending children array
* @param childId ID of the child token expected to be located at the specified index of the given parent token's
* pending children array
*/
function acceptChild(
uint256 parentId,
uint256 childIndex,
address childAddress,
uint256 childId
) external;
/**
* @notice Used to reject all pending children of a given parent token.
* @dev Removes the children from the pending array mapping.
* @dev This does not update the ownership storage data on children. If necessary, ownership can be reclaimed by the
* rootOwner of the previous parent.
* @dev Requirements:
*
* Requirements:
*
* - `parentId` must exist
* @param parentId ID of the parent token for which to reject all of the pending tokens.
* @param maxRejections Maximum number of expected children to reject, used to prevent from rejecting children which
* arrive just before this operation.
*/
function rejectAllChildren(
uint256 parentId,
uint256 maxRejections
) external;
/**
* @notice Used to transfer a child token from a given parent token.
* @dev When transferring a child token, the owner of the token is set to `to`, or is not updated in the event of
* `to` being the `0x0` address.
* @param tokenId ID of the parent token from which the child token is being transferred
* @param to Address to which to transfer the token to
* @param destinationId ID of the token to receive this child token (MUST be 0 if the destination is not a token)
* @param childIndex Index of a token we are transferring, in the array it belongs to (can be either active array or
* pending array)
* @param childAddress Address of the child token's collection smart contract.
* @param childId ID of the child token in its own collection smart contract.
* @param isPending A boolean value indicating whether the child token being transferred is in the pending array of
* the parent token (`true`) or in the active array (`false`)
* @param data Additional data with no specified format, sent in call to `_to`
*/
function transferChild(
uint256 tokenId,
address to,
uint256 destinationId,
uint256 childIndex,
address childAddress,
uint256 childId,
bool isPending,
bytes memory data
) external;
/**
* @notice Used to retrieve the active child tokens of a given parent token.
* @dev Returns array of Child structs existing for parent token.
* @dev The Child struct consists of the following values:
* [
* tokenId,
* contractAddress
* ]
* @param parentId ID of the parent token for which to retrieve the active child tokens
* @return An array of Child structs containing the parent token's active child tokens
*/
function childrenOf(
uint256 parentId
) external view returns (Child[] memory);
/**
* @notice Used to retrieve the pending child tokens of a given parent token.
* @dev Returns array of pending Child structs existing for given parent.
* @dev The Child struct consists of the following values:
* [
* tokenId,
* contractAddress
* ]
* @param parentId ID of the parent token for which to retrieve the pending child tokens
* @return An array of Child structs containing the parent token's pending child tokens
*/
function pendingChildrenOf(
uint256 parentId
) external view returns (Child[] memory);
/**
* @notice Used to retrieve a specific active child token for a given parent token.
* @dev Returns a single Child struct locating at `index` of parent token's active child tokens array.
* @dev The Child struct consists of the following values:
* [
* tokenId,
* contractAddress
* ]
* @param parentId ID of the parent token for which the child is being retrieved
* @param index Index of the child token in the parent token's active child tokens array
* @return A Child struct containing data about the specified child
*/
function childOf(
uint256 parentId,
uint256 index
) external view returns (Child memory);
/**
* @notice Used to retrieve a specific pending child token from a given parent token.
* @dev Returns a single Child struct locating at `index` of parent token's active child tokens array.
* @dev The Child struct consists of the following values:
* [
* tokenId,
* contractAddress
* ]
* @param parentId ID of the parent token for which the pending child token is being retrieved
* @param index Index of the child token in the parent token's pending child tokens array
* @return A Child struct containting data about the specified child
*/
function pendingChildOf(
uint256 parentId,
uint256 index
) external view returns (Child memory);
/**
* @notice Used to transfer the token into another token.
* @param from Address of the direct owner of the token to be transferred
* @param to Address of the receiving token's collection smart contract
* @param tokenId ID of the token being transferred
* @param destinationId ID of the token to receive the token being transferred
* @param data Additional data with no specified format, sent in the addChild call
*/
function nestTransferFrom(
address from,
address to,
uint256 tokenId,
uint256 destinationId,
bytes memory data
) external;
}// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.21;
interface INameChangeTicket {
function balanceOf(address owner) external view returns (uint256);
function useTicket(address owner) external;
}{
"optimizer": {
"enabled": true,
"runs": 200
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"snakeSoldiers","type":"address"},{"internalType":"address","name":"elementGems","type":"address"},{"internalType":"address","name":"skillGems","type":"address"},{"internalType":"address","name":"factionGems","type":"address"},{"internalType":"address","name":"landscapes","type":"address"},{"internalType":"address","name":"attributesRepository","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"CannotChangeName","type":"error"},{"inputs":[],"name":"NameChangeTicketNeeded","type":"error"},{"inputs":[],"name":"NotEnoughFreePoints","type":"error"},{"inputs":[],"name":"NotOwnedSnake","type":"error"},{"inputs":[],"name":"RMRKNewContributorIsZeroAddress","type":"error"},{"inputs":[],"name":"RMRKNewOwnerIsZeroAddress","type":"error"},{"inputs":[],"name":"RMRKNotOwner","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"contributor","type":"address"},{"indexed":false,"internalType":"bool","name":"isContributor","type":"bool"}],"name":"ContributorUpdate","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"},{"inputs":[{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint24","name":"attack","type":"uint24"},{"internalType":"uint24","name":"defense","type":"uint24"},{"internalType":"uint24","name":"health","type":"uint24"},{"internalType":"uint24","name":"stamina","type":"uint24"},{"internalType":"uint24","name":"maxHealth","type":"uint24"},{"internalType":"uint24","name":"maxStamina","type":"uint24"},{"internalType":"uint16","name":"level","type":"uint16"},{"internalType":"uint16","name":"freePoints","type":"uint16"},{"internalType":"uint32","name":"experience","type":"uint32"},{"internalType":"uint32","name":"lastStatsUpdate","type":"uint32"}],"internalType":"struct AttributesManager.BattleStats","name":"stats","type":"tuple"},{"components":[{"internalType":"int16","name":"elementElement","type":"int16"},{"internalType":"uint8","name":"elementSkill","type":"uint8"},{"internalType":"uint8","name":"elementTerritory","type":"uint8"},{"internalType":"uint8","name":"factionTerritory","type":"uint8"},{"internalType":"uint8","name":"forest","type":"uint8"},{"internalType":"uint8","name":"landscape","type":"uint8"}],"internalType":"struct AttributesManager.BattleBoostsPercentage","name":"boosts","type":"tuple"}],"name":"applyBoosts","outputs":[{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint24","name":"attack","type":"uint24"},{"internalType":"uint24","name":"defense","type":"uint24"},{"internalType":"uint24","name":"health","type":"uint24"},{"internalType":"uint24","name":"stamina","type":"uint24"},{"internalType":"uint24","name":"maxHealth","type":"uint24"},{"internalType":"uint24","name":"maxStamina","type":"uint24"},{"internalType":"uint16","name":"level","type":"uint16"},{"internalType":"uint16","name":"freePoints","type":"uint16"},{"internalType":"uint32","name":"experience","type":"uint32"},{"internalType":"uint32","name":"lastStatsUpdate","type":"uint32"}],"internalType":"struct AttributesManager.BattleStats","name":"adjustedStats","type":"tuple"}],"stateMutability":"pure","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint24","name":"attack","type":"uint24"},{"internalType":"uint24","name":"defense","type":"uint24"},{"internalType":"uint24","name":"health","type":"uint24"},{"internalType":"uint24","name":"stamina","type":"uint24"},{"internalType":"uint24","name":"maxHealth","type":"uint24"},{"internalType":"uint24","name":"maxStamina","type":"uint24"},{"internalType":"uint16","name":"level","type":"uint16"},{"internalType":"uint16","name":"freePoints","type":"uint16"},{"internalType":"uint32","name":"experience","type":"uint32"},{"internalType":"uint32","name":"lastStatsUpdate","type":"uint32"}],"internalType":"struct AttributesManager.BattleStats[]","name":"allStats","type":"tuple[]"}],"name":"batchSetStats","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint24","name":"attack","type":"uint24"},{"internalType":"uint24","name":"defense","type":"uint24"},{"internalType":"uint24","name":"health","type":"uint24"},{"internalType":"uint24","name":"stamina","type":"uint24"},{"internalType":"uint24","name":"maxHealth","type":"uint24"},{"internalType":"uint24","name":"maxStamina","type":"uint24"},{"internalType":"uint16","name":"level","type":"uint16"},{"internalType":"uint16","name":"freePoints","type":"uint16"},{"internalType":"uint32","name":"experience","type":"uint32"},{"internalType":"uint32","name":"lastStatsUpdate","type":"uint32"}],"internalType":"struct AttributesManager.BattleStats","name":"challengerStats","type":"tuple"},{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint24","name":"attack","type":"uint24"},{"internalType":"uint24","name":"defense","type":"uint24"},{"internalType":"uint24","name":"health","type":"uint24"},{"internalType":"uint24","name":"stamina","type":"uint24"},{"internalType":"uint24","name":"maxHealth","type":"uint24"},{"internalType":"uint24","name":"maxStamina","type":"uint24"},{"internalType":"uint16","name":"level","type":"uint16"},{"internalType":"uint16","name":"freePoints","type":"uint16"},{"internalType":"uint32","name":"experience","type":"uint32"},{"internalType":"uint32","name":"lastStatsUpdate","type":"uint32"}],"internalType":"struct AttributesManager.BattleStats","name":"challengedStats","type":"tuple"},{"internalType":"enum AttributesManager.Faction","name":"challengeTerritory","type":"uint8"},{"internalType":"bool","name":"challengeDayNight","type":"bool"}],"name":"getAdjustedStatsForBothSnakes","outputs":[{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint24","name":"attack","type":"uint24"},{"internalType":"uint24","name":"defense","type":"uint24"},{"internalType":"uint24","name":"health","type":"uint24"},{"internalType":"uint24","name":"stamina","type":"uint24"},{"internalType":"uint24","name":"maxHealth","type":"uint24"},{"internalType":"uint24","name":"maxStamina","type":"uint24"},{"internalType":"uint16","name":"level","type":"uint16"},{"internalType":"uint16","name":"freePoints","type":"uint16"},{"internalType":"uint32","name":"experience","type":"uint32"},{"internalType":"uint32","name":"lastStatsUpdate","type":"uint32"}],"internalType":"struct AttributesManager.BattleStats","name":"challengerAdjustedStats","type":"tuple"},{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint24","name":"attack","type":"uint24"},{"internalType":"uint24","name":"defense","type":"uint24"},{"internalType":"uint24","name":"health","type":"uint24"},{"internalType":"uint24","name":"stamina","type":"uint24"},{"internalType":"uint24","name":"maxHealth","type":"uint24"},{"internalType":"uint24","name":"maxStamina","type":"uint24"},{"internalType":"uint16","name":"level","type":"uint16"},{"internalType":"uint16","name":"freePoints","type":"uint16"},{"internalType":"uint32","name":"experience","type":"uint32"},{"internalType":"uint32","name":"lastStatsUpdate","type":"uint32"}],"internalType":"struct AttributesManager.BattleStats","name":"challengedAdjustedStats","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"soldierId","type":"uint256"},{"internalType":"enum AttributesManager.Element","name":"enemyElement","type":"uint8"}],"name":"getBoostedStatsForSnake","outputs":[{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint24","name":"attack","type":"uint24"},{"internalType":"uint24","name":"defense","type":"uint24"},{"internalType":"uint24","name":"health","type":"uint24"},{"internalType":"uint24","name":"stamina","type":"uint24"},{"internalType":"uint24","name":"maxHealth","type":"uint24"},{"internalType":"uint24","name":"maxStamina","type":"uint24"},{"internalType":"uint16","name":"level","type":"uint16"},{"internalType":"uint16","name":"freePoints","type":"uint16"},{"internalType":"uint32","name":"experience","type":"uint32"},{"internalType":"uint32","name":"lastStatsUpdate","type":"uint32"}],"internalType":"struct AttributesManager.BattleStats","name":"boostedStats","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBoostsConfig","outputs":[{"internalType":"uint8","name":"landscapeTerritoryBoost","type":"uint8"},{"internalType":"uint8","name":"landscapeDaynightBoost","type":"uint8"},{"internalType":"uint8","name":"elementSkillBoost","type":"uint8"},{"internalType":"uint8","name":"elementTerritoryBoost","type":"uint8"},{"internalType":"uint8","name":"factionTerritoryBoost","type":"uint8"},{"internalType":"uint8","name":"forestBoost","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"soldierId","type":"uint256"},{"internalType":"enum AttributesManager.Element","name":"enemyElement","type":"uint8"}],"name":"getBoostsForSnake","outputs":[{"components":[{"internalType":"int16","name":"elementElement","type":"int16"},{"internalType":"uint8","name":"elementSkill","type":"uint8"},{"internalType":"uint8","name":"elementTerritory","type":"uint8"},{"internalType":"uint8","name":"factionTerritory","type":"uint8"},{"internalType":"uint8","name":"forest","type":"uint8"},{"internalType":"uint8","name":"landscape","type":"uint8"}],"internalType":"struct AttributesManager.BattleBoostsPercentage","name":"boosts","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"enum AttributesManager.Element","name":"element","type":"uint8"},{"internalType":"enum AttributesManager.Faction","name":"faction","type":"uint8"},{"internalType":"enum AttributesManager.Skill","name":"skill","type":"uint8"},{"internalType":"enum AttributesManager.Landscape","name":"landscape","type":"uint8"}],"internalType":"struct AttributesManager.EquippedItems","name":"items","type":"tuple"},{"internalType":"enum AttributesManager.Faction","name":"challengeTerritory","type":"uint8"},{"internalType":"bool","name":"challengeDayNight","type":"bool"},{"internalType":"enum AttributesManager.Element","name":"enemyElement","type":"uint8"}],"name":"getBoostsFromGemsTerritoryAndCelestialPhase","outputs":[{"components":[{"internalType":"int16","name":"elementElement","type":"int16"},{"internalType":"uint8","name":"elementSkill","type":"uint8"},{"internalType":"uint8","name":"elementTerritory","type":"uint8"},{"internalType":"uint8","name":"factionTerritory","type":"uint8"},{"internalType":"uint8","name":"forest","type":"uint8"},{"internalType":"uint8","name":"landscape","type":"uint8"}],"internalType":"struct AttributesManager.BattleBoostsPercentage","name":"boosts","type":"tuple"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getCurrentLandAndDayNight","outputs":[{"internalType":"enum AttributesManager.Faction","name":"currentLand","type":"uint8"},{"internalType":"bool","name":"currentDayNight","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint24","name":"attack","type":"uint24"},{"internalType":"uint24","name":"defense","type":"uint24"},{"internalType":"uint24","name":"health","type":"uint24"},{"internalType":"uint24","name":"stamina","type":"uint24"},{"internalType":"uint24","name":"maxHealth","type":"uint24"},{"internalType":"uint24","name":"maxStamina","type":"uint24"},{"internalType":"uint16","name":"level","type":"uint16"},{"internalType":"uint16","name":"freePoints","type":"uint16"},{"internalType":"uint32","name":"experience","type":"uint32"},{"internalType":"uint32","name":"lastStatsUpdate","type":"uint32"}],"internalType":"struct AttributesManager.BattleStats","name":"stats","type":"tuple"}],"name":"getCurrentStamina","outputs":[{"internalType":"uint24","name":"","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"soldierId","type":"uint256"}],"name":"getCustomName","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"enum AttributesManager.Element","name":"element","type":"uint8"},{"internalType":"enum AttributesManager.Skill","name":"skill","type":"uint8"}],"name":"getElementSkillBoost","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"enum AttributesManager.Element","name":"element","type":"uint8"},{"internalType":"enum AttributesManager.Faction","name":"territory","type":"uint8"}],"name":"getElementTerritoryBoost","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"soldierId","type":"uint256"}],"name":"getEquippedItems","outputs":[{"components":[{"internalType":"enum AttributesManager.Element","name":"element","type":"uint8"},{"internalType":"enum AttributesManager.Faction","name":"faction","type":"uint8"},{"internalType":"enum AttributesManager.Skill","name":"skill","type":"uint8"},{"internalType":"enum AttributesManager.Landscape","name":"landscape","type":"uint8"}],"internalType":"struct AttributesManager.EquippedItems","name":"items","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"enum AttributesManager.Faction","name":"faction","type":"uint8"},{"internalType":"enum AttributesManager.Faction","name":"territory","type":"uint8"}],"name":"getFactionTerritoryBoost","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"enum AttributesManager.Element","name":"elementA","type":"uint8"},{"internalType":"enum AttributesManager.Element","name":"elementB","type":"uint8"}],"name":"getFightingElementsBoost","outputs":[{"internalType":"int16","name":"","type":"int16"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"enum AttributesManager.Faction","name":"faction","type":"uint8"}],"name":"getForestBoost","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"enum AttributesManager.Landscape","name":"landscape","type":"uint8"},{"internalType":"enum AttributesManager.Faction","name":"challengeTerritory","type":"uint8"},{"internalType":"bool","name":"challengeDayNight","type":"bool"}],"name":"getLandscapeBoost","outputs":[{"internalType":"uint8","name":"boost","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"soldierId","type":"uint256"}],"name":"getStats","outputs":[{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint24","name":"attack","type":"uint24"},{"internalType":"uint24","name":"defense","type":"uint24"},{"internalType":"uint24","name":"health","type":"uint24"},{"internalType":"uint24","name":"stamina","type":"uint24"},{"internalType":"uint24","name":"maxHealth","type":"uint24"},{"internalType":"uint24","name":"maxStamina","type":"uint24"},{"internalType":"uint16","name":"level","type":"uint16"},{"internalType":"uint16","name":"freePoints","type":"uint16"},{"internalType":"uint32","name":"experience","type":"uint32"},{"internalType":"uint32","name":"lastStatsUpdate","type":"uint32"}],"internalType":"struct AttributesManager.BattleStats","name":"stats","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"contributor","type":"address"}],"name":"isContributor","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"contributor","type":"address"},{"internalType":"bool","name":"grantRole","type":"bool"}],"name":"manageContributor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"landscapeTerritoryBoost","type":"uint8"},{"internalType":"uint8","name":"landscapeDaynightBoost","type":"uint8"},{"internalType":"uint8","name":"elementSkillBoost","type":"uint8"},{"internalType":"uint8","name":"elementTerritoryBoost","type":"uint8"},{"internalType":"uint8","name":"factionTerritoryBoost","type":"uint8"},{"internalType":"uint8","name":"forestBoost","type":"uint8"}],"name":"setBoostsConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"soldierId","type":"uint256"},{"internalType":"string","name":"name","type":"string"}],"name":"setCustomName","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"nameChangeTicket","type":"address"}],"name":"setNameChangeTicketAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"soldierId","type":"uint256"},{"internalType":"uint24","name":"attack","type":"uint24"},{"internalType":"uint24","name":"defense","type":"uint24"},{"internalType":"uint24","name":"maxHealth","type":"uint24"},{"internalType":"uint24","name":"maxStamina","type":"uint24"}],"name":"useFreePoints","outputs":[{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint24","name":"attack","type":"uint24"},{"internalType":"uint24","name":"defense","type":"uint24"},{"internalType":"uint24","name":"health","type":"uint24"},{"internalType":"uint24","name":"stamina","type":"uint24"},{"internalType":"uint24","name":"maxHealth","type":"uint24"},{"internalType":"uint24","name":"maxStamina","type":"uint24"},{"internalType":"uint16","name":"level","type":"uint16"},{"internalType":"uint16","name":"freePoints","type":"uint16"},{"internalType":"uint32","name":"experience","type":"uint32"},{"internalType":"uint32","name":"lastStatsUpdate","type":"uint32"}],"internalType":"struct AttributesManager.BattleStats","name":"stats","type":"tuple"}],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
6080604052600280556003805465ffffffffffff1916650a0a0a0a05051790553480156200002b575f80fd5b5060405162002e1c38038062002e1c8339810160408190526200004e9162000149565b6200005933620000de565b600380546001600160a01b03978816660100000000000002600160301b600160d01b0319909116179055600480549587166001600160a01b0319968716179055600580549487169486169490941790935560068054928616928516929092179091556007805491851691841691909117905560098054919093169116179055620001c6565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b80516001600160a01b038116811462000144575f80fd5b919050565b5f805f805f8060c087890312156200015f575f80fd5b6200016a876200012d565b95506200017a602088016200012d565b94506200018a604088016200012d565b93506200019a606088016200012d565b9250620001aa608088016200012d565b9150620001ba60a088016200012d565b90509295509295509295565b612c4880620001d45f395ff3fe608060405234801561000f575f80fd5b50600436106101a1575f3560e01c8063766d8019116100f3578063d8e7c8e311610093578063e2994ae21161006e578063e2994ae214610490578063e3633c94146104a3578063f2fde38b146104c9578063f682133b146104dc575f80fd5b8063d8e7c8e31461044a578063ddfbf2321461045d578063e1cb414814610470575f80fd5b80637bf8d90f116100ce5780637bf8d90f146103e95780638da5cb5b146103fc5780638f37df7d14610416578063beb738a314610429575f80fd5b8063766d8019146103b057806379e8ca9e146103c35780637b303965146103d6575f80fd5b80633440c75d1161015e5780636e40c757116101395780636e40c75714610321578063715018a614610334578063726c6d9a1461033c57806372a55c2d1461039a575f80fd5b80633440c75d146102d957806343d2cbcb146102f95780635f54092d1461030e575f80fd5b80630e4fc78a146101a55780631399e9791461021e578063193ec777146102315780631cb238b5146102565780631d0d35f51461027d578063228c1eeb146102b9575b5f80fd5b6101b86101b3366004611eb1565b6104ef565b60405161021591905f60c082019050825160010b825260ff602084015116602083015260ff604084015116604083015260ff606084015116606083015260ff608084015116608083015260ff60a08401511660a083015292915050565b60405180910390f35b6101b861022c366004611fb9565b61054f565b61024461023f36600461207b565b61060a565b60405160ff9091168152602001610215565b61026961026436600461219c565b610638565b60405162ffffff9091168152602001610215565b6102a961028b3660046121cb565b6001600160a01b03165f908152600160208190526040909120541490565b6040519015158152602001610215565b6102cc6102c73660046121e6565b6106cb565b6040516102159190612316565b6102ec6102e7366004612325565b6107bd565b6040516102159190612389565b61030c6103073660046123c1565b61085e565b005b61024461031c366004612444565b610a14565b6102cc61032f366004612487565b610a6e565b61030c610b6e565b6003546040805160ff80841682526101008404811660208301526201000084048116928201929092526301000000830482166060820152640100000000830482166080820152650100000000009092041660a082015260c001610215565b6103a2610b81565b604051610215929190612564565b6102446103be366004612581565b610bcd565b61030c6103d136600461259b565b610c0e565b6102cc6103e4366004612325565b610cc9565b61030c6103f73660046125c7565b610e10565b5f546040516001600160a01b039091168152602001610215565b6102cc610424366004611eb1565b610e98565b61043c610437366004612637565b610eeb565b604051610215929190612685565b61030c6104583660046126c4565b610f62565b61024461046b366004612759565b610fa4565b61048361047e366004612325565b6113ea565b60405161021591906127ad565b61030c61049e3660046121cb565b611798565b6104b66104b1366004612809565b6117c2565b60405160019190910b8152602001610215565b61030c6104d73660046121cb565b611adc565b6102446104ea366004612809565b611b17565b6040805160c0810182525f80825260208201819052918101829052606081018290526080810182905260a0810182905290610529846113ea565b90505f80610535610b81565b915091506105458383838861054f565b9695505050505050565b6040805160c0810182525f80825260208201819052818301819052606082018190526080820181905260a0820152855191860151909161058e91611b17565b60ff166020808301919091528501516105a79085610bcd565b60ff16606082015284516105bb9085610a14565b60ff16604082015260208501516105d19061060a565b60ff16608082015284516105e590836117c2565b60010b815260608501516105fa908585610fa4565b60ff1660a0820152949350505050565b5f600482600581111561061f5761061f61253c565b0361062c5750600a919050565b505f919050565b919050565b5f81610140015163ffffffff165f03610653575060c0015190565b5f600254610e1084610140015163ffffffff16426106719190612849565b61067b9190612870565b6106859190612883565b90508260c0015162ffffff168360800151826106a1919061289a565b62ffffff1611156106b557505060c0015190565b60808301516106c4908261289a565b9392505050565b6106d3611e4a565b856106dd81611b51565b6106e687610cc9565b91505f83856106f5888a61289a565b6106ff919061289a565b610709919061289a565b905082610100015161ffff168162ffffff16111561073a576040516336fbeeab60e21b815260040160405180910390fd5b868360200181815161074c919061289a565b62ffffff1690525060408301805187919061076890839061289a565b62ffffff1690525060a08301805186919061078490839061289a565b62ffffff1690525060c0830180518591906107a090839061289a565b62ffffff169052506107b2835f611bee565b505095945050505050565b6009546003546040805180820182526004808252634e414d4560e01b60208301529151632c6bd61b60e11b81526060946001600160a01b03908116946358d7ac369461081794600160301b909204909216928892016128bd565b5f60405180830381865afa158015610831573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f1916820160405261085891908101906128ec565b92915050565b8161086881611b51565b5f610872846107bd565b805190915015610986576008546001600160a01b03166108a457604051625e364b60e11b815260040160405180910390fd5b6008546040516370a0823160e01b81523360048201526001600160a01b03909116906370a0823190602401602060405180830381865afa1580156108ea573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061090e9190612954565b5f0361092d57604051639e28e8df60e01b815260040160405180910390fd5b600854604051631a1760c960e31b81523360048201526001600160a01b039091169063d0bb0648906024015f604051808303815f87803b15801561096f575f80fd5b505af1158015610981573d5f803e3d5ffd5b505050505b6009546003546040805180820182526004808252634e414d4560e01b6020830152915163cedb3f8960e01b81526001600160a01b039485169463cedb3f89946109e194600160301b909104909116928a9290918a910161296b565b5f604051808303815f87803b1580156109f8575f80fd5b505af1158015610a0a573d5f803e3d5ffd5b5050505050505050565b5f816005811115610a2757610a2761253c565b836004811115610a3957610a3961253c565b148015610a59575060045b836004811115610a5657610a5661253c565b14155b15610a665750600a610858565b505f92915050565b610a76611e4a565b50805182905f90610a889060646129ae565b61ffff1690505f836080015160ff168460a0015160ff16856040015160ff16866020015160ff1685610aba91906129d1565b610ac491906129d1565b610ace91906129d1565b610ad891906129d1565b90505f84608001518560a0015186606001516064610af691906129e4565b610b0091906129e4565b610b0a91906129e4565b60ff169050606482876020015162ffffff16610b269190612883565b610b309190612870565b62ffffff90811660208601526040870151606491610b5091849116612883565b610b5a9190612870565b62ffffff1660408501525091949350505050565b610b76611db4565b610b7f5f611dde565b565b5f806002610b9161546042612870565b610b9b91906129fd565b1590506005610bac61a8c042612870565b610bb691906129fd565b6005811115610bc757610bc761253c565b91509091565b5f816005811115610be057610be061253c565b836005811115610bf257610bf261253c565b148015610a5957506005836005811115610a5657610a5661253c565b610c16611db4565b6001600160a01b038216610c3d5760405163016b812760e71b815260040160405180910390fd5b80610c61576001600160a01b0382165f908152600160205260408120819055610c7f565b6001600160a01b0382165f9081526001602081905260409091208190555b50816001600160a01b03167f4b5657e84cf8a17ac5587bbeb3cc2bab9826c4c67b8bad81b4849de49d37aac282604051610cbd911515815260200190565b60405180910390a25050565b610cd1611e4a565b6009546003546040805180820182526005815264535441545360d81b60208201529051631b8bfea360e01b81525f936001600160a01b0390811693631b8bfea393610d2c93600160301b9092049092169188916004016128bd565b602060405180830381865afa158015610d47573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d6b9190612954565b83835262ffffff8082166020850152601882901c81166040850152603082901c8116606080860191909152604883901c8216608086015282901c811660a080860191909152607883901c90911660c085015261ffff609083901c811660e08601529082901c1661010084015263ffffffff60b082901c811661012085015260d082901c166101408401529050610e0082610638565b62ffffff16608083015250919050565b610e18611db4565b6003805460ff928316650100000000000265ff000000000019948416640100000000029490941665ffff000000001995841663010000000263ff0000001997851662010000029790971663ffff0000199885166101000261ffff199093169490991693909317179590951695909517929092171692909217919091179055565b610ea0611e4a565b5f610eaa84610cc9565b90505f610eb6856113ea565b90505f80610ec2610b81565b915091505f610ed38484848a61054f565b9050610edf8582610a6e565b98975050505050505050565b610ef3611e4a565b610efb611e4a565b5f610f08875f01516113ea565b90505f610f17875f01516113ea565b90505f610f29838888855f015161054f565b90505f610f3b838989875f015161054f565b9050610f478a83610a6e565b9550610f538982610a6e565b94505050505094509492505050565b610f6a611db4565b5f5b8151811015610fa057610f98828281518110610f8a57610f8a612a10565b60200260200101515f611bee565b600101610f6c565b5050565b5f80836005811115610fb857610fb861253c565b14801561100d5750600484600f811115610fd457610fd461253c565b1480610ff15750600584600f811115610fef57610fef61253c565b145b8061100d5750600684600f81111561100b5761100b61253c565b145b156110245761101d6005826129e4565b905061120b565b60048360058111156110385761103861253c565b14801561108d5750600d84600f8111156110545761105461253c565b14806110715750600e84600f81111561106f5761106f61253c565b145b8061108d5750600f84600f81111561108b5761108b61253c565b145b1561109d5761101d6005826129e4565b60028360058111156110b1576110b161253c565b1480156111065750600184600f8111156110cd576110cd61253c565b14806110ea5750600284600f8111156110e8576110e861253c565b145b806111065750600384600f8111156111045761110461253c565b145b156111165761101d6005826129e4565b600183600581111561112a5761112a61253c565b14801561117f5750600a84600f8111156111465761114661253c565b14806111635750600b84600f8111156111615761116161253c565b145b8061117f5750600c84600f81111561117d5761117d61253c565b145b1561118f5761101d6005826129e4565b60038360058111156111a3576111a361253c565b1480156111f85750600784600f8111156111bf576111bf61253c565b14806111dc5750600884600f8111156111da576111da61253c565b145b806111f85750600984600f8111156111f6576111f661253c565b145b1561120b576112086005826129e4565b90505b600684600f81111561121f5761121f61253c565b148061123c5750600f84600f81111561123a5761123a61253c565b145b806112585750600384600f8111156112565761125661253c565b145b806112745750600c84600f8111156112725761127261253c565b145b806112905750600984600f81111561128e5761128e61253c565b145b156112a7576112a06005826129e4565b90506106c4565b8180156113345750600484600f8111156112c3576112c361253c565b14806112e05750600d84600f8111156112de576112de61253c565b145b806112fc5750600184600f8111156112fa576112fa61253c565b145b806113185750600a84600f8111156113165761131661253c565b145b806113345750600784600f8111156113325761133261253c565b145b15611344576112a06005826129e4565b811580156113d25750600584600f8111156113615761136161253c565b148061137e5750600e84600f81111561137c5761137c61253c565b145b8061139a5750600284600f8111156113985761139861253c565b145b806113b65750600b84600f8111156113b4576113b461253c565b145b806113d25750600884600f8111156113d0576113d061253c565b145b156106c4576113e26005826129e4565b949350505050565b6114116040805160808101909152805f81526020015f81526020015f81526020015f905290565b600354604051631bc6654760e21b8152600481018490525f91600160301b90046001600160a01b031690636f19951c906024015f60405180830381865afa15801561145e573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526114859190810190612a24565b80519091505f5b81811015611790575f8382815181106114a7576114a7612a10565b60209081029190910181015160035491810151815160405163ee1dffcf60e01b8152600481018b90526001600160a01b0392831660248201526044810191909152919350600160301b9092049091169063ee1dffcf90606401602060405180830381865afa15801561151b573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061153f9190612ad2565b156117875760045460208201516001600160a01b039182169116036115ab57805161156c906004906129fd565b600481111561157d5761157d61253c565b859060048111156115905761159061253c565b908160048111156115a3576115a361253c565b905250611787565b60055460208201516001600160a01b0391821691160361161f57805160c810156116115780516002906115e0906008906129fd565b6115ea9190612870565b60048111156115fb576115fb61253c565b856040019060048111156115905761159061253c565b80516115ea906004906129fd565b60065460208201516001600160a01b039182169116036116995780516014101561168b578051611651906005906129fd565b60058111156116625761166261253c565b856020019060058111156116785761167861253c565b908160058111156115a3576115a361253c565b8051611651906004906129fd565b60075460208201516001600160a01b03918216911603611787576007548151604051633940140f60e11b815260048101919091525f916001600160a01b031690637280281e906024015f60405180830381865afa1580156116fc573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526117239190810190612aed565b9050805f8151811061173757611737612a10565b60200260200101516001600160401b0316600f8111156117595761175961253c565b8660600190600f81111561176f5761176f61253c565b9081600f8111156117825761178261253c565b905250505b5060010161148c565b505050919050565b6117a0611db4565b600880546001600160a01b0319166001600160a01b0392909216919091179055565b5f60048260048111156117d7576117d761253c565b036117e357505f610858565b5f8360048111156117f6576117f661253c565b148015611814575060038260048111156118125761181261253c565b145b156118215750601e610858565b5f8360048111156118345761183461253c565b148015611852575060018260048111156118505761185061253c565b145b156118605750600419610858565b5f8360048111156118735761187361253c565b1480156118915750600282600481111561188f5761188f61253c565b145b1561189d57505f610858565b60038360048111156118b1576118b161253c565b1480156118ce57505f8260048111156118cc576118cc61253c565b145b156118dc5750600919610858565b60038360048111156118f0576118f061253c565b14801561190e5750600182600481111561190c5761190c61253c565b145b1561191b57506019610858565b600383600481111561192f5761192f61253c565b14801561194d5750600282600481111561194b5761194b61253c565b145b1561195957505f610858565b600183600481111561196d5761196d61253c565b14801561198a57505f8260048111156119885761198861253c565b145b156119975750600a610858565b60018360048111156119ab576119ab61253c565b1480156119c9575060038260048111156119c7576119c761253c565b145b156119d75750601319610858565b60018360048111156119eb576119eb61253c565b148015611a0957506002826004811115611a0757611a0761253c565b145b15611a1657506014610858565b6002836004811115611a2a57611a2a61253c565b148015611a4757505f826004811115611a4557611a4561253c565b145b15611a5457506019610858565b6002836004811115611a6857611a6861253c565b148015611a8657506003826004811115611a8457611a8461253c565b145b15611a9357506005610858565b6002836004811115611aa757611aa761253c565b148015611ac557506001826004811115611ac357611ac361253c565b145b15611ad35750600919610858565b50601319610858565b611ae4611db4565b6001600160a01b038116611b0b57604051634ece6ecf60e01b815260040160405180910390fd5b611b1481611dde565b50565b5f816004811115611b2a57611b2a61253c565b60ff16836004811115611b3f57611b3f61253c565b60ff16148015610a5957506004610a44565b6003546040516331a9108f60e11b8152600481018390525f91600160301b90046001600160a01b031690636352211e90602401602060405180830381865afa158015611b9f573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611bc39190612b7f565b90506001600160a01b0381163314610fa0576040516334a50d8b60e21b815260040160405180910390fd5b8015611c695761012082015160e083015163ffffffff90911690611c13816001612b9a565b611c1d9190612bb5565b61ffff161115611c695760018260e001818151611c3a9190612b9a565b61ffff1690525060e0820151611c4f90611e2d565b8261010001818151611c619190612b9a565b61ffff169052505b6009546003548351604080518082019091526005815264535441545360d81b60208201526001600160a01b039384169363ed20867293600160301b9004169190611d64875f816020015162ffffff1690506018826040015162ffffff16901b811790506030826060015162ffffff16901b811790506048826080015162ffffff16901b8117905060608260a0015162ffffff16901b8117905060788260c0015162ffffff16901b8117905060908260e0015161ffff16901b8117905060a082610100015161ffff16901b8117905060b082610120015163ffffffff16901b8117905060d082610140015163ffffffff16901b81179050919050565b6040518563ffffffff1660e01b8152600401611d839493929190612bdb565b5f604051808303815f87803b158015611d9a575f80fd5b505af1158015611dac573d5f803e3d5ffd5b505050505050565b5f546001600160a01b03163314610b7f57604051631c62d58f60e11b815260040160405180910390fd5b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b5f5b61ffff8216156106335761ffff909116801c90600101611e2f565b60408051610160810182525f80825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081019190915290565b60058110611b14575f80fd5b5f8060408385031215611ec2575f80fd5b823591506020830135611ed481611ea5565b809150509250929050565b634e487b7160e01b5f52604160045260245ffd5b60405161016081016001600160401b0381118282101715611f1657611f16611edf565b60405290565b60405160c081016001600160401b0381118282101715611f1657611f16611edf565b604080519081016001600160401b0381118282101715611f1657611f16611edf565b604051601f8201601f191681016001600160401b0381118282101715611f8857611f88611edf565b604052919050565b803560068110610633575f80fd5b803560108110610633575f80fd5b8015158114611b14575f80fd5b5f805f8084860360e0811215611fcd575f80fd5b6080811215611fda575f80fd5b50604051608081018181106001600160401b0382111715611ffd57611ffd611edf565b604052853561200b81611ea5565b815261201960208701611f90565b6020820152604086013561202c81611ea5565b604082015261203d60608701611f9e565b6060820152935061205060808601611f90565b925060a085013561206081611fac565b915060c085013561207081611ea5565b939692955090935050565b5f6020828403121561208b575f80fd5b6106c482611f90565b803562ffffff81168114610633575f80fd5b803561ffff81168114610633575f80fd5b803563ffffffff81168114610633575f80fd5b5f61016082840312156120db575f80fd5b6120e3611ef3565b9050813581526120f560208301612094565b602082015261210660408301612094565b604082015261211760608301612094565b606082015261212860808301612094565b608082015261213960a08301612094565b60a082015261214a60c08301612094565b60c082015261215b60e083016120a6565b60e082015261010061216e8184016120a6565b908201526101206121808382016120b7565b908201526101406121928382016120b7565b9082015292915050565b5f61016082840312156121ad575f80fd5b6106c483836120ca565b6001600160a01b0381168114611b14575f80fd5b5f602082840312156121db575f80fd5b81356106c4816121b7565b5f805f805f60a086880312156121fa575f80fd5b8535945061220a60208701612094565b935061221860408701612094565b925061222660608701612094565b915061223460808701612094565b90509295509295909350565b80518252602081015161225a602084018262ffffff169052565b506040810151612271604084018262ffffff169052565b506060810151612288606084018262ffffff169052565b50608081015161229f608084018262ffffff169052565b5060a08101516122b660a084018262ffffff169052565b5060c08101516122cd60c084018262ffffff169052565b5060e08101516122e360e084018261ffff169052565b506101008181015161ffff16908301526101208082015163ffffffff908116918401919091526101409182015116910152565b61016081016108588284612240565b5f60208284031215612335575f80fd5b5035919050565b5f5b8381101561235657818101518382015260200161233e565b50505f910152565b5f815180845261237581602086016020860161233c565b601f01601f19169290920160200192915050565b602081525f6106c4602083018461235e565b5f6001600160401b038211156123b3576123b3611edf565b50601f01601f191660200190565b5f80604083850312156123d2575f80fd5b8235915060208301356001600160401b038111156123ee575f80fd5b8301601f810185136123fe575f80fd5b803561241161240c8261239b565b611f60565b818152866020838501011115612425575f80fd5b816020840160208301375f602083830101528093505050509250929050565b5f8060408385031215612455575f80fd5b823561246081611ea5565b915061246e60208401611f90565b90509250929050565b803560ff81168114610633575f80fd5b5f8082840361022081121561249a575f80fd5b6124a485856120ca565b925060c061015f19820112156124b8575f80fd5b506124c1611f1c565b6101608401358060010b81146124d5575f80fd5b81526124e46101808501612477565b60208201526124f66101a08501612477565b60408201526125086101c08501612477565b606082015261251a6101e08501612477565b608082015261252c6102008501612477565b60a0820152809150509250929050565b634e487b7160e01b5f52602160045260245ffd5b600681106125605761256061253c565b9052565b604081016125728285612550565b82151560208301529392505050565b5f8060408385031215612592575f80fd5b61246083611f90565b5f80604083850312156125ac575f80fd5b82356125b7816121b7565b91506020830135611ed481611fac565b5f805f805f8060c087890312156125dc575f80fd5b6125e587612477565b95506125f360208801612477565b945061260160408801612477565b935061260f60608801612477565b925061261d60808801612477565b915061262b60a08801612477565b90509295509295509295565b5f805f80610300858703121561264b575f80fd5b61265586866120ca565b93506126658661016087016120ca565b92506126746102c08601611f90565b91506102e085013561207081611fac565b6102c081016126948285612240565b6106c4610160830184612240565b5f6001600160401b038211156126ba576126ba611edf565b5060051b60200190565b5f60208083850312156126d5575f80fd5b82356001600160401b038111156126ea575f80fd5b8301601f810185136126fa575f80fd5b803561270861240c826126a2565b8181526101609182028301840191848201919088841115612727575f80fd5b938501935b8385101561274d5761273e89866120ca565b8352938401939185019161272c565b50979650505050505050565b5f805f6060848603121561276b575f80fd5b61277484611f9e565b925061278260208501611f90565b9150604084013561279281611fac565b809150509250925092565b60058110611b1457611b1461253c565b815160808201906127bd8161279d565b8083525060208301516127d36020840182612550565b5060408301516127e28161279d565b60408301526060830151601081106127fc576127fc61253c565b8060608401525092915050565b5f806040838503121561281a575f80fd5b823561282581611ea5565b91506020830135611ed481611ea5565b634e487b7160e01b5f52601160045260245ffd5b8181038181111561085857610858612835565b634e487b7160e01b5f52601260045260245ffd5b5f8261287e5761287e61285c565b500490565b808202811582820484141761085857610858612835565b62ffffff8181168382160190808211156128b6576128b6612835565b5092915050565b60018060a01b0384168152826020820152606060408201525f6128e3606083018461235e565b95945050505050565b5f602082840312156128fc575f80fd5b81516001600160401b03811115612911575f80fd5b8201601f81018413612921575f80fd5b805161292f61240c8261239b565b818152856020838501011115612943575f80fd5b6128e382602083016020860161233c565b5f60208284031215612964575f80fd5b5051919050565b60018060a01b0385168152836020820152608060408201525f612991608083018561235e565b82810360608401526129a3818561235e565b979650505050505050565b600181810b9083900b01617fff8113617fff198212171561085857610858612835565b8082018082111561085857610858612835565b60ff818116838216019081111561085857610858612835565b5f82612a0b57612a0b61285c565b500690565b634e487b7160e01b5f52603260045260245ffd5b5f6020808385031215612a35575f80fd5b82516001600160401b03811115612a4a575f80fd5b8301601f81018513612a5a575f80fd5b8051612a6861240c826126a2565b81815260069190911b82018301908381019087831115612a86575f80fd5b928401925b828410156129a35760408489031215612aa3575f8081fd5b612aab611f3e565b8451815285850151612abc816121b7565b8187015282526040939093019290840190612a8b565b5f60208284031215612ae2575f80fd5b81516106c481611fac565b5f6020808385031215612afe575f80fd5b82516001600160401b0380821115612b14575f80fd5b818501915085601f830112612b27575f80fd5b8151612b3561240c826126a2565b81815260059190911b83018401908481019088831115612b53575f80fd5b938501935b82851015610edf5784518481168114612b70575f8081fd5b82529385019390850190612b58565b5f60208284031215612b8f575f80fd5b81516106c4816121b7565b61ffff8181168382160190808211156128b6576128b6612835565b61ffff818116838216028082169190828114612bd357612bd3612835565b505092915050565b60018060a01b0385168152836020820152608060408201525f612c01608083018561235e565b90508260608301529594505050505056fea2646970667358221220bb4edadb5a97706c5cf4c36da78838cb7ae3af21f694b234a6241136da6f0cc064736f6c634300081500330000000000000000000000008f64ce931f0d36430b971548b81264eef3bd9b97000000000000000000000000a5b355125a2b7fd4c7a451c37b87e81b965a96b10000000000000000000000009e5babfad9a1a980b58db60585408735562b721e0000000000000000000000003f563d6d8e62405d01dc8a4e1dfb269f23aab1620000000000000000000000008e8e3ab3bfabb86b37f91b2f2ca83969ac2c0fad000000000000000000000000873526404f04d88bf7b4a8598b00a766a3393128
Deployed Bytecode
0x608060405234801561000f575f80fd5b50600436106101a1575f3560e01c8063766d8019116100f3578063d8e7c8e311610093578063e2994ae21161006e578063e2994ae214610490578063e3633c94146104a3578063f2fde38b146104c9578063f682133b146104dc575f80fd5b8063d8e7c8e31461044a578063ddfbf2321461045d578063e1cb414814610470575f80fd5b80637bf8d90f116100ce5780637bf8d90f146103e95780638da5cb5b146103fc5780638f37df7d14610416578063beb738a314610429575f80fd5b8063766d8019146103b057806379e8ca9e146103c35780637b303965146103d6575f80fd5b80633440c75d1161015e5780636e40c757116101395780636e40c75714610321578063715018a614610334578063726c6d9a1461033c57806372a55c2d1461039a575f80fd5b80633440c75d146102d957806343d2cbcb146102f95780635f54092d1461030e575f80fd5b80630e4fc78a146101a55780631399e9791461021e578063193ec777146102315780631cb238b5146102565780631d0d35f51461027d578063228c1eeb146102b9575b5f80fd5b6101b86101b3366004611eb1565b6104ef565b60405161021591905f60c082019050825160010b825260ff602084015116602083015260ff604084015116604083015260ff606084015116606083015260ff608084015116608083015260ff60a08401511660a083015292915050565b60405180910390f35b6101b861022c366004611fb9565b61054f565b61024461023f36600461207b565b61060a565b60405160ff9091168152602001610215565b61026961026436600461219c565b610638565b60405162ffffff9091168152602001610215565b6102a961028b3660046121cb565b6001600160a01b03165f908152600160208190526040909120541490565b6040519015158152602001610215565b6102cc6102c73660046121e6565b6106cb565b6040516102159190612316565b6102ec6102e7366004612325565b6107bd565b6040516102159190612389565b61030c6103073660046123c1565b61085e565b005b61024461031c366004612444565b610a14565b6102cc61032f366004612487565b610a6e565b61030c610b6e565b6003546040805160ff80841682526101008404811660208301526201000084048116928201929092526301000000830482166060820152640100000000830482166080820152650100000000009092041660a082015260c001610215565b6103a2610b81565b604051610215929190612564565b6102446103be366004612581565b610bcd565b61030c6103d136600461259b565b610c0e565b6102cc6103e4366004612325565b610cc9565b61030c6103f73660046125c7565b610e10565b5f546040516001600160a01b039091168152602001610215565b6102cc610424366004611eb1565b610e98565b61043c610437366004612637565b610eeb565b604051610215929190612685565b61030c6104583660046126c4565b610f62565b61024461046b366004612759565b610fa4565b61048361047e366004612325565b6113ea565b60405161021591906127ad565b61030c61049e3660046121cb565b611798565b6104b66104b1366004612809565b6117c2565b60405160019190910b8152602001610215565b61030c6104d73660046121cb565b611adc565b6102446104ea366004612809565b611b17565b6040805160c0810182525f80825260208201819052918101829052606081018290526080810182905260a0810182905290610529846113ea565b90505f80610535610b81565b915091506105458383838861054f565b9695505050505050565b6040805160c0810182525f80825260208201819052818301819052606082018190526080820181905260a0820152855191860151909161058e91611b17565b60ff166020808301919091528501516105a79085610bcd565b60ff16606082015284516105bb9085610a14565b60ff16604082015260208501516105d19061060a565b60ff16608082015284516105e590836117c2565b60010b815260608501516105fa908585610fa4565b60ff1660a0820152949350505050565b5f600482600581111561061f5761061f61253c565b0361062c5750600a919050565b505f919050565b919050565b5f81610140015163ffffffff165f03610653575060c0015190565b5f600254610e1084610140015163ffffffff16426106719190612849565b61067b9190612870565b6106859190612883565b90508260c0015162ffffff168360800151826106a1919061289a565b62ffffff1611156106b557505060c0015190565b60808301516106c4908261289a565b9392505050565b6106d3611e4a565b856106dd81611b51565b6106e687610cc9565b91505f83856106f5888a61289a565b6106ff919061289a565b610709919061289a565b905082610100015161ffff168162ffffff16111561073a576040516336fbeeab60e21b815260040160405180910390fd5b868360200181815161074c919061289a565b62ffffff1690525060408301805187919061076890839061289a565b62ffffff1690525060a08301805186919061078490839061289a565b62ffffff1690525060c0830180518591906107a090839061289a565b62ffffff169052506107b2835f611bee565b505095945050505050565b6009546003546040805180820182526004808252634e414d4560e01b60208301529151632c6bd61b60e11b81526060946001600160a01b03908116946358d7ac369461081794600160301b909204909216928892016128bd565b5f60405180830381865afa158015610831573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f1916820160405261085891908101906128ec565b92915050565b8161086881611b51565b5f610872846107bd565b805190915015610986576008546001600160a01b03166108a457604051625e364b60e11b815260040160405180910390fd5b6008546040516370a0823160e01b81523360048201526001600160a01b03909116906370a0823190602401602060405180830381865afa1580156108ea573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061090e9190612954565b5f0361092d57604051639e28e8df60e01b815260040160405180910390fd5b600854604051631a1760c960e31b81523360048201526001600160a01b039091169063d0bb0648906024015f604051808303815f87803b15801561096f575f80fd5b505af1158015610981573d5f803e3d5ffd5b505050505b6009546003546040805180820182526004808252634e414d4560e01b6020830152915163cedb3f8960e01b81526001600160a01b039485169463cedb3f89946109e194600160301b909104909116928a9290918a910161296b565b5f604051808303815f87803b1580156109f8575f80fd5b505af1158015610a0a573d5f803e3d5ffd5b5050505050505050565b5f816005811115610a2757610a2761253c565b836004811115610a3957610a3961253c565b148015610a59575060045b836004811115610a5657610a5661253c565b14155b15610a665750600a610858565b505f92915050565b610a76611e4a565b50805182905f90610a889060646129ae565b61ffff1690505f836080015160ff168460a0015160ff16856040015160ff16866020015160ff1685610aba91906129d1565b610ac491906129d1565b610ace91906129d1565b610ad891906129d1565b90505f84608001518560a0015186606001516064610af691906129e4565b610b0091906129e4565b610b0a91906129e4565b60ff169050606482876020015162ffffff16610b269190612883565b610b309190612870565b62ffffff90811660208601526040870151606491610b5091849116612883565b610b5a9190612870565b62ffffff1660408501525091949350505050565b610b76611db4565b610b7f5f611dde565b565b5f806002610b9161546042612870565b610b9b91906129fd565b1590506005610bac61a8c042612870565b610bb691906129fd565b6005811115610bc757610bc761253c565b91509091565b5f816005811115610be057610be061253c565b836005811115610bf257610bf261253c565b148015610a5957506005836005811115610a5657610a5661253c565b610c16611db4565b6001600160a01b038216610c3d5760405163016b812760e71b815260040160405180910390fd5b80610c61576001600160a01b0382165f908152600160205260408120819055610c7f565b6001600160a01b0382165f9081526001602081905260409091208190555b50816001600160a01b03167f4b5657e84cf8a17ac5587bbeb3cc2bab9826c4c67b8bad81b4849de49d37aac282604051610cbd911515815260200190565b60405180910390a25050565b610cd1611e4a565b6009546003546040805180820182526005815264535441545360d81b60208201529051631b8bfea360e01b81525f936001600160a01b0390811693631b8bfea393610d2c93600160301b9092049092169188916004016128bd565b602060405180830381865afa158015610d47573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d6b9190612954565b83835262ffffff8082166020850152601882901c81166040850152603082901c8116606080860191909152604883901c8216608086015282901c811660a080860191909152607883901c90911660c085015261ffff609083901c811660e08601529082901c1661010084015263ffffffff60b082901c811661012085015260d082901c166101408401529050610e0082610638565b62ffffff16608083015250919050565b610e18611db4565b6003805460ff928316650100000000000265ff000000000019948416640100000000029490941665ffff000000001995841663010000000263ff0000001997851662010000029790971663ffff0000199885166101000261ffff199093169490991693909317179590951695909517929092171692909217919091179055565b610ea0611e4a565b5f610eaa84610cc9565b90505f610eb6856113ea565b90505f80610ec2610b81565b915091505f610ed38484848a61054f565b9050610edf8582610a6e565b98975050505050505050565b610ef3611e4a565b610efb611e4a565b5f610f08875f01516113ea565b90505f610f17875f01516113ea565b90505f610f29838888855f015161054f565b90505f610f3b838989875f015161054f565b9050610f478a83610a6e565b9550610f538982610a6e565b94505050505094509492505050565b610f6a611db4565b5f5b8151811015610fa057610f98828281518110610f8a57610f8a612a10565b60200260200101515f611bee565b600101610f6c565b5050565b5f80836005811115610fb857610fb861253c565b14801561100d5750600484600f811115610fd457610fd461253c565b1480610ff15750600584600f811115610fef57610fef61253c565b145b8061100d5750600684600f81111561100b5761100b61253c565b145b156110245761101d6005826129e4565b905061120b565b60048360058111156110385761103861253c565b14801561108d5750600d84600f8111156110545761105461253c565b14806110715750600e84600f81111561106f5761106f61253c565b145b8061108d5750600f84600f81111561108b5761108b61253c565b145b1561109d5761101d6005826129e4565b60028360058111156110b1576110b161253c565b1480156111065750600184600f8111156110cd576110cd61253c565b14806110ea5750600284600f8111156110e8576110e861253c565b145b806111065750600384600f8111156111045761110461253c565b145b156111165761101d6005826129e4565b600183600581111561112a5761112a61253c565b14801561117f5750600a84600f8111156111465761114661253c565b14806111635750600b84600f8111156111615761116161253c565b145b8061117f5750600c84600f81111561117d5761117d61253c565b145b1561118f5761101d6005826129e4565b60038360058111156111a3576111a361253c565b1480156111f85750600784600f8111156111bf576111bf61253c565b14806111dc5750600884600f8111156111da576111da61253c565b145b806111f85750600984600f8111156111f6576111f661253c565b145b1561120b576112086005826129e4565b90505b600684600f81111561121f5761121f61253c565b148061123c5750600f84600f81111561123a5761123a61253c565b145b806112585750600384600f8111156112565761125661253c565b145b806112745750600c84600f8111156112725761127261253c565b145b806112905750600984600f81111561128e5761128e61253c565b145b156112a7576112a06005826129e4565b90506106c4565b8180156113345750600484600f8111156112c3576112c361253c565b14806112e05750600d84600f8111156112de576112de61253c565b145b806112fc5750600184600f8111156112fa576112fa61253c565b145b806113185750600a84600f8111156113165761131661253c565b145b806113345750600784600f8111156113325761133261253c565b145b15611344576112a06005826129e4565b811580156113d25750600584600f8111156113615761136161253c565b148061137e5750600e84600f81111561137c5761137c61253c565b145b8061139a5750600284600f8111156113985761139861253c565b145b806113b65750600b84600f8111156113b4576113b461253c565b145b806113d25750600884600f8111156113d0576113d061253c565b145b156106c4576113e26005826129e4565b949350505050565b6114116040805160808101909152805f81526020015f81526020015f81526020015f905290565b600354604051631bc6654760e21b8152600481018490525f91600160301b90046001600160a01b031690636f19951c906024015f60405180830381865afa15801561145e573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526114859190810190612a24565b80519091505f5b81811015611790575f8382815181106114a7576114a7612a10565b60209081029190910181015160035491810151815160405163ee1dffcf60e01b8152600481018b90526001600160a01b0392831660248201526044810191909152919350600160301b9092049091169063ee1dffcf90606401602060405180830381865afa15801561151b573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061153f9190612ad2565b156117875760045460208201516001600160a01b039182169116036115ab57805161156c906004906129fd565b600481111561157d5761157d61253c565b859060048111156115905761159061253c565b908160048111156115a3576115a361253c565b905250611787565b60055460208201516001600160a01b0391821691160361161f57805160c810156116115780516002906115e0906008906129fd565b6115ea9190612870565b60048111156115fb576115fb61253c565b856040019060048111156115905761159061253c565b80516115ea906004906129fd565b60065460208201516001600160a01b039182169116036116995780516014101561168b578051611651906005906129fd565b60058111156116625761166261253c565b856020019060058111156116785761167861253c565b908160058111156115a3576115a361253c565b8051611651906004906129fd565b60075460208201516001600160a01b03918216911603611787576007548151604051633940140f60e11b815260048101919091525f916001600160a01b031690637280281e906024015f60405180830381865afa1580156116fc573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526117239190810190612aed565b9050805f8151811061173757611737612a10565b60200260200101516001600160401b0316600f8111156117595761175961253c565b8660600190600f81111561176f5761176f61253c565b9081600f8111156117825761178261253c565b905250505b5060010161148c565b505050919050565b6117a0611db4565b600880546001600160a01b0319166001600160a01b0392909216919091179055565b5f60048260048111156117d7576117d761253c565b036117e357505f610858565b5f8360048111156117f6576117f661253c565b148015611814575060038260048111156118125761181261253c565b145b156118215750601e610858565b5f8360048111156118345761183461253c565b148015611852575060018260048111156118505761185061253c565b145b156118605750600419610858565b5f8360048111156118735761187361253c565b1480156118915750600282600481111561188f5761188f61253c565b145b1561189d57505f610858565b60038360048111156118b1576118b161253c565b1480156118ce57505f8260048111156118cc576118cc61253c565b145b156118dc5750600919610858565b60038360048111156118f0576118f061253c565b14801561190e5750600182600481111561190c5761190c61253c565b145b1561191b57506019610858565b600383600481111561192f5761192f61253c565b14801561194d5750600282600481111561194b5761194b61253c565b145b1561195957505f610858565b600183600481111561196d5761196d61253c565b14801561198a57505f8260048111156119885761198861253c565b145b156119975750600a610858565b60018360048111156119ab576119ab61253c565b1480156119c9575060038260048111156119c7576119c761253c565b145b156119d75750601319610858565b60018360048111156119eb576119eb61253c565b148015611a0957506002826004811115611a0757611a0761253c565b145b15611a1657506014610858565b6002836004811115611a2a57611a2a61253c565b148015611a4757505f826004811115611a4557611a4561253c565b145b15611a5457506019610858565b6002836004811115611a6857611a6861253c565b148015611a8657506003826004811115611a8457611a8461253c565b145b15611a9357506005610858565b6002836004811115611aa757611aa761253c565b148015611ac557506001826004811115611ac357611ac361253c565b145b15611ad35750600919610858565b50601319610858565b611ae4611db4565b6001600160a01b038116611b0b57604051634ece6ecf60e01b815260040160405180910390fd5b611b1481611dde565b50565b5f816004811115611b2a57611b2a61253c565b60ff16836004811115611b3f57611b3f61253c565b60ff16148015610a5957506004610a44565b6003546040516331a9108f60e11b8152600481018390525f91600160301b90046001600160a01b031690636352211e90602401602060405180830381865afa158015611b9f573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611bc39190612b7f565b90506001600160a01b0381163314610fa0576040516334a50d8b60e21b815260040160405180910390fd5b8015611c695761012082015160e083015163ffffffff90911690611c13816001612b9a565b611c1d9190612bb5565b61ffff161115611c695760018260e001818151611c3a9190612b9a565b61ffff1690525060e0820151611c4f90611e2d565b8261010001818151611c619190612b9a565b61ffff169052505b6009546003548351604080518082019091526005815264535441545360d81b60208201526001600160a01b039384169363ed20867293600160301b9004169190611d64875f816020015162ffffff1690506018826040015162ffffff16901b811790506030826060015162ffffff16901b811790506048826080015162ffffff16901b8117905060608260a0015162ffffff16901b8117905060788260c0015162ffffff16901b8117905060908260e0015161ffff16901b8117905060a082610100015161ffff16901b8117905060b082610120015163ffffffff16901b8117905060d082610140015163ffffffff16901b81179050919050565b6040518563ffffffff1660e01b8152600401611d839493929190612bdb565b5f604051808303815f87803b158015611d9a575f80fd5b505af1158015611dac573d5f803e3d5ffd5b505050505050565b5f546001600160a01b03163314610b7f57604051631c62d58f60e11b815260040160405180910390fd5b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b5f5b61ffff8216156106335761ffff909116801c90600101611e2f565b60408051610160810182525f80825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081019190915290565b60058110611b14575f80fd5b5f8060408385031215611ec2575f80fd5b823591506020830135611ed481611ea5565b809150509250929050565b634e487b7160e01b5f52604160045260245ffd5b60405161016081016001600160401b0381118282101715611f1657611f16611edf565b60405290565b60405160c081016001600160401b0381118282101715611f1657611f16611edf565b604080519081016001600160401b0381118282101715611f1657611f16611edf565b604051601f8201601f191681016001600160401b0381118282101715611f8857611f88611edf565b604052919050565b803560068110610633575f80fd5b803560108110610633575f80fd5b8015158114611b14575f80fd5b5f805f8084860360e0811215611fcd575f80fd5b6080811215611fda575f80fd5b50604051608081018181106001600160401b0382111715611ffd57611ffd611edf565b604052853561200b81611ea5565b815261201960208701611f90565b6020820152604086013561202c81611ea5565b604082015261203d60608701611f9e565b6060820152935061205060808601611f90565b925060a085013561206081611fac565b915060c085013561207081611ea5565b939692955090935050565b5f6020828403121561208b575f80fd5b6106c482611f90565b803562ffffff81168114610633575f80fd5b803561ffff81168114610633575f80fd5b803563ffffffff81168114610633575f80fd5b5f61016082840312156120db575f80fd5b6120e3611ef3565b9050813581526120f560208301612094565b602082015261210660408301612094565b604082015261211760608301612094565b606082015261212860808301612094565b608082015261213960a08301612094565b60a082015261214a60c08301612094565b60c082015261215b60e083016120a6565b60e082015261010061216e8184016120a6565b908201526101206121808382016120b7565b908201526101406121928382016120b7565b9082015292915050565b5f61016082840312156121ad575f80fd5b6106c483836120ca565b6001600160a01b0381168114611b14575f80fd5b5f602082840312156121db575f80fd5b81356106c4816121b7565b5f805f805f60a086880312156121fa575f80fd5b8535945061220a60208701612094565b935061221860408701612094565b925061222660608701612094565b915061223460808701612094565b90509295509295909350565b80518252602081015161225a602084018262ffffff169052565b506040810151612271604084018262ffffff169052565b506060810151612288606084018262ffffff169052565b50608081015161229f608084018262ffffff169052565b5060a08101516122b660a084018262ffffff169052565b5060c08101516122cd60c084018262ffffff169052565b5060e08101516122e360e084018261ffff169052565b506101008181015161ffff16908301526101208082015163ffffffff908116918401919091526101409182015116910152565b61016081016108588284612240565b5f60208284031215612335575f80fd5b5035919050565b5f5b8381101561235657818101518382015260200161233e565b50505f910152565b5f815180845261237581602086016020860161233c565b601f01601f19169290920160200192915050565b602081525f6106c4602083018461235e565b5f6001600160401b038211156123b3576123b3611edf565b50601f01601f191660200190565b5f80604083850312156123d2575f80fd5b8235915060208301356001600160401b038111156123ee575f80fd5b8301601f810185136123fe575f80fd5b803561241161240c8261239b565b611f60565b818152866020838501011115612425575f80fd5b816020840160208301375f602083830101528093505050509250929050565b5f8060408385031215612455575f80fd5b823561246081611ea5565b915061246e60208401611f90565b90509250929050565b803560ff81168114610633575f80fd5b5f8082840361022081121561249a575f80fd5b6124a485856120ca565b925060c061015f19820112156124b8575f80fd5b506124c1611f1c565b6101608401358060010b81146124d5575f80fd5b81526124e46101808501612477565b60208201526124f66101a08501612477565b60408201526125086101c08501612477565b606082015261251a6101e08501612477565b608082015261252c6102008501612477565b60a0820152809150509250929050565b634e487b7160e01b5f52602160045260245ffd5b600681106125605761256061253c565b9052565b604081016125728285612550565b82151560208301529392505050565b5f8060408385031215612592575f80fd5b61246083611f90565b5f80604083850312156125ac575f80fd5b82356125b7816121b7565b91506020830135611ed481611fac565b5f805f805f8060c087890312156125dc575f80fd5b6125e587612477565b95506125f360208801612477565b945061260160408801612477565b935061260f60608801612477565b925061261d60808801612477565b915061262b60a08801612477565b90509295509295509295565b5f805f80610300858703121561264b575f80fd5b61265586866120ca565b93506126658661016087016120ca565b92506126746102c08601611f90565b91506102e085013561207081611fac565b6102c081016126948285612240565b6106c4610160830184612240565b5f6001600160401b038211156126ba576126ba611edf565b5060051b60200190565b5f60208083850312156126d5575f80fd5b82356001600160401b038111156126ea575f80fd5b8301601f810185136126fa575f80fd5b803561270861240c826126a2565b8181526101609182028301840191848201919088841115612727575f80fd5b938501935b8385101561274d5761273e89866120ca565b8352938401939185019161272c565b50979650505050505050565b5f805f6060848603121561276b575f80fd5b61277484611f9e565b925061278260208501611f90565b9150604084013561279281611fac565b809150509250925092565b60058110611b1457611b1461253c565b815160808201906127bd8161279d565b8083525060208301516127d36020840182612550565b5060408301516127e28161279d565b60408301526060830151601081106127fc576127fc61253c565b8060608401525092915050565b5f806040838503121561281a575f80fd5b823561282581611ea5565b91506020830135611ed481611ea5565b634e487b7160e01b5f52601160045260245ffd5b8181038181111561085857610858612835565b634e487b7160e01b5f52601260045260245ffd5b5f8261287e5761287e61285c565b500490565b808202811582820484141761085857610858612835565b62ffffff8181168382160190808211156128b6576128b6612835565b5092915050565b60018060a01b0384168152826020820152606060408201525f6128e3606083018461235e565b95945050505050565b5f602082840312156128fc575f80fd5b81516001600160401b03811115612911575f80fd5b8201601f81018413612921575f80fd5b805161292f61240c8261239b565b818152856020838501011115612943575f80fd5b6128e382602083016020860161233c565b5f60208284031215612964575f80fd5b5051919050565b60018060a01b0385168152836020820152608060408201525f612991608083018561235e565b82810360608401526129a3818561235e565b979650505050505050565b600181810b9083900b01617fff8113617fff198212171561085857610858612835565b8082018082111561085857610858612835565b60ff818116838216019081111561085857610858612835565b5f82612a0b57612a0b61285c565b500690565b634e487b7160e01b5f52603260045260245ffd5b5f6020808385031215612a35575f80fd5b82516001600160401b03811115612a4a575f80fd5b8301601f81018513612a5a575f80fd5b8051612a6861240c826126a2565b81815260069190911b82018301908381019087831115612a86575f80fd5b928401925b828410156129a35760408489031215612aa3575f8081fd5b612aab611f3e565b8451815285850151612abc816121b7565b8187015282526040939093019290840190612a8b565b5f60208284031215612ae2575f80fd5b81516106c481611fac565b5f6020808385031215612afe575f80fd5b82516001600160401b0380821115612b14575f80fd5b818501915085601f830112612b27575f80fd5b8151612b3561240c826126a2565b81815260059190911b83018401908481019088831115612b53575f80fd5b938501935b82851015610edf5784518481168114612b70575f8081fd5b82529385019390850190612b58565b5f60208284031215612b8f575f80fd5b81516106c4816121b7565b61ffff8181168382160190808211156128b6576128b6612835565b61ffff818116838216028082169190828114612bd357612bd3612835565b505092915050565b60018060a01b0385168152836020820152608060408201525f612c01608083018561235e565b90508260608301529594505050505056fea2646970667358221220bb4edadb5a97706c5cf4c36da78838cb7ae3af21f694b234a6241136da6f0cc064736f6c63430008150033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000008f64ce931f0d36430b971548b81264eef3bd9b97000000000000000000000000a5b355125a2b7fd4c7a451c37b87e81b965a96b10000000000000000000000009e5babfad9a1a980b58db60585408735562b721e0000000000000000000000003f563d6d8e62405d01dc8a4e1dfb269f23aab1620000000000000000000000008e8e3ab3bfabb86b37f91b2f2ca83969ac2c0fad000000000000000000000000873526404f04d88bf7b4a8598b00a766a3393128
-----Decoded View---------------
Arg [0] : snakeSoldiers (address): 0x8F64Ce931f0D36430B971548b81264EeF3bD9B97
Arg [1] : elementGems (address): 0xa5B355125A2b7Fd4c7A451C37B87e81B965a96B1
Arg [2] : skillGems (address): 0x9E5bABfad9a1A980b58Db60585408735562B721E
Arg [3] : factionGems (address): 0x3f563D6d8E62405d01dc8A4e1dFB269f23aAB162
Arg [4] : landscapes (address): 0x8e8e3aB3BFaBB86b37F91b2f2cA83969Ac2c0FaD
Arg [5] : attributesRepository (address): 0x873526404f04D88Bf7b4A8598B00a766a3393128
-----Encoded View---------------
6 Constructor Arguments found :
Arg [0] : 0000000000000000000000008f64ce931f0d36430b971548b81264eef3bd9b97
Arg [1] : 000000000000000000000000a5b355125a2b7fd4c7a451c37b87e81b965a96b1
Arg [2] : 0000000000000000000000009e5babfad9a1a980b58db60585408735562b721e
Arg [3] : 0000000000000000000000003f563d6d8e62405d01dc8a4e1dfb269f23aab162
Arg [4] : 0000000000000000000000008e8e3ab3bfabb86b37f91b2f2ca83969ac2c0fad
Arg [5] : 000000000000000000000000873526404f04d88bf7b4a8598b00a766a3393128
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in GLMR
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.