Skip to content

Commit

Permalink
1.1.0: Optimizations, timestamps are now saved, and backward compat.
Browse files Browse the repository at this point in the history
  • Loading branch information
boyuanx committed Feb 8, 2024
1 parent 6c5c565 commit c91ce5c
Show file tree
Hide file tree
Showing 7 changed files with 201 additions and 145 deletions.
140 changes: 85 additions & 55 deletions src/core/SP.sol

Large diffs are not rendered by default.

60 changes: 32 additions & 28 deletions src/interfaces/ISP.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,36 +11,36 @@ import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
* @author Jack Xu @ EthSign
*/
interface ISP is IVersionable {
event SchemaRegistered(uint256 schemaId);
event AttestationMade(uint256 attestationId, string indexingKey);
event AttestationRevoked(uint256 attestationId, string reason);
event SchemaRegistered(uint64 schemaId);
event AttestationMade(uint64 attestationId, string indexingKey);
event AttestationRevoked(uint64 attestationId, string reason);
event OffchainAttestationMade(string attestationId);
event OffchainAttestationRevoked(string attestationId, string reason);

/**
* @dev 0x38f8c6c4
*/
error SchemaNonexistent(uint256 nonexistentSchemaId);
error SchemaNonexistent(uint64 nonexistentSchemaId);
/**
* @dev 0x71984561
*/
error SchemaWrongRegistrant(address expected, address actual);
/**
* @dev 0x8ac42f49
*/
error AttestationIrrevocable(uint256 schemaId, uint256 offendingAttestationId);
error AttestationIrrevocable(uint64 schemaId, uint64 offendingAttestationId);
/**
* @dev 0x54681a13
*/
error AttestationNonexistent(uint256 nonexistentAttestationId);
error AttestationNonexistent(uint64 nonexistentAttestationId);
/**
* @dev 0xa65e02ed
*/
error AttestationInvalidDuration(uint256 offendingAttestationId, uint64 maxDuration, uint64 inputDuration);
error AttestationInvalidDuration(uint64 offendingAttestationId, uint64 maxDuration, uint64 inputDuration);
/**
* @dev 0xd8c3da86
*/
error AttestationAlreadyRevoked(uint256 offendingAttestationId);
error AttestationAlreadyRevoked(uint64 offendingAttestationId);
/**
* @dev 0xa9ad2007
*/
Expand All @@ -61,6 +61,10 @@ interface ISP is IVersionable {
* @dev 0xfdf4e6f9
*/
error InvalidDelegateSignature();
/**
* @dev 0x5c34b9cc
*/
error LegacySPRequired(address legacySP);

/**
* @notice Registers a Schema.
Expand All @@ -70,7 +74,7 @@ interface ISP is IVersionable {
* otherwise.
* @return schemaId The assigned ID of the registered schema.
*/
function register(Schema memory schema, bytes calldata delegateSignature) external returns (uint256 schemaId);
function register(Schema memory schema, bytes calldata delegateSignature) external returns (uint64 schemaId);

/**
* @notice Makes an attestation.
Expand All @@ -89,7 +93,7 @@ interface ISP is IVersionable {
bytes calldata extraData
)
external
returns (uint256 attestationId);
returns (uint64 attestationId);

/**
* @notice Makes an attestation where the schema hook expects ETH payment.
Expand All @@ -111,7 +115,7 @@ interface ISP is IVersionable {
)
external
payable
returns (uint256 attestationId);
returns (uint64 attestationId);

/**
* @notice Makes an attestation where the schema hook expects ERC20 payment.
Expand All @@ -134,7 +138,7 @@ interface ISP is IVersionable {
bytes calldata extraData
)
external
returns (uint256 attestationId);
returns (uint64 attestationId);

/**
* @notice Timestamps an off-chain data ID.
Expand All @@ -161,7 +165,7 @@ interface ISP is IVersionable {
* @param extraData This is forwarded to the resolver directly.
*/
function revoke(
uint256 attestationId,
uint64 attestationId,
string calldata reason,
bytes calldata delegateSignature,
bytes calldata extraData
Expand All @@ -178,7 +182,7 @@ interface ISP is IVersionable {
* @param extraData This is forwarded to the resolver directly.
*/
function revoke(
uint256 attestationId,
uint64 attestationId,
string calldata reason,
uint256 resolverFeesETH,
bytes calldata delegateSignature,
Expand All @@ -198,7 +202,7 @@ interface ISP is IVersionable {
* @param extraData This is forwarded to the resolver directly.
*/
function revoke(
uint256 attestationId,
uint64 attestationId,
string calldata reason,
IERC20 resolverFeesERC20Token,
uint256 resolverFeesERC20Amount,
Expand Down Expand Up @@ -229,7 +233,7 @@ interface ISP is IVersionable {
bytes calldata delegateSignature
)
external
returns (uint256[] calldata schemaIds);
returns (uint64[] calldata schemaIds);

/**
* @notice Batch attests.
Expand All @@ -241,7 +245,7 @@ interface ISP is IVersionable {
bytes calldata extraData
)
external
returns (uint256[] calldata attestationIds);
returns (uint64[] calldata attestationIds);

/**
* @notice Batch attests where the schema hook expects ETH payment.
Expand All @@ -255,7 +259,7 @@ interface ISP is IVersionable {
)
external
payable
returns (uint256[] calldata attestationIds);
returns (uint64[] calldata attestationIds);

/**
* @notice Batch attests where the schema hook expects ERC20 payment.
Expand All @@ -269,7 +273,7 @@ interface ISP is IVersionable {
bytes calldata extraData
)
external
returns (uint256[] calldata attestationIds);
returns (uint64[] calldata attestationIds);

/**
* @notice Batch timestamps off-chain data IDs.
Expand All @@ -285,7 +289,7 @@ interface ISP is IVersionable {
* @notice Batch revokes revocable on-chain attestations.
*/
function revokeBatch(
uint256[] calldata attestationIds,
uint64[] calldata attestationIds,
string[] calldata reasons,
bytes calldata delegateSignature,
bytes calldata extraData
Expand All @@ -296,7 +300,7 @@ interface ISP is IVersionable {
* @notice Batch revokes revocable on-chain attestations where the schema hook expects ETH payment.
*/
function revokeBatch(
uint256[] calldata attestationIds,
uint64[] calldata attestationIds,
string[] calldata reasons,
uint256[] calldata resolverFeesETH,
bytes calldata delegateSignature,
Expand All @@ -309,7 +313,7 @@ interface ISP is IVersionable {
* @notice Batch revokes revocable on-chain attestations where the schema hook expects ERC20 payment.
*/
function revokeBatch(
uint256[] calldata attestationIds,
uint64[] calldata attestationIds,
string[] calldata reasons,
IERC20[] calldata resolverFeesERC20Tokens,
uint256[] calldata resolverFeesERC20Amount,
Expand All @@ -331,12 +335,12 @@ interface ISP is IVersionable {
/**
* @notice Returns the specified `Schema`.
*/
function getSchema(uint256 schemaId) external view returns (Schema calldata);
function getSchema(uint64 schemaId) external view returns (Schema calldata);

/**
* @notice Returns the specified `Attestation`.
*/
function getAttestation(uint256 attestationId) external view returns (Attestation calldata);
function getAttestation(uint64 attestationId) external view returns (Attestation calldata);

/**
* @notice Returns the specified `OffchainAttestation`.
Expand Down Expand Up @@ -382,13 +386,13 @@ interface ISP is IVersionable {
/**
* @notice Returns the hash that will be used to authorize a delegated revocation.
*/
function getDelegatedRevokeHash(uint256 attestationId, string memory reason) external pure returns (bytes32);
function getDelegatedRevokeHash(uint64 attestationId, string memory reason) external pure returns (bytes32);

/**
* @notice Returns the hash that will be used to authorize a delegated batch revocation.
*/
function getDelegatedRevokeBatchHash(
uint256[] memory attestationIds,
uint64[] memory attestationIds,
string[] memory reasons
)
external
Expand Down Expand Up @@ -420,10 +424,10 @@ interface ISP is IVersionable {
/**
* @notice Returns the current schema counter. This is incremented for each `Schema` registered.
*/
function schemaCounter() external view returns (uint256);
function schemaCounter() external view returns (uint64);

/**
* @notice Returns the current on-chain attestation counter. This is incremented for each `Attestation` made.
*/
function attestationCounter() external view returns (uint256);
function attestationCounter() external view returns (uint64);
}
16 changes: 8 additions & 8 deletions src/interfaces/ISPHook.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,17 @@ import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
interface ISPHook {
function didReceiveAttestation(
address attester,
uint256 schemaId,
uint256 attestationId,
uint64 schemaId,
uint64 attestationId,
bytes calldata extraData
)
external
payable;

function didReceiveAttestation(
address attester,
uint256 schemaId,
uint256 attestationId,
uint64 schemaId,
uint64 attestationId,
IERC20 resolverFeeERC20Token,
uint256 resolverFeeERC20Amount,
bytes calldata extraData
Expand All @@ -29,17 +29,17 @@ interface ISPHook {

function didReceiveRevocation(
address attester,
uint256 schemaId,
uint256 attestationId,
uint64 schemaId,
uint64 attestationId,
bytes calldata extraData
)
external
payable;

function didReceiveRevocation(
address attester,
uint256 schemaId,
uint256 attestationId,
uint64 schemaId,
uint64 attestationId,
IERC20 resolverFeeERC20Token,
uint256 resolverFeeERC20Amount,
bytes calldata extraData
Expand Down
38 changes: 19 additions & 19 deletions src/mock/MockResolver.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@ import { OwnableUpgradeable } from "@openzeppelin/contracts-upgradeable/access/O
contract MockResolverAdmin is OwnableUpgradeable {
using SafeERC20 for IERC20;

mapping(uint256 schemaId => uint256 ethFees) public schemaAttestETHFees;
mapping(uint256 schemaId => mapping(IERC20 tokenAddress => uint256 tokenFees)) public schemaAttestTokenFees;
mapping(uint256 attestationId => uint256 ethFees) public attestationETHFees;
mapping(uint256 attestationId => mapping(IERC20 tokenAddress => uint256 tokenFees)) public attestationTokenFees;
mapping(uint64 schemaId => uint256 ethFees) public schemaAttestETHFees;
mapping(uint64 schemaId => mapping(IERC20 tokenAddress => uint256 tokenFees)) public schemaAttestTokenFees;
mapping(uint64 attestationId => uint256 ethFees) public attestationETHFees;
mapping(uint64 attestationId => mapping(IERC20 tokenAddress => uint256 tokenFees)) public attestationTokenFees;
mapping(IERC20 tokenAddress => bool approved) public approvedTokens;

event ETHFeesReceived(uint256 attestationId, uint256 amount);
event TokenFeesReceived(uint256 attestationId, IERC20 token, uint256 amount);
event ETHFeesReceived(uint64 attestationId, uint256 amount);
event TokenFeesReceived(uint64 attestationId, IERC20 token, uint256 amount);

error MismatchETHFee();
error InsufficientETHFee();
Expand All @@ -26,19 +26,19 @@ contract MockResolverAdmin is OwnableUpgradeable {
__Ownable_init(_msgSender());
}

function setSchemaAttestETHFees(uint256 schemaId, uint256 fees) external onlyOwner {
function setSchemaAttestETHFees(uint64 schemaId, uint256 fees) external onlyOwner {
schemaAttestETHFees[schemaId] = fees;
}

function setSchemaAttestTokenFees(uint256 schemaId, IERC20 token, uint256 fees) external onlyOwner {
function setSchemaAttestTokenFees(uint64 schemaId, IERC20 token, uint256 fees) external onlyOwner {
schemaAttestTokenFees[schemaId][token] = fees;
}

function setFeeTokenApprovalStatus(IERC20 token, bool approved) external onlyOwner {
approvedTokens[token] = approved;
}

function _receiveEther(address attester, uint256 schemaId, uint256 attestationId) internal {
function _receiveEther(address attester, uint64 schemaId, uint64 attestationId) internal {
uint256 fees =
schemaAttestETHFees[schemaId] == 0 ? attestationETHFees[attestationId] : schemaAttestETHFees[schemaId];
if (msg.value != fees) revert InsufficientETHFee();
Expand All @@ -48,8 +48,8 @@ contract MockResolverAdmin is OwnableUpgradeable {

function _receiveTokens(
address attester,
uint256 schemaId,
uint256 attestationId,
uint64 schemaId,
uint64 attestationId,
IERC20 resolverFeeERC20Token,
uint256 resolverFeeERC20Amount
)
Expand All @@ -68,8 +68,8 @@ contract MockResolverAdmin is OwnableUpgradeable {
contract MockResolver is ISPHook, MockResolverAdmin {
function didReceiveAttestation(
address attester,
uint256 schemaId,
uint256 attestationId,
uint64 schemaId,
uint64 attestationId,
bytes calldata
)
external
Expand All @@ -80,8 +80,8 @@ contract MockResolver is ISPHook, MockResolverAdmin {

function didReceiveAttestation(
address attester,
uint256 schemaId,
uint256 attestationId,
uint64 schemaId,
uint64 attestationId,
IERC20 resolverFeeERC20Token,
uint256 resolverFeeERC20Amount,
bytes calldata
Expand All @@ -94,8 +94,8 @@ contract MockResolver is ISPHook, MockResolverAdmin {

function didReceiveRevocation(
address attester,
uint256 schemaId,
uint256 attestationId,
uint64 schemaId,
uint64 attestationId,
bytes calldata
)
external
Expand All @@ -107,8 +107,8 @@ contract MockResolver is ISPHook, MockResolverAdmin {

function didReceiveRevocation(
address attester,
uint256 schemaId,
uint256 attestationId,
uint64 schemaId,
uint64 attestationId,
IERC20 resolverFeeERC20Token,
uint256 resolverFeeERC20Amount,
bytes calldata
Expand Down
8 changes: 5 additions & 3 deletions src/models/Attestation.sol
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,13 @@ import { DataLocation } from "./DataLocation.sol";
* to use `abi.encode`.
*/
struct Attestation {
uint256 schemaId;
DataLocation dataLocation;
uint256 linkedAttestationId;
uint64 schemaId;
uint64 linkedAttestationId;
uint64 attestTimestamp;
uint64 revokeTimestamp;
address attester;
uint64 validUntil;
DataLocation dataLocation;
bool revoked;
bytes[] recipients;
bytes data;
Expand Down
1 change: 1 addition & 0 deletions src/models/Schema.sol
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,6 @@ struct Schema {
DataLocation dataLocation;
uint64 maxValidFor;
ISPHook hook;
uint64 timestamp;
string data;
}
Loading

0 comments on commit c91ce5c

Please sign in to comment.