编译器
0.8.25+commit.b61c2a91
文件 1 的 22:Context.sol
pragma solidity ^0.8.20;
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}
文件 2 的 22:ECDSA.sol
pragma solidity ^0.8.20;
library ECDSA {
enum RecoverError {
NoError,
InvalidSignature,
InvalidSignatureLength,
InvalidSignatureS
}
error ECDSAInvalidSignature();
error ECDSAInvalidSignatureLength(uint256 length);
error ECDSAInvalidSignatureS(bytes32 s);
function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError, bytes32) {
if (signature.length == 65) {
bytes32 r;
bytes32 s;
uint8 v;
assembly {
r := mload(add(signature, 0x20))
s := mload(add(signature, 0x40))
v := byte(0, mload(add(signature, 0x60)))
}
return tryRecover(hash, v, r, s);
} else {
return (address(0), RecoverError.InvalidSignatureLength, bytes32(signature.length));
}
}
function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {
(address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, signature);
_throwError(error, errorArg);
return recovered;
}
function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError, bytes32) {
unchecked {
bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);
uint8 v = uint8((uint256(vs) >> 255) + 27);
return tryRecover(hash, v, r, s);
}
}
function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {
(address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, r, vs);
_throwError(error, errorArg);
return recovered;
}
function tryRecover(
bytes32 hash,
uint8 v,
bytes32 r,
bytes32 s
) internal pure returns (address, RecoverError, bytes32) {
if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {
return (address(0), RecoverError.InvalidSignatureS, s);
}
address signer = ecrecover(hash, v, r, s);
if (signer == address(0)) {
return (address(0), RecoverError.InvalidSignature, bytes32(0));
}
return (signer, RecoverError.NoError, bytes32(0));
}
function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {
(address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, v, r, s);
_throwError(error, errorArg);
return recovered;
}
function _throwError(RecoverError error, bytes32 errorArg) private pure {
if (error == RecoverError.NoError) {
return;
} else if (error == RecoverError.InvalidSignature) {
revert ECDSAInvalidSignature();
} else if (error == RecoverError.InvalidSignatureLength) {
revert ECDSAInvalidSignatureLength(uint256(errorArg));
} else if (error == RecoverError.InvalidSignatureS) {
revert ECDSAInvalidSignatureS(errorArg);
}
}
}
文件 3 的 22:EIP712.sol
pragma solidity ^0.8.20;
import {MessageHashUtils} from "./MessageHashUtils.sol";
import {ShortStrings, ShortString} from "../ShortStrings.sol";
import {IERC5267} from "../../interfaces/IERC5267.sol";
abstract contract EIP712 is IERC5267 {
using ShortStrings for *;
bytes32 private constant TYPE_HASH =
keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)");
bytes32 private immutable _cachedDomainSeparator;
uint256 private immutable _cachedChainId;
address private immutable _cachedThis;
bytes32 private immutable _hashedName;
bytes32 private immutable _hashedVersion;
ShortString private immutable _name;
ShortString private immutable _version;
string private _nameFallback;
string private _versionFallback;
constructor(string memory name, string memory version) {
_name = name.toShortStringWithFallback(_nameFallback);
_version = version.toShortStringWithFallback(_versionFallback);
_hashedName = keccak256(bytes(name));
_hashedVersion = keccak256(bytes(version));
_cachedChainId = block.chainid;
_cachedDomainSeparator = _buildDomainSeparator();
_cachedThis = address(this);
}
function _domainSeparatorV4() internal view returns (bytes32) {
if (address(this) == _cachedThis && block.chainid == _cachedChainId) {
return _cachedDomainSeparator;
} else {
return _buildDomainSeparator();
}
}
function _buildDomainSeparator() private view returns (bytes32) {
return keccak256(abi.encode(TYPE_HASH, _hashedName, _hashedVersion, block.chainid, address(this)));
}
function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {
return MessageHashUtils.toTypedDataHash(_domainSeparatorV4(), structHash);
}
function eip712Domain()
public
view
virtual
returns (
bytes1 fields,
string memory name,
string memory version,
uint256 chainId,
address verifyingContract,
bytes32 salt,
uint256[] memory extensions
)
{
return (
hex"0f",
_EIP712Name(),
_EIP712Version(),
block.chainid,
address(this),
bytes32(0),
new uint256[](0)
);
}
function _EIP712Name() internal view returns (string memory) {
return _name.toStringWithFallback(_nameFallback);
}
function _EIP712Version() internal view returns (string memory) {
return _version.toStringWithFallback(_versionFallback);
}
}
文件 4 的 22:ERC20.sol
pragma solidity ^0.8.20;
import {IERC20} from "./IERC20.sol";
import {IERC20Metadata} from "./extensions/IERC20Metadata.sol";
import {Context} from "../../utils/Context.sol";
import {IERC20Errors} from "../../interfaces/draft-IERC6093.sol";
abstract contract ERC20 is Context, IERC20, IERC20Metadata, IERC20Errors {
mapping(address account => uint256) private _balances;
mapping(address account => mapping(address spender => 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 returns (string memory) {
return _name;
}
function symbol() public view virtual returns (string memory) {
return _symbol;
}
function decimals() public view virtual returns (uint8) {
return 18;
}
function totalSupply() public view virtual returns (uint256) {
return _totalSupply;
}
function balanceOf(address account) public view virtual returns (uint256) {
return _balances[account];
}
function transfer(address to, uint256 value) public virtual returns (bool) {
address owner = _msgSender();
_transfer(owner, to, value);
return true;
}
function allowance(address owner, address spender) public view virtual returns (uint256) {
return _allowances[owner][spender];
}
function approve(address spender, uint256 value) public virtual returns (bool) {
address owner = _msgSender();
_approve(owner, spender, value);
return true;
}
function transferFrom(address from, address to, uint256 value) public virtual returns (bool) {
address spender = _msgSender();
_spendAllowance(from, spender, value);
_transfer(from, to, value);
return true;
}
function _transfer(address from, address to, uint256 value) internal {
if (from == address(0)) {
revert ERC20InvalidSender(address(0));
}
if (to == address(0)) {
revert ERC20InvalidReceiver(address(0));
}
_update(from, to, value);
}
function _update(address from, address to, uint256 value) internal virtual {
if (from == address(0)) {
_totalSupply += value;
} else {
uint256 fromBalance = _balances[from];
if (fromBalance < value) {
revert ERC20InsufficientBalance(from, fromBalance, value);
}
unchecked {
_balances[from] = fromBalance - value;
}
}
if (to == address(0)) {
unchecked {
_totalSupply -= value;
}
} else {
unchecked {
_balances[to] += value;
}
}
emit Transfer(from, to, value);
}
function _mint(address account, uint256 value) internal {
if (account == address(0)) {
revert ERC20InvalidReceiver(address(0));
}
_update(address(0), account, value);
}
function _burn(address account, uint256 value) internal {
if (account == address(0)) {
revert ERC20InvalidSender(address(0));
}
_update(account, address(0), value);
}
function _approve(address owner, address spender, uint256 value) internal {
_approve(owner, spender, value, true);
}
function _approve(address owner, address spender, uint256 value, bool emitEvent) internal virtual {
if (owner == address(0)) {
revert ERC20InvalidApprover(address(0));
}
if (spender == address(0)) {
revert ERC20InvalidSpender(address(0));
}
_allowances[owner][spender] = value;
if (emitEvent) {
emit Approval(owner, spender, value);
}
}
function _spendAllowance(address owner, address spender, uint256 value) internal virtual {
uint256 currentAllowance = allowance(owner, spender);
if (currentAllowance != type(uint256).max) {
if (currentAllowance < value) {
revert ERC20InsufficientAllowance(spender, currentAllowance, value);
}
unchecked {
_approve(owner, spender, currentAllowance - value, false);
}
}
}
}
文件 5 的 22:EnumerableSet.sol
pragma solidity ^0.8.20;
library EnumerableSet {
struct Set {
bytes32[] _values;
mapping(bytes32 value => uint256) _positions;
}
function _add(Set storage set, bytes32 value) private returns (bool) {
if (!_contains(set, value)) {
set._values.push(value);
set._positions[value] = set._values.length;
return true;
} else {
return false;
}
}
function _remove(Set storage set, bytes32 value) private returns (bool) {
uint256 position = set._positions[value];
if (position != 0) {
uint256 valueIndex = position - 1;
uint256 lastIndex = set._values.length - 1;
if (valueIndex != lastIndex) {
bytes32 lastValue = set._values[lastIndex];
set._values[valueIndex] = lastValue;
set._positions[lastValue] = position;
}
set._values.pop();
delete set._positions[value];
return true;
} else {
return false;
}
}
function _contains(Set storage set, bytes32 value) private view returns (bool) {
return set._positions[value] != 0;
}
function _length(Set storage set) private view returns (uint256) {
return set._values.length;
}
function _at(Set storage set, uint256 index) private view returns (bytes32) {
return set._values[index];
}
function _values(Set storage set) private view returns (bytes32[] memory) {
return set._values;
}
struct Bytes32Set {
Set _inner;
}
function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {
return _add(set._inner, value);
}
function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {
return _remove(set._inner, value);
}
function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {
return _contains(set._inner, value);
}
function length(Bytes32Set storage set) internal view returns (uint256) {
return _length(set._inner);
}
function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {
return _at(set._inner, index);
}
function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {
bytes32[] memory store = _values(set._inner);
bytes32[] memory result;
assembly {
result := store
}
return result;
}
struct AddressSet {
Set _inner;
}
function add(AddressSet storage set, address value) internal returns (bool) {
return _add(set._inner, bytes32(uint256(uint160(value))));
}
function remove(AddressSet storage set, address value) internal returns (bool) {
return _remove(set._inner, bytes32(uint256(uint160(value))));
}
function contains(AddressSet storage set, address value) internal view returns (bool) {
return _contains(set._inner, bytes32(uint256(uint160(value))));
}
function length(AddressSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
function at(AddressSet storage set, uint256 index) internal view returns (address) {
return address(uint160(uint256(_at(set._inner, index))));
}
function values(AddressSet storage set) internal view returns (address[] memory) {
bytes32[] memory store = _values(set._inner);
address[] memory result;
assembly {
result := store
}
return result;
}
struct UintSet {
Set _inner;
}
function add(UintSet storage set, uint256 value) internal returns (bool) {
return _add(set._inner, bytes32(value));
}
function remove(UintSet storage set, uint256 value) internal returns (bool) {
return _remove(set._inner, bytes32(value));
}
function contains(UintSet storage set, uint256 value) internal view returns (bool) {
return _contains(set._inner, bytes32(value));
}
function length(UintSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
function at(UintSet storage set, uint256 index) internal view returns (uint256) {
return uint256(_at(set._inner, index));
}
function values(UintSet storage set) internal view returns (uint256[] memory) {
bytes32[] memory store = _values(set._inner);
uint256[] memory result;
assembly {
result := store
}
return result;
}
}
文件 6 的 22:HeroglyphAttestation.sol
pragma solidity ^0.8.25;
import { IHeroglyphAttestation } from "./IHeroglyphAttestation.sol";
import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";
import { SendNativeHelper } from "./SendNativeHelper.sol";
import { IValidatorIdentityV2 } from "./identity/wallet/v2/IValidatorIdentityV2.sol";
import { EnumerableSet } from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
import { SignatureChecker } from "@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol";
import { EIP712 } from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";
contract HeroglyphAttestation is IHeroglyphAttestation, ERC20, Ownable, SendNativeHelper, EIP712 {
using EnumerableSet for EnumerableSet.UintSet;
bytes32 public constant PERMIT_TYPEHASH = 0x86f00204b857ac7ae88c83be689a16079dab37b4bb4cbd8791afa0840efc2638;
uint32 public constant MAX_EPOCHS_LOOP = 68;
uint32 public constant FINALIZED_EPOCH_DELAY = 25 minutes;
uint32 public constant START_CLAIMING_EPOCH = 285_400;
uint32 public constant EPOCH_30_DAYS = 6750;
uint32 public constant START_CLAIMING_TIMESTAMP = 1_716_417_623;
uint32 public constant MAX_EPOCHS = 100;
uint32 public constant MAX_VALIDATORS = 100;
uint32 public constant CLAIM_REQUEST_TIMEOUT = 4 hours;
uint32 public constant IDLE_WAIT = 2 hours;
IValidatorIdentityV2 public validatorIdentity;
address public dedicatedMsgSender;
uint32 public timePerEpoch;
uint256 public attestationPointRate;
uint256 public sendingBatchesSize;
bool public isSoulbound;
bool public pausePermit;
mapping(uint32 validatorIndex => uint32 highestEpoch) internal latestEpochHeadRequested;
mapping(uint32 headEpoch => uint64[]) internal headEpochBatchIds;
mapping(uint32 validatorId => uint32) internal penalityPoints;
mapping(address => bool) public hasTransferPermission;
mapping(address => address) public redirectBadges;
mapping(address => uint32) public redirectNonce;
EnumerableSet.UintSet internal idleBatchIds;
mapping(uint64 => BatchRequest) internal allBatches;
uint64 public currentBatchId;
modifier onlyDedicatedMsgSender() {
if (msg.sender != dedicatedMsgSender) revert NotDedicatedMsgSender();
_;
}
constructor(address _dedicatedMsgSender, address _validatorIdentity, address _owner)
EIP712("HeroglyphAttestation", "v1")
ERC20("Badges", "BADGES")
Ownable(_owner)
{
dedicatedMsgSender = _dedicatedMsgSender;
validatorIdentity = IValidatorIdentityV2(_validatorIdentity);
timePerEpoch = 12 * 32;
attestationPointRate = 0.000297 ether;
sendingBatchesSize = 15;
isSoulbound = true;
}
function createAttestationRequest(string[] calldata _identityNames) external {
if (block.timestamp < START_CLAIMING_TIMESTAMP) revert CreateAttestationRequestIsNotActive();
uint32 timePerEpochCached = timePerEpoch;
uint32 epochHead;
uint32 validatorIndex;
uint64 batchId;
uint32 expectedTimelapse;
bool atLeastOneSuccess;
uint32 tailEpoch = getTailEpoch();
uint32 differenceEpoch;
IValidatorIdentityV2.Identifier memory identity;
for (uint256 i = 0; i < _identityNames.length; ++i) {
identity = validatorIdentity.getIdentityData(0, _identityNames[i]);
if (identity.walletReceiver == address(0)) continue;
validatorIndex = identity.validatorUUID;
epochHead = latestEpochHeadRequested[validatorIndex];
if (epochHead < tailEpoch) epochHead = tailEpoch;
for (uint256 j = 0; j < MAX_EPOCHS_LOOP; ++j) {
differenceEpoch = (epochHead + MAX_EPOCHS) - START_CLAIMING_EPOCH;
expectedTimelapse = (differenceEpoch * timePerEpochCached) + START_CLAIMING_TIMESTAMP;
if (expectedTimelapse + FINALIZED_EPOCH_DELAY > block.timestamp) {
break;
}
epochHead += MAX_EPOCHS;
batchId = _addReceiptToBatch(validatorIndex, epochHead);
atLeastOneSuccess = true;
emit ClaimRequest(validatorIndex, batchId, epochHead);
}
latestEpochHeadRequested[validatorIndex] = epochHead;
}
if (!atLeastOneSuccess) revert AttestationRequestFailed();
}
function _addReceiptToBatch(uint32 _validatorIndex, uint32 _head) internal returns (uint64 batchId_) {
uint64[] storage headBatchIds = headEpochBatchIds[_head];
BatchRequest storage epochBatch;
uint64 batchIdsSize = uint64(headBatchIds.length);
uint32 totalValidators;
if (batchIdsSize == 0) {
return _createNewBatch(_head, _validatorIndex);
}
batchId_ = headBatchIds[batchIdsSize - 1];
epochBatch = allBatches[batchId_];
if (epochBatch.success || epochBatch.expiredTime != 0) {
return _createNewBatch(_head, _validatorIndex);
}
epochBatch.validators.push(_validatorIndex);
totalValidators = uint32(epochBatch.validators.length);
if (totalValidators == MAX_VALIDATORS || epochBatch.idleEnd <= block.timestamp) {
_sendBatchToExecute(epochBatch, batchId_);
}
return batchId_;
}
function _createNewBatch(uint32 _epochHead, uint32 _validatorToAdd) internal returns (uint64 batchId_) {
BatchRequest memory newBatch = BatchRequest({
headEpoch: _epochHead,
validators: new uint32[](1),
idleEnd: uint32(block.timestamp) + IDLE_WAIT,
expiredTime: 0,
success: false
});
newBatch.validators[0] = _validatorToAdd;
++currentBatchId;
batchId_ = currentBatchId;
allBatches[batchId_] = newBatch;
headEpochBatchIds[_epochHead].push(batchId_);
idleBatchIds.add(batchId_);
emit NewBatchCreated(_epochHead, batchId_);
return batchId_;
}
function redirectClaimRewardsWithPermit(
address _withdrawalCredential,
address _to,
uint32 _nonce,
uint32 _deadline,
bytes calldata _signature
) external {
if (pausePermit) revert PermitPaused();
if (block.timestamp > _deadline) revert ExpiredSignature();
uint32 currentNonce = redirectNonce[_withdrawalCredential] + 1;
if (_nonce != currentNonce) revert InvalidRedirectNonce();
redirectNonce[_withdrawalCredential] = currentNonce;
bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(PERMIT_TYPEHASH, _to, currentNonce, _deadline)));
if (!SignatureChecker.isValidSignatureNow(_withdrawalCredential, digest, _signature)) {
revert InvalidSignature();
}
redirectBadges[_withdrawalCredential] = _to;
emit RedirectionSet(_withdrawalCredential, _to, currentNonce);
}
function redirectClaimRewards(address _to) external {
redirectBadges[msg.sender] = _to;
emit RedirectionSet(msg.sender, _to, 0);
}
function manuallyExecuteBatch(uint64 batchId) external {
_manuallyExecuteBatch(batchId, true);
}
function manuallyExecuteBatches(uint64[] calldata batchIds) external {
bool atLeastOneSuccess;
bool result;
for (uint256 i = 0; i < batchIds.length; ++i) {
result = _manuallyExecuteBatch(batchIds[i], false);
if (!atLeastOneSuccess) atLeastOneSuccess = result;
}
if (!atLeastOneSuccess) revert NothingToExecute();
}
function _manuallyExecuteBatch(uint64 _batchId, bool _allowsRevert) internal returns (bool success_) {
BatchRequest storage batch = allBatches[_batchId];
if (batch.headEpoch == 0) {
if (_allowsRevert) revert BatchNotFound();
return false;
}
if (batch.expiredTime > block.timestamp || batch.idleEnd > block.timestamp) {
if (_allowsRevert) revert BatchNotSentOrExpired();
return false;
}
if (batch.success) {
if (_allowsRevert) revert BatchAlreadyExecuted();
return false;
}
_sendBatchToExecute(batch, _batchId);
return true;
}
function checkerToExecuteIdles() external view returns (bool canExec, bytes memory execPayload) {
uint256 pendingLength = idleBatchIds.length();
canExec = pendingLength > 0;
execPayload = abi.encodeCall(HeroglyphAttestation.tryExecutingIdleBatches, (pendingLength));
return (canExec, execPayload);
}
function tryExecutingIdleBatches(uint256 _loop) external {
uint256[] memory cachedBatchIds = idleBatchIds.values();
uint256 totalPending = cachedBatchIds.length;
uint256 maxLoop = sendingBatchesSize;
if (_loop > maxLoop) _loop = maxLoop;
if (_loop == 0 || _loop > totalPending) _loop = totalPending;
bool atLeastOneTriggered;
BatchRequest storage batch;
uint64 batchId;
for (uint256 i = 0; i < _loop; ++i) {
batchId = uint64(cachedBatchIds[i]);
batch = allBatches[batchId];
if (batch.expiredTime > block.timestamp || batch.idleEnd > block.timestamp) continue;
_sendBatchToExecute(batch, uint64(batchId));
atLeastOneTriggered = true;
}
if (!atLeastOneTriggered) revert NothingToExecute();
}
function _sendBatchToExecute(BatchRequest storage _batch, uint64 _batchId) internal {
_batch.expiredTime = uint32(block.timestamp) + CLAIM_REQUEST_TIMEOUT;
idleBatchIds.remove(_batchId);
emit SendBatchToExecute(_batchId, _batch.headEpoch, _batch.validators);
}
function executeClaiming(
uint64 _batchId,
address[] calldata _withdrawalAddresses,
int32[] calldata _attestationPoints
) external onlyDedicatedMsgSender {
BatchRequest storage batch = allBatches[_batchId];
uint256 totalValidators = batch.validators.length;
if (batch.headEpoch == 0) revert BatchNotFound();
if (batch.success) revert BatchAlreadyExecuted();
if (_withdrawalAddresses.length != totalValidators || _attestationPoints.length != totalValidators) {
revert MismatchArrays();
}
batch.success = true;
uint32 validatorIndex;
address withdrawal;
int32 attestationPoint;
for (uint256 i = 0; i < _withdrawalAddresses.length; ++i) {
validatorIndex = batch.validators[i];
withdrawal = _withdrawalAddresses[i];
attestationPoint = _attestationPoints[i];
_executeSingleClaim(validatorIndex, withdrawal, attestationPoint);
emit ExecutionAttestationClaim(
_batchId, validatorIndex, withdrawal, attestationPoint, penalityPoints[validatorIndex]
);
}
emit BatchExecuted(_batchId, _attestationPoints);
}
function _executeSingleClaim(uint32 _validator, address _withdrawalAddress, int32 _attestationPoint) internal {
address redirectedAddress = redirectBadges[_withdrawalAddress];
if (redirectedAddress != address(0)) {
_withdrawalAddress = redirectedAddress;
}
uint32 penaltyPoints = penalityPoints[_validator];
if (_attestationPoint == 0) {
return;
}
if (_attestationPoint < 0) {
penalityPoints[_validator] += uint32(_attestationPoint * -1);
return;
}
uint32 pointUint32 = uint32(_attestationPoint);
if (penaltyPoints >= pointUint32) {
penaltyPoints -= pointUint32;
pointUint32 = 0;
} else {
pointUint32 -= penaltyPoints;
penaltyPoints = 0;
}
penalityPoints[_validator] = penaltyPoints;
if (pointUint32 == 0) return;
uint256 reward = uint256(pointUint32) * attestationPointRate;
if (reward == 0) return;
if (_withdrawalAddress != address(0)) {
_mint(_withdrawalAddress, reward);
return;
}
_mint(owner(), reward);
emit NoWithdrawalAddressFound(_validator, reward);
}
function _update(address from, address to, uint256 value) internal override {
super._update(from, to, value);
if ((from == address(0) || to == address(0)) || !isSoulbound) return;
if (!hasTransferPermission[msg.sender]) revert TokenSoulbound();
}
function setTransferPermissionOf(address _target, bool _enabled) external onlyOwner {
hasTransferPermission[_target] = _enabled;
emit TransferPermissionUpdated(_target, _enabled);
}
function updateDedicatedMsgSender(address _msg) external onlyOwner {
dedicatedMsgSender = _msg;
emit DedicatedMsgSenderUpdated(_msg);
}
function updateValidatorIdentity(address _validatorIdentity) external onlyOwner {
validatorIdentity = IValidatorIdentityV2(_validatorIdentity);
emit ValidatorIdentityUpdated(_validatorIdentity);
}
function updateAttestationPointRate(uint256 _rate) external onlyOwner {
attestationPointRate = _rate;
emit AttestationPointRateUpdated(_rate);
}
function updateTimePerEpoch(uint32 _perEpochInSeconds) external onlyOwner {
timePerEpoch = _perEpochInSeconds;
emit TimePerEpochUpdated(_perEpochInSeconds);
}
function updateSendingBatchesSize(uint256 _size) external onlyOwner {
sendingBatchesSize = _size;
emit SendingBatchesSizeUpdated(_size);
}
function updateSoulboundStatus(bool _isSoulbound) external onlyOwner {
isSoulbound = _isSoulbound;
emit SoulboundStatusUpdated(_isSoulbound);
}
function updatePausePermit(bool _status) external onlyOwner {
pausePermit = _status;
emit PermitPausedUpdated(_status);
}
function getDomainSeparatorV4() external view returns (bytes32) {
return _domainSeparatorV4();
}
function getTailEpoch() public view returns (uint32 tail_) {
if (block.timestamp <= START_CLAIMING_TIMESTAMP) return START_CLAIMING_EPOCH;
uint256 fromTheStart = (block.timestamp - START_CLAIMING_TIMESTAMP) / timePerEpoch;
uint256 ceil = (fromTheStart + START_CLAIMING_EPOCH - EPOCH_30_DAYS) / MAX_EPOCHS;
tail_ = uint32(ceil * MAX_EPOCHS);
return (tail_ < START_CLAIMING_EPOCH) ? START_CLAIMING_EPOCH : tail_;
}
function getValidatorLatestEpochClaimed(uint32 _validatorIndex) external view returns (uint256 latest_) {
latest_ = latestEpochHeadRequested[_validatorIndex];
uint32 tails = getTailEpoch();
return (latest_ > tails) ? latest_ : tails;
}
function getEpochHeadRequestBatchIds(uint32 _epochHead) external view returns (uint64[] memory) {
return headEpochBatchIds[_epochHead];
}
function getBatchRequest(uint64 _batchId) external view returns (BatchRequest memory) {
return allBatches[_batchId];
}
function getIdleRequestBatches() external view returns (uint256[] memory) {
return idleBatchIds.values();
}
function getPenaltyPointBalance(uint32 _validatorId) external view returns (uint256) {
return penalityPoints[_validatorId];
}
}
文件 7 的 22:IERC1271.sol
pragma solidity ^0.8.20;
interface IERC1271 {
function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);
}
文件 8 的 22:IERC20.sol
pragma solidity ^0.8.20;
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 value) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 value) external returns (bool);
function transferFrom(address from, address to, uint256 value) external returns (bool);
}
文件 9 的 22:IERC20Metadata.sol
pragma solidity ^0.8.20;
import {IERC20} from "../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);
}
文件 10 的 22:IERC5267.sol
pragma solidity ^0.8.20;
interface IERC5267 {
event EIP712DomainChanged();
function eip712Domain()
external
view
returns (
bytes1 fields,
string memory name,
string memory version,
uint256 chainId,
address verifyingContract,
bytes32 salt,
uint256[] memory extensions
);
}
文件 11 的 22:IHeroglyphAttestation.sol
pragma solidity >= 0.8.0;
interface IHeroglyphAttestation {
error NothingToExecute();
error NotDedicatedMsgSender();
error AttestationRequestFailed();
error BatchNotSentOrExpired();
error BatchAlreadyExecuted();
error MismatchArrays();
error CreateAttestationRequestIsNotActive();
error TokenSoulbound();
error ExpiredSignature();
error InvalidSignature();
error BatchNotFound();
error PermitPaused();
error InvalidRedirectNonce();
struct BatchRequest {
uint32 headEpoch;
uint32[] validators;
uint32 idleEnd;
uint32 expiredTime;
bool success;
}
event DedicatedMsgSenderUpdated(address indexed dedicatedMsgSender);
event NoWithdrawalAddressFound(uint32 indexed validator, uint256 rewards);
event SendBatchToExecute(uint64 indexed batchId, uint32 indexed headEpoch, uint32[] validators);
event ClaimRequest(uint32 indexed validatorId, uint64 indexed batchId, uint32 indexed headEpoch);
event ExecutionAttestationClaim(
uint64 indexed batchId,
uint32 indexed validatorId,
address indexed withdrawalAddress,
int32 receivedPoints,
uint32 penaltyBalance
);
event NewBatchCreated(uint32 indexed headEpoch, uint64 indexed batchId);
event AttestationPointRateUpdated(uint256 newRate);
event TimePerEpochUpdated(uint256 timePerEpochInSeconds);
event BatchExecuted(uint64 indexed batchId, int32[] attestationPoints);
event ValidatorIdentityUpdated(address validatorIdentity);
event SendingBatchesSizeUpdated(uint256 size);
event TransferPermissionUpdated(address indexed target, bool status);
event RedirectionSet(address indexed withdrawalCredential, address indexed to, uint32 nonce);
event SoulboundStatusUpdated(bool isSoulbound);
event PermitPausedUpdated(bool status);
}
文件 12 的 22:IValidatorIdentityV2.sol
pragma solidity >= 0.8.0;
interface IValidatorIdentityV2 {
error NoMigrationPossible();
error NotBackwardCompatible();
error MsgValueTooLow();
error NoNeedToPay();
error InvalidBPS();
struct Identifier {
string name;
uint32 validatorUUID;
address walletReceiver;
}
event WalletReceiverUpdated(uint256 indexed walletId, string indexed identityName, address newWallet);
event NewGraffitiIdentityCreated(
uint256 indexed walletId, uint32 indexed validatorId, string identityName, uint256 cost
);
event MaxIdentityPerDayAtInitialPriceUpdated(uint32 maxIdentityPerDayAtInitialPrice);
event PriceIncreaseThresholdUpdated(uint32 priceIncreaseThreshold);
event PriceDecayBPSUpdated(uint32 priceDecayBPS);
function isSoulboundIdentity(string calldata _name, uint32 _validatorId) external view returns (bool);
function migrateFromOldIdentity(string calldata _name, uint32 _validatorId) external;
function create(string calldata _name, address _receiverWallet, uint32 _validatorId) external payable;
function updateReceiverAddress(uint256 _nftId, string memory _name, address _receiver) external;
function getIdentityData(uint256 _nftId, string calldata _name) external view returns (Identifier memory);
}
文件 13 的 22:Math.sol
pragma solidity ^0.8.20;
library Math {
error MathOverflowedMulDiv();
enum Rounding {
Floor,
Ceil,
Trunc,
Expand
}
function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
uint256 c = a + b;
if (c < a) return (false, 0);
return (true, c);
}
}
function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b > a) return (false, 0);
return (true, a - b);
}
}
function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (a == 0) return (true, 0);
uint256 c = a * b;
if (c / a != b) return (false, 0);
return (true, c);
}
}
function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a / b);
}
}
function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a % b);
}
}
function max(uint256 a, uint256 b) internal pure returns (uint256) {
return a > b ? a : b;
}
function min(uint256 a, uint256 b) internal pure returns (uint256) {
return a < b ? a : b;
}
function average(uint256 a, uint256 b) internal pure returns (uint256) {
return (a & b) + (a ^ b) / 2;
}
function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
if (b == 0) {
return a / b;
}
return a == 0 ? 0 : (a - 1) / b + 1;
}
function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {
unchecked {
uint256 prod0 = x * y;
uint256 prod1;
assembly {
let mm := mulmod(x, y, not(0))
prod1 := sub(sub(mm, prod0), lt(mm, prod0))
}
if (prod1 == 0) {
return prod0 / denominator;
}
if (denominator <= prod1) {
revert MathOverflowedMulDiv();
}
uint256 remainder;
assembly {
remainder := mulmod(x, y, denominator)
prod1 := sub(prod1, gt(remainder, prod0))
prod0 := sub(prod0, remainder)
}
uint256 twos = denominator & (0 - denominator);
assembly {
denominator := div(denominator, twos)
prod0 := div(prod0, twos)
twos := add(div(sub(0, twos), twos), 1)
}
prod0 |= prod1 * twos;
uint256 inverse = (3 * denominator) ^ 2;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
result = prod0 * inverse;
return result;
}
}
function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {
uint256 result = mulDiv(x, y, denominator);
if (unsignedRoundsUp(rounding) && mulmod(x, y, denominator) > 0) {
result += 1;
}
return result;
}
function sqrt(uint256 a) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
uint256 result = 1 << (log2(a) >> 1);
unchecked {
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
return min(result, a / result);
}
}
function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = sqrt(a);
return result + (unsignedRoundsUp(rounding) && result * result < a ? 1 : 0);
}
}
function log2(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 128;
}
if (value >> 64 > 0) {
value >>= 64;
result += 64;
}
if (value >> 32 > 0) {
value >>= 32;
result += 32;
}
if (value >> 16 > 0) {
value >>= 16;
result += 16;
}
if (value >> 8 > 0) {
value >>= 8;
result += 8;
}
if (value >> 4 > 0) {
value >>= 4;
result += 4;
}
if (value >> 2 > 0) {
value >>= 2;
result += 2;
}
if (value >> 1 > 0) {
result += 1;
}
}
return result;
}
function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log2(value);
return result + (unsignedRoundsUp(rounding) && 1 << result < value ? 1 : 0);
}
}
function log10(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >= 10 ** 64) {
value /= 10 ** 64;
result += 64;
}
if (value >= 10 ** 32) {
value /= 10 ** 32;
result += 32;
}
if (value >= 10 ** 16) {
value /= 10 ** 16;
result += 16;
}
if (value >= 10 ** 8) {
value /= 10 ** 8;
result += 8;
}
if (value >= 10 ** 4) {
value /= 10 ** 4;
result += 4;
}
if (value >= 10 ** 2) {
value /= 10 ** 2;
result += 2;
}
if (value >= 10 ** 1) {
result += 1;
}
}
return result;
}
function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log10(value);
return result + (unsignedRoundsUp(rounding) && 10 ** result < value ? 1 : 0);
}
}
function log256(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 16;
}
if (value >> 64 > 0) {
value >>= 64;
result += 8;
}
if (value >> 32 > 0) {
value >>= 32;
result += 4;
}
if (value >> 16 > 0) {
value >>= 16;
result += 2;
}
if (value >> 8 > 0) {
result += 1;
}
}
return result;
}
function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log256(value);
return result + (unsignedRoundsUp(rounding) && 1 << (result << 3) < value ? 1 : 0);
}
}
function unsignedRoundsUp(Rounding rounding) internal pure returns (bool) {
return uint8(rounding) % 2 == 1;
}
}
文件 14 的 22:MessageHashUtils.sol
pragma solidity ^0.8.20;
import {Strings} from "../Strings.sol";
library MessageHashUtils {
function toEthSignedMessageHash(bytes32 messageHash) internal pure returns (bytes32 digest) {
assembly {
mstore(0x00, "\x19Ethereum Signed Message:\n32")
mstore(0x1c, messageHash)
digest := keccak256(0x00, 0x3c)
}
}
function toEthSignedMessageHash(bytes memory message) internal pure returns (bytes32) {
return
keccak256(bytes.concat("\x19Ethereum Signed Message:\n", bytes(Strings.toString(message.length)), message));
}
function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {
return keccak256(abi.encodePacked(hex"19_00", validator, data));
}
function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 digest) {
assembly {
let ptr := mload(0x40)
mstore(ptr, hex"19_01")
mstore(add(ptr, 0x02), domainSeparator)
mstore(add(ptr, 0x22), structHash)
digest := keccak256(ptr, 0x42)
}
}
}
文件 15 的 22:Ownable.sol
pragma solidity ^0.8.20;
import {Context} from "../utils/Context.sol";
abstract contract Ownable is Context {
address private _owner;
error OwnableUnauthorizedAccount(address account);
error OwnableInvalidOwner(address owner);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor(address initialOwner) {
if (initialOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(initialOwner);
}
modifier onlyOwner() {
_checkOwner();
_;
}
function owner() public view virtual returns (address) {
return _owner;
}
function _checkOwner() internal view virtual {
if (owner() != _msgSender()) {
revert OwnableUnauthorizedAccount(_msgSender());
}
}
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
function transferOwnership(address newOwner) public virtual onlyOwner {
if (newOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(newOwner);
}
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
文件 16 的 22:SendNativeHelper.sol
pragma solidity ^0.8.25;
abstract contract SendNativeHelper {
error NotEnough();
error FailedToSendETH();
mapping(address wallet => uint256) internal pendingClaims;
function _sendNative(address _to, uint256 _amount, bool _revertIfFails) internal {
if (_amount == 0) return;
(bool success,) = _to.call{ gas: 60_000, value: _amount }("");
if (!success) {
if (_revertIfFails) revert FailedToSendETH();
pendingClaims[_to] += _amount;
}
}
function claimFund() external {
uint256 balance = pendingClaims[msg.sender];
pendingClaims[msg.sender] = 0;
if (balance == 0) revert NotEnough();
_sendNative(msg.sender, balance, true);
}
function getPendingToClaim(address _user) external view returns (uint256) {
return pendingClaims[_user];
}
}
文件 17 的 22:ShortStrings.sol
pragma solidity ^0.8.20;
import {StorageSlot} from "./StorageSlot.sol";
type ShortString is bytes32;
library ShortStrings {
bytes32 private constant FALLBACK_SENTINEL = 0x00000000000000000000000000000000000000000000000000000000000000FF;
error StringTooLong(string str);
error InvalidShortString();
function toShortString(string memory str) internal pure returns (ShortString) {
bytes memory bstr = bytes(str);
if (bstr.length > 31) {
revert StringTooLong(str);
}
return ShortString.wrap(bytes32(uint256(bytes32(bstr)) | bstr.length));
}
function toString(ShortString sstr) internal pure returns (string memory) {
uint256 len = byteLength(sstr);
string memory str = new string(32);
assembly {
mstore(str, len)
mstore(add(str, 0x20), sstr)
}
return str;
}
function byteLength(ShortString sstr) internal pure returns (uint256) {
uint256 result = uint256(ShortString.unwrap(sstr)) & 0xFF;
if (result > 31) {
revert InvalidShortString();
}
return result;
}
function toShortStringWithFallback(string memory value, string storage store) internal returns (ShortString) {
if (bytes(value).length < 32) {
return toShortString(value);
} else {
StorageSlot.getStringSlot(store).value = value;
return ShortString.wrap(FALLBACK_SENTINEL);
}
}
function toStringWithFallback(ShortString value, string storage store) internal pure returns (string memory) {
if (ShortString.unwrap(value) != FALLBACK_SENTINEL) {
return toString(value);
} else {
return store;
}
}
function byteLengthWithFallback(ShortString value, string storage store) internal view returns (uint256) {
if (ShortString.unwrap(value) != FALLBACK_SENTINEL) {
return byteLength(value);
} else {
return bytes(store).length;
}
}
}
文件 18 的 22:SignatureChecker.sol
pragma solidity ^0.8.20;
import {ECDSA} from "./ECDSA.sol";
import {IERC1271} from "../../interfaces/IERC1271.sol";
library SignatureChecker {
function isValidSignatureNow(address signer, bytes32 hash, bytes memory signature) internal view returns (bool) {
(address recovered, ECDSA.RecoverError error, ) = ECDSA.tryRecover(hash, signature);
return
(error == ECDSA.RecoverError.NoError && recovered == signer) ||
isValidERC1271SignatureNow(signer, hash, signature);
}
function isValidERC1271SignatureNow(
address signer,
bytes32 hash,
bytes memory signature
) internal view returns (bool) {
(bool success, bytes memory result) = signer.staticcall(
abi.encodeCall(IERC1271.isValidSignature, (hash, signature))
);
return (success &&
result.length >= 32 &&
abi.decode(result, (bytes32)) == bytes32(IERC1271.isValidSignature.selector));
}
}
文件 19 的 22:SignedMath.sol
pragma solidity ^0.8.20;
library SignedMath {
function max(int256 a, int256 b) internal pure returns (int256) {
return a > b ? a : b;
}
function min(int256 a, int256 b) internal pure returns (int256) {
return a < b ? a : b;
}
function average(int256 a, int256 b) internal pure returns (int256) {
int256 x = (a & b) + ((a ^ b) >> 1);
return x + (int256(uint256(x) >> 255) & (a ^ b));
}
function abs(int256 n) internal pure returns (uint256) {
unchecked {
return uint256(n >= 0 ? n : -n);
}
}
}
文件 20 的 22:StorageSlot.sol
pragma solidity ^0.8.20;
library StorageSlot {
struct AddressSlot {
address value;
}
struct BooleanSlot {
bool value;
}
struct Bytes32Slot {
bytes32 value;
}
struct Uint256Slot {
uint256 value;
}
struct StringSlot {
string value;
}
struct BytesSlot {
bytes value;
}
function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {
assembly {
r.slot := slot
}
}
function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {
assembly {
r.slot := slot
}
}
function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {
assembly {
r.slot := slot
}
}
function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {
assembly {
r.slot := slot
}
}
function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) {
assembly {
r.slot := slot
}
}
function getStringSlot(string storage store) internal pure returns (StringSlot storage r) {
assembly {
r.slot := store.slot
}
}
function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) {
assembly {
r.slot := slot
}
}
function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) {
assembly {
r.slot := store.slot
}
}
}
文件 21 的 22:Strings.sol
pragma solidity ^0.8.20;
import {Math} from "./math/Math.sol";
import {SignedMath} from "./math/SignedMath.sol";
library Strings {
bytes16 private constant HEX_DIGITS = "0123456789abcdef";
uint8 private constant ADDRESS_LENGTH = 20;
error StringsInsufficientHexLength(uint256 value, uint256 length);
function toString(uint256 value) internal pure returns (string memory) {
unchecked {
uint256 length = Math.log10(value) + 1;
string memory buffer = new string(length);
uint256 ptr;
assembly {
ptr := add(buffer, add(32, length))
}
while (true) {
ptr--;
assembly {
mstore8(ptr, byte(mod(value, 10), HEX_DIGITS))
}
value /= 10;
if (value == 0) break;
}
return buffer;
}
}
function toStringSigned(int256 value) internal pure returns (string memory) {
return string.concat(value < 0 ? "-" : "", toString(SignedMath.abs(value)));
}
function toHexString(uint256 value) internal pure returns (string memory) {
unchecked {
return toHexString(value, Math.log256(value) + 1);
}
}
function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
uint256 localValue = value;
bytes memory buffer = new bytes(2 * length + 2);
buffer[0] = "0";
buffer[1] = "x";
for (uint256 i = 2 * length + 1; i > 1; --i) {
buffer[i] = HEX_DIGITS[localValue & 0xf];
localValue >>= 4;
}
if (localValue != 0) {
revert StringsInsufficientHexLength(value, length);
}
return string(buffer);
}
function toHexString(address addr) internal pure returns (string memory) {
return toHexString(uint256(uint160(addr)), ADDRESS_LENGTH);
}
function equal(string memory a, string memory b) internal pure returns (bool) {
return bytes(a).length == bytes(b).length && keccak256(bytes(a)) == keccak256(bytes(b));
}
}
文件 22 的 22:draft-IERC6093.sol
pragma solidity ^0.8.20;
interface IERC20Errors {
error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed);
error ERC20InvalidSender(address sender);
error ERC20InvalidReceiver(address receiver);
error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed);
error ERC20InvalidApprover(address approver);
error ERC20InvalidSpender(address spender);
}
interface IERC721Errors {
error ERC721InvalidOwner(address owner);
error ERC721NonexistentToken(uint256 tokenId);
error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner);
error ERC721InvalidSender(address sender);
error ERC721InvalidReceiver(address receiver);
error ERC721InsufficientApproval(address operator, uint256 tokenId);
error ERC721InvalidApprover(address approver);
error ERC721InvalidOperator(address operator);
}
interface IERC1155Errors {
error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId);
error ERC1155InvalidSender(address sender);
error ERC1155InvalidReceiver(address receiver);
error ERC1155MissingApprovalForAll(address operator, address owner);
error ERC1155InvalidApprover(address approver);
error ERC1155InvalidOperator(address operator);
error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength);
}
{
"compilationTarget": {
"src/HeroglyphAttestation.sol": "HeroglyphAttestation"
},
"evmVersion": "paris",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": [
":@layerzerolabs/=node_modules/@layerzerolabs/",
":@openzeppelin/=node_modules/@openzeppelin/",
":ds-test/=node_modules/@layerzerolabs/toolbox-foundry/lib/ds-test/",
":forge-std/=node_modules/@layerzerolabs/toolbox-foundry/lib/forge-std/src/",
":heroglyph-library/=node_modules/@layerzerolabs/toolbox-foundry/lib/heroglyph-library/",
":solidity-bytes-utils/=node_modules/solidity-bytes-utils/",
":solmate/=node_modules/@layerzerolabs/toolbox-foundry/lib/solmate/",
":src/=src/"
],
"viaIR": true
}
[{"inputs":[{"internalType":"address","name":"_dedicatedMsgSender","type":"address"},{"internalType":"address","name":"_validatorIdentity","type":"address"},{"internalType":"address","name":"_owner","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AttestationRequestFailed","type":"error"},{"inputs":[],"name":"BatchAlreadyExecuted","type":"error"},{"inputs":[],"name":"BatchNotFound","type":"error"},{"inputs":[],"name":"BatchNotSentOrExpired","type":"error"},{"inputs":[],"name":"CreateAttestationRequestIsNotActive","type":"error"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"allowance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"name":"ERC20InsufficientAllowance","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"name":"ERC20InsufficientBalance","type":"error"},{"inputs":[{"internalType":"address","name":"approver","type":"address"}],"name":"ERC20InvalidApprover","type":"error"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"ERC20InvalidReceiver","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"ERC20InvalidSender","type":"error"},{"inputs":[{"internalType":"address","name":"spender","type":"address"}],"name":"ERC20InvalidSpender","type":"error"},{"inputs":[],"name":"ExpiredSignature","type":"error"},{"inputs":[],"name":"FailedToSendETH","type":"error"},{"inputs":[],"name":"InvalidRedirectNonce","type":"error"},{"inputs":[],"name":"InvalidShortString","type":"error"},{"inputs":[],"name":"InvalidSignature","type":"error"},{"inputs":[],"name":"MismatchArrays","type":"error"},{"inputs":[],"name":"NotDedicatedMsgSender","type":"error"},{"inputs":[],"name":"NotEnough","type":"error"},{"inputs":[],"name":"NothingToExecute","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[],"name":"PermitPaused","type":"error"},{"inputs":[{"internalType":"string","name":"str","type":"string"}],"name":"StringTooLong","type":"error"},{"inputs":[],"name":"TokenSoulbound","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newRate","type":"uint256"}],"name":"AttestationPointRateUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint64","name":"batchId","type":"uint64"},{"indexed":false,"internalType":"int32[]","name":"attestationPoints","type":"int32[]"}],"name":"BatchExecuted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint32","name":"validatorId","type":"uint32"},{"indexed":true,"internalType":"uint64","name":"batchId","type":"uint64"},{"indexed":true,"internalType":"uint32","name":"headEpoch","type":"uint32"}],"name":"ClaimRequest","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"dedicatedMsgSender","type":"address"}],"name":"DedicatedMsgSenderUpdated","type":"event"},{"anonymous":false,"inputs":[],"name":"EIP712DomainChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint64","name":"batchId","type":"uint64"},{"indexed":true,"internalType":"uint32","name":"validatorId","type":"uint32"},{"indexed":true,"internalType":"address","name":"withdrawalAddress","type":"address"},{"indexed":false,"internalType":"int32","name":"receivedPoints","type":"int32"},{"indexed":false,"internalType":"uint32","name":"penaltyBalance","type":"uint32"}],"name":"ExecutionAttestationClaim","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint32","name":"headEpoch","type":"uint32"},{"indexed":true,"internalType":"uint64","name":"batchId","type":"uint64"}],"name":"NewBatchCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint32","name":"validator","type":"uint32"},{"indexed":false,"internalType":"uint256","name":"rewards","type":"uint256"}],"name":"NoWithdrawalAddressFound","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"status","type":"bool"}],"name":"PermitPausedUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"withdrawalCredential","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint32","name":"nonce","type":"uint32"}],"name":"RedirectionSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint64","name":"batchId","type":"uint64"},{"indexed":true,"internalType":"uint32","name":"headEpoch","type":"uint32"},{"indexed":false,"internalType":"uint32[]","name":"validators","type":"uint32[]"}],"name":"SendBatchToExecute","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"size","type":"uint256"}],"name":"SendingBatchesSizeUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"isSoulbound","type":"bool"}],"name":"SoulboundStatusUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"timePerEpochInSeconds","type":"uint256"}],"name":"TimePerEpochUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"target","type":"address"},{"indexed":false,"internalType":"bool","name":"status","type":"bool"}],"name":"TransferPermissionUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"validatorIdentity","type":"address"}],"name":"ValidatorIdentityUpdated","type":"event"},{"inputs":[],"name":"CLAIM_REQUEST_TIMEOUT","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"EPOCH_30_DAYS","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FINALIZED_EPOCH_DELAY","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"IDLE_WAIT","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_EPOCHS","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_EPOCHS_LOOP","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_VALIDATORS","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PERMIT_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"START_CLAIMING_EPOCH","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"START_CLAIMING_TIMESTAMP","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"attestationPointRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"checkerToExecuteIdles","outputs":[{"internalType":"bool","name":"canExec","type":"bool"},{"internalType":"bytes","name":"execPayload","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claimFund","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string[]","name":"_identityNames","type":"string[]"}],"name":"createAttestationRequest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"currentBatchId","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"dedicatedMsgSender","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"eip712Domain","outputs":[{"internalType":"bytes1","name":"fields","type":"bytes1"},{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"version","type":"string"},{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"address","name":"verifyingContract","type":"address"},{"internalType":"bytes32","name":"salt","type":"bytes32"},{"internalType":"uint256[]","name":"extensions","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"_batchId","type":"uint64"},{"internalType":"address[]","name":"_withdrawalAddresses","type":"address[]"},{"internalType":"int32[]","name":"_attestationPoints","type":"int32[]"}],"name":"executeClaiming","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"_batchId","type":"uint64"}],"name":"getBatchRequest","outputs":[{"components":[{"internalType":"uint32","name":"headEpoch","type":"uint32"},{"internalType":"uint32[]","name":"validators","type":"uint32[]"},{"internalType":"uint32","name":"idleEnd","type":"uint32"},{"internalType":"uint32","name":"expiredTime","type":"uint32"},{"internalType":"bool","name":"success","type":"bool"}],"internalType":"struct IHeroglyphAttestation.BatchRequest","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getDomainSeparatorV4","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_epochHead","type":"uint32"}],"name":"getEpochHeadRequestBatchIds","outputs":[{"internalType":"uint64[]","name":"","type":"uint64[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getIdleRequestBatches","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_validatorId","type":"uint32"}],"name":"getPenaltyPointBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"getPendingToClaim","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTailEpoch","outputs":[{"internalType":"uint32","name":"tail_","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_validatorIndex","type":"uint32"}],"name":"getValidatorLatestEpochClaimed","outputs":[{"internalType":"uint256","name":"latest_","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"hasTransferPermission","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isSoulbound","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"batchId","type":"uint64"}],"name":"manuallyExecuteBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64[]","name":"batchIds","type":"uint64[]"}],"name":"manuallyExecuteBatches","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pausePermit","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"redirectBadges","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"}],"name":"redirectClaimRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_withdrawalCredential","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint32","name":"_nonce","type":"uint32"},{"internalType":"uint32","name":"_deadline","type":"uint32"},{"internalType":"bytes","name":"_signature","type":"bytes"}],"name":"redirectClaimRewardsWithPermit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"redirectNonce","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"sendingBatchesSize","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_target","type":"address"},{"internalType":"bool","name":"_enabled","type":"bool"}],"name":"setTransferPermissionOf","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"timePerEpoch","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_loop","type":"uint256"}],"name":"tryExecutingIdleBatches","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_rate","type":"uint256"}],"name":"updateAttestationPointRate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_msg","type":"address"}],"name":"updateDedicatedMsgSender","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_status","type":"bool"}],"name":"updatePausePermit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_size","type":"uint256"}],"name":"updateSendingBatchesSize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_isSoulbound","type":"bool"}],"name":"updateSoulboundStatus","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"_perEpochInSeconds","type":"uint32"}],"name":"updateTimePerEpoch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_validatorIdentity","type":"address"}],"name":"updateValidatorIdentity","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"validatorIdentity","outputs":[{"internalType":"contract IValidatorIdentityV2","name":"","type":"address"}],"stateMutability":"view","type":"function"}]