编译器
0.8.20+commit.a1b79de6
文件 1 的 32:Actions.sol
pragma solidity ^0.8.17;
uint64 constant DAILY_EPOCH_DURATION = 1 days;
uint64 constant DAILY_EPOCH_OFFSET = 0 hours;
uint64 constant HOURLY_EPOCH_DURATION = 1 hours;
uint64 constant NO_OFFSET = 0 hours;
uint256 constant ACTION_LOCK = 101;
uint256 constant ACTION_ADVENTURER_HOMAGE = 1001;
uint256 constant ACTION_ADVENTURER_BATTLE_V3 = 1002;
uint256 constant ACTION_ADVENTURER_COLLECT_EPOCH_REWARDS = 1003;
uint256 constant ACTION_ADVENTURER_VOID_CRAFTING = 1004;
uint256 constant ACTION_ADVENTURER_REALM_CRAFTING = 1005;
uint256 constant ACTION_ADVENTURER_ANIMA_REGENERATION = 1006;
uint256 constant ACTION_ADVENTURER_BATTLE_V3_OPPONENT = 1007;
uint256 constant ACTION_ADVENTURER_TRAINING = 1008;
uint256 constant ACTION_ADVENTURER_TRANSCENDENCE = 1009;
uint256 constant ACTION_ADVENTURER_MINT_MULTIPASS = 1010;
uint256 constant ACTION_ARMORY_STAKE_RARITY_ITEM = 2001;
uint256 constant ACTION_ARMORY_UNSTAKE_RARITY_ITEM = 2002;
uint256 constant ACTION_ARMORY_STAKE_RARITY_ITEM_SHARD = 2011;
uint256 constant ACTION_ARMORY_UNSTAKE_RARITY_ITEM_SHARD = 2012;
uint256 constant ACTION_ARMORY_STAKE_MATERIAL_SHARD = 2021;
uint256 constant ACTION_ARMORY_UNSTAKE_MATERIAL_SHARD = 2022;
uint256 constant ACTION_ARMORY_STAKE_LAB = 2031;
uint256 constant ACTION_ARMORY_UNSTAKE_LAB = 2032;
uint256 constant ACTION_ARMORY_STAKE_COLLECTIBLE = 2041;
uint256 constant ACTION_ARMORY_UNSTAKE_COLLECTIBLE = 2042;
uint256 constant ACTION_ARMORY_STAKE_MATERIAL = 2051;
uint256 constant ACTION_ARMORY_UNSTAKE_MATERIAL = 2052;
uint256 constant ACTION_ARMORY_STAKE_CITY = 2061;
uint256 constant ACTION_ARMORY_UNSTAKE_CITY = 2062;
uint256 constant ACTION_ARMORY_STAKE_MONUMENT = 2071;
uint256 constant ACTION_ARMORY_UNSTAKE_MONUMENT = 2072;
uint256 constant ACTION_ARMORY_STAKE_ANIMA_CHAMBER = 2081;
uint256 constant ACTION_ARMORY_UNSTAKE_ANIMA_CHAMBER = 2082;
uint256 constant ACTION_ANIMA_STAKING_COLLECT_STAKER_REWARDS = 2083;
uint256 constant ACTION_ANIMA_STAKING_COLLECT_REALMER_REWARDS = 2084;
uint256 constant ACTION_REALM_COLLECT_COLLECTIBLES = 4001;
uint256 constant ACTION_REALM_BUILD_LAB = 4011;
uint256 constant ACTION_REALM_BUILD_MONUMENT = 4012;
uint256 constant ACTION_REALM_BUILD_CITY = 4013;
文件 2 的 32:Address.sol
pragma solidity ^0.8.1;
library Address {
function isContract(address account) internal view returns (bool) {
return account.code.length > 0;
}
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, "Address: low-level call failed");
}
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
function functionCallWithValue(
address target,
bytes memory data,
uint256 value
) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata,
string memory errorMessage
) internal view returns (bytes memory) {
if (success) {
if (returndata.length == 0) {
require(isContract(target), "Address: call to non-contract");
}
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
function _revert(bytes memory returndata, string memory errorMessage) private pure {
if (returndata.length > 0) {
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
文件 3 的 32:Anima.sol
pragma solidity ^0.8.4;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import "@openzeppelin/contracts/security/Pausable.sol";
import "../Bound/IERC20Bound.sol";
import "./IAnima.sol";
import "../Manager/ManagerModifier.sol";
contract Anima is
IAnima,
ERC20,
ERC20Burnable,
ManagerModifier,
ReentrancyGuard,
Pausable
{
IERC20Bound public immutable BOUND;
uint256 public immutable CAP;
constructor(
address _manager,
address _bound,
uint256 _cap
) ERC20("Anima", "ANIMA") ManagerModifier(_manager) {
BOUND = IERC20Bound(_bound);
CAP = _cap;
}
function mintFor(
address _for,
uint256 _amount
) external override onlyTokenMinter {
require(ERC20.totalSupply() + _amount <= CAP, "Anima: Cap exceeded");
_mint(_for, _amount);
}
function burnFrom(
address account,
uint256 amount
) public override(IAnima, ERC20Burnable) {
super.burnFrom(account, amount);
}
function pause() external onlyAdmin {
_pause();
}
function unpause() external onlyAdmin {
_unpause();
}
function _beforeTokenTransfer(
address from,
address to,
uint256 amount
) internal override {
super._beforeTokenTransfer(from, to, amount);
if (!MANAGER.isManager(msg.sender, 0)) {
if (from != address(0) && to != address(0)) {
require(BOUND.isUnbound(address(this)), "Anima: Token not unbound");
}
}
require(!paused(), "Anima: Paused");
}
}
文件 4 的 32:ArrayUtils.sol
pragma solidity ^0.8.17;
library ArrayUtils {
error ArrayLengthMismatch(uint _length1, uint _length2);
error InvalidArrayOrder(uint index);
function ensureSameLength(uint _l1, uint _l2) internal pure {
if (_l1 != _l2) {
revert ArrayLengthMismatch(_l1, _l2);
}
}
function ensureSameLength(uint _l1, uint _l2, uint _l3) internal pure {
ensureSameLength(_l1, _l2);
ensureSameLength(_l1, _l3);
}
function ensureSameLength(
uint _l1,
uint _l2,
uint _l3,
uint _l4
) internal pure {
ensureSameLength(_l1, _l2);
ensureSameLength(_l1, _l3);
ensureSameLength(_l1, _l4);
}
function ensureSameLength(
uint _l1,
uint _l2,
uint _l3,
uint _l4,
uint _l5
) internal pure {
ensureSameLength(_l1, _l2);
ensureSameLength(_l1, _l3);
ensureSameLength(_l1, _l4);
ensureSameLength(_l1, _l5);
}
function checkAddressesForDuplicates(
address[] memory _tokenAddrs
) internal pure {
address lastAddress;
for (uint i = 0; i < _tokenAddrs.length; i++) {
if (lastAddress > _tokenAddrs[i]) {
revert InvalidArrayOrder(i);
}
lastAddress = _tokenAddrs[i];
}
}
function checkForDuplicates(uint[] memory _ids) internal pure {
uint lastId;
for (uint i = 0; i < _ids.length; i++) {
if (lastId > _ids[i]) {
revert InvalidArrayOrder(i);
}
lastId = _ids[i];
}
}
function checkForDuplicates(
address[] memory _tokenAddrs,
uint[] memory _tokenIds
) internal pure {
address lastAddress;
int256 lastTokenId = -1;
for (uint i = 0; i < _tokenAddrs.length; i++) {
if (_tokenAddrs[i] > lastAddress) {
lastTokenId = -1;
}
if (_tokenAddrs[i] < lastAddress || int(_tokenIds[i]) <= lastTokenId) {
revert InvalidArrayOrder(i);
}
lastAddress = _tokenAddrs[i];
lastTokenId = int(_tokenIds[i]);
}
}
function toSingleValueDoubleArray(
uint[] memory _vals
) internal pure returns (uint[][] memory result) {
result = new uint[][](_vals.length);
for (uint i = 0; i < _vals.length; i++) {
result[i] = ArrayUtils.toMemoryArray(_vals[i], 1);
}
}
function toMemoryArray(
uint _value,
uint _length
) internal pure returns (uint[] memory result) {
result = new uint[](_length);
for (uint i = 0; i < _length; i++) {
result[i] = _value;
}
}
function toMemoryArray(
uint[] calldata _value
) internal pure returns (uint[] memory result) {
result = new uint[](_value.length);
for (uint i = 0; i < _value.length; i++) {
result[i] = _value[i];
}
}
function toMemoryArray(
address _address,
uint _length
) internal pure returns (address[] memory result) {
result = new address[](_length);
for (uint i = 0; i < _length; i++) {
result[i] = _address;
}
}
function toMemoryArray(
address[] calldata _addresses
) internal pure returns (address[] memory result) {
result = new address[](_addresses.length);
for (uint i = 0; i < _addresses.length; i++) {
result[i] = _addresses[i];
}
}
}
文件 5 的 32:Context.sol
pragma solidity ^0.8.0;
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
文件 6 的 32:ERC20.sol
pragma solidity ^0.8.0;
import "./IERC20.sol";
import "./extensions/IERC20Metadata.sol";
import "../../utils/Context.sol";
contract ERC20 is Context, IERC20, IERC20Metadata {
mapping(address => uint256) private _balances;
mapping(address => mapping(address => uint256)) private _allowances;
uint256 private _totalSupply;
string private _name;
string private _symbol;
constructor(string memory name_, string memory symbol_) {
_name = name_;
_symbol = symbol_;
}
function name() public view virtual override returns (string memory) {
return _name;
}
function symbol() public view virtual override returns (string memory) {
return _symbol;
}
function decimals() public view virtual override returns (uint8) {
return 18;
}
function totalSupply() public view virtual override returns (uint256) {
return _totalSupply;
}
function balanceOf(address account) public view virtual override returns (uint256) {
return _balances[account];
}
function transfer(address to, uint256 amount) public virtual override returns (bool) {
address owner = _msgSender();
_transfer(owner, to, amount);
return true;
}
function allowance(address owner, address spender) public view virtual override returns (uint256) {
return _allowances[owner][spender];
}
function approve(address spender, uint256 amount) public virtual override returns (bool) {
address owner = _msgSender();
_approve(owner, spender, amount);
return true;
}
function transferFrom(
address from,
address to,
uint256 amount
) public virtual override returns (bool) {
address spender = _msgSender();
_spendAllowance(from, spender, amount);
_transfer(from, to, amount);
return true;
}
function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
address owner = _msgSender();
_approve(owner, spender, allowance(owner, spender) + addedValue);
return true;
}
function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
address owner = _msgSender();
uint256 currentAllowance = allowance(owner, spender);
require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
unchecked {
_approve(owner, spender, currentAllowance - subtractedValue);
}
return true;
}
function _transfer(
address from,
address to,
uint256 amount
) internal virtual {
require(from != address(0), "ERC20: transfer from the zero address");
require(to != address(0), "ERC20: transfer to the zero address");
_beforeTokenTransfer(from, to, amount);
uint256 fromBalance = _balances[from];
require(fromBalance >= amount, "ERC20: transfer amount exceeds balance");
unchecked {
_balances[from] = fromBalance - amount;
_balances[to] += amount;
}
emit Transfer(from, to, amount);
_afterTokenTransfer(from, to, amount);
}
function _mint(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: mint to the zero address");
_beforeTokenTransfer(address(0), account, amount);
_totalSupply += amount;
unchecked {
_balances[account] += amount;
}
emit Transfer(address(0), account, amount);
_afterTokenTransfer(address(0), account, amount);
}
function _burn(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: burn from the zero address");
_beforeTokenTransfer(account, address(0), amount);
uint256 accountBalance = _balances[account];
require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
unchecked {
_balances[account] = accountBalance - amount;
_totalSupply -= amount;
}
emit Transfer(account, address(0), amount);
_afterTokenTransfer(account, address(0), amount);
}
function _approve(
address owner,
address spender,
uint256 amount
) internal virtual {
require(owner != address(0), "ERC20: approve from the zero address");
require(spender != address(0), "ERC20: approve to the zero address");
_allowances[owner][spender] = amount;
emit Approval(owner, spender, amount);
}
function _spendAllowance(
address owner,
address spender,
uint256 amount
) internal virtual {
uint256 currentAllowance = allowance(owner, spender);
if (currentAllowance != type(uint256).max) {
require(currentAllowance >= amount, "ERC20: insufficient allowance");
unchecked {
_approve(owner, spender, currentAllowance - amount);
}
}
}
function _beforeTokenTransfer(
address from,
address to,
uint256 amount
) internal virtual {}
function _afterTokenTransfer(
address from,
address to,
uint256 amount
) internal virtual {}
}
文件 7 的 32:ERC20Burnable.sol
pragma solidity ^0.8.0;
import "../ERC20.sol";
import "../../../utils/Context.sol";
abstract contract ERC20Burnable is Context, ERC20 {
function burn(uint256 amount) public virtual {
_burn(_msgSender(), amount);
}
function burnFrom(address account, uint256 amount) public virtual {
_spendAllowance(account, _msgSender(), amount);
_burn(account, amount);
}
}
文件 8 的 32:ERC721A.sol
pragma solidity ^0.8.4;
import "./IERC721A.sol";
interface ERC721A__IERC721Receiver {
function onERC721Received(
address operator,
address from,
uint256 tokenId,
bytes calldata data
) external returns (bytes4);
}
contract ERC721A is IERC721A {
uint256 private constant BITMASK_ADDRESS_DATA_ENTRY = (1 << 64) - 1;
uint256 private constant BITPOS_NUMBER_MINTED = 64;
uint256 private constant BITPOS_NUMBER_BURNED = 128;
uint256 private constant BITPOS_AUX = 192;
uint256 private constant BITMASK_AUX_COMPLEMENT = (1 << 192) - 1;
uint256 private constant BITPOS_START_TIMESTAMP = 160;
uint256 private constant BITMASK_BURNED = 1 << 224;
uint256 private constant BITPOS_NEXT_INITIALIZED = 225;
uint256 private constant BITMASK_NEXT_INITIALIZED = 1 << 225;
uint256 private constant BITPOS_EXTRA_DATA = 232;
uint256 private constant BITMASK_EXTRA_DATA_COMPLEMENT = (1 << 232) - 1;
uint256 private constant BITMASK_ADDRESS = (1 << 160) - 1;
uint256 private constant MAX_MINT_ERC2309_QUANTITY_LIMIT = 5000;
uint256 private _currentIndex;
uint256 private _burnCounter;
string private _name;
string private _symbol;
mapping(uint256 => uint256) private _packedOwnerships;
mapping(address => uint256) private _packedAddressData;
mapping(uint256 => address) private _tokenApprovals;
mapping(address => mapping(address => bool)) private _operatorApprovals;
constructor(string memory name_, string memory symbol_) {
_name = name_;
_symbol = symbol_;
_currentIndex = _startTokenId();
}
function _startTokenId() internal view virtual returns (uint256) {
return 0;
}
function _nextTokenId() internal view returns (uint256) {
return _currentIndex;
}
function totalSupply() public view override returns (uint256) {
unchecked {
return _currentIndex - _burnCounter - _startTokenId();
}
}
function _totalMinted() internal view returns (uint256) {
unchecked {
return _currentIndex - _startTokenId();
}
}
function _totalBurned() internal view returns (uint256) {
return _burnCounter;
}
function supportsInterface(
bytes4 interfaceId
) public view virtual override returns (bool) {
return
interfaceId == 0x01ffc9a7 ||
interfaceId == 0x80ac58cd ||
interfaceId == 0x5b5e139f;
}
function balanceOf(address owner) public view override returns (uint256) {
if (owner == address(0)) revert BalanceQueryForZeroAddress();
return _packedAddressData[owner] & BITMASK_ADDRESS_DATA_ENTRY;
}
function _numberMinted(address owner) internal view returns (uint256) {
return
(_packedAddressData[owner] >> BITPOS_NUMBER_MINTED) &
BITMASK_ADDRESS_DATA_ENTRY;
}
function _numberBurned(address owner) internal view returns (uint256) {
return
(_packedAddressData[owner] >> BITPOS_NUMBER_BURNED) &
BITMASK_ADDRESS_DATA_ENTRY;
}
function _getAux(address owner) internal view returns (uint64) {
return uint64(_packedAddressData[owner] >> BITPOS_AUX);
}
function _setAux(address owner, uint64 aux) internal {
uint256 packed = _packedAddressData[owner];
uint256 auxCasted;
assembly {
auxCasted := aux
}
packed = (packed & BITMASK_AUX_COMPLEMENT) | (auxCasted << BITPOS_AUX);
_packedAddressData[owner] = packed;
}
function _packedOwnershipOf(uint256 tokenId) private view returns (uint256) {
uint256 curr = tokenId;
unchecked {
if (_startTokenId() <= curr)
if (curr < _currentIndex) {
uint256 packed = _packedOwnerships[curr];
if (packed & BITMASK_BURNED == 0) {
while (packed == 0) {
packed = _packedOwnerships[--curr];
}
return packed;
}
}
}
revert OwnerQueryForNonexistentToken();
}
function _unpackedOwnership(
uint256 packed
) private pure returns (TokenOwnership memory ownership) {
ownership.addr = address(uint160(packed));
ownership.startTimestamp = uint64(packed >> BITPOS_START_TIMESTAMP);
ownership.burned = packed & BITMASK_BURNED != 0;
ownership.extraData = uint24(packed >> BITPOS_EXTRA_DATA);
}
function _ownershipAt(
uint256 index
) internal view returns (TokenOwnership memory) {
return _unpackedOwnership(_packedOwnerships[index]);
}
function _initializeOwnershipAt(uint256 index) internal {
if (_packedOwnerships[index] == 0) {
_packedOwnerships[index] = _packedOwnershipOf(index);
}
}
function _ownershipOf(
uint256 tokenId
) internal view returns (TokenOwnership memory) {
return _unpackedOwnership(_packedOwnershipOf(tokenId));
}
function _packOwnershipData(
address owner,
uint256 flags
) private view returns (uint256 result) {
assembly {
owner := and(owner, BITMASK_ADDRESS)
result := or(owner, or(shl(BITPOS_START_TIMESTAMP, timestamp()), flags))
}
}
function ownerOf(uint256 tokenId) public view override returns (address) {
return address(uint160(_packedOwnershipOf(tokenId)));
}
function name() public view virtual override returns (string memory) {
return _name;
}
function symbol() public view virtual override returns (string memory) {
return _symbol;
}
function tokenURI(
uint256 tokenId
) public view virtual override returns (string memory) {
if (!_exists(tokenId)) revert URIQueryForNonexistentToken();
string memory baseURI = _baseURI();
return
bytes(baseURI).length != 0
? string(abi.encodePacked(baseURI, _toString(tokenId)))
: "";
}
function _baseURI() internal view virtual returns (string memory) {
return "";
}
function _nextInitializedFlag(
uint256 quantity
) private pure returns (uint256 result) {
assembly {
result := shl(BITPOS_NEXT_INITIALIZED, eq(quantity, 1))
}
}
function approve(address to, uint256 tokenId) public override {
address owner = ownerOf(tokenId);
if (_msgSenderERC721A() != owner)
if (!isApprovedForAll(owner, _msgSenderERC721A())) {
revert ApprovalCallerNotOwnerNorApproved();
}
_tokenApprovals[tokenId] = to;
emit Approval(owner, to, tokenId);
}
function getApproved(uint256 tokenId) public view override returns (address) {
if (!_exists(tokenId)) revert ApprovalQueryForNonexistentToken();
return _tokenApprovals[tokenId];
}
function setApprovalForAll(
address operator,
bool approved
) public virtual override {
if (operator == _msgSenderERC721A()) revert ApproveToCaller();
_operatorApprovals[_msgSenderERC721A()][operator] = approved;
emit ApprovalForAll(_msgSenderERC721A(), operator, approved);
}
function isApprovedForAll(
address owner,
address operator
) public view virtual override returns (bool) {
return _operatorApprovals[owner][operator];
}
function safeTransferFrom(
address from,
address to,
uint256 tokenId
) public virtual override {
safeTransferFrom(from, to, tokenId, "");
}
function safeTransferFrom(
address from,
address to,
uint256 tokenId,
bytes memory _data
) public virtual override {
transferFrom(from, to, tokenId);
if (to.code.length != 0)
if (!_checkContractOnERC721Received(from, to, tokenId, _data)) {
revert TransferToNonERC721ReceiverImplementer();
}
}
function _exists(uint256 tokenId) internal view returns (bool) {
return
_startTokenId() <= tokenId &&
tokenId < _currentIndex &&
_packedOwnerships[tokenId] & BITMASK_BURNED == 0;
}
function _safeMint(address to, uint256 quantity) internal returns (uint256) {
return _safeMint(to, quantity, "");
}
function _safeMint(
address to,
uint256 quantity,
bytes memory _data
) internal returns (uint256) {
uint256 startTokenId = _mint(to, quantity);
unchecked {
if (to.code.length != 0) {
uint256 end = _currentIndex;
uint256 index = end - quantity;
do {
if (!_checkContractOnERC721Received(address(0), to, index++, _data)) {
revert TransferToNonERC721ReceiverImplementer();
}
} while (index < end);
if (_currentIndex != end) revert();
}
}
return startTokenId;
}
function _mint(address to, uint256 quantity) internal returns (uint256) {
uint256 startTokenId = _currentIndex;
if (to == address(0)) revert MintToZeroAddress();
if (quantity == 0) revert MintZeroQuantity();
_beforeTokenTransfers(address(0), to, startTokenId, quantity);
unchecked {
_packedAddressData[to] += quantity * ((1 << BITPOS_NUMBER_MINTED) | 1);
_packedOwnerships[startTokenId] = _packOwnershipData(
to,
_nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0)
);
uint256 tokenId = startTokenId;
uint256 end = startTokenId + quantity;
do {
emit Transfer(address(0), to, tokenId++);
} while (tokenId < end);
_currentIndex = end;
}
_afterTokenTransfers(address(0), to, startTokenId, quantity);
return startTokenId;
}
function _mintERC2309(address to, uint256 quantity) internal {
uint256 startTokenId = _currentIndex;
if (to == address(0)) revert MintToZeroAddress();
if (quantity == 0) revert MintZeroQuantity();
if (quantity > MAX_MINT_ERC2309_QUANTITY_LIMIT)
revert MintERC2309QuantityExceedsLimit();
_beforeTokenTransfers(address(0), to, startTokenId, quantity);
unchecked {
_packedAddressData[to] += quantity * ((1 << BITPOS_NUMBER_MINTED) | 1);
_packedOwnerships[startTokenId] = _packOwnershipData(
to,
_nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0)
);
emit ConsecutiveTransfer(
startTokenId,
startTokenId + quantity - 1,
address(0),
to
);
_currentIndex = startTokenId + quantity;
}
_afterTokenTransfers(address(0), to, startTokenId, quantity);
}
function _getApprovedAddress(
uint256 tokenId
)
private
view
returns (uint256 approvedAddressSlot, address approvedAddress)
{
mapping(uint256 => address) storage tokenApprovalsPtr = _tokenApprovals;
assembly {
mstore(0x00, tokenId)
mstore(0x20, tokenApprovalsPtr.slot)
approvedAddressSlot := keccak256(0x00, 0x40)
approvedAddress := sload(approvedAddressSlot)
}
}
function _isOwnerOrApproved(
address approvedAddress,
address from,
address msgSender
) private pure returns (bool result) {
assembly {
from := and(from, BITMASK_ADDRESS)
msgSender := and(msgSender, BITMASK_ADDRESS)
result := or(eq(msgSender, from), eq(msgSender, approvedAddress))
}
}
function transferFrom(
address from,
address to,
uint256 tokenId
) public virtual override {
uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId);
if (address(uint160(prevOwnershipPacked)) != from)
revert TransferFromIncorrectOwner();
(
uint256 approvedAddressSlot,
address approvedAddress
) = _getApprovedAddress(tokenId);
if (!_isOwnerOrApproved(approvedAddress, from, _msgSenderERC721A()))
if (!isApprovedForAll(from, _msgSenderERC721A()))
revert TransferCallerNotOwnerNorApproved();
if (to == address(0)) revert TransferToZeroAddress();
_beforeTokenTransfers(from, to, tokenId, 1);
assembly {
if approvedAddress {
sstore(approvedAddressSlot, 0)
}
}
unchecked {
--_packedAddressData[from];
++_packedAddressData[to];
_packedOwnerships[tokenId] = _packOwnershipData(
to,
BITMASK_NEXT_INITIALIZED | _nextExtraData(from, to, prevOwnershipPacked)
);
if (prevOwnershipPacked & BITMASK_NEXT_INITIALIZED == 0) {
uint256 nextTokenId = tokenId + 1;
if (_packedOwnerships[nextTokenId] == 0) {
if (nextTokenId != _currentIndex) {
_packedOwnerships[nextTokenId] = prevOwnershipPacked;
}
}
}
}
emit Transfer(from, to, tokenId);
_afterTokenTransfers(from, to, tokenId, 1);
}
function _burn(uint256 tokenId) internal virtual {
_burn(tokenId, false);
}
function _burn(uint256 tokenId, bool approvalCheck) internal virtual {
uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId);
address from = address(uint160(prevOwnershipPacked));
(
uint256 approvedAddressSlot,
address approvedAddress
) = _getApprovedAddress(tokenId);
if (approvalCheck) {
if (!_isOwnerOrApproved(approvedAddress, from, _msgSenderERC721A()))
if (!isApprovedForAll(from, _msgSenderERC721A()))
revert TransferCallerNotOwnerNorApproved();
}
_beforeTokenTransfers(from, address(0), tokenId, 1);
assembly {
if approvedAddress {
sstore(approvedAddressSlot, 0)
}
}
unchecked {
_packedAddressData[from] += (1 << BITPOS_NUMBER_BURNED) - 1;
_packedOwnerships[tokenId] = _packOwnershipData(
from,
(BITMASK_BURNED | BITMASK_NEXT_INITIALIZED) |
_nextExtraData(from, address(0), prevOwnershipPacked)
);
if (prevOwnershipPacked & BITMASK_NEXT_INITIALIZED == 0) {
uint256 nextTokenId = tokenId + 1;
if (_packedOwnerships[nextTokenId] == 0) {
if (nextTokenId != _currentIndex) {
_packedOwnerships[nextTokenId] = prevOwnershipPacked;
}
}
}
}
emit Transfer(from, address(0), tokenId);
_afterTokenTransfers(from, address(0), tokenId, 1);
unchecked {
_burnCounter++;
}
}
function _checkContractOnERC721Received(
address from,
address to,
uint256 tokenId,
bytes memory _data
) private returns (bool) {
try
ERC721A__IERC721Receiver(to).onERC721Received(
_msgSenderERC721A(),
from,
tokenId,
_data
)
returns (bytes4 retval) {
return retval == ERC721A__IERC721Receiver(to).onERC721Received.selector;
} catch (bytes memory reason) {
if (reason.length == 0) {
revert TransferToNonERC721ReceiverImplementer();
} else {
assembly {
revert(add(32, reason), mload(reason))
}
}
}
}
function _setExtraDataAt(uint256 index, uint24 extraData) internal {
uint256 packed = _packedOwnerships[index];
if (packed == 0) revert OwnershipNotInitializedForExtraData();
uint256 extraDataCasted;
assembly {
extraDataCasted := extraData
}
packed =
(packed & BITMASK_EXTRA_DATA_COMPLEMENT) |
(extraDataCasted << BITPOS_EXTRA_DATA);
_packedOwnerships[index] = packed;
}
function _nextExtraData(
address from,
address to,
uint256 prevOwnershipPacked
) private view returns (uint256) {
uint24 extraData = uint24(prevOwnershipPacked >> BITPOS_EXTRA_DATA);
return uint256(_extraData(from, to, extraData)) << BITPOS_EXTRA_DATA;
}
function _extraData(
address from,
address to,
uint24 previousExtraData
) internal view virtual returns (uint24) {}
function _beforeTokenTransfers(
address from,
address to,
uint256 startTokenId,
uint256 quantity
) internal virtual {}
function _afterTokenTransfers(
address from,
address to,
uint256 startTokenId,
uint256 quantity
) internal virtual {}
function _msgSenderERC721A() internal view virtual returns (address) {
return msg.sender;
}
function _toString(uint256 value) internal pure returns (string memory ptr) {
assembly {
ptr := add(mload(0x40), 128)
mstore(0x40, ptr)
let end := ptr
for {
let temp := value
ptr := sub(ptr, 1)
mstore8(ptr, add(48, mod(temp, 10)))
temp := div(temp, 10)
} temp {
temp := div(temp, 10)
} {
ptr := sub(ptr, 1)
mstore8(ptr, add(48, mod(temp, 10)))
}
let length := sub(end, ptr)
ptr := sub(ptr, 32)
mstore(ptr, length)
}
}
}
文件 9 的 32:Epoch.sol
pragma solidity ^0.8.17;
import "../lib/FloatingPointConstants.sol";
uint256 constant MASK_128 = ((1 << 128) - 1);
uint128 constant MASK_64 = ((1 << 64) - 1);
library Epoch {
function toEpochNumber(
uint256 _timestamp,
uint256 _duration,
uint256 _offset
) internal pure returns (uint256) {
return (_timestamp + _offset) / _duration;
}
function toEpochNumber(uint256 _timestamp, uint128 _config) internal pure returns (uint256) {
return (_timestamp + (_config & MASK_64)) / ((_config >> 64) & MASK_64);
}
function toEpochCompleteness(
uint256 _timestamp,
uint128 _config
) internal pure returns (uint256 result) {
result = (_config >> 64) & MASK_64;
result = (ONE_HUNDRED * ((_timestamp + (_config & MASK_64)) % result)) / result;
}
function epochToTimestamp(
uint256 _epoch,
uint128 _config
) internal pure returns (uint256 result) {
result = _epoch * ((_config >> 64) & MASK_64);
if (result > 0) {
result -= (_config & MASK_64);
}
}
function toConfig(uint64 _duration, uint64 _offset) internal pure returns (uint128) {
return (uint128(_duration) << 64) | uint128(_offset);
}
function packEpoch(uint256 _epochNumber, uint128 _config) internal pure returns (uint256) {
return (uint256(_config) << 128) | uint128(_epochNumber);
}
function packTimestampToEpoch(
uint256 _timestamp,
uint128 _config
) internal pure returns (uint256) {
return packEpoch(toEpochNumber(_timestamp, _config), _config);
}
function unpack(
uint256 _packedEpoch
) internal pure returns (uint256 epochNumber, uint128 config) {
config = uint128(_packedEpoch >> 128);
epochNumber = _packedEpoch & MASK_128;
}
}
文件 10 的 32:EpochConfigurable.sol
pragma solidity ^0.8.17;
import "./Epoch.sol";
import "../Manager/ManagerModifier.sol";
import "./IEpochConfigurable.sol";
import "@openzeppelin/contracts/security/Pausable.sol";
contract EpochConfigurable is Pausable, ManagerModifier, IEpochConfigurable {
uint128 public EPOCH_CONFIG;
constructor(
address _manager,
uint64 _epochDuration,
uint64 _epochOffset
) ManagerModifier(_manager) {
EPOCH_CONFIG = Epoch.toConfig(_epochDuration, _epochOffset);
}
function currentEpoch() public view returns (uint) {
return epochAtTimestamp(block.timestamp);
}
function epochAtTimestamp(uint _timestamp) public view returns (uint) {
return Epoch.toEpochNumber(_timestamp, EPOCH_CONFIG);
}
function pause() external onlyAdmin {
_pause();
}
function unpause() external onlyAdmin {
_unpause();
}
function updateEpochConfig(uint64 duration, uint64 offset) external onlyAdmin {
EPOCH_CONFIG = Epoch.toConfig(duration, offset);
}
}
文件 11 的 32:FloatingPointConstants.sol
pragma solidity ^0.8.17;
uint256 constant DECIMAL_POINT = 10 ** 3;
uint256 constant ROUNDING_ADJUSTER = DECIMAL_POINT - 1;
int256 constant SIGNED_DECIMAL_POINT = int256(DECIMAL_POINT);
uint256 constant ONE_HUNDRED = 100 * DECIMAL_POINT;
uint256 constant ONE_HUNDRED_SQUARE = ONE_HUNDRED * ONE_HUNDRED;
int256 constant SIGNED_ONE_HUNDRED = 100 * SIGNED_DECIMAL_POINT;
int256 constant SIGNED_ONE_HUNDRED_SQUARE = SIGNED_ONE_HUNDRED * SIGNED_ONE_HUNDRED;
int256 constant SIGNED_ZERO = 0;
文件 12 的 32:IActionPermit.sol
pragma solidity ^0.8.17;
error Unauthorized(address _tokenAddr, uint256 _tokenId);
error EntityLocked(address _tokenAddr, uint256 _tokenId, uint _lockedUntil);
error MinEpochsTooLow(uint256 _minEpochs);
error InsufficientEpochSpan(
uint256 _minEpochs,
uint256 _epochs,
address _tokenAddr,
uint256 _tokenId
);
error DuplicateActionAttempt(address _tokenAddr, uint256 _tokenId);
interface IActionPermit {
function checkAndMarkActionComplete(
address _sender,
address _tokenAddr,
uint256 _tokenId,
bytes32[] calldata _proof,
uint256 _action,
uint256 _minEpochs,
uint128 _epochConfig
) external;
function checkAndMarkActionCompleteMany(
address _sender,
address[] calldata _tokenAddrs,
uint256[] calldata _tokenIds,
bytes32[][] calldata _proofs,
uint256 _action,
uint256 _minEpochs,
uint128 _epochConfig
) external;
function checkAndMarkActionCompleteMany(
address _sender,
address[] calldata _tokenAddrs,
uint256[] calldata _tokenIds,
bytes32[][] calldata _proofs,
uint256 _action,
uint256[] calldata _minEpochs,
uint128 _epochConfig
) external;
function forceMarkActionComplete(address _tokenAddr, uint256 _tokenId, uint256 _action) external;
function checkPermissions(
address _sender,
address _tokenAddr,
uint256 _tokenId,
bytes32[] calldata _proof,
uint256 _action
) external view;
function checkOwner(
address _tokenAddr,
uint256 _tokenId,
bytes32[] calldata _proof
) external view returns (address);
function checkPermissionsMany(
address _sender,
address[] calldata _tokenAddr,
uint256[] calldata _tokenId,
bytes32[][] calldata _proofs,
uint256 _action
) external view;
function checkPermissionsMany(
address _sender,
address _tokenAddr,
uint256[] calldata _tokenId,
bytes32[][] calldata _proofs,
uint256 _action
) external view;
function checkOwnerBatch(
address[] calldata _tokenAddrs,
uint256[] calldata _tokenIds,
bytes32[][] calldata _proofs
) external view returns (address[] memory);
function checkIfEnoughEpochsElapsed(
address _tokenAddr,
uint256 _tokenId,
uint256 _action,
uint256 _minEpochs,
uint128 _epochConfig
) external view;
function checkIfEnoughEpochsElapsedBatch(
address[] calldata _tokenAddrs,
uint256[] calldata _tokenIds,
uint256 _action,
uint256 _minEpochs,
uint128 _epochConfig
) external view;
function checkIfEnoughEpochsElapsedBatch(
address[] calldata _tokenAddrs,
uint256[] calldata _tokenIds,
uint256 _action,
uint256[] calldata _minEpochs,
uint128 _epochConfig
) external view;
function getElapsedEpochs(
address[] calldata _tokenAddrs,
uint256[] calldata _tokenIds,
uint256 _action,
uint128 _epochConfig
) external view returns (uint[] memory result);
}
文件 13 的 32:IAnima.sol
pragma solidity ^0.8.4;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";
interface IAnima is IERC20, IERC20Metadata {
function CAP() external view returns (uint256);
function mintFor(address _for, uint256 _amount) external;
function burnFrom(address account, uint256 amount) external;
}
文件 14 的 32:IAovLegacy.sol
pragma solidity ^0.8.4;
interface IAovLegacy {
function chronicle(
address _addr,
uint256 _adventurerId,
uint256 _currentArchetype,
uint256 _archetype
) external;
}
文件 15 的 32:IBatchAdventurerData.sol
pragma solidity ^0.8.4;
uint constant ADVENTURER_DATA_BASE = 0;
uint constant ADVENTURER_DATA_AOV = 1;
uint constant ADVENTURER_DATA_EXTENSION = 2;
interface IBatchAdventurerData {
function STORAGE(
address _addr,
uint256 _id,
uint256 _type,
uint256 _prop
) external view returns (uint24);
function add(address _addr, uint256 _id, uint256 _type, uint256 _prop, uint256 _val) external;
function addBatch(
address[] calldata _addr,
uint256[] calldata _id,
uint256 _type,
uint256[][] calldata _prop,
uint256[][] calldata _val
) external;
function addBatch(
address[] calldata _addr,
uint256[] calldata _id,
uint256 _type,
uint256 _prop,
uint256 _val
) external;
function addBatch(
address[] calldata _addr,
uint256[] calldata _id,
uint256 _type,
uint256 _prop,
uint256[] calldata _val
) external;
function update(address _addr, uint256 _id, uint256 _type, uint256 _prop, uint256 _val) external;
function updateRaw(address _addr, uint256 _id, uint256 _type, uint24[10] calldata _val) external;
function updateBatch(
address[] calldata _addr,
uint256[] calldata _id,
uint256 _type,
uint256 _prop,
uint256[] calldata _val
) external;
function updateBatchRaw(
address[] calldata _addr,
uint256[] calldata _id,
uint256 _type,
uint24[10][] calldata _val
) external;
function remove(address _addr, uint256 _id, uint256 _type, uint256 _prop, uint256 _val) external;
function removeBatch(
address[] calldata _addr,
uint256[] calldata _id,
uint256 _type,
uint256[][] calldata _prop,
uint256[][] calldata _val
) external;
function get(address _addr, uint256 _id, uint256 _type, uint256 _prop) external returns (uint256);
function getRaw(address _addr, uint256 _id, uint256 _type) external returns (uint24[10] memory);
function getMulti(
address _addr,
uint256 _id,
uint256 _type,
uint256[] calldata _prop
) external returns (uint256[] memory result);
function getBatch(
address[] calldata _addr,
uint256[] calldata _id,
uint256 _type,
uint256 _prop
) external returns (uint256[] memory);
function getBatchMulti(
address[] calldata _addrs,
uint256[] calldata _ids,
uint256 _type,
uint256[] calldata _props
) external returns (uint256[][] memory);
function getRawBatch(
address[] calldata _addrs,
uint256[] calldata _ids,
uint256 _type
) external returns (uint24[10][] memory result);
}
文件 16 的 32:IBatchAdventurerGateway.sol
pragma solidity ^0.8.4;
interface IBatchAdventurerGateway {
function checkAddress(address _addr, bytes32[] calldata _proof) external view;
function checkAddressBatch(address[] calldata _addr, bytes32[][] calldata _proof) external view;
}
文件 17 的 32:IERC20.sol
pragma solidity ^0.8.0;
interface IERC20 {
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address to, uint256 amount) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(
address from,
address to,
uint256 amount
) external returns (bool);
}
文件 18 的 32:IERC20Bound.sol
pragma solidity ^0.8.4;
interface IERC20Bound {
function unbind(address _addresses) external;
function isUnbound(address _addr) external view returns (bool);
}
文件 19 的 32:IERC20Metadata.sol
pragma solidity ^0.8.0;
import "../IERC20.sol";
interface IERC20Metadata is IERC20 {
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function decimals() external view returns (uint8);
}
文件 20 的 32:IERC721A.sol
pragma solidity ^0.8.4;
interface IERC721A {
error ApprovalCallerNotOwnerNorApproved();
error ApprovalQueryForNonexistentToken();
error ApproveToCaller();
error BalanceQueryForZeroAddress();
error MintToZeroAddress();
error MintZeroQuantity();
error OwnerQueryForNonexistentToken();
error TransferCallerNotOwnerNorApproved();
error TransferFromIncorrectOwner();
error TransferToNonERC721ReceiverImplementer();
error TransferToZeroAddress();
error URIQueryForNonexistentToken();
error MintERC2309QuantityExceedsLimit();
error OwnershipNotInitializedForExtraData();
struct TokenOwnership {
address addr;
uint64 startTimestamp;
bool burned;
uint24 extraData;
}
function totalSupply() external view returns (uint256);
function supportsInterface(bytes4 interfaceId) external view returns (bool);
event Transfer(
address indexed from,
address indexed to,
uint256 indexed tokenId
);
event Approval(
address indexed owner,
address indexed approved,
uint256 indexed tokenId
);
event ApprovalForAll(
address indexed owner,
address indexed operator,
bool approved
);
function balanceOf(address owner) external view returns (uint256 balance);
function ownerOf(uint256 tokenId) external view returns (address owner);
function safeTransferFrom(
address from,
address to,
uint256 tokenId,
bytes calldata data
) external;
function safeTransferFrom(address from, address to, uint256 tokenId) external;
function transferFrom(address from, address to, uint256 tokenId) external;
function approve(address to, uint256 tokenId) external;
function setApprovalForAll(address operator, bool _approved) external;
function getApproved(
uint256 tokenId
) external view returns (address operator);
function isApprovedForAll(
address owner,
address operator
) external view returns (bool);
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function tokenURI(uint256 tokenId) external view returns (string memory);
event ConsecutiveTransfer(
uint256 indexed fromTokenId,
uint256 toTokenId,
address indexed from,
address indexed to
);
}
文件 21 的 32:IEpochConfigurable.sol
pragma solidity ^0.8.17;
interface IEpochConfigurable {
function currentEpoch() external view returns (uint);
function epochAtTimestamp(uint _timestamp) external view returns (uint);
}
文件 22 的 32:ILootBoxDispenser.sol
pragma solidity ^0.8.17;
interface ILootBoxDispenser {
function dispense(address _address, uint256 _id, uint256 _amount) external;
function dispenseBatch(
address _address,
uint256[] calldata _ids,
uint256[] calldata _amounts
) external;
event LootBoxesDispensed(address _address, uint256 _tokenId, uint256 _amount);
}
文件 23 的 32:IManager.sol
pragma solidity ^0.8.4;
interface IManager {
function isAdmin(address _addr) external view returns (bool);
function isManager(address _addr, uint256 _type) external view returns (bool);
function addManager(address _addr, uint256 _type) external;
function removeManager(address _addr, uint256 _type) external;
function addAdmin(address _addr) external;
function removeAdmin(address _addr) external;
}
文件 24 的 32:ITokenSpender.sol
pragma solidity ^0.8.17;
import "../Utils/IEpochConfigurable.sol";
uint constant SPENDER_ADVENTURER_BUCKET = 1;
uint constant SPENDER_REALM_BUCKET = 2;
interface ITokenSpender is IEpochConfigurable {
function getEpochValue(uint _epoch) external view returns (uint);
function getEpochValueBatch(
uint startEpoch,
uint endEpoch
) external view returns (uint[] memory result);
function getBucketEpochValueBatch(
uint _startEpoch,
uint _endEpoch,
uint _bucket
) external view returns (uint[] memory result);
function getEpochValueBatchTotal(
uint startEpoch,
uint endEpoch
) external view returns (uint result);
function getBucketEpochValueBatchTotal(
uint _startEpoch,
uint _endEpoch,
uint _bucket
) external view returns (uint result);
function spend(address _owner, uint _amount, uint _bucket) external;
}
文件 25 的 32:ManagerModifier.sol
pragma solidity ^0.8.4;
import "../Manager/IManager.sol";
abstract contract ManagerModifier {
IManager public immutable MANAGER;
constructor(address _manager) {
MANAGER = IManager(_manager);
}
modifier onlyAdmin() {
require(MANAGER.isAdmin(msg.sender), "Manager: Not an Admin");
_;
}
modifier onlyManager() {
require(MANAGER.isManager(msg.sender, 0), "Manager: Not manager");
_;
}
modifier onlyMinter() {
require(MANAGER.isManager(msg.sender, 1), "Manager: Not minter");
_;
}
modifier onlyTokenMinter() {
require(MANAGER.isManager(msg.sender, 2), "Manager: Not token minter");
_;
}
modifier onlyBinder() {
require(MANAGER.isManager(msg.sender, 3), "Manager: Not binder");
_;
}
modifier onlyConfigManager() {
require(MANAGER.isManager(msg.sender, 4), "Manager: Not config manager");
_;
}
modifier onlyTokenSpender() {
require(MANAGER.isManager(msg.sender, 5), "Manager: Not token spender");
_;
}
modifier onlyTokenEmitter() {
require(MANAGER.isManager(msg.sender, 6), "Manager: Not token emitter");
_;
}
modifier onlyPauser() {
require(
MANAGER.isAdmin(msg.sender) || MANAGER.isManager(msg.sender, 6),
"Manager: Not pauser"
);
_;
}
}
文件 26 的 32:MerkleProof.sol
pragma solidity ^0.8.0;
library MerkleProof {
function verify(
bytes32[] memory proof,
bytes32 root,
bytes32 leaf
) internal pure returns (bool) {
return processProof(proof, leaf) == root;
}
function verifyCalldata(
bytes32[] calldata proof,
bytes32 root,
bytes32 leaf
) internal pure returns (bool) {
return processProofCalldata(proof, leaf) == root;
}
function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) {
bytes32 computedHash = leaf;
for (uint256 i = 0; i < proof.length; i++) {
computedHash = _hashPair(computedHash, proof[i]);
}
return computedHash;
}
function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) internal pure returns (bytes32) {
bytes32 computedHash = leaf;
for (uint256 i = 0; i < proof.length; i++) {
computedHash = _hashPair(computedHash, proof[i]);
}
return computedHash;
}
function multiProofVerify(
bytes32[] memory proof,
bool[] memory proofFlags,
bytes32 root,
bytes32[] memory leaves
) internal pure returns (bool) {
return processMultiProof(proof, proofFlags, leaves) == root;
}
function multiProofVerifyCalldata(
bytes32[] calldata proof,
bool[] calldata proofFlags,
bytes32 root,
bytes32[] memory leaves
) internal pure returns (bool) {
return processMultiProofCalldata(proof, proofFlags, leaves) == root;
}
function processMultiProof(
bytes32[] memory proof,
bool[] memory proofFlags,
bytes32[] memory leaves
) internal pure returns (bytes32 merkleRoot) {
uint256 leavesLen = leaves.length;
uint256 totalHashes = proofFlags.length;
require(leavesLen + proof.length - 1 == totalHashes, "MerkleProof: invalid multiproof");
bytes32[] memory hashes = new bytes32[](totalHashes);
uint256 leafPos = 0;
uint256 hashPos = 0;
uint256 proofPos = 0;
for (uint256 i = 0; i < totalHashes; i++) {
bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];
bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++];
hashes[i] = _hashPair(a, b);
}
if (totalHashes > 0) {
return hashes[totalHashes - 1];
} else if (leavesLen > 0) {
return leaves[0];
} else {
return proof[0];
}
}
function processMultiProofCalldata(
bytes32[] calldata proof,
bool[] calldata proofFlags,
bytes32[] memory leaves
) internal pure returns (bytes32 merkleRoot) {
uint256 leavesLen = leaves.length;
uint256 totalHashes = proofFlags.length;
require(leavesLen + proof.length - 1 == totalHashes, "MerkleProof: invalid multiproof");
bytes32[] memory hashes = new bytes32[](totalHashes);
uint256 leafPos = 0;
uint256 hashPos = 0;
uint256 proofPos = 0;
for (uint256 i = 0; i < totalHashes; i++) {
bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];
bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++];
hashes[i] = _hashPair(a, b);
}
if (totalHashes > 0) {
return hashes[totalHashes - 1];
} else if (leavesLen > 0) {
return leaves[0];
} else {
return proof[0];
}
}
function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) {
return a < b ? _efficientHash(a, b) : _efficientHash(b, a);
}
function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) {
assembly {
mstore(0x00, a)
mstore(0x20, b)
value := keccak256(0x00, 0x40)
}
}
}
文件 27 的 32:Pausable.sol
pragma solidity ^0.8.0;
import "../utils/Context.sol";
abstract contract Pausable is Context {
event Paused(address account);
event Unpaused(address account);
bool private _paused;
constructor() {
_paused = false;
}
modifier whenNotPaused() {
_requireNotPaused();
_;
}
modifier whenPaused() {
_requirePaused();
_;
}
function paused() public view virtual returns (bool) {
return _paused;
}
function _requireNotPaused() internal view virtual {
require(!paused(), "Pausable: paused");
}
function _requirePaused() internal view virtual {
require(paused(), "Pausable: not paused");
}
function _pause() internal virtual whenNotPaused {
_paused = true;
emit Paused(_msgSender());
}
function _unpause() internal virtual whenPaused {
_paused = false;
emit Unpaused(_msgSender());
}
}
文件 28 的 32:ReentrancyGuard.sol
pragma solidity ^0.8.0;
abstract contract ReentrancyGuard {
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
constructor() {
_status = _NOT_ENTERED;
}
modifier nonReentrant() {
_nonReentrantBefore();
_;
_nonReentrantAfter();
}
function _nonReentrantBefore() private {
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
_status = _ENTERED;
}
function _nonReentrantAfter() private {
_status = _NOT_ENTERED;
}
}
文件 29 的 32:SafeERC20.sol
pragma solidity ^0.8.0;
import "../IERC20.sol";
import "../extensions/draft-IERC20Permit.sol";
import "../../../utils/Address.sol";
library SafeERC20 {
using Address for address;
function safeTransfer(
IERC20 token,
address to,
uint256 value
) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
function safeTransferFrom(
IERC20 token,
address from,
address to,
uint256 value
) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
}
function safeApprove(
IERC20 token,
address spender,
uint256 value
) internal {
require(
(value == 0) || (token.allowance(address(this), spender) == 0),
"SafeERC20: approve from non-zero to non-zero allowance"
);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
function safeIncreaseAllowance(
IERC20 token,
address spender,
uint256 value
) internal {
uint256 newAllowance = token.allowance(address(this), spender) + value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
function safeDecreaseAllowance(
IERC20 token,
address spender,
uint256 value
) internal {
unchecked {
uint256 oldAllowance = token.allowance(address(this), spender);
require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
uint256 newAllowance = oldAllowance - value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
}
function safePermit(
IERC20Permit token,
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) internal {
uint256 nonceBefore = token.nonces(owner);
token.permit(owner, spender, value, deadline, v, r, s);
uint256 nonceAfter = token.nonces(owner);
require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed");
}
function _callOptionalReturn(IERC20 token, bytes memory data) private {
bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
if (returndata.length > 0) {
require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
}
}
文件 30 的 32:TraitConstants.sol
pragma solidity ^0.8.17;
library traits {
uint256 public constant ADV_TRAIT_GROUP_BASE = 0;
uint256 public constant ADV_TRAIT_BASE_LEVEL = 0;
uint256 public constant ADV_TRAIT_BASE_XP = 1;
uint256 public constant ADV_TRAIT_BASE_STRENGTH = 2;
uint256 public constant ADV_TRAIT_BASE_DEXTERITY = 3;
uint256 public constant ADV_TRAIT_BASE_CONSTITUTION = 4;
uint256 public constant ADV_TRAIT_BASE_INTELLIGENCE = 5;
uint256 public constant ADV_TRAIT_BASE_WISDOM = 6;
uint256 public constant ADV_TRAIT_BASE_CHARISMA = 7;
uint256 public constant ADV_TRAIT_BASE_CLASS = 8;
uint256 public constant ADV_TRAIT_GROUP_ADVANCED = 1;
uint256 public constant ADV_TRAIT_ADVANCED_ARCHETYPE = 0;
uint256 public constant ADV_TRAIT_ADVANCED_PROFESSION = 1;
uint256 public constant ADV_TRAIT_ADVANCED_TRAINING_POINTS = 2;
uint256 public constant LEGACY_ADV_BASE_TRAIT_XP = 0;
uint256 public constant LEGACY_ADV_BASE_TRAIT_XP_BROKEN = 1;
uint256 public constant LEGACY_ADV_BASE_TRAIT_STRENGTH = 2;
uint256 public constant LEGACY_ADV_BASE_TRAIT_DEXTERITY = 3;
uint256 public constant LEGACY_ADV_BASE_TRAIT_CONSTITUTION = 4;
uint256 public constant LEGACY_ADV_BASE_TRAIT_INTELLIGENCE = 5;
uint256 public constant LEGACY_ADV_BASE_TRAIT_WISDOM = 6;
uint256 public constant LEGACY_ADV_BASE_TRAIT_CHARISMA = 7;
uint256 public constant LEGACY_ADV_BASE_TRAIT_HP = 8;
uint256 public constant LEGACY_ADV_BASE_TRAIT_HP_USED = 9;
uint256 public constant LEGACY_ADV_AOV_TRAIT_LEVEL = 0;
uint256 public constant LEGACY_ADV_AOV_TRAIT_ARCHETYPE = 1;
uint256 public constant LEGACY_ADV_AOV_TRAIT_CLASS = 2;
uint256 public constant LEGACY_ADV_AOV_TRAIT_PROFESSION = 3;
function baseTraitNames() public pure returns (string[10] memory) {
return [
"Level",
"XP",
"Strength",
"Dexterity",
"Constitution",
"Intelligence",
"Wisdom",
"Charisma",
"Class",
""
];
}
function advancedTraitNames() public pure returns (string[2] memory) {
return ["Archetype", "Profession"];
}
function baseTraitName(uint256 traitId) public pure returns (string memory) {
return baseTraitNames()[traitId];
}
function advancedTraitName(uint256 traitId) public pure returns (string memory) {
return advancedTraitNames()[traitId];
}
}
文件 31 的 32:Transcendence.sol
pragma solidity ^0.8.17;
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import { MerkleProof } from "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol";
import "../Adventurer/IBatchAdventurerData.sol";
import "../Anima/Anima.sol";
import "../Adventurer/IAovLegacy.sol";
import "../Utils/ArrayUtils.sol";
import "../Utils/Epoch.sol";
import "../lib/ERC721A.sol";
import "../Manager/ManagerModifier.sol";
import "../Lootbox/ILootBoxDispenser.sol";
import "../Action/IActionPermit.sol";
import "../Action/Actions.sol";
import "../Adventurer/TraitConstants.sol";
import { EpochConfigurable } from "../Utils/EpochConfigurable.sol";
import "../Adventurer/IBatchAdventurerGateway.sol";
import "../ERC20/ITokenSpender.sol";
struct TranscendenceConfig {
uint256 baseCostMultiplier;
uint16 epochsPerLevel;
uint16 epochDiscount;
uint16 maxCooldownEpochs;
uint16 maxCostEpochs;
uint16 costPerEpoch;
uint16 costPerLevel;
uint16 costDiscount;
uint16 costDivider;
uint16 minTrainingPointsPerTranscendence;
}
uint256 constant OLD_MAX_TRANSCENDENCE = 16 days;
struct TranscendenceMemory {
TranscendenceConfig config;
uint128 epochConfig;
uint maxProfession;
uint24[10][] baseStats;
uint24[10][] advancedStats;
uint totalAnima;
LootBoxMemory lootBoxes;
address addr;
uint256 adventurerId;
uint256 archetypeId;
bytes32[] proof;
bytes32[] archetypeProof;
uint256[] requiredEpochs;
uint256 profession;
uint level;
uint class;
uint currentArchetype;
bool isSameArchetype;
uint cost;
uint rewardTokenId;
}
struct LootBoxMemory {
uint[] ids;
uint[] amounts;
bool atLeastOneDispensed;
}
struct TranscendenceRequest {
address[] _addresses;
uint256[] _adventurerIds;
bytes32[][] _proofs;
uint256[] _archetypeIds;
bytes32[][] _archetypeProofs;
uint256[] _professions;
}
contract Transcendence is EpochConfigurable, ReentrancyGuard {
using Epoch for uint256;
IBatchAdventurerData public immutable ADVENTURER_DATA;
IBatchAdventurerGateway public immutable GATEWAY;
IActionPermit public immutable ACTION_PERMIT;
ITokenSpender public immutable TOKEN_SPENDER;
IAovLegacy public immutable LEGACY;
ILootBoxDispenser public immutable LOOT_BOX_DISPENSER;
address public immutable AOV_ADDRESS;
TranscendenceConfig public CONFIG;
uint256 public immutable DEPLOY_TIME;
uint256 public maxProfession;
bytes32 public merkleRoot;
uint256[] rewardTokenIds;
uint256[] rewardTranscendenceLevelCaps;
event Transcended(
address addr,
uint256 adventurerId,
uint256 archetypeId,
uint256 profession,
uint256 cost,
uint256 rewardTokenId
);
constructor(
address _manager,
address _adventurerData,
address _tokenSpender,
address _gateway,
address _actionPermit,
address _legacy,
address _lootBoxDispenser,
address _aov,
bytes32 _merkleRoot
) EpochConfigurable(_manager, 1 days, 0 hours) {
CONFIG.baseCostMultiplier = 1 ether;
CONFIG.costDiscount = 45;
CONFIG.epochDiscount = 1;
CONFIG.epochsPerLevel = 2;
CONFIG.maxCostEpochs = 30;
CONFIG.maxCooldownEpochs = 20;
CONFIG.costPerEpoch = 1;
CONFIG.costDivider = 5;
ADVENTURER_DATA = IBatchAdventurerData(_adventurerData);
TOKEN_SPENDER = ITokenSpender(_tokenSpender);
GATEWAY = IBatchAdventurerGateway(_gateway);
ACTION_PERMIT = IActionPermit(_actionPermit);
LEGACY = IAovLegacy(_legacy);
LOOT_BOX_DISPENSER = ILootBoxDispenser(_lootBoxDispenser);
AOV_ADDRESS = _aov;
merkleRoot = _merkleRoot;
maxProfession = 3;
DEPLOY_TIME = block.timestamp;
}
function transcend(
address[] calldata _addresses,
uint256[] calldata _adventurerIds,
bytes32[][] calldata _proofs,
uint256[] calldata _archetypeIds,
bytes32[][] calldata _archetypeProofs,
uint256[] calldata _professions
) external nonReentrant whenNotPaused {
ArrayUtils.ensureSameLength(
_addresses.length,
_adventurerIds.length,
_archetypeIds.length,
_professions.length
);
ArrayUtils.checkForDuplicates(_addresses, _adventurerIds);
TranscendenceMemory memory mem;
mem.config = CONFIG;
mem.epochConfig = EPOCH_CONFIG;
mem.advancedStats = ADVENTURER_DATA.getRawBatch(
_addresses,
_adventurerIds,
traits.ADV_TRAIT_GROUP_ADVANCED
);
mem.baseStats = ADVENTURER_DATA.getRawBatch(
_addresses,
_adventurerIds,
traits.ADV_TRAIT_GROUP_BASE
);
mem.lootBoxes = _prepareLootboxes();
mem.maxProfession = maxProfession;
GATEWAY.checkAddressBatch(_addresses, _proofs);
mem.requiredEpochs = new uint256[](_addresses.length);
for (uint256 j = 0; j < _adventurerIds.length; j++) {
mem.addr = _addresses[j];
mem.adventurerId = _adventurerIds[j];
mem.archetypeId = _archetypeIds[j];
mem.proof = _proofs[j];
mem.archetypeProof = _archetypeProofs[j];
mem.profession = _professions[j];
mem.level = mem.baseStats[j][traits.ADV_TRAIT_BASE_LEVEL];
mem.class = mem.baseStats[j][traits.ADV_TRAIT_BASE_CLASS];
mem.requiredEpochs[j] = _cooldownInEpochs(
mem.level,
mem.config,
mem.config.maxCooldownEpochs
);
require(
mem.profession <= mem.maxProfession,
"Transcendence: Profession not valid"
);
mem.advancedStats[j][traits.ADV_TRAIT_ADVANCED_PROFESSION] = uint24(
mem.profession
);
mem.advancedStats[j][traits.ADV_TRAIT_ADVANCED_TRAINING_POINTS] += uint24(
mem.requiredEpochs[j] < mem.config.minTrainingPointsPerTranscendence
? mem.config.minTrainingPointsPerTranscendence
: mem.requiredEpochs[j]
);
if (mem.requiredEpochs[j] > mem.config.epochsPerLevel) {
mem.requiredEpochs[j] -= mem.config.epochsPerLevel;
} else {
mem.requiredEpochs[j] = 0;
}
mem.currentArchetype = uint(
mem.advancedStats[j][traits.ADV_TRAIT_ADVANCED_ARCHETYPE]
);
mem.isSameArchetype = mem.currentArchetype == mem.archetypeId;
if (!mem.isSameArchetype && mem.addr == AOV_ADDRESS) {
bytes32 leaf = keccak256(abi.encodePacked(mem.archetypeId, mem.class));
bool isValidLeaf = MerkleProof.verify(
mem.archetypeProof,
merkleRoot,
leaf
);
require(
isValidLeaf,
"Transcendence: Variant class does not match your Adventurer class"
);
mem.advancedStats[j][traits.ADV_TRAIT_ADVANCED_ARCHETYPE] = uint24(
mem.archetypeId
);
}
mem.cost = _animaCost(mem.addr, mem.level, mem.config);
mem.totalAnima += mem.cost;
LEGACY.chronicle(
mem.addr,
mem.adventurerId,
mem.currentArchetype,
mem.archetypeId
);
for (
uint16 rewardIndex = 0;
rewardIndex < rewardTranscendenceLevelCaps.length &&
mem.level > rewardTranscendenceLevelCaps[rewardIndex];
rewardIndex++
) {
mem.rewardTokenId = rewardTokenIds[rewardIndex];
}
if (mem.rewardTokenId > 0) {
mem.lootBoxes.amounts[mem.rewardTokenId - 1]++;
mem.lootBoxes.atLeastOneDispensed = true;
}
emit Transcended(
mem.addr,
mem.adventurerId,
mem.archetypeId,
mem.profession,
mem.cost,
mem.rewardTokenId
);
}
ACTION_PERMIT.checkAndMarkActionCompleteMany(
msg.sender,
_addresses,
_adventurerIds,
_proofs,
ACTION_ADVENTURER_TRANSCENDENCE,
mem.requiredEpochs,
mem.epochConfig
);
TOKEN_SPENDER.spend(msg.sender, mem.totalAnima, SPENDER_ADVENTURER_BUCKET);
ADVENTURER_DATA.addBatch(
_addresses,
_adventurerIds,
traits.ADV_TRAIT_GROUP_BASE,
traits.LEGACY_ADV_AOV_TRAIT_LEVEL,
1
);
if (mem.lootBoxes.atLeastOneDispensed) {
LOOT_BOX_DISPENSER.dispenseBatch(
msg.sender,
mem.lootBoxes.ids,
mem.lootBoxes.amounts
);
}
ADVENTURER_DATA.updateBatchRaw(
_addresses,
_adventurerIds,
traits.ADV_TRAIT_GROUP_ADVANCED,
mem.advancedStats
);
}
function _cooldownInEpochs(
uint level,
TranscendenceConfig memory _config,
uint16 limit
) internal pure returns (uint256 result) {
result = level * uint(_config.epochsPerLevel);
if (result < _config.epochDiscount) {
return 0;
}
result -= _config.epochDiscount;
if (result > uint(limit)) {
result = uint(limit);
}
}
function _animaCost(
address _address,
uint _level,
TranscendenceConfig memory _config
) internal view returns (uint256 result) {
result =
_config.costPerLevel +
_cooldownInEpochs(_level, _config, _config.maxCostEpochs) *
_config.costPerEpoch;
result *= _level;
if (result <= _config.costDiscount) {
return 0;
}
result -= _config.costDiscount;
result *= _config.baseCostMultiplier;
if (_address != AOV_ADDRESS) {
result = result / _config.costDivider;
}
}
function _prepareLootboxes()
internal
pure
returns (LootBoxMemory memory result)
{
result.ids = new uint[](4);
result.amounts = new uint[](4);
for (uint i = 0; i < 4; i++) {
result.ids[i] = i + 1;
}
}
function updateMaxProfession(uint256 _value) external onlyAdmin {
maxProfession = _value;
}
function updateMerkleRoot(bytes32 _value) external onlyAdmin {
merkleRoot = _value;
}
function configureRewards(
uint256[] calldata _rewardTranscendenceLevelCaps,
uint256[] calldata _rewardTokenIds
) external onlyAdmin {
require(_rewardTranscendenceLevelCaps.length == _rewardTokenIds.length);
rewardTranscendenceLevelCaps = _rewardTranscendenceLevelCaps;
rewardTokenIds = _rewardTokenIds;
}
function updateTranscendenceConfig(
TranscendenceConfig calldata _config
) external onlyAdmin {
CONFIG = _config;
}
}
文件 32 的 32:draft-IERC20Permit.sol
pragma solidity ^0.8.0;
interface IERC20Permit {
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
function nonces(address owner) external view returns (uint256);
function DOMAIN_SEPARATOR() external view returns (bytes32);
}
{
"compilationTarget": {
"contracts/Trascendence/Transcendence.sol": "Transcendence"
},
"evmVersion": "paris",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"inputs":[{"internalType":"address","name":"_manager","type":"address"},{"internalType":"address","name":"_adventurerData","type":"address"},{"internalType":"address","name":"_tokenSpender","type":"address"},{"internalType":"address","name":"_gateway","type":"address"},{"internalType":"address","name":"_actionPermit","type":"address"},{"internalType":"address","name":"_legacy","type":"address"},{"internalType":"address","name":"_lootBoxDispenser","type":"address"},{"internalType":"address","name":"_aov","type":"address"},{"internalType":"bytes32","name":"_merkleRoot","type":"bytes32"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint256","name":"_length1","type":"uint256"},{"internalType":"uint256","name":"_length2","type":"uint256"}],"name":"ArrayLengthMismatch","type":"error"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"InvalidArrayOrder","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"addr","type":"address"},{"indexed":false,"internalType":"uint256","name":"adventurerId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"archetypeId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"profession","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"cost","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"rewardTokenId","type":"uint256"}],"name":"Transcended","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[],"name":"ACTION_PERMIT","outputs":[{"internalType":"contract IActionPermit","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ADVENTURER_DATA","outputs":[{"internalType":"contract IBatchAdventurerData","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"AOV_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"CONFIG","outputs":[{"internalType":"uint256","name":"baseCostMultiplier","type":"uint256"},{"internalType":"uint16","name":"epochsPerLevel","type":"uint16"},{"internalType":"uint16","name":"epochDiscount","type":"uint16"},{"internalType":"uint16","name":"maxCooldownEpochs","type":"uint16"},{"internalType":"uint16","name":"maxCostEpochs","type":"uint16"},{"internalType":"uint16","name":"costPerEpoch","type":"uint16"},{"internalType":"uint16","name":"costPerLevel","type":"uint16"},{"internalType":"uint16","name":"costDiscount","type":"uint16"},{"internalType":"uint16","name":"costDivider","type":"uint16"},{"internalType":"uint16","name":"minTrainingPointsPerTranscendence","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEPLOY_TIME","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"EPOCH_CONFIG","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"GATEWAY","outputs":[{"internalType":"contract IBatchAdventurerGateway","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"LEGACY","outputs":[{"internalType":"contract IAovLegacy","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"LOOT_BOX_DISPENSER","outputs":[{"internalType":"contract ILootBoxDispenser","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MANAGER","outputs":[{"internalType":"contract IManager","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TOKEN_SPENDER","outputs":[{"internalType":"contract ITokenSpender","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_rewardTranscendenceLevelCaps","type":"uint256[]"},{"internalType":"uint256[]","name":"_rewardTokenIds","type":"uint256[]"}],"name":"configureRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"currentEpoch","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_timestamp","type":"uint256"}],"name":"epochAtTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxProfession","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"merkleRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_addresses","type":"address[]"},{"internalType":"uint256[]","name":"_adventurerIds","type":"uint256[]"},{"internalType":"bytes32[][]","name":"_proofs","type":"bytes32[][]"},{"internalType":"uint256[]","name":"_archetypeIds","type":"uint256[]"},{"internalType":"bytes32[][]","name":"_archetypeProofs","type":"bytes32[][]"},{"internalType":"uint256[]","name":"_professions","type":"uint256[]"}],"name":"transcend","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"duration","type":"uint64"},{"internalType":"uint64","name":"offset","type":"uint64"}],"name":"updateEpochConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"updateMaxProfession","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_value","type":"bytes32"}],"name":"updateMerkleRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"baseCostMultiplier","type":"uint256"},{"internalType":"uint16","name":"epochsPerLevel","type":"uint16"},{"internalType":"uint16","name":"epochDiscount","type":"uint16"},{"internalType":"uint16","name":"maxCooldownEpochs","type":"uint16"},{"internalType":"uint16","name":"maxCostEpochs","type":"uint16"},{"internalType":"uint16","name":"costPerEpoch","type":"uint16"},{"internalType":"uint16","name":"costPerLevel","type":"uint16"},{"internalType":"uint16","name":"costDiscount","type":"uint16"},{"internalType":"uint16","name":"costDivider","type":"uint16"},{"internalType":"uint16","name":"minTrainingPointsPerTranscendence","type":"uint16"}],"internalType":"struct TranscendenceConfig","name":"_config","type":"tuple"}],"name":"updateTranscendenceConfig","outputs":[],"stateMutability":"nonpayable","type":"function"}]