Source Code
Overview
ETH Balance
0 ETH
More Info
ContractCreator
Multichain Info
N/A
Latest 1 from a total of 1 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
0x61012060 | 5191494 | 246 days ago | IN | 0 ETH | 0.02379355 |
Loading...
Loading
Contract Name:
RoyaltyResolver
Compiler Version
v0.8.20+commit.a1b79de6
Optimization Enabled:
Yes with 200 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.19; import {Address} from "@openzeppelin/contracts/utils/Address.sol"; import {ReentrancyGuard} from "@openzeppelin/contracts/utils/ReentrancyGuard.sol"; import {SchemaResolver} from "eas-contracts/resolver/SchemaResolver.sol"; import {IEAS, Attestation} from "eas-contracts/IEAS.sol"; import {IAuthorStake} from "./interfaces/IAuthorStake.sol"; /// @notice A struct representing the additional custom Olas attestation fields. struct CustomAttestationSchema { bytes32[] citationUID; // An array of citation UIDs bytes32 authorName; // The author's name string articleTitle; // The title of the article bytes32 articleHash; // A hash of the article content string urlOfContent; // The URL where the content can be accessed } /// @title RoyaltyResolver /// @notice Distributes royalties among citation attesters and stakes the remaining ether on behalf of the attester. contract RoyaltyResolver is SchemaResolver, ReentrancyGuard { using Address for address payable; error InsufficientEthValueSent(); error InvalidCitationUID(); error InsufficientIndividualRoyaltyPayment(); error DirectPaymentsNotAllowed(); event RoyaltyDistributed(address indexed receiver, uint256 amount); event TransferredStake(address indexed stakingContract, uint256 amount); event ValueReceived(address indexed attester, uint256 value); address private immutable _stakingContract; uint256 private constant ROYALTY_PERCENTAGE = 10; // Represents the royalty percentage. constructor(IEAS eas, address stakingContract) SchemaResolver(eas) { require( stakingContract != address(0), "Invalid staking contract address" ); _stakingContract = stakingContract; } function isPayable() public pure override returns (bool) { return true; } // Decodes the custom Olas schema data from the standard attestation schema's data field function decodeCustomData( bytes memory data ) private pure returns (CustomAttestationSchema memory) { ( bytes32[] memory citationUID, bytes32 authorName, string memory articleTitle, bytes32 articleHash, string memory urlOfContent ) = abi.decode(data, (bytes32[], bytes32, string, bytes32, string)); return CustomAttestationSchema({ citationUID: citationUID, authorName: authorName, articleTitle: articleTitle, articleHash: articleHash, urlOfContent: urlOfContent }); } /// @param value = article stake amount function onAttest( Attestation calldata attestation, uint256 value ) internal override nonReentrant returns (bool) { if (value == 0) revert InsufficientEthValueSent(); emit ValueReceived(msg.sender, value); // Decode the attestation's data field into a struct CustomAttestationSchema memory customData = decodeCustomData( attestation.data ); uint256 receiversUIDsListLength = customData.citationUID.length; if (receiversUIDsListLength == 0) { IAuthorStake(_stakingContract).stakeEtherFrom{value: msg.value}( msg.sender ); emit TransferredStake(_stakingContract, msg.value); return true; } uint256 totalRoyalty = (value * ROYALTY_PERCENTAGE) / 100; uint256 individualRoyalty = totalRoyalty / receiversUIDsListLength; if (individualRoyalty == 0) { revert InsufficientIndividualRoyaltyPayment(); } uint256 stakingAmount = value - totalRoyalty; // Calculate the remaining staking amount after deducting royalty fee and transfer to the staking contract. for (uint256 i = 0; i < receiversUIDsListLength; ++i) { // Access each citationUID from the decoded data bytes32 citationUID = customData.citationUID[i]; // Fetch the attestation for each citationUID Attestation memory receiverAttestation = _eas.getAttestation( citationUID ); if (address(receiverAttestation.attester) == address(0)) { revert InvalidCitationUID(); } address payable royaltyReceiverAddress = payable( receiverAttestation.attester ); royaltyReceiverAddress.sendValue(individualRoyalty); // Using OpenZeppelin's sendValue() for safe Eth transfer. emit RoyaltyDistributed(royaltyReceiverAddress, individualRoyalty); } IAuthorStake(_stakingContract).stakeEtherFrom{value: stakingAmount}( msg.sender ); emit TransferredStake(_stakingContract, stakingAmount); return true; } function onRevoke( Attestation calldata attestation, uint256 value ) internal override returns (bool) {} receive() external payable override { revert DirectPaymentsNotAllowed(); } } // 1: add Solady safeTransfer // 2: check for potential integer overflow / underflow issues when calculating the individualRoyalty // 4: add import specific contract versions
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/Address.sol) pragma solidity ^0.8.20; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev The ETH balance of the account is not enough to perform the operation. */ error AddressInsufficientBalance(address account); /** * @dev There's no code at `target` (it is not a contract). */ error AddressEmptyCode(address target); /** * @dev A call to an address target failed. The target may have reverted. */ error FailedInnerCall(); /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.8.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { if (address(this).balance < amount) { revert AddressInsufficientBalance(address(this)); } (bool success, ) = recipient.call{value: amount}(""); if (!success) { revert FailedInnerCall(); } } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason or custom error, it is bubbled * up by this function (like regular Solidity function calls). However, if * the call reverted with no returned reason, this function reverts with a * {FailedInnerCall} error. * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { if (address(this).balance < value) { revert AddressInsufficientBalance(address(this)); } (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target * was not a contract or bubbling up the revert reason (falling back to {FailedInnerCall}) in case of an * unsuccessful call. */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata ) internal view returns (bytes memory) { if (!success) { _revert(returndata); } else { // only check if target is a contract if the call was successful and the return data is empty // otherwise we already know that it was a contract if (returndata.length == 0 && target.code.length == 0) { revert AddressEmptyCode(target); } return returndata; } } /** * @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the * revert reason or with a default {FailedInnerCall} error. */ function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) { if (!success) { _revert(returndata); } else { return returndata; } } /** * @dev Reverts with returndata if present. Otherwise reverts with {FailedInnerCall}. */ function _revert(bytes memory returndata) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert FailedInnerCall(); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/ReentrancyGuard.sol) pragma solidity ^0.8.20; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant NOT_ENTERED = 1; uint256 private constant ENTERED = 2; uint256 private _status; /** * @dev Unauthorized reentrant call. */ error ReentrancyGuardReentrantCall(); constructor() { _status = NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { _nonReentrantBefore(); _; _nonReentrantAfter(); } function _nonReentrantBefore() private { // On the first call to nonReentrant, _status will be NOT_ENTERED if (_status == ENTERED) { revert ReentrancyGuardReentrantCall(); } // Any calls to nonReentrant after this point will fail _status = ENTERED; } function _nonReentrantAfter() private { // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = NOT_ENTERED; } /** * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a * `nonReentrant` function in the call stack. */ function _reentrancyGuardEntered() internal view returns (bool) { return _status == ENTERED; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; import { IEAS, Attestation } from "../IEAS.sol"; import { AccessDenied, InvalidEAS, InvalidLength, uncheckedInc } from "../Common.sol"; import { Semver } from "../Semver.sol"; import { ISchemaResolver } from "./ISchemaResolver.sol"; /// @title SchemaResolver /// @notice The base schema resolver contract. abstract contract SchemaResolver is ISchemaResolver, Semver { error InsufficientValue(); error NotPayable(); // The global EAS contract. IEAS internal immutable _eas; /// @dev Creates a new resolver. /// @param eas The address of the global EAS contract. constructor(IEAS eas) Semver(1, 3, 0) { if (address(eas) == address(0)) { revert InvalidEAS(); } _eas = eas; } /// @dev Ensures that only the EAS contract can make this call. modifier onlyEAS() { _onlyEAS(); _; } /// @inheritdoc ISchemaResolver function isPayable() public pure virtual returns (bool) { return false; } /// @dev ETH callback. receive() external payable virtual { if (!isPayable()) { revert NotPayable(); } } /// @inheritdoc ISchemaResolver function attest(Attestation calldata attestation) external payable onlyEAS returns (bool) { return onAttest(attestation, msg.value); } /// @inheritdoc ISchemaResolver function multiAttest( Attestation[] calldata attestations, uint256[] calldata values ) external payable onlyEAS returns (bool) { uint256 length = attestations.length; if (length != values.length) { revert InvalidLength(); } // We are keeping track of the remaining ETH amount that can be sent to resolvers and will keep deducting // from it to verify that there isn't any attempt to send too much ETH to resolvers. Please note that unless // some ETH was stuck in the contract by accident (which shouldn't happen in normal conditions), it won't be // possible to send too much ETH anyway. uint256 remainingValue = msg.value; for (uint256 i = 0; i < length; i = uncheckedInc(i)) { // Ensure that the attester/revoker doesn't try to spend more than available. uint256 value = values[i]; if (value > remainingValue) { revert InsufficientValue(); } // Forward the attestation to the underlying resolver and return false in case it isn't approved. if (!onAttest(attestations[i], value)) { return false; } unchecked { // Subtract the ETH amount, that was provided to this attestation, from the global remaining ETH amount. remainingValue -= value; } } return true; } /// @inheritdoc ISchemaResolver function revoke(Attestation calldata attestation) external payable onlyEAS returns (bool) { return onRevoke(attestation, msg.value); } /// @inheritdoc ISchemaResolver function multiRevoke( Attestation[] calldata attestations, uint256[] calldata values ) external payable onlyEAS returns (bool) { uint256 length = attestations.length; if (length != values.length) { revert InvalidLength(); } // We are keeping track of the remaining ETH amount that can be sent to resolvers and will keep deducting // from it to verify that there isn't any attempt to send too much ETH to resolvers. Please note that unless // some ETH was stuck in the contract by accident (which shouldn't happen in normal conditions), it won't be // possible to send too much ETH anyway. uint256 remainingValue = msg.value; for (uint256 i = 0; i < length; i = uncheckedInc(i)) { // Ensure that the attester/revoker doesn't try to spend more than available. uint256 value = values[i]; if (value > remainingValue) { revert InsufficientValue(); } // Forward the revocation to the underlying resolver and return false in case it isn't approved. if (!onRevoke(attestations[i], value)) { return false; } unchecked { // Subtract the ETH amount, that was provided to this attestation, from the global remaining ETH amount. remainingValue -= value; } } return true; } /// @notice A resolver callback that should be implemented by child contracts. /// @param attestation The new attestation. /// @param value An explicit ETH amount that was sent to the resolver. Please note that this value is verified in /// both attest() and multiAttest() callbacks EAS-only callbacks and that in case of multi attestations, it'll /// usually hold that msg.value != value, since msg.value aggregated the sent ETH amounts for all the /// attestations in the batch. /// @return Whether the attestation is valid. function onAttest(Attestation calldata attestation, uint256 value) internal virtual returns (bool); /// @notice Processes an attestation revocation and verifies if it can be revoked. /// @param attestation The existing attestation to be revoked. /// @param value An explicit ETH amount that was sent to the resolver. Please note that this value is verified in /// both revoke() and multiRevoke() callbacks EAS-only callbacks and that in case of multi attestations, it'll /// usually hold that msg.value != value, since msg.value aggregated the sent ETH amounts for all the /// attestations in the batch. /// @return Whether the attestation can be revoked. function onRevoke(Attestation calldata attestation, uint256 value) internal virtual returns (bool); /// @dev Ensures that only the EAS contract can make this call. function _onlyEAS() private view { if (msg.sender != address(_eas)) { revert AccessDenied(); } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { ISchemaRegistry } from "./ISchemaRegistry.sol"; import { ISemver } from "./ISemver.sol"; import { Attestation, Signature } from "./Common.sol"; /// @notice A struct representing the arguments of the attestation request. struct AttestationRequestData { address recipient; // The recipient of the attestation. uint64 expirationTime; // The time when the attestation expires (Unix timestamp). bool revocable; // Whether the attestation is revocable. bytes32 refUID; // The UID of the related attestation. bytes data; // Custom attestation data. uint256 value; // An explicit ETH amount to send to the resolver. This is important to prevent accidental user errors. } /// @notice A struct representing the full arguments of the attestation request. struct AttestationRequest { bytes32 schema; // The unique identifier of the schema. AttestationRequestData data; // The arguments of the attestation request. } /// @notice A struct representing the full arguments of the full delegated attestation request. struct DelegatedAttestationRequest { bytes32 schema; // The unique identifier of the schema. AttestationRequestData data; // The arguments of the attestation request. Signature signature; // The ECDSA signature data. address attester; // The attesting account. uint64 deadline; // The deadline of the signature/request. } /// @notice A struct representing the full arguments of the multi attestation request. struct MultiAttestationRequest { bytes32 schema; // The unique identifier of the schema. AttestationRequestData[] data; // The arguments of the attestation request. } /// @notice A struct representing the full arguments of the delegated multi attestation request. struct MultiDelegatedAttestationRequest { bytes32 schema; // The unique identifier of the schema. AttestationRequestData[] data; // The arguments of the attestation requests. Signature[] signatures; // The ECDSA signatures data. Please note that the signatures are assumed to be signed with increasing nonces. address attester; // The attesting account. uint64 deadline; // The deadline of the signature/request. } /// @notice A struct representing the arguments of the revocation request. struct RevocationRequestData { bytes32 uid; // The UID of the attestation to revoke. uint256 value; // An explicit ETH amount to send to the resolver. This is important to prevent accidental user errors. } /// @notice A struct representing the full arguments of the revocation request. struct RevocationRequest { bytes32 schema; // The unique identifier of the schema. RevocationRequestData data; // The arguments of the revocation request. } /// @notice A struct representing the arguments of the full delegated revocation request. struct DelegatedRevocationRequest { bytes32 schema; // The unique identifier of the schema. RevocationRequestData data; // The arguments of the revocation request. Signature signature; // The ECDSA signature data. address revoker; // The revoking account. uint64 deadline; // The deadline of the signature/request. } /// @notice A struct representing the full arguments of the multi revocation request. struct MultiRevocationRequest { bytes32 schema; // The unique identifier of the schema. RevocationRequestData[] data; // The arguments of the revocation request. } /// @notice A struct representing the full arguments of the delegated multi revocation request. struct MultiDelegatedRevocationRequest { bytes32 schema; // The unique identifier of the schema. RevocationRequestData[] data; // The arguments of the revocation requests. Signature[] signatures; // The ECDSA signatures data. Please note that the signatures are assumed to be signed with increasing nonces. address revoker; // The revoking account. uint64 deadline; // The deadline of the signature/request. } /// @title IEAS /// @notice EAS - Ethereum Attestation Service interface. interface IEAS is ISemver { /// @notice Emitted when an attestation has been made. /// @param recipient The recipient of the attestation. /// @param attester The attesting account. /// @param uid The UID the revoked attestation. /// @param schemaUID The UID of the schema. event Attested(address indexed recipient, address indexed attester, bytes32 uid, bytes32 indexed schemaUID); /// @notice Emitted when an attestation has been revoked. /// @param recipient The recipient of the attestation. /// @param attester The attesting account. /// @param schemaUID The UID of the schema. /// @param uid The UID the revoked attestation. event Revoked(address indexed recipient, address indexed attester, bytes32 uid, bytes32 indexed schemaUID); /// @notice Emitted when a data has been timestamped. /// @param data The data. /// @param timestamp The timestamp. event Timestamped(bytes32 indexed data, uint64 indexed timestamp); /// @notice Emitted when a data has been revoked. /// @param revoker The address of the revoker. /// @param data The data. /// @param timestamp The timestamp. event RevokedOffchain(address indexed revoker, bytes32 indexed data, uint64 indexed timestamp); /// @notice Returns the address of the global schema registry. /// @return The address of the global schema registry. function getSchemaRegistry() external view returns (ISchemaRegistry); /// @notice Attests to a specific schema. /// @param request The arguments of the attestation request. /// @return The UID of the new attestation. /// /// Example: /// attest({ /// schema: "0facc36681cbe2456019c1b0d1e7bedd6d1d40f6f324bf3dd3a4cef2999200a0", /// data: { /// recipient: "0xdEADBeAFdeAdbEafdeadbeafDeAdbEAFdeadbeaf", /// expirationTime: 0, /// revocable: true, /// refUID: "0x0000000000000000000000000000000000000000000000000000000000000000", /// data: "0xF00D", /// value: 0 /// } /// }) function attest(AttestationRequest calldata request) external payable returns (bytes32); /// @notice Attests to a specific schema via the provided ECDSA signature. /// @param delegatedRequest The arguments of the delegated attestation request. /// @return The UID of the new attestation. /// /// Example: /// attestByDelegation({ /// schema: '0x8e72f5bc0a8d4be6aa98360baa889040c50a0e51f32dbf0baa5199bd93472ebc', /// data: { /// recipient: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', /// expirationTime: 1673891048, /// revocable: true, /// refUID: '0x0000000000000000000000000000000000000000000000000000000000000000', /// data: '0x1234', /// value: 0 /// }, /// signature: { /// v: 28, /// r: '0x148c...b25b', /// s: '0x5a72...be22' /// }, /// attester: '0xc5E8740aD971409492b1A63Db8d83025e0Fc427e', /// deadline: 1673891048 /// }) function attestByDelegation( DelegatedAttestationRequest calldata delegatedRequest ) external payable returns (bytes32); /// @notice Attests to multiple schemas. /// @param multiRequests The arguments of the multi attestation requests. The requests should be grouped by distinct /// schema ids to benefit from the best batching optimization. /// @return The UIDs of the new attestations. /// /// Example: /// multiAttest([{ /// schema: '0x33e9094830a5cba5554d1954310e4fbed2ef5f859ec1404619adea4207f391fd', /// data: [{ /// recipient: '0xdEADBeAFdeAdbEafdeadbeafDeAdbEAFdeadbeaf', /// expirationTime: 1673891048, /// revocable: true, /// refUID: '0x0000000000000000000000000000000000000000000000000000000000000000', /// data: '0x1234', /// value: 1000 /// }, /// { /// recipient: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', /// expirationTime: 0, /// revocable: false, /// refUID: '0x480df4a039efc31b11bfdf491b383ca138b6bde160988222a2a3509c02cee174', /// data: '0x00', /// value: 0 /// }], /// }, /// { /// schema: '0x5ac273ce41e3c8bfa383efe7c03e54c5f0bff29c9f11ef6ffa930fc84ca32425', /// data: [{ /// recipient: '0xdEADBeAFdeAdbEafdeadbeafDeAdbEAFdeadbeaf', /// expirationTime: 0, /// revocable: true, /// refUID: '0x75bf2ed8dca25a8190c50c52db136664de25b2449535839008ccfdab469b214f', /// data: '0x12345678', /// value: 0 /// }, /// }]) function multiAttest(MultiAttestationRequest[] calldata multiRequests) external payable returns (bytes32[] memory); /// @notice Attests to multiple schemas using via provided ECDSA signatures. /// @param multiDelegatedRequests The arguments of the delegated multi attestation requests. The requests should be /// grouped by distinct schema ids to benefit from the best batching optimization. /// @return The UIDs of the new attestations. /// /// Example: /// multiAttestByDelegation([{ /// schema: '0x8e72f5bc0a8d4be6aa98360baa889040c50a0e51f32dbf0baa5199bd93472ebc', /// data: [{ /// recipient: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', /// expirationTime: 1673891048, /// revocable: true, /// refUID: '0x0000000000000000000000000000000000000000000000000000000000000000', /// data: '0x1234', /// value: 0 /// }, /// { /// recipient: '0xdEADBeAFdeAdbEafdeadbeafDeAdbEAFdeadbeaf', /// expirationTime: 0, /// revocable: false, /// refUID: '0x0000000000000000000000000000000000000000000000000000000000000000', /// data: '0x00', /// value: 0 /// }], /// signatures: [{ /// v: 28, /// r: '0x148c...b25b', /// s: '0x5a72...be22' /// }, /// { /// v: 28, /// r: '0x487s...67bb', /// s: '0x12ad...2366' /// }], /// attester: '0x1D86495b2A7B524D747d2839b3C645Bed32e8CF4', /// deadline: 1673891048 /// }]) function multiAttestByDelegation( MultiDelegatedAttestationRequest[] calldata multiDelegatedRequests ) external payable returns (bytes32[] memory); /// @notice Revokes an existing attestation to a specific schema. /// @param request The arguments of the revocation request. /// /// Example: /// revoke({ /// schema: '0x8e72f5bc0a8d4be6aa98360baa889040c50a0e51f32dbf0baa5199bd93472ebc', /// data: { /// uid: '0x101032e487642ee04ee17049f99a70590c735b8614079fc9275f9dd57c00966d', /// value: 0 /// } /// }) function revoke(RevocationRequest calldata request) external payable; /// @notice Revokes an existing attestation to a specific schema via the provided ECDSA signature. /// @param delegatedRequest The arguments of the delegated revocation request. /// /// Example: /// revokeByDelegation({ /// schema: '0x8e72f5bc0a8d4be6aa98360baa889040c50a0e51f32dbf0baa5199bd93472ebc', /// data: { /// uid: '0xcbbc12102578c642a0f7b34fe7111e41afa25683b6cd7b5a14caf90fa14d24ba', /// value: 0 /// }, /// signature: { /// v: 27, /// r: '0xb593...7142', /// s: '0x0f5b...2cce' /// }, /// revoker: '0x244934dd3e31bE2c81f84ECf0b3E6329F5381992', /// deadline: 1673891048 /// }) function revokeByDelegation(DelegatedRevocationRequest calldata delegatedRequest) external payable; /// @notice Revokes existing attestations to multiple schemas. /// @param multiRequests The arguments of the multi revocation requests. The requests should be grouped by distinct /// schema ids to benefit from the best batching optimization. /// /// Example: /// multiRevoke([{ /// schema: '0x8e72f5bc0a8d4be6aa98360baa889040c50a0e51f32dbf0baa5199bd93472ebc', /// data: [{ /// uid: '0x211296a1ca0d7f9f2cfebf0daaa575bea9b20e968d81aef4e743d699c6ac4b25', /// value: 1000 /// }, /// { /// uid: '0xe160ac1bd3606a287b4d53d5d1d6da5895f65b4b4bab6d93aaf5046e48167ade', /// value: 0 /// }], /// }, /// { /// schema: '0x5ac273ce41e3c8bfa383efe7c03e54c5f0bff29c9f11ef6ffa930fc84ca32425', /// data: [{ /// uid: '0x053d42abce1fd7c8fcddfae21845ad34dae287b2c326220b03ba241bc5a8f019', /// value: 0 /// }, /// }]) function multiRevoke(MultiRevocationRequest[] calldata multiRequests) external payable; /// @notice Revokes existing attestations to multiple schemas via provided ECDSA signatures. /// @param multiDelegatedRequests The arguments of the delegated multi revocation attestation requests. The requests /// should be grouped by distinct schema ids to benefit from the best batching optimization. /// /// Example: /// multiRevokeByDelegation([{ /// schema: '0x8e72f5bc0a8d4be6aa98360baa889040c50a0e51f32dbf0baa5199bd93472ebc', /// data: [{ /// uid: '0x211296a1ca0d7f9f2cfebf0daaa575bea9b20e968d81aef4e743d699c6ac4b25', /// value: 1000 /// }, /// { /// uid: '0xe160ac1bd3606a287b4d53d5d1d6da5895f65b4b4bab6d93aaf5046e48167ade', /// value: 0 /// }], /// signatures: [{ /// v: 28, /// r: '0x148c...b25b', /// s: '0x5a72...be22' /// }, /// { /// v: 28, /// r: '0x487s...67bb', /// s: '0x12ad...2366' /// }], /// revoker: '0x244934dd3e31bE2c81f84ECf0b3E6329F5381992', /// deadline: 1673891048 /// }]) function multiRevokeByDelegation( MultiDelegatedRevocationRequest[] calldata multiDelegatedRequests ) external payable; /// @notice Timestamps the specified bytes32 data. /// @param data The data to timestamp. /// @return The timestamp the data was timestamped with. function timestamp(bytes32 data) external returns (uint64); /// @notice Timestamps the specified multiple bytes32 data. /// @param data The data to timestamp. /// @return The timestamp the data was timestamped with. function multiTimestamp(bytes32[] calldata data) external returns (uint64); /// @notice Revokes the specified bytes32 data. /// @param data The data to timestamp. /// @return The timestamp the data was revoked with. function revokeOffchain(bytes32 data) external returns (uint64); /// @notice Revokes the specified multiple bytes32 data. /// @param data The data to timestamp. /// @return The timestamp the data was revoked with. function multiRevokeOffchain(bytes32[] calldata data) external returns (uint64); /// @notice Returns an existing attestation by UID. /// @param uid The UID of the attestation to retrieve. /// @return The attestation data members. function getAttestation(bytes32 uid) external view returns (Attestation memory); /// @notice Checks whether an attestation exists. /// @param uid The UID of the attestation to retrieve. /// @return Whether an attestation exists. function isAttestationValid(bytes32 uid) external view returns (bool); /// @notice Returns the timestamp that the specified data was timestamped with. /// @param data The data to query. /// @return The timestamp the data was timestamped with. function getTimestamp(bytes32 data) external view returns (uint64); /// @notice Returns the timestamp that the specified data was timestamped with. /// @param data The data to query. /// @return The timestamp the data was timestamped with. function getRevokeOffchain(address revoker, bytes32 data) external view returns (uint64); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.19; interface IAuthorStake { /// @notice Allows a user to stake Ether in the contract. function stakeEtherFrom(address staker) external payable; /// @notice Allows a user to withdraw their staked Ether from the contract. /// @param amount The amount of Ether to withdraw. function withdrawStake(uint256 amount) external; /// @notice Returns the amount of Ether staked by a specific user. /// @param staker The address of the user to check the staked balance for. /// @return The amount of Ether staked by the user. function getStakedBalance(address staker) external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; // A representation of an empty/uninitialized UID. bytes32 constant EMPTY_UID = 0; // A zero expiration represents an non-expiring attestation. uint64 constant NO_EXPIRATION_TIME = 0; error AccessDenied(); error DeadlineExpired(); error InvalidEAS(); error InvalidLength(); error InvalidSignature(); error NotFound(); /// @notice A struct representing ECDSA signature data. struct Signature { uint8 v; // The recovery ID. bytes32 r; // The x-coordinate of the nonce R. bytes32 s; // The signature data. } /// @notice A struct representing a single attestation. struct Attestation { bytes32 uid; // A unique identifier of the attestation. bytes32 schema; // The unique identifier of the schema. uint64 time; // The time when the attestation was created (Unix timestamp). uint64 expirationTime; // The time when the attestation expires (Unix timestamp). uint64 revocationTime; // The time when the attestation was revoked (Unix timestamp). bytes32 refUID; // The UID of the related attestation. address recipient; // The recipient of the attestation. address attester; // The attester/sender of the attestation. bool revocable; // Whether the attestation is revocable. bytes data; // Custom attestation data. } /// @notice A helper function to work with unchecked iterators in loops. function uncheckedInc(uint256 i) pure returns (uint256 j) { unchecked { j = i + 1; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; import { Strings } from "@openzeppelin/contracts/utils/Strings.sol"; import { ISemver } from "./ISemver.sol"; /// @title Semver /// @notice A simple contract for managing contract versions. contract Semver is ISemver { // Contract's major version number. uint256 private immutable _major; // Contract's minor version number. uint256 private immutable _minor; // Contract's patch version number. uint256 private immutable _patch; /// @dev Create a new Semver instance. /// @param major Major version number. /// @param minor Minor version number. /// @param patch Patch version number. constructor(uint256 major, uint256 minor, uint256 patch) { _major = major; _minor = minor; _patch = patch; } /// @notice Returns the full semver contract version. /// @return Semver contract version as a string. function version() external view returns (string memory) { return string( abi.encodePacked(Strings.toString(_major), ".", Strings.toString(_minor), ".", Strings.toString(_patch)) ); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { ISemver } from "../ISemver.sol"; import { Attestation } from "../Common.sol"; /// @title ISchemaResolver /// @notice The interface of an optional schema resolver. interface ISchemaResolver is ISemver { /// @notice Checks if the resolver can be sent ETH. /// @return Whether the resolver supports ETH transfers. function isPayable() external pure returns (bool); /// @notice Processes an attestation and verifies whether it's valid. /// @param attestation The new attestation. /// @return Whether the attestation is valid. function attest(Attestation calldata attestation) external payable returns (bool); /// @notice Processes multiple attestations and verifies whether they are valid. /// @param attestations The new attestations. /// @param values Explicit ETH amounts which were sent with each attestation. /// @return Whether all the attestations are valid. function multiAttest( Attestation[] calldata attestations, uint256[] calldata values ) external payable returns (bool); /// @notice Processes an attestation revocation and verifies if it can be revoked. /// @param attestation The existing attestation to be revoked. /// @return Whether the attestation can be revoked. function revoke(Attestation calldata attestation) external payable returns (bool); /// @notice Processes revocation of multiple attestation and verifies they can be revoked. /// @param attestations The existing attestations to be revoked. /// @param values Explicit ETH amounts which were sent with each revocation. /// @return Whether the attestations can be revoked. function multiRevoke( Attestation[] calldata attestations, uint256[] calldata values ) external payable returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { ISemver } from "./ISemver.sol"; import { ISchemaResolver } from "./resolver/ISchemaResolver.sol"; /// @notice A struct representing a record for a submitted schema. struct SchemaRecord { bytes32 uid; // The unique identifier of the schema. ISchemaResolver resolver; // Optional schema resolver. bool revocable; // Whether the schema allows revocations explicitly. string schema; // Custom specification of the schema (e.g., an ABI). } /// @title ISchemaRegistry /// @notice The interface of global attestation schemas for the Ethereum Attestation Service protocol. interface ISchemaRegistry is ISemver { /// @notice Emitted when a new schema has been registered /// @param uid The schema UID. /// @param registerer The address of the account used to register the schema. /// @param schema The schema data. event Registered(bytes32 indexed uid, address indexed registerer, SchemaRecord schema); /// @notice Submits and reserves a new schema /// @param schema The schema data schema. /// @param resolver An optional schema resolver. /// @param revocable Whether the schema allows revocations explicitly. /// @return The UID of the new schema. function register(string calldata schema, ISchemaResolver resolver, bool revocable) external returns (bytes32); /// @notice Returns an existing schema by UID /// @param uid The UID of the schema to retrieve. /// @return The schema data members. function getSchema(bytes32 uid) external view returns (SchemaRecord memory); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /// @title ISemver /// @notice A semver interface. interface ISemver { /// @notice Returns the full semver contract version. /// @return Semver contract version as a string. function version() external view returns (string memory); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/Strings.sol) pragma solidity ^0.8.20; import {Math} from "./math/Math.sol"; import {SignedMath} from "./math/SignedMath.sol"; /** * @dev String operations. */ library Strings { bytes16 private constant HEX_DIGITS = "0123456789abcdef"; uint8 private constant ADDRESS_LENGTH = 20; /** * @dev The `value` string doesn't fit in the specified `length`. */ error StringsInsufficientHexLength(uint256 value, uint256 length); /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { unchecked { uint256 length = Math.log10(value) + 1; string memory buffer = new string(length); uint256 ptr; /// @solidity memory-safe-assembly assembly { ptr := add(buffer, add(32, length)) } while (true) { ptr--; /// @solidity memory-safe-assembly assembly { mstore8(ptr, byte(mod(value, 10), HEX_DIGITS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `int256` to its ASCII `string` decimal representation. */ function toStringSigned(int256 value) internal pure returns (string memory) { return string.concat(value < 0 ? "-" : "", toString(SignedMath.abs(value))); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { unchecked { return toHexString(value, Math.log256(value) + 1); } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ 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); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal * representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), ADDRESS_LENGTH); } /** * @dev Returns true if the two strings are equal. */ 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)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/math/Math.sol) pragma solidity ^0.8.20; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { /** * @dev Muldiv operation overflow. */ error MathOverflowedMulDiv(); enum Rounding { Floor, // Toward negative infinity Ceil, // Toward positive infinity Trunc, // Toward zero Expand // Away from zero } /** * @dev Returns the addition of two unsigned integers, with an overflow flag. */ 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); } } /** * @dev Returns the subtraction of two unsigned integers, with an overflow flag. */ function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b > a) return (false, 0); return (true, a - b); } } /** * @dev Returns the multiplication of two unsigned integers, with an overflow flag. */ function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) return (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } } /** * @dev Returns the division of two unsigned integers, with a division by zero flag. */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a / b); } } /** * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. */ function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a % b); } } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds towards infinity instead * of rounding towards zero. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { if (b == 0) { // Guarantee the same behavior as in a regular Solidity division. return a / b; } // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or * denominator == 0. * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) with further edits by * Uniswap Labs also under MIT license. */ function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0 = x * y; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { // Solidity will revert if denominator == 0, unlike the div opcode on its own. // The surrounding unchecked block does not change this fact. // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic. return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. if (denominator <= prod1) { revert MathOverflowedMulDiv(); } /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. // Always >= 1. See https://cs.stackexchange.com/q/138556/92363. uint256 twos = denominator & (0 - denominator); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also // works in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ 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; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded * towards zero. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. // // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` // // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1 << (log2(a) >> 1); // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. 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); } } /** * @notice Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = sqrt(a); return result + (unsignedRoundsUp(rounding) && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2 of a positive value rounded towards zero. * Returns 0 if given 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; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + (unsignedRoundsUp(rounding) && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10 of a positive value rounded towards zero. * Returns 0 if given 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; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + (unsignedRoundsUp(rounding) && 10 ** result < value ? 1 : 0); } } /** * @dev Return the log in base 256 of a positive value rounded towards zero. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ 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; } /** * @dev Return the log in base 256, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ 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); } } /** * @dev Returns whether a provided rounding mode is considered rounding up for unsigned integers. */ function unsignedRoundsUp(Rounding rounding) internal pure returns (bool) { return uint8(rounding) % 2 == 1; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/math/SignedMath.sol) pragma solidity ^0.8.20; /** * @dev Standard signed math utilities missing in the Solidity language. */ library SignedMath { /** * @dev Returns the largest of two signed numbers. */ function max(int256 a, int256 b) internal pure returns (int256) { return a > b ? a : b; } /** * @dev Returns the smallest of two signed numbers. */ function min(int256 a, int256 b) internal pure returns (int256) { return a < b ? a : b; } /** * @dev Returns the average of two signed numbers without overflow. * The result is rounded towards zero. */ function average(int256 a, int256 b) internal pure returns (int256) { // Formula from the book "Hacker's Delight" int256 x = (a & b) + ((a ^ b) >> 1); return x + (int256(uint256(x) >> 255) & (a ^ b)); } /** * @dev Returns the absolute unsigned value of a signed value. */ function abs(int256 n) internal pure returns (uint256) { unchecked { // must be unchecked in order to support `n = type(int256).min` return uint256(n >= 0 ? n : -n); } } }
{ "remappings": [ "@openzeppelin/=lib/openzeppelin-contracts/", "eas-contracts/=lib/eas-contracts/contracts/", "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/", "ds-test/=lib/forge-std/lib/ds-test/src/", "erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/", "forge-std/=lib/forge-std/src/", "openzeppelin-contracts/=lib/openzeppelin-contracts/" ], "optimizer": { "enabled": true, "runs": 200 }, "metadata": { "useLiteralContent": false, "bytecodeHash": "ipfs", "appendCBOR": true }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "evmVersion": "paris", "libraries": {} }
[{"inputs":[{"internalType":"contract IEAS","name":"eas","type":"address"},{"internalType":"address","name":"stakingContract","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AccessDenied","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"AddressInsufficientBalance","type":"error"},{"inputs":[],"name":"DirectPaymentsNotAllowed","type":"error"},{"inputs":[],"name":"FailedInnerCall","type":"error"},{"inputs":[],"name":"InsufficientEthValueSent","type":"error"},{"inputs":[],"name":"InsufficientIndividualRoyaltyPayment","type":"error"},{"inputs":[],"name":"InsufficientValue","type":"error"},{"inputs":[],"name":"InvalidCitationUID","type":"error"},{"inputs":[],"name":"InvalidEAS","type":"error"},{"inputs":[],"name":"InvalidLength","type":"error"},{"inputs":[],"name":"NotPayable","type":"error"},{"inputs":[],"name":"ReentrancyGuardReentrantCall","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"receiver","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"RoyaltyDistributed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"stakingContract","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"TransferredStake","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"attester","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"ValueReceived","type":"event"},{"inputs":[{"components":[{"internalType":"bytes32","name":"uid","type":"bytes32"},{"internalType":"bytes32","name":"schema","type":"bytes32"},{"internalType":"uint64","name":"time","type":"uint64"},{"internalType":"uint64","name":"expirationTime","type":"uint64"},{"internalType":"uint64","name":"revocationTime","type":"uint64"},{"internalType":"bytes32","name":"refUID","type":"bytes32"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"address","name":"attester","type":"address"},{"internalType":"bool","name":"revocable","type":"bool"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct Attestation","name":"attestation","type":"tuple"}],"name":"attest","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"isPayable","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[{"components":[{"internalType":"bytes32","name":"uid","type":"bytes32"},{"internalType":"bytes32","name":"schema","type":"bytes32"},{"internalType":"uint64","name":"time","type":"uint64"},{"internalType":"uint64","name":"expirationTime","type":"uint64"},{"internalType":"uint64","name":"revocationTime","type":"uint64"},{"internalType":"bytes32","name":"refUID","type":"bytes32"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"address","name":"attester","type":"address"},{"internalType":"bool","name":"revocable","type":"bool"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct Attestation[]","name":"attestations","type":"tuple[]"},{"internalType":"uint256[]","name":"values","type":"uint256[]"}],"name":"multiAttest","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"bytes32","name":"uid","type":"bytes32"},{"internalType":"bytes32","name":"schema","type":"bytes32"},{"internalType":"uint64","name":"time","type":"uint64"},{"internalType":"uint64","name":"expirationTime","type":"uint64"},{"internalType":"uint64","name":"revocationTime","type":"uint64"},{"internalType":"bytes32","name":"refUID","type":"bytes32"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"address","name":"attester","type":"address"},{"internalType":"bool","name":"revocable","type":"bool"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct Attestation[]","name":"attestations","type":"tuple[]"},{"internalType":"uint256[]","name":"values","type":"uint256[]"}],"name":"multiRevoke","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"bytes32","name":"uid","type":"bytes32"},{"internalType":"bytes32","name":"schema","type":"bytes32"},{"internalType":"uint64","name":"time","type":"uint64"},{"internalType":"uint64","name":"expirationTime","type":"uint64"},{"internalType":"uint64","name":"revocationTime","type":"uint64"},{"internalType":"bytes32","name":"refUID","type":"bytes32"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"address","name":"attester","type":"address"},{"internalType":"bool","name":"revocable","type":"bool"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct Attestation","name":"attestation","type":"tuple"}],"name":"revoke","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"version","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
61012060405234801561001157600080fd5b50604051611244380380611244833981016040819052610030916100f7565b6001608052600360a052600060c052816001600160a01b038116610067576040516341bc07ff60e11b815260040160405180910390fd5b6001600160a01b0390811660e052600160005581166100cc5760405162461bcd60e51b815260206004820181905260248201527f496e76616c6964207374616b696e6720636f6e74726163742061646472657373604482015260640160405180910390fd5b6001600160a01b03166101005250610131565b6001600160a01b03811681146100f457600080fd5b50565b6000806040838503121561010a57600080fd5b8251610115816100df565b6020840151909250610126816100df565b809150509250929050565b60805160a05160c05160e051610100516110b36101916000396000818161051f01528181610587015281816107c0015261082801526000818161040e015261067c0152600061016f015260006101460152600061011d01526110b36000f3fe6080604052600436106100595760003560e01c806354fd4d501461007b57806388e5b2d9146100a657806391db0b7e146100c9578063ce46e046146100dc578063e49617e1146100f0578063e60c35051461010357600080fd5b366100765760405162a8b0c760e21b815260040160405180910390fd5b600080fd5b34801561008757600080fd5b50610090610116565b60405161009d9190610aee565b60405180910390f35b6100b96100b4366004610b6d565b6101b9565b604051901515815260200161009d565b6100b96100d7366004610b6d565b610288565b3480156100e857600080fd5b5060016100b9565b6100b96100fe366004610bd9565b610347565b6100b9610111366004610bd9565b61035c565b60606101417f0000000000000000000000000000000000000000000000000000000000000000610370565b61016a7f0000000000000000000000000000000000000000000000000000000000000000610370565b6101937f0000000000000000000000000000000000000000000000000000000000000000610370565b6040516020016101a593929190610c1c565b604051602081830303815290604052905090565b60006101c3610403565b838281146101e45760405163251f56a160e21b815260040160405180910390fd5b3460005b8281101561027857600086868381811061020457610204610c76565b9050602002013590508281111561022e5760405163044044a560e21b815260040160405180910390fd5b61025b89898481811061024357610243610c76565b90506020028101906102559190610c8c565b50600090565b61026c576000945050505050610280565b909103906001016101e8565b506001925050505b949350505050565b6000610292610403565b838281146102b35760405163251f56a160e21b815260040160405180910390fd5b3460005b828110156102785760008686838181106102d3576102d3610c76565b905060200201359050828111156102fd5760405163044044a560e21b815260040160405180910390fd5b61032a89898481811061031257610312610c76565b90506020028101906103249190610c8c565b8261044e565b61033b576000945050505050610280565b909103906001016102b7565b6000610351610403565b60005b90505b919050565b6000610366610403565b610354823461044e565b6060600061037d836108a3565b600101905060008167ffffffffffffffff81111561039d5761039d610cad565b6040519080825280601f01601f1916602001820160405280156103c7576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a85049450846103d157509392505050565b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461044c57604051634ca8886760e01b815260040160405180910390fd5b565b600061045861097b565b81600003610479576040516379aa648b60e11b815260040160405180910390fd5b60405182815233907f7e71433ddf847725166244795048ecf3e3f9f35628254ecbf7360566642334939060200160405180910390a260006104fb6104c1610120860186610cc3565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506109a592505050565b80515190915060008190036105f357604051633c796a9360e21b81523360048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063f1e5aa4c9034906024016000604051808303818588803b15801561056c57600080fd5b505af1158015610580573d6000803e3d6000fd5b50505050507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03167f11731f01d03db7338d50639c2f04103fb648a430bcf486c9c6bf790003f009a7346040516105e091815260200190565b60405180910390a2600192505050610893565b60006064610602600a87610d20565b61060c9190610d37565b9050600061061a8383610d37565b90508060000361063d57604051632fd96c5f60e01b815260040160405180910390fd5b60006106498388610d59565b905060005b848110156107aa5760008660000151828151811061066e5761066e610c76565b6020026020010151905060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a3112a64836040518263ffffffff1660e01b81526004016106c891815260200190565b600060405180830381865afa1580156106e5573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261070d9190810190610e6a565b60e08101519091506001600160a01b031661073b576040516303f00df160e31b815260040160405180910390fd5b60e08101516107536001600160a01b03821687610a2a565b806001600160a01b03167fc34f30165071f2be6258315cf60279fa343e720cdf6a8b91c1660270d201ea6d8760405161078e91815260200190565b60405180910390a2505050806107a390610f61565b905061064e565b50604051633c796a9360e21b81523360048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063f1e5aa4c9083906024016000604051808303818588803b15801561080d57600080fd5b505af1158015610821573d6000803e3d6000fd5b50505050507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03167f11731f01d03db7338d50639c2f04103fb648a430bcf486c9c6bf790003f009a78260405161088191815260200190565b60405180910390a26001955050505050505b61089d6001600055565b92915050565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b83106108e25772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef8100000000831061090e576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc10000831061092c57662386f26fc10000830492506010015b6305f5e1008310610944576305f5e100830492506008015b612710831061095857612710830492506004015b6064831061096a576064830492506002015b600a831061089d5760010192915050565b60026000540361099e57604051633ee5aeb560e01b815260040160405180910390fd5b6002600055565b6109dd6040518060a0016040528060608152602001600080191681526020016060815260200160008019168152602001606081525090565b6000806000806000868060200190518101906109f99190610f7a565b6040805160a08101825295865260208601949094529284019190915260608301526080820152979650505050505050565b80471015610a515760405163cd78605960e01b815230600482015260240160405180910390fd5b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114610a9e576040519150601f19603f3d011682016040523d82523d6000602084013e610aa3565b606091505b5050905080610ac557604051630a12f52160e11b815260040160405180910390fd5b505050565b60005b83811015610ae5578181015183820152602001610acd565b50506000910152565b6020815260008251806020840152610b0d816040850160208701610aca565b601f01601f19169190910160400192915050565b60008083601f840112610b3357600080fd5b50813567ffffffffffffffff811115610b4b57600080fd5b6020830191508360208260051b8501011115610b6657600080fd5b9250929050565b60008060008060408587031215610b8357600080fd5b843567ffffffffffffffff80821115610b9b57600080fd5b610ba788838901610b21565b90965094506020870135915080821115610bc057600080fd5b50610bcd87828801610b21565b95989497509550505050565b600060208284031215610beb57600080fd5b813567ffffffffffffffff811115610c0257600080fd5b82016101408185031215610c1557600080fd5b9392505050565b60008451610c2e818460208901610aca565b8083019050601760f91b8082528551610c4e816001850160208a01610aca565b60019201918201528351610c69816002840160208801610aca565b0160020195945050505050565b634e487b7160e01b600052603260045260246000fd5b6000823561013e19833603018112610ca357600080fd5b9190910192915050565b634e487b7160e01b600052604160045260246000fd5b6000808335601e19843603018112610cda57600080fd5b83018035915067ffffffffffffffff821115610cf557600080fd5b602001915036819003821315610b6657600080fd5b634e487b7160e01b600052601160045260246000fd5b808202811582820484141761089d5761089d610d0a565b600082610d5457634e487b7160e01b600052601260045260246000fd5b500490565b8181038181111561089d5761089d610d0a565b604051610140810167ffffffffffffffff81118282101715610d9057610d90610cad565b60405290565b604051601f8201601f1916810167ffffffffffffffff81118282101715610dbf57610dbf610cad565b604052919050565b805167ffffffffffffffff8116811461035757600080fd5b80516001600160a01b038116811461035757600080fd5b8051801515811461035757600080fd5b600082601f830112610e1757600080fd5b815167ffffffffffffffff811115610e3157610e31610cad565b610e44601f8201601f1916602001610d96565b818152846020838601011115610e5957600080fd5b610280826020830160208701610aca565b600060208284031215610e7c57600080fd5b815167ffffffffffffffff80821115610e9457600080fd5b908301906101408286031215610ea957600080fd5b610eb1610d6c565b8251815260208301516020820152610ecb60408401610dc7565b6040820152610edc60608401610dc7565b6060820152610eed60808401610dc7565b608082015260a083015160a0820152610f0860c08401610ddf565b60c0820152610f1960e08401610ddf565b60e0820152610100610f2c818501610df6565b908201526101208381015183811115610f4457600080fd5b610f5088828701610e06565b918301919091525095945050505050565b600060018201610f7357610f73610d0a565b5060010190565b600080600080600060a08688031215610f9257600080fd5b855167ffffffffffffffff80821115610faa57600080fd5b818801915088601f830112610fbe57600080fd5b8151602082821115610fd257610fd2610cad565b8160051b610fe1828201610d96565b928352848101820192828101908d851115610ffb57600080fd5b958301955b8487101561101957865182529583019590830190611000565b928c015160408d0151939b5099509194505050508082111561103a57600080fd5b61104689838a01610e06565b945060608801519350608088015191508082111561106357600080fd5b5061107088828901610e06565b915050929550929590935056fea2646970667358221220f3a32842467c28d43db799d770c3f68c4e4b57a53b60a4f363da3706bf2f9bb964736f6c63430008140033000000000000000000000000c2679fbd37d54388ce493f1db75320d236e1815e000000000000000000000000d9e2e5131a97882867fcedb99149f4050c4f6aac
Deployed Bytecode
0x6080604052600436106100595760003560e01c806354fd4d501461007b57806388e5b2d9146100a657806391db0b7e146100c9578063ce46e046146100dc578063e49617e1146100f0578063e60c35051461010357600080fd5b366100765760405162a8b0c760e21b815260040160405180910390fd5b600080fd5b34801561008757600080fd5b50610090610116565b60405161009d9190610aee565b60405180910390f35b6100b96100b4366004610b6d565b6101b9565b604051901515815260200161009d565b6100b96100d7366004610b6d565b610288565b3480156100e857600080fd5b5060016100b9565b6100b96100fe366004610bd9565b610347565b6100b9610111366004610bd9565b61035c565b60606101417f0000000000000000000000000000000000000000000000000000000000000001610370565b61016a7f0000000000000000000000000000000000000000000000000000000000000003610370565b6101937f0000000000000000000000000000000000000000000000000000000000000000610370565b6040516020016101a593929190610c1c565b604051602081830303815290604052905090565b60006101c3610403565b838281146101e45760405163251f56a160e21b815260040160405180910390fd5b3460005b8281101561027857600086868381811061020457610204610c76565b9050602002013590508281111561022e5760405163044044a560e21b815260040160405180910390fd5b61025b89898481811061024357610243610c76565b90506020028101906102559190610c8c565b50600090565b61026c576000945050505050610280565b909103906001016101e8565b506001925050505b949350505050565b6000610292610403565b838281146102b35760405163251f56a160e21b815260040160405180910390fd5b3460005b828110156102785760008686838181106102d3576102d3610c76565b905060200201359050828111156102fd5760405163044044a560e21b815260040160405180910390fd5b61032a89898481811061031257610312610c76565b90506020028101906103249190610c8c565b8261044e565b61033b576000945050505050610280565b909103906001016102b7565b6000610351610403565b60005b90505b919050565b6000610366610403565b610354823461044e565b6060600061037d836108a3565b600101905060008167ffffffffffffffff81111561039d5761039d610cad565b6040519080825280601f01601f1916602001820160405280156103c7576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a85049450846103d157509392505050565b336001600160a01b037f000000000000000000000000c2679fbd37d54388ce493f1db75320d236e1815e161461044c57604051634ca8886760e01b815260040160405180910390fd5b565b600061045861097b565b81600003610479576040516379aa648b60e11b815260040160405180910390fd5b60405182815233907f7e71433ddf847725166244795048ecf3e3f9f35628254ecbf7360566642334939060200160405180910390a260006104fb6104c1610120860186610cc3565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506109a592505050565b80515190915060008190036105f357604051633c796a9360e21b81523360048201527f000000000000000000000000d9e2e5131a97882867fcedb99149f4050c4f6aac6001600160a01b03169063f1e5aa4c9034906024016000604051808303818588803b15801561056c57600080fd5b505af1158015610580573d6000803e3d6000fd5b50505050507f000000000000000000000000d9e2e5131a97882867fcedb99149f4050c4f6aac6001600160a01b03167f11731f01d03db7338d50639c2f04103fb648a430bcf486c9c6bf790003f009a7346040516105e091815260200190565b60405180910390a2600192505050610893565b60006064610602600a87610d20565b61060c9190610d37565b9050600061061a8383610d37565b90508060000361063d57604051632fd96c5f60e01b815260040160405180910390fd5b60006106498388610d59565b905060005b848110156107aa5760008660000151828151811061066e5761066e610c76565b6020026020010151905060007f000000000000000000000000c2679fbd37d54388ce493f1db75320d236e1815e6001600160a01b031663a3112a64836040518263ffffffff1660e01b81526004016106c891815260200190565b600060405180830381865afa1580156106e5573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261070d9190810190610e6a565b60e08101519091506001600160a01b031661073b576040516303f00df160e31b815260040160405180910390fd5b60e08101516107536001600160a01b03821687610a2a565b806001600160a01b03167fc34f30165071f2be6258315cf60279fa343e720cdf6a8b91c1660270d201ea6d8760405161078e91815260200190565b60405180910390a2505050806107a390610f61565b905061064e565b50604051633c796a9360e21b81523360048201527f000000000000000000000000d9e2e5131a97882867fcedb99149f4050c4f6aac6001600160a01b03169063f1e5aa4c9083906024016000604051808303818588803b15801561080d57600080fd5b505af1158015610821573d6000803e3d6000fd5b50505050507f000000000000000000000000d9e2e5131a97882867fcedb99149f4050c4f6aac6001600160a01b03167f11731f01d03db7338d50639c2f04103fb648a430bcf486c9c6bf790003f009a78260405161088191815260200190565b60405180910390a26001955050505050505b61089d6001600055565b92915050565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b83106108e25772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef8100000000831061090e576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc10000831061092c57662386f26fc10000830492506010015b6305f5e1008310610944576305f5e100830492506008015b612710831061095857612710830492506004015b6064831061096a576064830492506002015b600a831061089d5760010192915050565b60026000540361099e57604051633ee5aeb560e01b815260040160405180910390fd5b6002600055565b6109dd6040518060a0016040528060608152602001600080191681526020016060815260200160008019168152602001606081525090565b6000806000806000868060200190518101906109f99190610f7a565b6040805160a08101825295865260208601949094529284019190915260608301526080820152979650505050505050565b80471015610a515760405163cd78605960e01b815230600482015260240160405180910390fd5b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114610a9e576040519150601f19603f3d011682016040523d82523d6000602084013e610aa3565b606091505b5050905080610ac557604051630a12f52160e11b815260040160405180910390fd5b505050565b60005b83811015610ae5578181015183820152602001610acd565b50506000910152565b6020815260008251806020840152610b0d816040850160208701610aca565b601f01601f19169190910160400192915050565b60008083601f840112610b3357600080fd5b50813567ffffffffffffffff811115610b4b57600080fd5b6020830191508360208260051b8501011115610b6657600080fd5b9250929050565b60008060008060408587031215610b8357600080fd5b843567ffffffffffffffff80821115610b9b57600080fd5b610ba788838901610b21565b90965094506020870135915080821115610bc057600080fd5b50610bcd87828801610b21565b95989497509550505050565b600060208284031215610beb57600080fd5b813567ffffffffffffffff811115610c0257600080fd5b82016101408185031215610c1557600080fd5b9392505050565b60008451610c2e818460208901610aca565b8083019050601760f91b8082528551610c4e816001850160208a01610aca565b60019201918201528351610c69816002840160208801610aca565b0160020195945050505050565b634e487b7160e01b600052603260045260246000fd5b6000823561013e19833603018112610ca357600080fd5b9190910192915050565b634e487b7160e01b600052604160045260246000fd5b6000808335601e19843603018112610cda57600080fd5b83018035915067ffffffffffffffff821115610cf557600080fd5b602001915036819003821315610b6657600080fd5b634e487b7160e01b600052601160045260246000fd5b808202811582820484141761089d5761089d610d0a565b600082610d5457634e487b7160e01b600052601260045260246000fd5b500490565b8181038181111561089d5761089d610d0a565b604051610140810167ffffffffffffffff81118282101715610d9057610d90610cad565b60405290565b604051601f8201601f1916810167ffffffffffffffff81118282101715610dbf57610dbf610cad565b604052919050565b805167ffffffffffffffff8116811461035757600080fd5b80516001600160a01b038116811461035757600080fd5b8051801515811461035757600080fd5b600082601f830112610e1757600080fd5b815167ffffffffffffffff811115610e3157610e31610cad565b610e44601f8201601f1916602001610d96565b818152846020838601011115610e5957600080fd5b610280826020830160208701610aca565b600060208284031215610e7c57600080fd5b815167ffffffffffffffff80821115610e9457600080fd5b908301906101408286031215610ea957600080fd5b610eb1610d6c565b8251815260208301516020820152610ecb60408401610dc7565b6040820152610edc60608401610dc7565b6060820152610eed60808401610dc7565b608082015260a083015160a0820152610f0860c08401610ddf565b60c0820152610f1960e08401610ddf565b60e0820152610100610f2c818501610df6565b908201526101208381015183811115610f4457600080fd5b610f5088828701610e06565b918301919091525095945050505050565b600060018201610f7357610f73610d0a565b5060010190565b600080600080600060a08688031215610f9257600080fd5b855167ffffffffffffffff80821115610faa57600080fd5b818801915088601f830112610fbe57600080fd5b8151602082821115610fd257610fd2610cad565b8160051b610fe1828201610d96565b928352848101820192828101908d851115610ffb57600080fd5b958301955b8487101561101957865182529583019590830190611000565b928c015160408d0151939b5099509194505050508082111561103a57600080fd5b61104689838a01610e06565b945060608801519350608088015191508082111561106357600080fd5b5061107088828901610e06565b915050929550929590935056fea2646970667358221220f3a32842467c28d43db799d770c3f68c4e4b57a53b60a4f363da3706bf2f9bb964736f6c63430008140033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000c2679fbd37d54388ce493f1db75320d236e1815e000000000000000000000000d9e2e5131a97882867fcedb99149f4050c4f6aac
-----Decoded View---------------
Arg [0] : eas (address): 0xC2679fBD37d54388Ce493F1DB75320D236e1815e
Arg [1] : stakingContract (address): 0xd9e2e5131A97882867fcedb99149f4050C4f6AAc
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000c2679fbd37d54388ce493f1db75320d236e1815e
Arg [1] : 000000000000000000000000d9e2e5131a97882867fcedb99149f4050c4f6aac
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.