Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

simplify inheritance graph by using RegistrationLib #14

Merged
merged 1 commit into from
Nov 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified images/TheCompact-Inheritance-Graph.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 4 additions & 7 deletions src/lib/ClaimProcessorLogic.sol
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,11 @@ import { EfficiencyLib } from "./EfficiencyLib.sol";
import { FunctionCastLib } from "./FunctionCastLib.sol";
import { HashLib } from "./HashLib.sol";
import { IdLib } from "./IdLib.sol";
import { RegistrationLogic } from "./RegistrationLogic.sol";
import { RegistrationLib } from "./RegistrationLib.sol";
import { ValidityLib } from "./ValidityLib.sol";
import { SharedLogic } from "./SharedLogic.sol";

contract ClaimProcessorLogic is SharedLogic, RegistrationLogic {
contract ClaimProcessorLogic is SharedLogic {
using HashLib for address;
using HashLib for bytes32;
using HashLib for uint256;
Expand Down Expand Up @@ -116,6 +116,7 @@ contract ClaimProcessorLogic is SharedLogic, RegistrationLogic {
using EfficiencyLib for bool;
using EfficiencyLib for bytes32;
using EfficiencyLib for uint256;
using RegistrationLib for address;
using ValidityLib for uint96;
using ValidityLib for uint256;
using ValidityLib for bytes32;
Expand Down Expand Up @@ -527,7 +528,7 @@ contract ClaimProcessorLogic is SharedLogic, RegistrationLogic {
sponsorDomainSeparator := add(sponsorDomainSeparator, mul(iszero(sponsorDomainSeparator), domainSeparator))
}

if ((sponsorDomainSeparator != domainSeparator).or(sponsorSignature.length != 0) || _hasNoActiveRegistration(sponsor, messageHash, typehash)) {
if ((sponsorDomainSeparator != domainSeparator).or(sponsorSignature.length != 0) || sponsor.hasNoActiveRegistration(messageHash, typehash)) {
messageHash.signedBy(sponsor, sponsorSignature, sponsorDomainSeparator);
}
qualificationMessageHash.signedBy(allocator, allocatorSignature, domainSeparator);
Expand Down Expand Up @@ -878,10 +879,6 @@ contract ClaimProcessorLogic is SharedLogic, RegistrationLogic {
return true;
}

function _hasNoActiveRegistration(address sponsor, bytes32 claimHash, bytes32 typehash) private view returns (bool) {
return _getRegistrationStatus(sponsor, claimHash, typehash) <= block.timestamp;
}

function _ensureValidScope(bytes32 sponsorDomainSeparator, uint256 id) private pure {
assembly ("memory-safe") {
if iszero(or(iszero(sponsorDomainSeparator), iszero(shr(255, id)))) {
Expand Down
9 changes: 5 additions & 4 deletions src/lib/DepositViaPermit2Logic.sol
Original file line number Diff line number Diff line change
Expand Up @@ -43,20 +43,21 @@ import { ResetPeriod } from "../types/ResetPeriod.sol";
import { Scope } from "../types/Scope.sol";

import { DepositLogic } from "./DepositLogic.sol";
import { RegistrationLogic } from "./RegistrationLogic.sol";
import { RegistrationLib } from "./RegistrationLib.sol";
import { EfficiencyLib } from "./EfficiencyLib.sol";
import { IdLib } from "./IdLib.sol";
import { ValidityLib } from "./ValidityLib.sol";

import { SafeTransferLib } from "solady/utils/SafeTransferLib.sol";
import { ISignatureTransfer } from "permit2/src/interfaces/ISignatureTransfer.sol";

contract DepositViaPermit2Logic is DepositLogic, RegistrationLogic {
contract DepositViaPermit2Logic is DepositLogic {
using IdLib for uint256;
using IdLib for address;
using IdLib for ResetPeriod;
using EfficiencyLib for bool;
using EfficiencyLib for uint256;
using RegistrationLib for address;
using ValidityLib for address;
using SafeTransferLib for address;

Expand Down Expand Up @@ -109,7 +110,7 @@ contract DepositViaPermit2Logic is DepositLogic, RegistrationLogic {

_checkBalanceAndDeposit(token, depositor, id, initialBalance);

_register(depositor, claimHash, compactTypehash, resetPeriod.toSeconds());
depositor.registerCompact(claimHash, compactTypehash, resetPeriod);

_clearReentrancyGuard();

Expand Down Expand Up @@ -175,7 +176,7 @@ contract DepositViaPermit2Logic is DepositLogic, RegistrationLogic {

_verifyBalancesAndPerformDeposits(ids, permitted, initialTokenBalances, depositor, firstUnderlyingTokenIsNative);

_register(depositor, claimHash, compactTypehash, resetPeriod.toSeconds());
depositor.registerCompact(claimHash, compactTypehash, resetPeriod);

return ids;
}
Expand Down
77 changes: 77 additions & 0 deletions src/lib/RegistrationLib.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.27;

import { ResetPeriod } from "../types/ResetPeriod.sol";

import { EfficiencyLib } from "./EfficiencyLib.sol";
import { IdLib } from "./IdLib.sol";

library RegistrationLib {
using RegistrationLib for address;
using EfficiencyLib for uint256;
using IdLib for ResetPeriod;

/// @dev `keccak256(bytes("CompactRegistered(address,bytes32,bytes32,uint256)"))`.
uint256 private constant _COMPACT_REGISTERED_SIGNATURE = 0xf78a2f33ff80ef4391f7449c748dc2d577a62cd645108f4f4069f4a7e0635b6a;

// slot: keccak256(_ACTIVE_REGISTRATIONS_SCOPE ++ sponsor ++ claimHash ++ typehash) => expires
uint256 private constant _ACTIVE_REGISTRATIONS_SCOPE = 0x68a30dd0;

function registerCompactWithSpecificDuration(address sponsor, bytes32 claimHash, bytes32 typehash, uint256 duration) internal {
assembly ("memory-safe") {
let m := mload(0x40)
mstore(add(m, 0x14), sponsor)
mstore(m, _ACTIVE_REGISTRATIONS_SCOPE)
mstore(add(m, 0x34), claimHash)
mstore(add(m, 0x54), typehash)
let cutoffSlot := keccak256(add(m, 0x1c), 0x58)

let expires := add(timestamp(), duration)
if or(lt(expires, sload(cutoffSlot)), gt(duration, 0x278d00)) {
// revert InvalidRegistrationDuration(uint256 duration)
mstore(0, 0x1f9a96f4)
mstore(0x20, duration)
revert(0x1c, 0x24)
}

sstore(cutoffSlot, expires)
mstore(add(m, 0x74), expires)
log2(add(m, 0x34), 0x60, _COMPACT_REGISTERED_SIGNATURE, shr(0x60, shl(0x60, sponsor)))
}
}

function registerCompact(address sponsor, bytes32 claimHash, bytes32 typehash, ResetPeriod duration) internal {
sponsor.registerCompactWithSpecificDuration(claimHash, typehash, duration.toSeconds());
}

function registerAsCallerWithDefaultDuration(bytes32 claimHash, bytes32 typehash) internal {
msg.sender.registerCompactWithSpecificDuration(claimHash, typehash, uint256(0x258).asStubborn());
}

function registerBatchAsCaller(bytes32[2][] calldata claimHashesAndTypehashes, uint256 duration) internal returns (bool) {
unchecked {
uint256 totalClaimHashes = claimHashesAndTypehashes.length;
for (uint256 i = 0; i < totalClaimHashes; ++i) {
bytes32[2] calldata claimHashAndTypehash = claimHashesAndTypehashes[i];
msg.sender.registerCompactWithSpecificDuration(claimHashAndTypehash[0], claimHashAndTypehash[1], duration);
}
}

return true;
}

function toRegistrationExpiration(address sponsor, bytes32 claimHash, bytes32 typehash) internal view returns (uint256 expires) {
assembly ("memory-safe") {
let m := mload(0x40)
mstore(add(m, 0x14), sponsor)
mstore(m, _ACTIVE_REGISTRATIONS_SCOPE)
mstore(add(m, 0x34), claimHash)
mstore(add(m, 0x54), typehash)
expires := sload(keccak256(add(m, 0x1c), 0x58))
}
}

function hasNoActiveRegistration(address sponsor, bytes32 claimHash, bytes32 typehash) internal view returns (bool) {
return sponsor.toRegistrationExpiration(claimHash, typehash) <= block.timestamp;
}
}
54 changes: 8 additions & 46 deletions src/lib/RegistrationLogic.sol
Original file line number Diff line number Diff line change
@@ -1,64 +1,26 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.27;

import { EfficiencyLib } from "./EfficiencyLib.sol";
import { RegistrationLib } from "./RegistrationLib.sol";

contract RegistrationLogic {
using EfficiencyLib for uint256;

/// @dev `keccak256(bytes("CompactRegistered(address,bytes32,bytes32,uint256)"))`.
uint256 private constant _COMPACT_REGISTERED_SIGNATURE = 0xf78a2f33ff80ef4391f7449c748dc2d577a62cd645108f4f4069f4a7e0635b6a;

// slot: keccak256(_ACTIVE_REGISTRATIONS_SCOPE ++ sponsor ++ claimHash ++ typehash) => expires
uint256 private constant _ACTIVE_REGISTRATIONS_SCOPE = 0x68a30dd0;
using RegistrationLib for address;
using RegistrationLib for bytes32;
using RegistrationLib for bytes32[2][];

function _register(address sponsor, bytes32 claimHash, bytes32 typehash, uint256 duration) internal {
assembly ("memory-safe") {
let m := mload(0x40)
mstore(add(m, 0x14), sponsor)
mstore(m, _ACTIVE_REGISTRATIONS_SCOPE)
mstore(add(m, 0x34), claimHash)
mstore(add(m, 0x54), typehash)
let cutoffSlot := keccak256(add(m, 0x1c), 0x58)

let expires := add(timestamp(), duration)
if or(lt(expires, sload(cutoffSlot)), gt(duration, 0x278d00)) {
// revert InvalidRegistrationDuration(uint256 duration)
mstore(0, 0x1f9a96f4)
mstore(0x20, duration)
revert(0x1c, 0x24)
}

sstore(cutoffSlot, expires)
mstore(add(m, 0x74), expires)
log2(add(m, 0x34), 0x60, _COMPACT_REGISTERED_SIGNATURE, shr(0x60, shl(0x60, sponsor)))
}
sponsor.registerCompactWithSpecificDuration(claimHash, typehash, duration);
}

function _registerWithDefaults(bytes32 claimHash, bytes32 typehash) internal {
_register(msg.sender, claimHash, typehash, uint256(0x258).asStubborn());
claimHash.registerAsCallerWithDefaultDuration(typehash);
}

function _registerBatch(bytes32[2][] calldata claimHashesAndTypehashes, uint256 duration) internal returns (bool) {
unchecked {
uint256 totalClaimHashes = claimHashesAndTypehashes.length;
for (uint256 i = 0; i < totalClaimHashes; ++i) {
bytes32[2] calldata claimHashAndTypehash = claimHashesAndTypehashes[i];
_register(msg.sender, claimHashAndTypehash[0], claimHashAndTypehash[1], duration);
}
}

return true;
return claimHashesAndTypehashes.registerBatchAsCaller(duration);
}

function _getRegistrationStatus(address sponsor, bytes32 claimHash, bytes32 typehash) internal view returns (uint256 expires) {
assembly ("memory-safe") {
let m := mload(0x40)
mstore(add(m, 0x14), sponsor)
mstore(m, _ACTIVE_REGISTRATIONS_SCOPE)
mstore(add(m, 0x34), claimHash)
mstore(add(m, 0x54), typehash)
expires := sload(keccak256(add(m, 0x1c), 0x58))
}
return sponsor.toRegistrationExpiration(claimHash, typehash);
}
}
3 changes: 2 additions & 1 deletion src/lib/TheCompactLogic.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ import { ClaimProcessor } from "./ClaimProcessor.sol";
import { DepositViaPermit2Logic } from "./DepositViaPermit2Logic.sol";
import { DirectDepositLogic } from "./DirectDepositLogic.sol";
import { Extsload } from "./Extsload.sol";
import { RegistrationLogic } from "./RegistrationLogic.sol";
import { TransferLogic } from "./TransferLogic.sol";
import { WithdrawalLogic } from "./WithdrawalLogic.sol";

contract TheCompactLogic is AllocatorLogic, ClaimProcessor, DepositViaPermit2Logic, DirectDepositLogic, Extsload, TransferLogic, WithdrawalLogic { }
contract TheCompactLogic is AllocatorLogic, ClaimProcessor, DepositViaPermit2Logic, DirectDepositLogic, Extsload, RegistrationLogic, TransferLogic, WithdrawalLogic { }